From 9c5028bc884ab4c704cc7b8d813da93da68f4093 Mon Sep 17 00:00:00 2001 From: Evilebot Tnawi Date: Tue, 20 Aug 2019 20:12:10 +0300 Subject: [PATCH] refactor: move all `sass` options to the `sassOptions` option (#736) BREAKING CHANGE: move all sass (`includePaths`, `importer`, `functions`) options to the `sassOptions` option. The `functions` option can't be used as `Function`, you should use `sassOption` as `Function` to achieve this. --- README.md | 129 ++++++++++++------ src/getSassOptions.js | 37 +++-- test/__snapshots__/loader.test.js.snap | 80 ----------- .../sassOptions-option.test.js.snap | 81 +++++++++++ test/helpers/getCodeFromSass.js | 19 +-- test/loader.test.js | 91 +----------- test/sassOptions-option.test.js | 124 +++++++++++++++++ 7 files changed, 323 insertions(+), 238 deletions(-) create mode 100644 test/__snapshots__/sassOptions-option.test.js.snap create mode 100644 test/sassOptions-option.test.js diff --git a/README.md b/README.md index bf2a80c9..063a43e0 100644 --- a/README.md +++ b/README.md @@ -107,46 +107,6 @@ Thankfully there are a two solutions to this problem: ## Options -By default all options passed to loader also passed to to [Node Sass](https://github.com/sass/node-sass) or [Dart Sass](http://sass-lang.com/dart-sass) - -> ℹ️ The `indentedSyntax` option has `true` value for the `sass` extension. - -> ℹ️ Options such as `file` and `outFile` are unavailable. - -> ℹ️ Only the "expanded" and "compressed" values of outputStyle are supported for `dart-sass`. - -> ℹ We recommend don't use `sourceMapContents`, `sourceMapEmbed`, `sourceMapRoot` options because loader automatically setup this options. - -There is a slight difference between the `node-sass` and `sass` options. We recommend look documentation before used them: - -- [the Node Sass documentation](https://github.com/sass/node-sass/#options) for all available `node-sass` options. -- [the Dart Sass documentation](https://github.com/sass/dart-sass#javascript-api) for all available `sass` options. - -**webpack.config.js** - -```js -module.exports = { - module: { - rules: [ - { - test: /\.s[ac]ss$/i, - use: [ - 'style-loader', - 'css-loader', - { - loader: 'sass-loader', - options: { - indentWidth: 4, - includePaths: ['absolute/path/a', 'absolute/path/b'], - }, - }, - ], - }, - ], - }, -}; -``` - ### `implementation` The special `implementation` option determines which implementation of Sass to use. @@ -239,6 +199,95 @@ module.exports = { }; ``` +### `sassOptions` + +Type: `Object|Function` + +Setups options for [Node Sass](https://github.com/sass/node-sass) or [Dart Sass](http://sass-lang.com/dart-sass). + +> ℹ️ The `indentedSyntax` option has `true` value for the `sass` extension. + +> ℹ️ Options such as `file` and `outFile` are unavailable. + +> ℹ We recommend don't use `sourceMapContents`, `sourceMapEmbed`, `sourceMapRoot` options because loader automatically setup this options. + +There is a slight difference between the `node-sass` and `sass` (`Dart Sass`) options. +We recommend look documentation before used them: + +- [the Node Sass documentation](https://github.com/sass/node-sass/#options) for all available `node-sass` options. +- [the Dart Sass documentation](https://github.com/sass/dart-sass#javascript-api) for all available `sass` options. + +#### `Object` + +Setups option as object for sass implementation. + +**webpack.config.js** + +```js +module.exports = { + module: { + rules: [ + { + test: /\.s[ac]ss$/i, + use: [ + 'style-loader', + 'css-loader', + { + loader: 'sass-loader', + options: { + sassOptions: { + indentWidth: 4, + includePaths: ['absolute/path/a', 'absolute/path/b'], + }, + }, + }, + ], + }, + ], + }, +}; +``` + +#### `Function` + +Allows setup difference options based on loader context. + +```js +module.exports = { + module: { + rules: [ + { + test: /\.s[ac]ss$/i, + use: [ + 'style-loader', + 'css-loader', + { + loader: 'sass-loader', + options: { + sassOptions: (loaderContext) => { + // More information about available properties https://webpack.js.org/api/loaders/ + const { resourcePath, rootContext } = loaderContext; + const relativePath = path.relative(rootContext, resourcePath); + + if (relativePath === 'styles/foo.scss') { + return { + includePaths: ['absolute/path/c', 'absolute/path/d'], + }; + } + + return { + includePaths: ['absolute/path/a', 'absolute/path/b'], + }; + }, + }, + }, + ], + }, + ], + }, +}; +``` + ### `prependData` Type: `String|Function` diff --git a/src/getSassOptions.js b/src/getSassOptions.js index ab3bd27e..76f97dee 100644 --- a/src/getSassOptions.js +++ b/src/getSassOptions.js @@ -16,30 +16,25 @@ function isProductionLikeMode(loaderContext) { /** * Derives the sass options from the loader context and normalizes its values with sane defaults. * - * Please note: If loaderContext.query is an options object, it will be re-used across multiple invocations. - * That's why we must not modify the object directly. - * * @param {LoaderContext} loaderContext - * @param {string} loaderOptions - * @param {object} content + * @param {object} loaderOptions + * @param {string} content * @returns {Object} */ function getSassOptions(loaderContext, loaderOptions, content) { - const options = cloneDeep(loaderOptions); - const { resourcePath } = loaderContext; - - // allow opt.functions to be configured WRT loaderContext - if (typeof options.functions === 'function') { - options.functions = options.functions(loaderContext); - } - - let { prependData } = options; - - if (typeof prependData === 'function') { - prependData = prependData(loaderContext); - } + const options = cloneDeep( + loaderOptions.sassOptions + ? typeof loaderOptions.sassOptions === 'function' + ? loaderOptions.sassOptions(loaderContext) + : loaderOptions.sassOptions + : {} + ); - options.data = prependData ? prependData + os.EOL + content : content; + options.data = loaderOptions.prependData + ? typeof loaderOptions.prependData === 'function' + ? loaderOptions.prependData(loaderContext) + os.EOL + content + : loaderOptions.prependData + os.EOL + content + : content; // opt.outputStyle if (!options.outputStyle && isProductionLikeMode(loaderContext)) { @@ -49,7 +44,7 @@ function getSassOptions(loaderContext, loaderOptions, content) { // opt.sourceMap // Not using the `this.sourceMap` flag because css source maps are different // @see https://github.com/webpack/css-loader/pull/40 - if (options.sourceMap) { + if (loaderOptions.sourceMap) { // Deliberately overriding the sourceMap option here. // node-sass won't produce source maps if the data option is used and options.sourceMap is not a string. // In case it is a string, options.sourceMap should be a path where the source map is written. @@ -75,7 +70,7 @@ function getSassOptions(loaderContext, loaderOptions, content) { } } - // indentedSyntax is a boolean flag. + const { resourcePath } = loaderContext; const ext = path.extname(resourcePath); // If we are compiling sass and indentedSyntax isn't set, automatically set it. diff --git a/test/__snapshots__/loader.test.js.snap b/test/__snapshots__/loader.test.js.snap index b88a06bc..5c16c09d 100644 --- a/test/__snapshots__/loader.test.js.snap +++ b/test/__snapshots__/loader.test.js.snap @@ -657,83 +657,3 @@ exports[`loader should work with the "bootstrap-sass" package, import as a packa exports[`loader should work with the "bootstrap-sass" package, import as a package (node-sass) (scss): errors 1`] = `Array []`; exports[`loader should work with the "bootstrap-sass" package, import as a package (node-sass) (scss): warnings 1`] = `Array []`; - -exports[`loader should work with the "functions" option as a function (dart-sass) (sass): errors 1`] = `Array []`; - -exports[`loader should work with the "functions" option as a function (dart-sass) (sass): warnings 1`] = `Array []`; - -exports[`loader should work with the "functions" option as a function (dart-sass) (scss): errors 1`] = `Array []`; - -exports[`loader should work with the "functions" option as a function (dart-sass) (scss): warnings 1`] = `Array []`; - -exports[`loader should work with the "functions" option as a function (node-sass) (sass): errors 1`] = `Array []`; - -exports[`loader should work with the "functions" option as a function (node-sass) (sass): warnings 1`] = `Array []`; - -exports[`loader should work with the "functions" option as a function (node-sass) (scss): errors 1`] = `Array []`; - -exports[`loader should work with the "functions" option as a function (node-sass) (scss): warnings 1`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (dart-sass) (sass): errors 1`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (dart-sass) (sass): errors 2`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (dart-sass) (sass): warnings 1`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (dart-sass) (sass): warnings 2`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (dart-sass) (scss): errors 1`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (dart-sass) (scss): errors 2`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (dart-sass) (scss): warnings 1`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (dart-sass) (scss): warnings 2`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (node-sass) (sass): errors 1`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (node-sass) (sass): errors 2`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (node-sass) (sass): warnings 1`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (node-sass) (sass): warnings 2`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (node-sass) (scss): errors 1`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (node-sass) (scss): errors 2`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (node-sass) (scss): warnings 1`] = `Array []`; - -exports[`loader should work with the "functions" option as an object (node-sass) (scss): warnings 2`] = `Array []`; - -exports[`loader should work with the "importer" option (dart-sass) (sass): errors 1`] = `Array []`; - -exports[`loader should work with the "importer" option (dart-sass) (sass): warnings 1`] = `Array []`; - -exports[`loader should work with the "importer" option (dart-sass) (scss): errors 1`] = `Array []`; - -exports[`loader should work with the "importer" option (dart-sass) (scss): warnings 1`] = `Array []`; - -exports[`loader should work with the "importer" option (node-sass) (sass): errors 1`] = `Array []`; - -exports[`loader should work with the "importer" option (node-sass) (sass): warnings 1`] = `Array []`; - -exports[`loader should work with the "importer" option (node-sass) (scss): errors 1`] = `Array []`; - -exports[`loader should work with the "importer" option (node-sass) (scss): warnings 1`] = `Array []`; - -exports[`loader should work with the "includePaths" option (dart-sass) (sass): errors 1`] = `Array []`; - -exports[`loader should work with the "includePaths" option (dart-sass) (sass): warnings 1`] = `Array []`; - -exports[`loader should work with the "includePaths" option (dart-sass) (scss): errors 1`] = `Array []`; - -exports[`loader should work with the "includePaths" option (dart-sass) (scss): warnings 1`] = `Array []`; - -exports[`loader should work with the "includePaths" option (node-sass) (sass): errors 1`] = `Array []`; - -exports[`loader should work with the "includePaths" option (node-sass) (sass): warnings 1`] = `Array []`; - -exports[`loader should work with the "includePaths" option (node-sass) (scss): errors 1`] = `Array []`; - -exports[`loader should work with the "includePaths" option (node-sass) (scss): warnings 1`] = `Array []`; diff --git a/test/__snapshots__/sassOptions-option.test.js.snap b/test/__snapshots__/sassOptions-option.test.js.snap new file mode 100644 index 00000000..85d2ddc2 --- /dev/null +++ b/test/__snapshots__/sassOptions-option.test.js.snap @@ -0,0 +1,81 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`sassOptions option should work when the option like "Function" (dart-sass) (sass): errors 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Function" (dart-sass) (sass): warnings 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Function" (dart-sass) (scss): errors 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Function" (dart-sass) (scss): warnings 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Function" (node-sass) (sass): errors 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Function" (node-sass) (sass): warnings 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Function" (node-sass) (scss): errors 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Function" (node-sass) (scss): warnings 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Object" (dart-sass) (sass): errors 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Object" (dart-sass) (sass): warnings 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Object" (dart-sass) (scss): errors 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Object" (dart-sass) (scss): warnings 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Object" (node-sass) (sass): errors 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Object" (node-sass) (sass): warnings 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Object" (node-sass) (scss): errors 1`] = `Array []`; + +exports[`sassOptions option should work when the option like "Object" (node-sass) (scss): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "functions" option (dart-sass) (sass): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "functions" option (dart-sass) (sass): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "functions" option (dart-sass) (scss): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "functions" option (dart-sass) (scss): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "functions" option (node-sass) (sass): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "functions" option (node-sass) (sass): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "functions" option (node-sass) (scss): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "functions" option (node-sass) (scss): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "importer" option (dart-sass) (sass): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "importer" option (dart-sass) (sass): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "importer" option (dart-sass) (scss): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "importer" option (dart-sass) (scss): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "importer" option (node-sass) (sass): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "importer" option (node-sass) (sass): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "importer" option (node-sass) (scss): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "importer" option (node-sass) (scss): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "includePaths" option (dart-sass) (sass): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "includePaths" option (dart-sass) (sass): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "includePaths" option (dart-sass) (scss): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "includePaths" option (dart-sass) (scss): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "includePaths" option (node-sass) (sass): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "includePaths" option (node-sass) (sass): warnings 1`] = `Array []`; + +exports[`sassOptions option should work with the "includePaths" option (node-sass) (scss): errors 1`] = `Array []`; + +exports[`sassOptions option should work with the "includePaths" option (node-sass) (scss): warnings 1`] = `Array []`; diff --git a/test/helpers/getCodeFromSass.js b/test/helpers/getCodeFromSass.js index fa350621..e7e84b46 100644 --- a/test/helpers/getCodeFromSass.js +++ b/test/helpers/getCodeFromSass.js @@ -3,18 +3,23 @@ import os from 'os'; import fs from 'fs'; function getCodeFromSass(testId, options) { - const sassOptions = Object.assign({}, options); + const loaderOptions = Object.assign({}, options); + let sassOptions = options.sassOptions || {}; - const { implementation } = sassOptions; - const isNodeSassImplementation = sassOptions.implementation.info.includes( + if (typeof sassOptions === 'function') { + sassOptions = sassOptions({ mock: true }); + } + + const { implementation } = loaderOptions; + const isNodeSassImplementation = loaderOptions.implementation.info.includes( 'node-sass' ); - delete sassOptions.implementation; + delete loaderOptions.implementation; const isSass = /\.sass$/i.test(testId); - if (sassOptions.prependData) { + if (loaderOptions.prependData) { sassOptions.indentedSyntax = isSass; sassOptions.data = `$prepended-data: hotpink${ sassOptions.indentedSyntax ? '\n' : ';' @@ -26,10 +31,6 @@ function getCodeFromSass(testId, options) { sassOptions.file = path.resolve(__dirname, '..', testId); } - if (typeof sassOptions.functions === 'function') { - sassOptions.functions = sassOptions.functions({ moc: true }); - } - const testFolder = path.resolve(__dirname, '../'); const testNodeModules = path.resolve(testFolder, 'node_modules') + path.sep; const pathToSassPackageWithIndexFile = path.resolve( diff --git a/test/loader.test.js b/test/loader.test.js index 149933c2..39563220 100644 --- a/test/loader.test.js +++ b/test/loader.test.js @@ -15,9 +15,6 @@ import { normalizeError, } from './helpers'; -import customImporter from './helpers/customImporter'; -import customFunctions from './helpers/customFunctions'; - const implementations = [nodeSass, dartSass]; const syntaxStyles = ['scss', 'sass']; @@ -41,90 +38,6 @@ describe('loader', () => { expect(stats.compilation.errors).toMatchSnapshot('errors'); }); - it(`should work with the "importer" option (${implementationName}) (${syntax})`, async () => { - const testId = getTestId('custom-importer', syntax); - const options = { - importer: customImporter, - implementation: getImplementationByName(implementationName), - }; - const stats = await compile(testId, { loader: { options } }); - - expect(getCodeFromBundle(stats).css).toBe( - getCodeFromSass(testId, options).css - ); - - expect(stats.compilation.warnings).toMatchSnapshot('warnings'); - expect(stats.compilation.errors).toMatchSnapshot('errors'); - }); - - it(`should work with the "functions" option as an object (${implementationName}) (${syntax})`, async () => { - const testId = getTestId('custom-functions', syntax); - const options = { - functions: customFunctions(implementation), - implementation: getImplementationByName(implementationName), - }; - const stats = await compile(testId, { loader: { options } }); - - expect(getCodeFromBundle(stats).css).toBe( - getCodeFromSass(testId, options).css - ); - - expect(stats.compilation.warnings).toMatchSnapshot('warnings'); - expect(stats.compilation.errors).toMatchSnapshot('errors'); - }); - - it(`should work with the "functions" option as an object (${implementationName}) (${syntax})`, async () => { - const testId = getTestId('custom-functions', syntax); - const options = { - implementation: getImplementationByName(implementationName), - functions: customFunctions(implementation), - }; - const stats = await compile(testId, { loader: { options } }); - - expect(getCodeFromBundle(stats).css).toBe( - getCodeFromSass(testId, options).css - ); - - expect(stats.compilation.warnings).toMatchSnapshot('warnings'); - expect(stats.compilation.errors).toMatchSnapshot('errors'); - }); - - it(`should work with the "functions" option as a function (${implementationName}) (${syntax})`, async () => { - const testId = getTestId('custom-functions', syntax); - const options = { - functions: (loaderContext) => { - expect(loaderContext).toBeDefined(); - - return customFunctions(implementation); - }, - implementation: getImplementationByName(implementationName), - }; - const stats = await compile(testId, { loader: { options } }); - - expect(getCodeFromBundle(stats).css).toBe( - getCodeFromSass(testId, options).css - ); - - expect(stats.compilation.warnings).toMatchSnapshot('warnings'); - expect(stats.compilation.errors).toMatchSnapshot('errors'); - }); - - it(`should work with the "includePaths" option (${implementationName}) (${syntax})`, async () => { - const testId = getTestId('import-include-paths', syntax); - const options = { - implementation: getImplementationByName(implementationName), - includePaths: [path.resolve(__dirname, syntax, 'includePath')], - }; - const stats = await compile(testId, { loader: { options } }); - - expect(getCodeFromBundle(stats).css).toBe( - getCodeFromSass(testId, options).css - ); - - expect(stats.compilation.warnings).toMatchSnapshot('warnings'); - expect(stats.compilation.errors).toMatchSnapshot('errors'); - }); - // See https://github.com/webpack-contrib/sass-loader/issues/21 it(`should work with an empty file (${implementationName}) (${syntax})`, async () => { const testId = getTestId('empty', syntax); @@ -603,7 +516,9 @@ describe('loader', () => { getCodeFromSass( testId, Object.assign({}, options, { - outputStyle: 'compressed', + sassOptions: { + outputStyle: 'compressed', + }, }) ).css ); diff --git a/test/sassOptions-option.test.js b/test/sassOptions-option.test.js new file mode 100644 index 00000000..2b5d0c6e --- /dev/null +++ b/test/sassOptions-option.test.js @@ -0,0 +1,124 @@ +/** + * @jest-environment node + */ +import path from 'path'; + +import nodeSass from 'node-sass'; +import dartSass from 'sass'; + +import { + compile, + getTestId, + getCodeFromBundle, + getCodeFromSass, + getImplementationByName, +} from './helpers'; +import customImporter from './helpers/customImporter'; +import customFunctions from './helpers/customFunctions'; + +const implementations = [nodeSass, dartSass]; +const syntaxStyles = ['scss', 'sass']; + +describe('sassOptions option', () => { + implementations.forEach((implementation) => { + const [implementationName] = implementation.info.split('\t'); + + syntaxStyles.forEach((syntax) => { + it(`should work when the option like "Object" (${implementationName}) (${syntax})`, async () => { + const testId = getTestId('language', syntax); + const options = { + implementation: getImplementationByName(implementationName), + sassOptions: { + indentWidth: 10, + }, + }; + const stats = await compile(testId, { loader: { options } }); + + expect(getCodeFromBundle(stats).css).toBe( + getCodeFromSass(testId, options).css + ); + + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); + + it(`should work when the option like "Function" (${implementationName}) (${syntax})`, async () => { + expect.assertions(5); + + const testId = getTestId('language', syntax); + const options = { + implementation: getImplementationByName(implementationName), + sassOptions: (loaderContext) => { + expect(loaderContext).toBeDefined(); + + return { + indentWidth: 10, + }; + }, + }; + const stats = await compile(testId, { loader: { options } }); + + expect(getCodeFromBundle(stats).css).toBe( + getCodeFromSass(testId, options).css + ); + + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); + + it(`should work with the "importer" option (${implementationName}) (${syntax})`, async () => { + const testId = getTestId('custom-importer', syntax); + const options = { + implementation: getImplementationByName(implementationName), + sassOptions: { + importer: customImporter, + }, + }; + const stats = await compile(testId, { loader: { options } }); + + expect(getCodeFromBundle(stats).css).toBe( + getCodeFromSass(testId, options).css + ); + + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); + + it(`should work with the "functions" option (${implementationName}) (${syntax})`, async () => { + const testId = getTestId('custom-functions', syntax); + const options = { + implementation: getImplementationByName(implementationName), + sassOptions: { + functions: customFunctions(implementation), + }, + }; + const stats = await compile(testId, { loader: { options } }); + + expect(getCodeFromBundle(stats).css).toBe( + getCodeFromSass(testId, options).css + ); + + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); + + it(`should work with the "includePaths" option (${implementationName}) (${syntax})`, async () => { + const testId = getTestId('import-include-paths', syntax); + const options = { + implementation: getImplementationByName(implementationName), + sassOptions: { + includePaths: [path.resolve(__dirname, syntax, 'includePath')], + }, + }; + const stats = await compile(testId, { loader: { options } }); + + expect(getCodeFromBundle(stats).css).toBe( + getCodeFromSass(testId, options).css + ); + + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); + }); + }); +});