diff --git a/src/index.js b/src/index.js index 71267aa2..baede74d 100644 --- a/src/index.js +++ b/src/index.js @@ -9,7 +9,7 @@ import { getSassOptions, getWebpackImporter, getRenderFunctionFromSassImplementation, - absolutifySourceMapSource, + normalizeSourceMap, } from './utils'; import SassError from './SassError'; @@ -66,33 +66,18 @@ function loader(content) { return; } + let map = result.map ? JSON.parse(result.map) : null; + // Modify source paths only for webpack, otherwise we do nothing - if (result.map && useSourceMap) { - // eslint-disable-next-line no-param-reassign - result.map = JSON.parse(result.map); - - // result.map.file is an optional property that provides the output filename. - // Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it. - // eslint-disable-next-line no-param-reassign - delete result.map.file; - - // eslint-disable-next-line no-param-reassign - result.sourceRoot = ''; - - // node-sass returns POSIX paths, that's why we need to transform them back to native paths. - // This fixes an error on windows where the source-map module cannot resolve the source maps. - // @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722 - // eslint-disable-next-line no-param-reassign - result.map.sources = result.map.sources.map((source) => - absolutifySourceMapSource(this.rootContext, source) - ); + if (map && useSourceMap) { + map = normalizeSourceMap(map, this.rootContext); } result.stats.includedFiles.forEach((includedFile) => { this.addDependency(path.normalize(includedFile)); }); - callback(null, result.css.toString(), result.map); + callback(null, result.css.toString(), map); }); } diff --git a/src/utils.js b/src/utils.js index d4b6ec09..8cde61e9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -159,7 +159,6 @@ function getSassOptions( // Pretty complicated... :( options.sourceMap = true; options.outFile = path.join(loaderContext.rootContext, 'style.css.map'); - // options.sourceMapRoot = process.cwd(); options.sourceMapContents = true; options.omitSourceMapUrl = true; options.sourceMapEmbed = false; @@ -507,15 +506,33 @@ function getURLType(source) { return ABSOLUTE_SCHEME.test(source) ? 'absolute' : 'path-relative'; } -function absolutifySourceMapSource(sourceRoot, source) { - const sourceType = getURLType(source); +function normalizeSourceMap(map, rootContext) { + const newMap = map; - // Do no touch `scheme-relative`, `path-absolute` and `absolute` types - if (sourceType === 'path-relative') { - return path.resolve(sourceRoot, path.normalize(source)); - } + // result.map.file is an optional property that provides the output filename. + // Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it. + // eslint-disable-next-line no-param-reassign + delete newMap.file; + + // eslint-disable-next-line no-param-reassign + newMap.sourceRoot = ''; + + // node-sass returns POSIX paths, that's why we need to transform them back to native paths. + // This fixes an error on windows where the source-map module cannot resolve the source maps. + // @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722 + // eslint-disable-next-line no-param-reassign + newMap.sources = newMap.sources.map((source) => { + const sourceType = getURLType(source); + + // Do no touch `scheme-relative`, `path-absolute` and `absolute` types + if (sourceType === 'path-relative') { + return path.resolve(rootContext, path.normalize(source)); + } + + return source; + }); - return source; + return newMap; } export { @@ -524,5 +541,5 @@ export { getWebpackResolver, getWebpackImporter, getRenderFunctionFromSassImplementation, - absolutifySourceMapSource, + normalizeSourceMap, }; diff --git a/test/__snapshots__/sourceMap-options.test.js.snap b/test/__snapshots__/sourceMap-options.test.js.snap index 8e96d575..c5d74be2 100644 --- a/test/__snapshots__/sourceMap-options.test.js.snap +++ b/test/__snapshots__/sourceMap-options.test.js.snap @@ -1,5 +1,479 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (dart-sass) (sass): css 1`] = ` +"@charset \\"UTF-8\\"; +body { + font: 100% Helvetica, sans-serif; + color: #333; +} + +nav ul { + margin: 0; + padding: 0; + list-style: none; +} +nav li { + display: inline-block; +} +nav a { + display: block; + padding: 6px 12px; + text-decoration: none; +} + +.box { + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + -ms-border-radius: 10px; + border-radius: 10px; +} + +.message, .warning, .error, .success { + border: 1px solid #ccc; + padding: 10px; + color: #333; +} + +.success { + border-color: green; +} + +.error { + border-color: red; +} + +.warning { + border-color: yellow; +} + +.foo:before { + content: \\"\\"; +} + +.bar:before { + content: \\"∑\\"; +}" +`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (dart-sass) (sass): errors 1`] = `Array []`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (dart-sass) (sass): source map 1`] = ` +Object { + "file": "style.css.map", + "mappings": ";AAMA;EACE;EACA,OALc;;;AAQd;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;;AAQJ;EALE,uBAMe;EALf,oBAKe;EAJf,mBAIe;EAHf,eAGe;;;AAEjB;EACE;EACA;EACA;;;AAEF;EAEE;;;AAEF;EAEE;;;AAEF;EAEE;;;AAGA;EACE,SAhDY;;;AAmDd;EACE,SCxDc", + "names": Array [], + "sourceRoot": "", + "sources": Array [ + "sass/language.sass", + "sass/another/variables.sass", + ], + "sourcesContent": Array [ + "@import \\"another/variables\\" + +$font-stack: Helvetica, sans-serif +$primary-color: #333 +$pi: '\\\\e0C6' + +body + font: 100% $font-stack + color: $primary-color + +nav + ul + margin: 0 + padding: 0 + list-style: none + + li + display: inline-block + + a + display: block + padding: 6px 12px + text-decoration: none + +=border-radius($radius) + -webkit-border-radius: $radius + -moz-border-radius: $radius + -ms-border-radius: $radius + border-radius: $radius + +.box + +border-radius(10px) + +.message + border: 1px solid #ccc + padding: 10px + color: #333 + +.success + @extend .message + border-color: green + +.error + @extend .message + border-color: red + +.warning + @extend .message + border-color: yellow + +.foo + &:before + content: $pi + +.bar + &:before + content: $n-ary-summation + +", + "$n-ary-summation: '\\\\2211' +", + ], + "version": 3, +} +`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (dart-sass) (sass): warnings 1`] = `Array []`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (dart-sass) (scss): css 1`] = ` +"@charset \\"UTF-8\\"; +body { + font: 100% Helvetica, sans-serif; + color: #333; +} + +nav ul { + margin: 0; + padding: 0; + list-style: none; +} +nav li { + display: inline-block; +} +nav a { + display: block; + padding: 6px 12px; + text-decoration: none; +} + +.box { + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + -ms-border-radius: 10px; + border-radius: 10px; +} + +.foo:before { + content: \\"\\"; +} + +.bar:before { + content: \\"∑\\"; +}" +`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (dart-sass) (scss): errors 1`] = `Array []`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (dart-sass) (scss): source map 1`] = ` +Object { + "file": "style.css.map", + "mappings": ";AAMA;EACE;EACA,OALc;;;AASd;EACE;EACA;EACA;;AAGF;EAAK;;AAEL;EACE;EACA;EACA;;;AAWJ;EANE,uBAM4B;EALzB,oBAKyB;EAJxB,mBAIwB;EAHpB,eAGoB;;;AAG5B;EACE,SAlCY;;;AAuCd;EACE,SC5Cc", + "names": Array [], + "sourceRoot": "", + "sources": Array [ + "scss/language.scss", + "scss/another/_variables.scss", + ], + "sourcesContent": Array [ + "@import \\"another/variables\\"; + +$font-stack: Helvetica, sans-serif; +$primary-color: #333; +$pi: '\\\\e0C6'; + +body { + font: 100% $font-stack; + color: $primary-color; +} + +nav { + ul { + margin: 0; + padding: 0; + list-style: none; + } + + li { display: inline-block; } + + a { + display: block; + padding: 6px 12px; + text-decoration: none; + } +} + +@mixin border-radius($radius) { + -webkit-border-radius: $radius; + -moz-border-radius: $radius; + -ms-border-radius: $radius; + border-radius: $radius; +} + +.box { @include border-radius(10px); } + +.foo { + &:before { + content: $pi; + } +} + +.bar { + &:before { + content: $n-ary-summation; + } +} +", + "$n-ary-summation: '\\\\2211' +", + ], + "version": 3, +} +`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (dart-sass) (scss): warnings 1`] = `Array []`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (node-sass) (sass): css 1`] = ` +"@charset \\"UTF-8\\"; +body { + font: 100% Helvetica, sans-serif; + color: #333; } + +nav ul { + margin: 0; + padding: 0; + list-style: none; } + +nav li { + display: inline-block; } + +nav a { + display: block; + padding: 6px 12px; + text-decoration: none; } + +.box { + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + -ms-border-radius: 10px; + border-radius: 10px; } + +.message, .success, .error, .warning { + border: 1px solid #ccc; + padding: 10px; + color: #333; } + +.success { + border-color: green; } + +.error { + border-color: red; } + +.warning { + border-color: yellow; } + +.foo:before { + content: \\"\\"; } + +.bar:before { + content: \\"∑\\"; } +" +`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (node-sass) (sass): errors 1`] = `Array []`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (node-sass) (sass): source map 1`] = ` +Object { + "file": "style.css.map", + "mappings": ";AAMA,AAAA,IAAI,CAAC;EACH,IAAI,EAAE,IAAI,CALI,SAAS,EAAE,UAAU;EAMnC,KAAK,EALS,IAAI,GAKM;;AAE1B,AACE,GADC,CACD,EAAE,CAAC;EACD,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,IAAI,GAAG;;AAJvB,AAME,GANC,CAMD,EAAE,CAAC;EACD,OAAO,EAAE,YAAY,GAAG;;AAP5B,AASE,GATC,CASD,CAAC,CAAC;EACA,OAAO,EAAE,KAAK;EACd,OAAO,EAAE,QAAQ;EACjB,eAAe,EAAE,IAAI,GAAG;;AAQ5B,AAAA,IAAI,CAAC;EALH,qBAAqB,EAME,IAAI;EAL3B,kBAAkB,EAKK,IAAI;EAJ3B,iBAAiB,EAIM,IAAI;EAH3B,aAAa,EAGU,IAAI,GAAI;;AAEjC,AAAA,QAAQ,EAKR,QAAQ,EAIR,MAAM,EAIN,QAAQ,CAbC;EACP,MAAM,EAAE,cAAc;EACtB,OAAO,EAAE,IAAI;EACb,KAAK,EAAE,IAAI,GAAG;;AAEhB,AAAA,QAAQ,CAAC;EAEP,YAAY,EAAE,KAAK,GAAG;;AAExB,AAAA,MAAM,CAAC;EAEL,YAAY,EAAE,GAAG,GAAG;;AAEtB,AAAA,QAAQ,CAAC;EAEP,YAAY,EAAE,MAAM,GAAG;;AAEzB,AACE,IADE,AACD,OAAO,CAAC;EACP,OAAO,EAhDK,IAAO,GAgDJ;;AAEnB,AACE,IADE,AACD,OAAO,CAAC;EACP,OAAO,ECxDO,IAAO,GDwDO", + "names": Array [], + "sourceRoot": "", + "sources": Array [ + "sass/language.sass", + "sass/another/variables.sass", + ], + "sourcesContent": Array [ + "@import \\"another/variables\\"; + +$font-stack: Helvetica, sans-serif; +$primary-color: #333; +$pi: '\\\\e0C6'; + +body { + font: 100% $font-stack; + color: $primary-color; } + +nav { + ul { + margin: 0; + padding: 0; + list-style: none; } + + li { + display: inline-block; } + + a { + display: block; + padding: 6px 12px; + text-decoration: none; } } + +@mixin border-radius($radius) { + -webkit-border-radius: $radius; + -moz-border-radius: $radius; + -ms-border-radius: $radius; + border-radius: $radius; } + +.box { + @include border-radius(10px); } + +.message { + border: 1px solid #ccc; + padding: 10px; + color: #333; } + +.success { + @extend .message; + border-color: green; } + +.error { + @extend .message; + border-color: red; } + +.warning { + @extend .message; + border-color: yellow; } + +.foo { + &:before { + content: $pi; } } + +.bar { + &:before { + content: $n-ary-summation; } } + +", + "$n-ary-summation: '\\\\2211'; +", + ], + "version": 3, +} +`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (node-sass) (sass): warnings 1`] = `Array []`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (node-sass) (scss): css 1`] = ` +"@charset \\"UTF-8\\"; +body { + font: 100% Helvetica, sans-serif; + color: #333; } + +nav ul { + margin: 0; + padding: 0; + list-style: none; } + +nav li { + display: inline-block; } + +nav a { + display: block; + padding: 6px 12px; + text-decoration: none; } + +.box { + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + -ms-border-radius: 10px; + border-radius: 10px; } + +.foo:before { + content: \\"\\"; } + +.bar:before { + content: \\"∑\\"; } +" +`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (node-sass) (scss): errors 1`] = `Array []`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (node-sass) (scss): source map 1`] = ` +Object { + "file": "style.css.map", + "mappings": ";AAMA,AAAA,IAAI,CAAC;EACH,IAAI,EAAE,IAAI,CALI,SAAS,EAAE,UAAU;EAMnC,KAAK,EALS,IAAI,GAMnB;;AAED,AACE,GADC,CACD,EAAE,CAAC;EACD,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,IAAI,GACjB;;AALH,AAOE,GAPC,CAOD,EAAE,CAAC;EAAE,OAAO,EAAE,YAAY,GAAI;;AAPhC,AASE,GATC,CASD,CAAC,CAAC;EACA,OAAO,EAAE,KAAK;EACd,OAAO,EAAE,QAAQ;EACjB,eAAe,EAAE,IAAI,GACtB;;AAUH,AAAA,IAAI,CAAC;EANH,qBAAqB,EAMO,IAAI;EAL7B,kBAAkB,EAKO,IAAI;EAJ5B,iBAAiB,EAIO,IAAI;EAHxB,aAAa,EAGO,IAAI,GAAK;;AAEvC,AACE,IADE,AACD,OAAO,CAAC;EACP,OAAO,EAlCK,IAAO,GAmCpB;;AAGH,AACE,IADE,AACD,OAAO,CAAC;EACP,OAAO,EC5CO,IAAO,GD6CtB", + "names": Array [], + "sourceRoot": "", + "sources": Array [ + "scss/language.scss", + "scss/another/_variables.scss", + ], + "sourcesContent": Array [ + "@import \\"another/variables\\"; + +$font-stack: Helvetica, sans-serif; +$primary-color: #333; +$pi: '\\\\e0C6'; + +body { + font: 100% $font-stack; + color: $primary-color; +} + +nav { + ul { + margin: 0; + padding: 0; + list-style: none; + } + + li { display: inline-block; } + + a { + display: block; + padding: 6px 12px; + text-decoration: none; + } +} + +@mixin border-radius($radius) { + -webkit-border-radius: $radius; + -moz-border-radius: $radius; + -ms-border-radius: $radius; + border-radius: $radius; +} + +.box { @include border-radius(10px); } + +.foo { + &:before { + content: $pi; + } +} + +.bar { + &:before { + content: $n-ary-summation; + } +} +", + "$n-ary-summation: '\\\\2211' +", + ], + "version": 3, +} +`; + +exports[`sourceMap option should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (node-sass) (scss): warnings 1`] = `Array []`; + exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "false" value (dart-sass) (sass): css 1`] = ` "@charset \\"UTF-8\\"; body { diff --git a/test/sourceMap-options.test.js b/test/sourceMap-options.test.js index 21925d48..109c2ef5 100644 --- a/test/sourceMap-options.test.js +++ b/test/sourceMap-options.test.js @@ -29,6 +29,8 @@ describe('sourceMap option', () => { const [implementationName] = implementation.info.split('\t'); it(`should generate source maps when value is not specified and the "devtool" option has "source-map" value (${implementationName}) (${syntax})`, async () => { + expect.assertions(10); + const testId = getTestId('language', syntax); const options = { implementation: getImplementationByName(implementationName), @@ -41,11 +43,17 @@ describe('sourceMap option', () => { const { css, sourceMap } = getCodeFromBundle(stats, compiler); sourceMap.sourceRoot = ''; - sourceMap.sources = sourceMap.sources.map((source) => - path + sourceMap.sources = sourceMap.sources.map((source) => { + expect(path.isAbsolute(source)).toBe(true); + expect(source).toBe(path.normalize(source)); + expect( + fs.existsSync(path.resolve(sourceMap.sourceRoot, source)) + ).toBe(true); + + return path .relative(path.resolve(__dirname, '..'), source) - .replace(/\\/g, '/') - ); + .replace(/\\/g, '/'); + }); expect(css).toMatchSnapshot('css'); expect(sourceMap).toMatchSnapshot('source map'); @@ -53,48 +61,88 @@ describe('sourceMap option', () => { expect(getErrors(stats)).toMatchSnapshot('errors'); }); - it(`should not generate source maps when value is not specified and the "devtool" option has "false" value (${implementationName}) (${syntax})`, async () => { + it(`should generate source maps when value has "true" value and the "devtool" option has "source-map" value (${implementationName}) (${syntax})`, async () => { + expect.assertions(10); + const testId = getTestId('language', syntax); const options = { implementation: getImplementationByName(implementationName), + sourceMap: true, }; const compiler = getCompiler(testId, { - devtool: false, + devtool: 'source-map', loader: { options }, }); const stats = await compile(compiler); const { css, sourceMap } = getCodeFromBundle(stats, compiler); + sourceMap.sourceRoot = ''; + sourceMap.sources = sourceMap.sources.map((source) => { + expect(path.isAbsolute(source)).toBe(true); + expect(source).toBe(path.normalize(source)); + expect( + fs.existsSync(path.resolve(sourceMap.sourceRoot, source)) + ).toBe(true); + + return path + .relative(path.resolve(__dirname, '..'), source) + .replace(/\\/g, '/'); + }); + expect(css).toMatchSnapshot('css'); expect(sourceMap).toMatchSnapshot('source map'); expect(getWarnings(stats)).toMatchSnapshot('warnings'); expect(getErrors(stats)).toMatchSnapshot('errors'); }); - it(`should not generate source maps when value has "false" value and the "devtool" option has "source-map" value (${implementationName}) (${syntax})`, async () => { + it(`should generate source maps when value has "true" value and the "devtool" option has "false" value (${implementationName}) (${syntax})`, async () => { + expect.assertions(10); + const testId = getTestId('language', syntax); const options = { implementation: getImplementationByName(implementationName), - sourceMap: false, + sourceMap: true, }; const compiler = getCompiler(testId, { - devtool: 'source-map', + devtool: false, loader: { options }, }); const stats = await compile(compiler); const { css, sourceMap } = getCodeFromBundle(stats, compiler); + sourceMap.sourceRoot = ''; + sourceMap.sources = sourceMap.sources.map((source) => { + expect(path.isAbsolute(source)).toBe(true); + expect(source).toBe(path.normalize(source)); + expect( + fs.existsSync(path.resolve(sourceMap.sourceRoot, source)) + ).toBe(true); + + return path + .relative(path.resolve(__dirname, '..'), source) + .replace(/\\/g, '/'); + }); + expect(css).toMatchSnapshot('css'); expect(sourceMap).toMatchSnapshot('source map'); expect(getWarnings(stats)).toMatchSnapshot('warnings'); expect(getErrors(stats)).toMatchSnapshot('errors'); }); - it(`should not generate source maps when value has "false" value and the "devtool" option has "false" value (${implementationName}) (${syntax})`, async () => { + it(`should generate source maps when value has "false" value, but the "sassOptions.sourceMap" has the "true" value (${implementationName}) (${syntax})`, async () => { + expect.assertions(8); + const testId = getTestId('language', syntax); const options = { implementation: getImplementationByName(implementationName), sourceMap: false, + sassOptions: { + sourceMap: true, + outFile: path.join(__dirname, 'style.css.map'), + sourceMapContents: true, + omitSourceMapUrl: true, + sourceMapEmbed: false, + }, }; const compiler = getCompiler(testId, { devtool: false, @@ -103,54 +151,66 @@ describe('sourceMap option', () => { const stats = await compile(compiler); const { css, sourceMap } = getCodeFromBundle(stats, compiler); + sourceMap.sourceRoot = ''; + sourceMap.sources = sourceMap.sources.map((source) => { + expect(path.isAbsolute(source)).toBe(false); + expect( + fs.existsSync(path.resolve(__dirname, path.normalize(source))) + ).toBe(true); + + return path + .relative(path.resolve(__dirname, '..'), source) + .replace(/\\/g, '/'); + }); + expect(css).toMatchSnapshot('css'); expect(sourceMap).toMatchSnapshot('source map'); expect(getWarnings(stats)).toMatchSnapshot('warnings'); expect(getErrors(stats)).toMatchSnapshot('errors'); }); - it(`should generate source maps when value has "true" value and the "devtool" option has "source-map" value (${implementationName}) (${syntax})`, async () => { - expect.assertions(6); - + it(`should not generate source maps when value is not specified and the "devtool" option has "false" value (${implementationName}) (${syntax})`, async () => { const testId = getTestId('language', syntax); const options = { implementation: getImplementationByName(implementationName), - sourceMap: true, }; const compiler = getCompiler(testId, { - devtool: 'source-map', + devtool: false, loader: { options }, }); const stats = await compile(compiler); const { css, sourceMap } = getCodeFromBundle(stats, compiler); - sourceMap.sourceRoot = ''; - sourceMap.sources = sourceMap.sources.map((source) => - path - .relative(path.resolve(__dirname, '..'), source) - .replace(/\\/g, '/') - ); - expect(css).toMatchSnapshot('css'); expect(sourceMap).toMatchSnapshot('source map'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + }); - sourceMap.sources.forEach((sourcePath) => { - expect( - fs.existsSync(path.resolve(sourceMap.sourceRoot, sourcePath)) - ).toBe(true); + it(`should not generate source maps when value has "false" value and the "devtool" option has "source-map" value (${implementationName}) (${syntax})`, async () => { + const testId = getTestId('language', syntax); + const options = { + implementation: getImplementationByName(implementationName), + sourceMap: false, + }; + const compiler = getCompiler(testId, { + devtool: 'source-map', + loader: { options }, }); + const stats = await compile(compiler); + const { css, sourceMap } = getCodeFromBundle(stats, compiler); + expect(css).toMatchSnapshot('css'); + expect(sourceMap).toMatchSnapshot('source map'); expect(getWarnings(stats)).toMatchSnapshot('warnings'); expect(getErrors(stats)).toMatchSnapshot('errors'); }); - it(`should generate source maps when value has "true" value and the "devtool" option has "false" value (${implementationName}) (${syntax})`, async () => { - expect.assertions(6); - + it(`should not generate source maps when value has "false" value and the "devtool" option has "false" value (${implementationName}) (${syntax})`, async () => { const testId = getTestId('language', syntax); const options = { implementation: getImplementationByName(implementationName), - sourceMap: true, + sourceMap: false, }; const compiler = getCompiler(testId, { devtool: false, @@ -159,22 +219,8 @@ describe('sourceMap option', () => { const stats = await compile(compiler); const { css, sourceMap } = getCodeFromBundle(stats, compiler); - sourceMap.sourceRoot = ''; - sourceMap.sources = sourceMap.sources.map((source) => - path - .relative(path.resolve(__dirname, '..'), source) - .replace(/\\/g, '/') - ); - expect(css).toMatchSnapshot('css'); expect(sourceMap).toMatchSnapshot('source map'); - - sourceMap.sources.forEach((sourcePath) => { - expect( - fs.existsSync(path.resolve(sourceMap.sourceRoot, sourcePath)) - ).toBe(true); - }); - expect(getWarnings(stats)).toMatchSnapshot('warnings'); expect(getErrors(stats)).toMatchSnapshot('errors'); });