Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Shared Resources] Add JS API tests #1954

Merged
merged 24 commits into from
Jan 18, 2024
Merged

Conversation

jerivas
Copy link
Contributor

@jerivas jerivas commented Nov 14, 2023

@jerivas
Copy link
Contributor Author

jerivas commented Nov 14, 2023

Copy link
Contributor Author

@jerivas jerivas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some basic tests to verify the behavior described in the proposal. I think we should also run all the tests from compile.node.test.ts and compile.test.ts. What do you think of parametrizing these tests to accept both the standalone compile* functions as well as the compiler methods?

js-api-spec/compiler.test.ts Outdated Show resolved Hide resolved
@jerivas jerivas marked this pull request as ready for review November 15, 2023 19:09
@jerivas jerivas requested a review from nex3 November 15, 2023 19:10
Copy link
Contributor

@jgerigmeyer jgerigmeyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor

@nex3 nex3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, thinking about this more, it's probably a good idea to verify that the async compiler in particular gracefully handles multiple concurrent compilations, especially when those compilations are "chatty" (calling custom functions, importers, and loggers). Probably just one integration test case is sufficient as long as it handles a large number of chatty compilations at once and verifies that the right compilation calls get the right events.

Edit: I suppose we should also verify that at least two concurrent compilations work for the sync compiler, since it's theoretically possible to start a second one in a callback from the first.

js-api-spec/compiler.test.ts Outdated Show resolved Hide resolved
Comment on lines +44 to +47
const result = compiler.compileString(
'@import "bar"; .fn {value: foo(baz)}',
{importers, functions, logger}
);
Copy link
Contributor Author

@jerivas jerivas Nov 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should also verify that at least two concurrent compilations work for the sync compiler, since it's theoretically possible to start a second one in a callback from the first.

I'm not sure I 100% understand the request, but this is my attempt to do it by using importers and functions similar to the async case

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to testing running multiple synchronous compilations at the same time. This means you'll need to start a second compilation within a callback for the first one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 7c17ae5

@jerivas jerivas requested a review from nex3 November 17, 2023 01:23
@jerivas jerivas force-pushed the feature.shared-resources branch from 3834597 to 286e7fa Compare November 27, 2023 23:49
export const getSlowImporter = (callback: () => void) => ({
canonicalize: async () => new URL('foo:bar'),
load: async () => {
await new Promise(resolve => setTimeout(resolve, 100));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than using a timeout when testing that concurrent systems wait for a given event, it's usually better to have a promise whose resolution you control explicitly so you can guarantee it won't finish until you want it to (and then you don't end up writing tests that take a lot longer than they need to because of delays). You can run await Promise(resolve => setTimeout(resolve, 0)) to force all outstanding non-time-based tasks to complete, then resolve the promise and verify that the behavior happens as expected.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved in 6dcdd38

export const getLogger = () => ({debug: spy(() => {})});

/* A slow importer that executes a callback after a delay */
export const getSlowImporter = (callback: () => void) => ({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declare functions as export function, and don't forget to include a return type.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved in 6dcdd38

@jamesnw jamesnw requested a review from nex3 December 12, 2023 17:44
canonicalize: () => new URL('foo:bar'),
load: () => ({
contents: compiler.compile(dir('input-nested.scss')).css,
syntax: 'scss' as const,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Rather than as const, I think it's cleaner to add a type declaration to the variable itself (const nestedImporter: Importer) so that it infers the correct types for all its components. Similarly for the top-level fields in compiler.test.ts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 0a14b6f.


describe('AsyncCompiler', () => {
let compiler: AsyncCompiler;
const runs = 1000; // Number of concurrent compilations to run
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declare this in the test where it's used

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved in 0a14b6f

@jamesnw jamesnw requested a review from nex3 December 14, 2023 15:19
Comment on lines 22 to 23
canonicalize: (url: string) => new URL(`u:${url}`),
load: (url: typeof URL) => ({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think now that importers itself is typed you don't need to type the parameters here (or in asyncImporters).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

expect(() => compiler.compileString('$a: b; c {d: $a}')).toThrowError();
});
});
it('errors if constructor invoked directly', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blank line before test case

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 76e676a

@nex3 nex3 merged commit f013971 into sass:main Jan 18, 2024
7 checks passed
@nex3 nex3 deleted the feature.shared-resources branch January 18, 2024 02:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants