Skip to content

Commit ddeff88

Browse files
test: refactor (#835)
1 parent 24c852a commit ddeff88

File tree

2 files changed

+164
-69
lines changed

2 files changed

+164
-69
lines changed
Lines changed: 78 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,30 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`validate options 1`] = `
3+
exports[`validate options should throw an error on the "implementation" option with "string" value 1`] = `
44
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
55
- options.implementation should be an object:
66
object {}
77
-> The implementation of the sass to be used (https://github.com/webpack-contrib/sass-loader#implementation)."
88
`;
99

10-
exports[`validate options 2`] = `
10+
exports[`validate options should throw an error on the "implementation" option with "true" value 1`] = `
11+
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
12+
- options.implementation should be an object:
13+
object {}
14+
-> The implementation of the sass to be used (https://github.com/webpack-contrib/sass-loader#implementation)."
15+
`;
16+
17+
exports[`validate options should throw an error on the "prependData" option with "true" value 1`] = `
18+
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
19+
- options.prependData should be one of these:
20+
string | function
21+
-> Prepends \`Sass\`/\`SCSS\` code before the actual entry file (https://github.com/webpack-contrib/sass-loader#prependdata).
22+
Details:
23+
* options.prependData should be a string.
24+
* options.prependData should be an instance of function."
25+
`;
26+
27+
exports[`validate options should throw an error on the "sassOptions" option with "string" value 1`] = `
1128
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
1229
- options.sassOptions should be one of these:
1330
object {} | function
@@ -18,24 +35,73 @@ exports[`validate options 2`] = `
1835
* options.sassOptions should be an instance of function."
1936
`;
2037

21-
exports[`validate options 3`] = `
38+
exports[`validate options should throw an error on the "sassOptions" option with "true" value 1`] = `
2239
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
23-
- options.prependData should be one of these:
24-
string | function
25-
-> Prepends \`Sass\`/\`SCSS\` code before the actual entry file (https://github.com/webpack-contrib/sass-loader#prependdata).
40+
- options.sassOptions should be one of these:
41+
object {} | function
42+
-> Options for \`node-sass\` or \`sass\` (\`Dart Sass\`) implementation. (https://github.com/webpack-contrib/sass-loader#implementation).
2643
Details:
27-
* options.prependData should be a string.
28-
* options.prependData should be an instance of function."
44+
* options.sassOptions should be an object:
45+
object {}
46+
* options.sassOptions should be an instance of function."
2947
`;
3048

31-
exports[`validate options 4`] = `
49+
exports[`validate options should throw an error on the "sourceMap" option with "string" value 1`] = `
3250
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
33-
- options.webpackImporter should be a boolean.
34-
-> Enables/Disables default \`webpack\` importer (https://github.com/webpack-contrib/sass-loader#webpackimporter)."
51+
- options.sourceMap should be a boolean.
52+
-> Enables/Disables generation of source maps (https://github.com/webpack-contrib/sass-loader#sourcemap)."
53+
`;
54+
55+
exports[`validate options should throw an error on the "unknown" option with "/test/" value 1`] = `
56+
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
57+
- options has an unknown property 'unknown'. These properties are valid:
58+
object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }"
59+
`;
60+
61+
exports[`validate options should throw an error on the "unknown" option with "[]" value 1`] = `
62+
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
63+
- options has an unknown property 'unknown'. These properties are valid:
64+
object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }"
65+
`;
66+
67+
exports[`validate options should throw an error on the "unknown" option with "{"foo":"bar"}" value 1`] = `
68+
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
69+
- options has an unknown property 'unknown'. These properties are valid:
70+
object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }"
71+
`;
72+
73+
exports[`validate options should throw an error on the "unknown" option with "{}" value 1`] = `
74+
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
75+
- options has an unknown property 'unknown'. These properties are valid:
76+
object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }"
77+
`;
78+
79+
exports[`validate options should throw an error on the "unknown" option with "1" value 1`] = `
80+
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
81+
- options has an unknown property 'unknown'. These properties are valid:
82+
object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }"
3583
`;
3684
37-
exports[`validate options 5`] = `
85+
exports[`validate options should throw an error on the "unknown" option with "false" value 1`] = `
3886
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
3987
- options has an unknown property 'unknown'. These properties are valid:
4088
object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }"
4189
`;
90+
91+
exports[`validate options should throw an error on the "unknown" option with "test" value 1`] = `
92+
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
93+
- options has an unknown property 'unknown'. These properties are valid:
94+
object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }"
95+
`;
96+
97+
exports[`validate options should throw an error on the "unknown" option with "true" value 1`] = `
98+
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
99+
- options has an unknown property 'unknown'. These properties are valid:
100+
object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }"
101+
`;
102+
103+
exports[`validate options should throw an error on the "webpackImporter" option with "string" value 1`] = `
104+
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
105+
- options.webpackImporter should be a boolean.
106+
-> Enables/Disables default \`webpack\` importer (https://github.com/webpack-contrib/sass-loader#webpackimporter)."
107+
`;

test/validate-options.test.js

Lines changed: 86 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,96 @@
11
import Fiber from 'fibers';
22

