diff --git a/test/__snapshots__/implementation-option.test.js.snap b/test/__snapshots__/implementation-option.test.js.snap index a7b29a27..97fc08b4 100644 --- a/test/__snapshots__/implementation-option.test.js.snap +++ b/test/__snapshots__/implementation-option.test.js.snap @@ -40,6 +40,10 @@ exports[`implementation option not specify with modern API: errors 1`] = `[]`; exports[`implementation option not specify with modern API: warnings 1`] = `[]`; +exports[`implementation option not specify with modern-compiler API: errors 1`] = `[]`; + +exports[`implementation option not specify with modern-compiler API: warnings 1`] = `[]`; + exports[`implementation option not specify: errors 1`] = `[]`; exports[`implementation option not specify: warnings 1`] = `[]`; @@ -53,6 +57,14 @@ Some error", exports[`implementation option should not swallow an error when trying to load a sass implementation: warnings 1`] = `[]`; +exports[`implementation option should support switching the implementation within the same process when using the modern-compiler API: errors 1`] = `[]`; + +exports[`implementation option should support switching the implementation within the same process when using the modern-compiler API: errors 2`] = `[]`; + +exports[`implementation option should support switching the implementation within the same process when using the modern-compiler API: warnings 1`] = `[]`; + +exports[`implementation option should support switching the implementation within the same process when using the modern-compiler API: warnings 2`] = `[]`; + exports[`implementation option should throw an error on an unknown sass implementation: errors 1`] = ` [ "ModuleBuildError: Module build failed (from ../src/cjs.js): diff --git a/test/helpers/getImplementationByName.js b/test/helpers/getImplementationByName.js index 50a60583..01926a24 100644 --- a/test/helpers/getImplementationByName.js +++ b/test/helpers/getImplementationByName.js @@ -5,6 +5,9 @@ function getImplementationByName(implementationName) { } else if (implementationName === "dart-sass") { // eslint-disable-next-line global-require return require("sass"); + } else if (implementationName === "sass-embedded") { + // eslint-disable-next-line global-require + return require("sass-embedded"); } else if (implementationName === "sass_string") { return require.resolve("sass"); } diff --git a/test/implementation-option.test.js b/test/implementation-option.test.js index f6ab17a3..4c3734fb 100644 --- a/test/implementation-option.test.js +++ b/test/implementation-option.test.js @@ -31,17 +31,34 @@ const spyOnCompiler = (implementation) => { return compiler; }); - const mockRestore = () => initSpy.mockRestore(); - const spies = { initSpy, - mockRestore, + mockClear() { + if (this.compileStringSpy) { + this.compileStringSpy.mockClear(); + } + }, + mockRestore() { + initSpy.mockRestore(); + delete this.compileStringSpy; + }, }; return spies; }; describe("implementation option", () => { + const nodeSassSpy = jest.spyOn(nodeSass, "render"); + const dartSassSpy = jest.spyOn(dartSass, "render"); + const dartSassSpyModernAPI = jest.spyOn(dartSass, "compileStringAsync"); + const dartSassCompilerSpies = spyOnCompiler(dartSass); + const sassEmbeddedSpy = jest.spyOn(sassEmbedded, "render"); + const sassEmbeddedSpyModernAPI = jest.spyOn( + sassEmbedded, + "compileStringAsync", + ); + const sassEmbeddedCompilerSpies = spyOnCompiler(sassEmbedded); + implementations.forEach((item) => { let implementationName; let implementation; @@ -56,17 +73,6 @@ describe("implementation option", () => { } it(`'${implementationName}', '${api}' API`, async () => { - const nodeSassSpy = jest.spyOn(nodeSass, "render"); - const dartSassSpy = jest.spyOn(dartSass, "render"); - const dartSassSpyModernAPI = jest.spyOn(dartSass, "compileStringAsync"); - const dartSassCompilerSpies = spyOnCompiler(dartSass); - const sassEmbeddedSpy = jest.spyOn(sassEmbedded, "render"); - const sassEmbeddedSpyModernAPI = jest.spyOn( - sassEmbedded, - "compileStringAsync", - ); - const sassEmbeddedCompilerSpies = spyOnCompiler(sassEmbedded); - const testId = getTestId("language", "scss"); const options = { api, implementation }; const compiler = getCompiler(testId, { loader: { options } }); @@ -83,10 +89,8 @@ describe("implementation option", () => { expect(nodeSassSpy).toHaveBeenCalledTimes(1); expect(dartSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpyModernAPI).toHaveBeenCalledTimes(0); - expect(dartSassCompilerSpies.initSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpyModernAPI).toHaveBeenCalledTimes(0); - expect(sassEmbeddedCompilerSpies.initSpy).toHaveBeenCalledTimes(0); } else if ( implementationName === "dart-sass" || implementationName === "dart-sass_string" @@ -95,47 +99,37 @@ describe("implementation option", () => { expect(nodeSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpyModernAPI).toHaveBeenCalledTimes(1); - expect(dartSassCompilerSpies.initSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpyModernAPI).toHaveBeenCalledTimes(0); - expect(sassEmbeddedCompilerSpies.initSpy).toHaveBeenCalledTimes(0); } else if (api === "modern-compiler") { expect(nodeSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpyModernAPI).toHaveBeenCalledTimes(0); - expect(dartSassCompilerSpies.initSpy).toHaveBeenCalledTimes(1); expect(dartSassCompilerSpies.compileStringSpy).toHaveBeenCalledTimes( 1, ); expect(sassEmbeddedSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpyModernAPI).toHaveBeenCalledTimes(0); - expect(sassEmbeddedCompilerSpies.initSpy).toHaveBeenCalledTimes(0); } else if (api === "legacy") { expect(nodeSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpy).toHaveBeenCalledTimes(1); expect(dartSassSpyModernAPI).toHaveBeenCalledTimes(0); - expect(dartSassCompilerSpies.initSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpyModernAPI).toHaveBeenCalledTimes(0); - expect(sassEmbeddedCompilerSpies.initSpy).toHaveBeenCalledTimes(0); } } else if (implementationName === "sass-embedded") { if (api === "modern") { expect(nodeSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpyModernAPI).toHaveBeenCalledTimes(0); - expect(dartSassCompilerSpies.initSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpyModernAPI).toHaveBeenCalledTimes(1); - expect(sassEmbeddedCompilerSpies.initSpy).toHaveBeenCalledTimes(0); } else if (api === "modern-compiler") { expect(nodeSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpyModernAPI).toHaveBeenCalledTimes(0); - expect(dartSassCompilerSpies.initSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpyModernAPI).toHaveBeenCalledTimes(0); - expect(sassEmbeddedCompilerSpies.initSpy).toHaveBeenCalledTimes(1); expect( sassEmbeddedCompilerSpies.compileStringSpy, ).toHaveBeenCalledTimes(1); @@ -143,20 +137,18 @@ describe("implementation option", () => { expect(nodeSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpyModernAPI).toHaveBeenCalledTimes(0); - expect(dartSassCompilerSpies.initSpy).toHaveBeenCalledTimes(0); expect(sassEmbeddedSpy).toHaveBeenCalledTimes(1); expect(sassEmbeddedSpyModernAPI).toHaveBeenCalledTimes(0); - expect(sassEmbeddedCompilerSpies.initSpy).toHaveBeenCalledTimes(0); } } - nodeSassSpy.mockRestore(); - dartSassSpy.mockRestore(); - dartSassSpyModernAPI.mockRestore(); - dartSassCompilerSpies.mockRestore(); - sassEmbeddedSpy.mockRestore(); - sassEmbeddedSpyModernAPI.mockRestore(); - sassEmbeddedCompilerSpies.mockRestore(); + nodeSassSpy.mockClear(); + dartSassSpy.mockClear(); + dartSassSpyModernAPI.mockClear(); + dartSassCompilerSpies.mockClear(); + sassEmbeddedSpy.mockClear(); + sassEmbeddedSpyModernAPI.mockClear(); + sassEmbeddedCompilerSpies.mockClear(); }); }); @@ -173,9 +165,6 @@ describe("implementation option", () => { }); it("not specify", async () => { - const nodeSassSpy = jest.spyOn(nodeSass, "render"); - const dartSassSpy = jest.spyOn(dartSass, "render"); - const testId = getTestId("language", "scss"); const options = {}; const compiler = getCompiler(testId, { loader: { options } }); @@ -191,14 +180,11 @@ describe("implementation option", () => { expect(nodeSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpy).toHaveBeenCalledTimes(1); - nodeSassSpy.mockRestore(); - dartSassSpy.mockRestore(); + nodeSassSpy.mockClear(); + dartSassSpy.mockClear(); }); it("not specify with legacy API", async () => { - const nodeSassSpy = jest.spyOn(nodeSass, "render"); - const dartSassSpy = jest.spyOn(dartSass, "render"); - const testId = getTestId("language", "scss"); const options = { api: "legacy", @@ -216,14 +202,11 @@ describe("implementation option", () => { expect(nodeSassSpy).toHaveBeenCalledTimes(0); expect(dartSassSpy).toHaveBeenCalledTimes(1); - nodeSassSpy.mockRestore(); - dartSassSpy.mockRestore(); + nodeSassSpy.mockClear(); + dartSassSpy.mockClear(); }); it("not specify with modern API", async () => { - const nodeSassSpy = jest.spyOn(nodeSass, "render"); - const dartSassSpy = jest.spyOn(dartSass, "compileStringAsync"); - const testId = getTestId("language", "scss"); const options = { api: "modern", @@ -239,17 +222,13 @@ describe("implementation option", () => { expect(getErrors(stats)).toMatchSnapshot("errors"); expect(nodeSassSpy).toHaveBeenCalledTimes(0); - expect(dartSassSpy).toHaveBeenCalledTimes(1); + expect(dartSassSpyModernAPI).toHaveBeenCalledTimes(1); - nodeSassSpy.mockRestore(); - dartSassSpy.mockRestore(); + nodeSassSpy.mockClear(); + dartSassSpyModernAPI.mockClear(); }); - it.skip("not specify with modern-compiler API", async () => { - const nodeSassSpy = jest.spyOn(nodeSass, "render"); - const dartSassSpy = jest.spyOn(dartSass, "compileStringAsync"); - const dartSassCompilerSpies = spyOnCompiler(dartSass); - + it("not specify with modern-compiler API", async () => { const testId = getTestId("language", "scss"); const options = { api: "modern-compiler", @@ -265,17 +244,44 @@ describe("implementation option", () => { expect(getErrors(stats)).toMatchSnapshot("errors"); expect(nodeSassSpy).toHaveBeenCalledTimes(0); - expect(dartSassSpy).toHaveBeenCalledTimes(0); - // TODO: this isn't being called because the compiler is already initialized - // from a previous test. - expect(dartSassCompilerSpies.initSpy).toHaveBeenCalledTimes(1); + expect(dartSassSpyModernAPI).toHaveBeenCalledTimes(0); expect(dartSassCompilerSpies.compileStringSpy).toHaveBeenCalledTimes(1); - nodeSassSpy.mockRestore(); - dartSassSpy.mockRestore(); - dartSassCompilerSpies.mockRestore(); + nodeSassSpy.mockClear(); + dartSassSpyModernAPI.mockClear(); + dartSassCompilerSpies.mockClear(); }); + it.each(["dart-sass", "sass-embedded"])( + "should support switching the implementation within the same process when using the modern-compiler API", + async (implementationName) => { + const testId = getTestId("language", "scss"); + const options = { + api: "modern-compiler", + implementation: getImplementationByName(implementationName), + }; + const compiler = getCompiler(testId, { loader: { options } }); + const stats = await compile(compiler); + const { css, sourceMap } = getCodeFromBundle(stats, compiler); + + expect(css).toBeDefined(); + expect(sourceMap).toBeUndefined(); + + expect(getWarnings(stats)).toMatchSnapshot("warnings"); + expect(getErrors(stats)).toMatchSnapshot("errors"); + + expect(dartSassCompilerSpies.compileStringSpy).toHaveBeenCalledTimes( + implementationName === "dart-sass" ? 1 : 0, + ); + expect(sassEmbeddedCompilerSpies.compileStringSpy).toHaveBeenCalledTimes( + implementationName === "sass-embedded" ? 1 : 0, + ); + + dartSassCompilerSpies.mockClear(); + sassEmbeddedCompilerSpies.mockClear(); + }, + ); + it("should throw an error on an unknown sass implementation", async () => { const testId = getTestId("language", "scss"); const options = {