2 * @fileoverview Tests for FlatConfigArray
3 * @author Nicholas C. Zakas
8 //-----------------------------------------------------------------------------
10 //-----------------------------------------------------------------------------
12 const { FlatConfigArray
} = require("../../../lib/config/flat-config-array");
13 const assert
= require("chai").assert
;
14 const allConfig
= require("../../../conf/eslint-all");
15 const recommendedConfig
= require("../../../conf/eslint-recommended");
17 //-----------------------------------------------------------------------------
19 //-----------------------------------------------------------------------------
30 enum: ["always", "never"]
74 * Creates a config array with the correct default options.
75 * @param {*[]} configs An array of configs to use in the config array.
76 * @returns {FlatConfigArray} The config array;
78 function createFlatConfigArray(configs
) {
79 return new FlatConfigArray(configs
, {
86 * Asserts that a given set of configs will be merged into the given
88 * @param {*[]} values An array of configs to use in the config array.
89 * @param {Object} result The expected merged result of the configs.
91 * @throws {AssertionError} If the actual result doesn't match the
94 async
function assertMergedResult(values
, result
) {
95 const configs
= createFlatConfigArray(values
);
97 await configs
.normalize();
99 const config
= configs
.getConfig("foo.js");
101 assert
.deepStrictEqual(config
, result
);
105 * Asserts that a given set of configs results in an invalid config.
106 * @param {*[]} values An array of configs to use in the config array.
107 * @param {string|RegExp} message The expected error message.
109 * @throws {AssertionError} If the config is valid or if the error
110 * has an unexpected message.
112 async
function assertInvalidConfig(values
, message
) {
113 const configs
= createFlatConfigArray(values
);
115 await configs
.normalize();
117 assert
.throws(() => {
118 configs
.getConfig("foo.js");
123 * Normalizes the rule configs to an array with severity to match
124 * how Flat Config merges rule options.
125 * @param {Object} rulesConfig The rules config portion of a config.
126 * @returns {Array} The rules config object.
128 function normalizeRuleConfig(rulesConfig
) {
129 const rulesConfigCopy
= {
133 for (const ruleId
of Object
.keys(rulesConfigCopy
)) {
134 rulesConfigCopy
[ruleId
] = [2];
137 return rulesConfigCopy
;
140 //-----------------------------------------------------------------------------
142 //-----------------------------------------------------------------------------
144 describe("FlatConfigArray", () => {
146 describe("Special configs", () => {
147 it("eslint:recommended is replaced with an actual config", async () => {
148 const configs
= new FlatConfigArray(["eslint:recommended"], { basePath
: __dirname
});
150 await configs
.normalize();
151 const config
= configs
.getConfig("foo.js");
153 assert
.deepStrictEqual(config
.rules
, normalizeRuleConfig(recommendedConfig
.rules
));
156 it("eslint:all is replaced with an actual config", async () => {
157 const configs
= new FlatConfigArray(["eslint:all"], { basePath
: __dirname
});
159 await configs
.normalize();
160 const config
= configs
.getConfig("foo.js");
162 assert
.deepStrictEqual(config
.rules
, normalizeRuleConfig(allConfig
.rules
));
166 describe("Config Properties", () => {
168 describe("settings", () => {
170 it("should merge two objects", () => assertMergedResult([
184 plugins
: baseConfig
.plugins
,
194 it("should merge two objects when second object has overrides", () => assertMergedResult([
211 plugins
: baseConfig
.plugins
,
222 it("should deeply merge two objects when second object has overrides", () => assertMergedResult([
240 plugins
: baseConfig
.plugins
,
251 it("should merge an object and undefined into one object", () => assertMergedResult([
261 plugins
: baseConfig
.plugins
,
269 it("should merge undefined and an object into one object", () => assertMergedResult([
279 plugins
: baseConfig
.plugins
,
289 describe("plugins", () => {
295 it("should merge two objects", () => assertMergedResult([
312 ...baseConfig
.plugins
316 it("should merge an object and undefined into one object", () => assertMergedResult([
329 ...baseConfig
.plugins
333 it("should error when attempting to redefine a plugin", async () => {
335 await
assertInvalidConfig([
347 ], "Cannot redefine plugin \"a\".");
350 it("should error when plugin is not an object", async () => {
352 await
assertInvalidConfig([
358 ], "Key \"a\": Expected an object.");
364 describe("processor", () => {
366 it("should merge two values when second is a string", () => {
368 const stubProcessor
= {
373 return assertMergedResult([
384 markdown
: stubProcessor
388 processor
: "markdown/markdown"
394 markdown
: stubProcessor
397 ...baseConfig
.plugins
399 processor
: stubProcessor
403 it("should merge two values when second is an object", () => {
410 return assertMergedResult([
412 processor
: "markdown/markdown"
418 plugins
: baseConfig
.plugins
,
424 it("should error when an invalid string is used", async () => {
426 await
assertInvalidConfig([
430 ], "pluginName/objectName");
433 it("should error when an empty string is used", async () => {
435 await
assertInvalidConfig([
439 ], "pluginName/objectName");
442 it("should error when an invalid processor is used", async () => {
443 await
assertInvalidConfig([
447 ], "Object must have a preprocess() and a postprocess() method.");
451 it("should error when a processor cannot be found in a plugin", async () => {
452 await
assertInvalidConfig([
459 ], /Could not find "bar" in plugin "foo"/u);
465 describe("linterOptions", () => {
467 it("should error when an unexpected key is found", async () => {
469 await
assertInvalidConfig([
475 ], "Unexpected key \"foo\" found.");
479 describe("noInlineConfig", () => {
481 it("should error when an unexpected value is found", async () => {
483 await
assertInvalidConfig([
486 noInlineConfig
: "true"
489 ], "Expected a Boolean.");
492 it("should merge two objects when second object has overrides", () => assertMergedResult([
500 noInlineConfig
: false
504 plugins
: baseConfig
.plugins
,
507 noInlineConfig
: false
511 it("should merge an object and undefined into one object", () => assertMergedResult([
514 noInlineConfig
: false
520 plugins
: baseConfig
.plugins
,
523 noInlineConfig
: false
527 it("should merge undefined and an object into one object", () => assertMergedResult([
532 noInlineConfig
: false
536 plugins
: baseConfig
.plugins
,
539 noInlineConfig
: false
545 describe("reportUnusedDisableDirectives", () => {
547 it("should error when an unexpected value is found", async () => {
549 await
assertInvalidConfig([
552 reportUnusedDisableDirectives
: "true"
555 ], /Expected a Boolean/u);
558 it("should merge two objects when second object has overrides", () => assertMergedResult([
561 reportUnusedDisableDirectives
: false
566 reportUnusedDisableDirectives
: true
570 plugins
: baseConfig
.plugins
,
573 reportUnusedDisableDirectives
: true
577 it("should merge an object and undefined into one object", () => assertMergedResult([
581 reportUnusedDisableDirectives
: true
585 plugins
: baseConfig
.plugins
,
588 reportUnusedDisableDirectives
: true
597 describe("languageOptions", () => {
599 it("should error when an unexpected key is found", async () => {
601 await
assertInvalidConfig([
607 ], "Unexpected key \"foo\" found.");
611 it("should merge two languageOptions objects with different properties", () => assertMergedResult([
619 sourceType
: "commonjs"
623 plugins
: baseConfig
.plugins
,
627 sourceType
: "commonjs"
631 describe("ecmaVersion", () => {
633 it("should error when an unexpected value is found", async () => {
635 await
assertInvalidConfig([
641 ], "Expected a number.");
644 it("should merge two objects when second object has overrides", () => assertMergedResult([
656 plugins
: baseConfig
.plugins
,
663 it("should merge an object and undefined into one object", () => assertMergedResult([
672 plugins
: baseConfig
.plugins
,
680 it("should merge undefined and an object into one object", () => assertMergedResult([
689 plugins
: baseConfig
.plugins
,
699 describe("sourceType", () => {
701 it("should error when an unexpected value is found", async () => {
703 await
assertInvalidConfig([
709 ], "Expected \"script\", \"module\", or \"commonjs\".");
712 it("should merge two objects when second object has overrides", () => assertMergedResult([
724 plugins
: baseConfig
.plugins
,
731 it("should merge an object and undefined into one object", () => assertMergedResult([
740 plugins
: baseConfig
.plugins
,
748 it("should merge undefined and an object into one object", () => assertMergedResult([
757 plugins
: baseConfig
.plugins
,
767 describe("globals", () => {
769 it("should error when an unexpected value is found", async () => {
771 await
assertInvalidConfig([
777 ], "Expected an object.");
780 it("should error when an unexpected key value is found", async () => {
782 await
assertInvalidConfig([
790 ], "Key \"foo\": Expected \"readonly\", \"writable\", or \"off\".");
793 it("should error when a global has leading whitespace", async () => {
795 await
assertInvalidConfig([
803 ], /Global " foo" has leading or trailing whitespace/u);
806 it("should error when a global has trailing whitespace", async () => {
808 await
assertInvalidConfig([
816 ], /Global "foo " has leading or trailing whitespace/u);
819 it("should merge two objects when second object has different keys", () => assertMergedResult([
835 plugins
: baseConfig
.plugins
,
845 it("should merge two objects when second object has overrides", () => assertMergedResult([
861 plugins
: baseConfig
.plugins
,
870 it("should merge an object and undefined into one object", () => assertMergedResult([
881 plugins
: baseConfig
.plugins
,
891 it("should merge undefined and an object into one object", () => assertMergedResult([
902 plugins
: baseConfig
.plugins
,
914 describe("parser", () => {
916 it("should error when an unexpected value is found", async () => {
918 await
assertInvalidConfig([
924 ], "Expected an object or string.");
927 it("should error when an unexpected value is found", async () => {
929 await
assertInvalidConfig([
935 ], /Expected string in the form "pluginName\/objectName"/u);
938 it("should error when a plugin parser can't be found", async () => {
940 await
assertInvalidConfig([
946 ], "Key \"parser\": Could not find \"bar\" in plugin \"foo\".");
949 it("should error when a value doesn't have a parse() method", async () => {
951 await
assertInvalidConfig([
957 ], "Expected object to have a parse() or parseForESLint() method.");
960 it("should merge two objects when second object has overrides", () => {
962 const parser
= { parse() {} };
963 const stubParser
= { parse() { } };
965 return assertMergedResult([
980 parser
: "@foo/baz/bar"
990 ...baseConfig
.plugins
998 it("should merge an object and undefined into one object", () => {
1000 const stubParser
= { parse() { } };
1002 return assertMergedResult([
1025 ...baseConfig
.plugins
1036 it("should merge undefined and an object into one object", () => {
1038 const stubParser
= { parse() {} };
1040 return assertMergedResult([
1063 ...baseConfig
.plugins
1076 describe("parserOptions", () => {
1078 it("should error when an unexpected value is found", async () => {
1080 await
assertInvalidConfig([
1083 parserOptions
: "true"
1086 ], "Expected an object.");
1089 it("should merge two objects when second object has different keys", () => assertMergedResult([
1105 plugins
: baseConfig
.plugins
,
1115 it("should deeply merge two objects when second object has different keys", () => assertMergedResult([
1135 plugins
: baseConfig
.plugins
,
1147 it("should deeply merge two objects when second object has missing key", () => assertMergedResult([
1163 plugins
: baseConfig
.plugins
,
1175 it("should merge two objects when second object has overrides", () => assertMergedResult([
1191 plugins
: baseConfig
.plugins
,
1200 it("should merge an object and undefined into one object", () => assertMergedResult([
1211 plugins
: baseConfig
.plugins
,
1221 it("should merge undefined and an object into one object", () => assertMergedResult([
1232 plugins
: baseConfig
.plugins
,
1247 describe("rules", () => {
1249 it("should error when an unexpected value is found", async () => {
1251 await
assertInvalidConfig([
1255 ], "Expected an object.");
1258 it("should error when an invalid rule severity is set", async () => {
1260 await
assertInvalidConfig([
1266 ], "Key \"rules\": Key \"foo\": Expected a string, number, or array.");
1269 it("should error when an invalid rule severity of the right type is set", async () => {
1271 await
assertInvalidConfig([
1277 ], "Key \"rules\": Key \"foo\": Expected severity of \"off\", 0, \"warn\", 1, \"error\", or 2.");
1280 it("should error when an invalid rule severity is set in an array", async () => {
1282 await
assertInvalidConfig([
1288 ], "Key \"rules\": Key \"foo\": Expected severity of \"off\", 0, \"warn\", 1, \"error\", or 2.");
1291 it("should error when rule doesn't exist", async () => {
1293 await
assertInvalidConfig([
1299 ], /Key "rules": Key "foox": Could not find "foox" in plugin "@"./u);
1302 it("should error and suggest alternative when rule doesn't exist", async () => {
1304 await
assertInvalidConfig([
1307 "test2/match": "error"
1310 ], /Key "rules": Key "test2\/match": Could not find "match" in plugin "test2"\. Did you mean "test1\/match"\?/u);
1313 it("should error when plugin for rule doesn't exist", async () => {
1315 await
assertInvalidConfig([
1318 "doesnt-exist/match": "error"
1321 ], /Key "rules": Key "doesnt-exist\/match": Could not find plugin "doesnt-exist"\./u);
1324 it("should error when rule options don't match schema", async () => {
1326 await
assertInvalidConfig([
1332 ], /Value "bar" should be equal to one of the allowed values/u);
1335 it("should error when rule options don't match schema requiring at least one item", async () => {
1337 await
assertInvalidConfig([
1343 ], /Value \[\] should NOT have fewer than 1 items/u);
1346 it("should merge two objects", () => assertMergedResult([
1360 plugins
: baseConfig
.plugins
,
1370 it("should merge two objects when second object has simple overrides", () => assertMergedResult([
1384 plugins
: baseConfig
.plugins
,
1392 it("should merge two objects when second object has array overrides", () => assertMergedResult([
1401 foo
: ["error", "never"],
1402 bar
: ["warn", "foo"]
1406 plugins
: baseConfig
.plugins
,
1413 it("should merge two objects and options when second object overrides without options", () => assertMergedResult([
1431 "foo/baz/boom/bang": "error"
1436 ...baseConfig
.plugins
,
1446 "foo/baz/boom/bang": [2]
1450 it("should merge an object and undefined into one object", () => assertMergedResult([
1460 plugins
: baseConfig
.plugins
,
1467 it("should merge a rule that doesn't exist without error when the rule is off", () => assertMergedResult([
1477 nonExistentRule2
: ["off", "bar"]
1481 plugins
: baseConfig
.plugins
,
1485 nonExistentRule
: [0],
1486 nonExistentRule2
: [0, "bar"]