3-
import loader from '../src/cjs';
3+
import {
4+
getCompiler,
5+
compile,
6+
getTestId,
7+
getImplementationByName,
8+
} from './helpers/index';
49

5-
beforeEach(() => {
6-
// The `sass` (`Dart Sass`) package modify the `Function` prototype, but the `jest` lose a prototype
7-
Object.setPrototypeOf(Fiber, Function.prototype);
8-
});
10+
describe('validate options', () => {
11+
beforeEach(() => {
12+
// The `sass` (`Dart Sass`) package modify the `Function` prototype, but the `jest` lose a prototype
13+
Object.setPrototypeOf(Fiber, Function.prototype);
14+
});
915

10-
it('validate options', () => {
11-
const validate = (options) =>
12-
loader.call(
13-
Object.assign(
14-
{},
15-
{
16-
query: options,
17-
loaders: [],
18-
resourcePath: 'file.scss',
19-
getResolve: () => () => {},
20-
async: () => (error) => {
21-
if (error) {
22-
throw error;
23-
}
24-
},
25-
}
26-
),
27-
'a { color: red; }'
28-
);
16+
const tests = {
17+
implementation: {
18+
// eslint-disable-next-line global-require
19+
success: [require('sass'), require('node-sass')],
20+
failure: [true, 'string'],
21+
},
22+
sassOptions: {
23+
success: [{}, { indentWidth: 6 }, () => ({ indentWidth: 6 })],
24+
failure: [true, 'string'],
25+
},
26+
prependData: {
27+
success: ['$color: red;', () => '$color: red;'],
28+
failure: [true],
29+
},
30+
sourceMap: {
31+
success: [true, false],
32+
failure: ['string'],
33+
},
34+
webpackImporter: {
35+
success: [true, false],
36+
failure: ['string'],
37+
},
38+
unknown: {
39+
success: [],
40+
failure: [1, true, false, 'test', /test/, [], {}, { foo: 'bar' }],
41+
},
42+
};
2943

30-
expect(() =>
31-
// eslint-disable-next-line global-require
32-
validate({ implementation: require('node-sass') })
33-
).not.toThrow();
34-
expect(() =>
35-
// eslint-disable-next-line global-require
36-
validate({ implementation: require('sass') })
37-
).not.toThrow();
38-
expect(() =>
39-
validate({ implementation: true })
40-
).toThrowErrorMatchingSnapshot();
44+
function stringifyValue(value) {
45+
if (
46+
Array.isArray(value) ||
47+
(value && typeof value === 'object' && value.constructor === Object)
48+
) {
49+
return JSON.stringify(value);
50+
}
4151

42-
expect(() => validate({ sassOptions: {} })).not.toThrow();
43-
expect(() =>
44-
validate({
45-
sassOptions: () => {
46-
return {};
47-
},
48-
})
49-
).not.toThrow();
50-
expect(() => validate({ sassOptions: () => {} })).not.toThrow();
51-
expect(() => validate({ sassOptions: true })).toThrowErrorMatchingSnapshot();
52-
expect(() =>
53-
validate({ sassOptions: { indentWidth: 6, linefeed: 'crlf' } })
54-
).not.toThrow();
52+
return value;
53+
}
5554

56-
expect(() => validate({ prependData: '$color: red;' })).not.toThrow();
57-
expect(() => validate({ prependData: () => '$color: red;' })).not.toThrow();
58-
expect(() => validate({ prependData: true })).toThrowErrorMatchingSnapshot();
55+
async function createTestCase(key, value, type) {
56+
it(`should ${
57+
type === 'success' ? 'successfully validate' : 'throw an error on'
58+
} the "${key}" option with "${stringifyValue(value)}" value`, async () => {
59+
const testId = getTestId('language', 'scss');
60+
const compiler = getCompiler(testId, {
61+
loader: {
62+
options: {
63+
implementation: getImplementationByName('dart-sass'),
64+
[key]: value,
65+
},
66+
},
67+
});
68+
let stats;
69+
70+
try {
71+
stats = await compile(compiler);
72+
} finally {
73+
if (type === 'success') {
74+
expect(stats.hasErrors()).toBe(false);
75+
} else if (type === 'failure') {
76+
const {
77+
compilation: { errors },
78+
} = stats;
5979

60-
expect(() => validate({ webpackImporter: true })).not.toThrow();
61-
expect(() => validate({ webpackImporter: false })).not.toThrow();
62-
expect(() =>
63-
validate({ webpackImporter: 'unknown' })
64-
).toThrowErrorMatchingSnapshot();
80+
expect(errors).toHaveLength(1);
81+
expect(() => {
82+
throw new Error(errors[0].error.message);
83+
}).toThrowErrorMatchingSnapshot();
84+
}
85+
}
86+
});
87+
}
6588

66-
expect(() => validate({ unknown: 'unknown' })).toThrowErrorMatchingSnapshot();
89+
for (const [key, values] of Object.entries(tests)) {
90+
for (const type of Object.keys(values)) {
91+
for (const value of values[type]) {
92+
createTestCase(key, value, type);
93+
}
94+
}
95+
}
6796
});

0 commit comments

Comments
 (0)