]> git.proxmox.com Git - pve-eslint.git/blob - eslint/tests/lib/config/flat-config-array.js
f6b099096e1694555b97d09a4beba32aa6250518
[pve-eslint.git] / eslint / tests / lib / config / flat-config-array.js
1 /**
2 * @fileoverview Tests for FlatConfigArray
3 * @author Nicholas C. Zakas
4 */
5
6 "use strict";
7
8 //-----------------------------------------------------------------------------
9 // Requirements
10 //-----------------------------------------------------------------------------
11
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");
16
17 //-----------------------------------------------------------------------------
18 // Helpers
19 //-----------------------------------------------------------------------------
20
21 const baseConfig = {
22 plugins: {
23 "@": {
24 rules: {
25 foo: {
26 schema: {
27 type: "array",
28 items: [
29 {
30 enum: ["always", "never"]
31 }
32 ],
33 minItems: 0,
34 maxItems: 1
35 }
36
37 },
38 bar: {
39
40 },
41 baz: {
42
43 },
44
45 // old-style
46 boom() {},
47
48 foo2: {
49 schema: {
50 type: "array",
51 items: {
52 type: "string"
53 },
54 uniqueItems: true,
55 minItems: 1
56 }
57 }
58 }
59 },
60 test1: {
61 rules: {
62 match: {}
63 }
64 },
65 test2: {
66 rules: {
67 nomatch: {}
68 }
69 }
70 }
71 };
72
73 /**
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;
77 */
78 function createFlatConfigArray(configs) {
79 return new FlatConfigArray(configs, {
80 basePath: __dirname,
81 baseConfig
82 });
83 }
84
85 /**
86 * Asserts that a given set of configs will be merged into the given
87 * result config.
88 * @param {*[]} values An array of configs to use in the config array.
89 * @param {Object} result The expected merged result of the configs.
90 * @returns {void}
91 * @throws {AssertionError} If the actual result doesn't match the
92 * expected result.
93 */
94 async function assertMergedResult(values, result) {
95 const configs = createFlatConfigArray(values);
96
97 await configs.normalize();
98
99 const config = configs.getConfig("foo.js");
100
101 assert.deepStrictEqual(config, result);
102 }
103
104 /**
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.
108 * @returns {void}
109 * @throws {AssertionError} If the config is valid or if the error
110 * has an unexpected message.
111 */
112 async function assertInvalidConfig(values, message) {
113 const configs = createFlatConfigArray(values);
114
115 await configs.normalize();
116
117 assert.throws(() => {
118 configs.getConfig("foo.js");
119 }, message);
120 }
121
122 /**
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.
127 */
128 function normalizeRuleConfig(rulesConfig) {
129 const rulesConfigCopy = {
130 ...rulesConfig
131 };
132
133 for (const ruleId of Object.keys(rulesConfigCopy)) {
134 rulesConfigCopy[ruleId] = [2];
135 }
136
137 return rulesConfigCopy;
138 }
139
140 //-----------------------------------------------------------------------------
141 // Tests
142 //-----------------------------------------------------------------------------
143
144 describe("FlatConfigArray", () => {
145
146 describe("Special configs", () => {
147 it("eslint:recommended is replaced with an actual config", async () => {
148 const configs = new FlatConfigArray(["eslint:recommended"], { basePath: __dirname });
149
150 await configs.normalize();
151 const config = configs.getConfig("foo.js");
152
153 assert.deepStrictEqual(config.rules, normalizeRuleConfig(recommendedConfig.rules));
154 });
155
156 it("eslint:all is replaced with an actual config", async () => {
157 const configs = new FlatConfigArray(["eslint:all"], { basePath: __dirname });
158
159 await configs.normalize();
160 const config = configs.getConfig("foo.js");
161
162 assert.deepStrictEqual(config.rules, normalizeRuleConfig(allConfig.rules));
163 });
164 });
165
166 describe("Config Properties", () => {
167
168 describe("settings", () => {
169
170 it("should merge two objects", () => assertMergedResult([
171 {
172 settings: {
173 a: true,
174 b: false
175 }
176 },
177 {
178 settings: {
179 c: true,
180 d: false
181 }
182 }
183 ], {
184 plugins: baseConfig.plugins,
185
186 settings: {
187 a: true,
188 b: false,
189 c: true,
190 d: false
191 }
192 }));
193
194 it("should merge two objects when second object has overrides", () => assertMergedResult([
195 {
196 settings: {
197 a: true,
198 b: false,
199 d: [1, 2],
200 e: [5, 6]
201 }
202 },
203 {
204 settings: {
205 c: true,
206 a: false,
207 d: [3, 4]
208 }
209 }
210 ], {
211 plugins: baseConfig.plugins,
212
213 settings: {
214 a: false,
215 b: false,
216 c: true,
217 d: [3, 4],
218 e: [5, 6]
219 }
220 }));
221
222 it("should deeply merge two objects when second object has overrides", () => assertMergedResult([
223 {
224 settings: {
225 object: {
226 a: true,
227 b: false
228 }
229 }
230 },
231 {
232 settings: {
233 object: {
234 c: true,
235 a: false
236 }
237 }
238 }
239 ], {
240 plugins: baseConfig.plugins,
241
242 settings: {
243 object: {
244 a: false,
245 b: false,
246 c: true
247 }
248 }
249 }));
250
251 it("should merge an object and undefined into one object", () => assertMergedResult([
252 {
253 settings: {
254 a: true,
255 b: false
256 }
257 },
258 {
259 }
260 ], {
261 plugins: baseConfig.plugins,
262
263 settings: {
264 a: true,
265 b: false
266 }
267 }));
268
269 it("should merge undefined and an object into one object", () => assertMergedResult([
270 {
271 },
272 {
273 settings: {
274 a: true,
275 b: false
276 }
277 }
278 ], {
279 plugins: baseConfig.plugins,
280
281 settings: {
282 a: true,
283 b: false
284 }
285 }));
286
287 });
288
289 describe("plugins", () => {
290
291 const pluginA = {};
292 const pluginB = {};
293 const pluginC = {};
294
295 it("should merge two objects", () => assertMergedResult([
296 {
297 plugins: {
298 a: pluginA,
299 b: pluginB
300 }
301 },
302 {
303 plugins: {
304 c: pluginC
305 }
306 }
307 ], {
308 plugins: {
309 a: pluginA,
310 b: pluginB,
311 c: pluginC,
312 ...baseConfig.plugins
313 }
314 }));
315
316 it("should merge an object and undefined into one object", () => assertMergedResult([
317 {
318 plugins: {
319 a: pluginA,
320 b: pluginB
321 }
322 },
323 {
324 }
325 ], {
326 plugins: {
327 a: pluginA,
328 b: pluginB,
329 ...baseConfig.plugins
330 }
331 }));
332
333 it("should error when attempting to redefine a plugin", async () => {
334
335 await assertInvalidConfig([
336 {
337 plugins: {
338 a: pluginA,
339 b: pluginB
340 }
341 },
342 {
343 plugins: {
344 a: pluginC
345 }
346 }
347 ], "Cannot redefine plugin \"a\".");
348 });
349
350 it("should error when plugin is not an object", async () => {
351
352 await assertInvalidConfig([
353 {
354 plugins: {
355 a: true
356 }
357 }
358 ], "Key \"a\": Expected an object.");
359 });
360
361
362 });
363
364 describe("processor", () => {
365
366 it("should merge two values when second is a string", () => {
367
368 const stubProcessor = {
369 preprocess() {},
370 postprocess() {}
371 };
372
373 return assertMergedResult([
374 {
375 processor: {
376 preprocess() {},
377 postprocess() {}
378 }
379 },
380 {
381 plugins: {
382 markdown: {
383 processors: {
384 markdown: stubProcessor
385 }
386 }
387 },
388 processor: "markdown/markdown"
389 }
390 ], {
391 plugins: {
392 markdown: {
393 processors: {
394 markdown: stubProcessor
395 }
396 },
397 ...baseConfig.plugins
398 },
399 processor: stubProcessor
400 });
401 });
402
403 it("should merge two values when second is an object", () => {
404
405 const processor = {
406 preprocess() { },
407 postprocess() { }
408 };
409
410 return assertMergedResult([
411 {
412 processor: "markdown/markdown"
413 },
414 {
415 processor
416 }
417 ], {
418 plugins: baseConfig.plugins,
419
420 processor
421 });
422 });
423
424 it("should error when an invalid string is used", async () => {
425
426 await assertInvalidConfig([
427 {
428 processor: "foo"
429 }
430 ], "pluginName/objectName");
431 });
432
433 it("should error when an empty string is used", async () => {
434
435 await assertInvalidConfig([
436 {
437 processor: ""
438 }
439 ], "pluginName/objectName");
440 });
441
442 it("should error when an invalid processor is used", async () => {
443 await assertInvalidConfig([
444 {
445 processor: {}
446 }
447 ], "Object must have a preprocess() and a postprocess() method.");
448
449 });
450
451 it("should error when a processor cannot be found in a plugin", async () => {
452 await assertInvalidConfig([
453 {
454 plugins: {
455 foo: {}
456 },
457 processor: "foo/bar"
458 }
459 ], /Could not find "bar" in plugin "foo"/u);
460
461 });
462
463 });
464
465 describe("linterOptions", () => {
466
467 it("should error when an unexpected key is found", async () => {
468
469 await assertInvalidConfig([
470 {
471 linterOptions: {
472 foo: true
473 }
474 }
475 ], "Unexpected key \"foo\" found.");
476
477 });
478
479 describe("noInlineConfig", () => {
480
481 it("should error when an unexpected value is found", async () => {
482
483 await assertInvalidConfig([
484 {
485 linterOptions: {
486 noInlineConfig: "true"
487 }
488 }
489 ], "Expected a Boolean.");
490 });
491
492 it("should merge two objects when second object has overrides", () => assertMergedResult([
493 {
494 linterOptions: {
495 noInlineConfig: true
496 }
497 },
498 {
499 linterOptions: {
500 noInlineConfig: false
501 }
502 }
503 ], {
504 plugins: baseConfig.plugins,
505
506 linterOptions: {
507 noInlineConfig: false
508 }
509 }));
510
511 it("should merge an object and undefined into one object", () => assertMergedResult([
512 {
513 linterOptions: {
514 noInlineConfig: false
515 }
516 },
517 {
518 }
519 ], {
520 plugins: baseConfig.plugins,
521
522 linterOptions: {
523 noInlineConfig: false
524 }
525 }));
526
527 it("should merge undefined and an object into one object", () => assertMergedResult([
528 {
529 },
530 {
531 linterOptions: {
532 noInlineConfig: false
533 }
534 }
535 ], {
536 plugins: baseConfig.plugins,
537
538 linterOptions: {
539 noInlineConfig: false
540 }
541 }));
542
543
544 });
545 describe("reportUnusedDisableDirectives", () => {
546
547 it("should error when an unexpected value is found", async () => {
548
549 await assertInvalidConfig([
550 {
551 linterOptions: {
552 reportUnusedDisableDirectives: "true"
553 }
554 }
555 ], /Expected a Boolean/u);
556 });
557
558 it("should merge two objects when second object has overrides", () => assertMergedResult([
559 {
560 linterOptions: {
561 reportUnusedDisableDirectives: false
562 }
563 },
564 {
565 linterOptions: {
566 reportUnusedDisableDirectives: true
567 }
568 }
569 ], {
570 plugins: baseConfig.plugins,
571
572 linterOptions: {
573 reportUnusedDisableDirectives: true
574 }
575 }));
576
577 it("should merge an object and undefined into one object", () => assertMergedResult([
578 {},
579 {
580 linterOptions: {
581 reportUnusedDisableDirectives: true
582 }
583 }
584 ], {
585 plugins: baseConfig.plugins,
586
587 linterOptions: {
588 reportUnusedDisableDirectives: true
589 }
590 }));
591
592
593 });
594
595 });
596
597 describe("languageOptions", () => {
598
599 it("should error when an unexpected key is found", async () => {
600
601 await assertInvalidConfig([
602 {
603 languageOptions: {
604 foo: true
605 }
606 }
607 ], "Unexpected key \"foo\" found.");
608
609 });
610
611 it("should merge two languageOptions objects with different properties", () => assertMergedResult([
612 {
613 languageOptions: {
614 ecmaVersion: 2019
615 }
616 },
617 {
618 languageOptions: {
619 sourceType: "commonjs"
620 }
621 }
622 ], {
623 plugins: baseConfig.plugins,
624
625 languageOptions: {
626 ecmaVersion: 2019,
627 sourceType: "commonjs"
628 }
629 }));
630
631 describe("ecmaVersion", () => {
632
633 it("should error when an unexpected value is found", async () => {
634
635 await assertInvalidConfig([
636 {
637 languageOptions: {
638 ecmaVersion: "true"
639 }
640 }
641 ], "Expected a number.");
642 });
643
644 it("should merge two objects when second object has overrides", () => assertMergedResult([
645 {
646 languageOptions: {
647 ecmaVersion: 2019
648 }
649 },
650 {
651 languageOptions: {
652 ecmaVersion: 2021
653 }
654 }
655 ], {
656 plugins: baseConfig.plugins,
657
658 languageOptions: {
659 ecmaVersion: 2021
660 }
661 }));
662
663 it("should merge an object and undefined into one object", () => assertMergedResult([
664 {
665 languageOptions: {
666 ecmaVersion: 2021
667 }
668 },
669 {
670 }
671 ], {
672 plugins: baseConfig.plugins,
673
674 languageOptions: {
675 ecmaVersion: 2021
676 }
677 }));
678
679
680 it("should merge undefined and an object into one object", () => assertMergedResult([
681 {
682 },
683 {
684 languageOptions: {
685 ecmaVersion: 2021
686 }
687 }
688 ], {
689 plugins: baseConfig.plugins,
690
691 languageOptions: {
692 ecmaVersion: 2021
693 }
694 }));
695
696
697 });
698
699 describe("sourceType", () => {
700
701 it("should error when an unexpected value is found", async () => {
702
703 await assertInvalidConfig([
704 {
705 languageOptions: {
706 sourceType: "true"
707 }
708 }
709 ], "Expected \"script\", \"module\", or \"commonjs\".");
710 });
711
712 it("should merge two objects when second object has overrides", () => assertMergedResult([
713 {
714 languageOptions: {
715 sourceType: "module"
716 }
717 },
718 {
719 languageOptions: {
720 sourceType: "script"
721 }
722 }
723 ], {
724 plugins: baseConfig.plugins,
725
726 languageOptions: {
727 sourceType: "script"
728 }
729 }));
730
731 it("should merge an object and undefined into one object", () => assertMergedResult([
732 {
733 languageOptions: {
734 sourceType: "script"
735 }
736 },
737 {
738 }
739 ], {
740 plugins: baseConfig.plugins,
741
742 languageOptions: {
743 sourceType: "script"
744 }
745 }));
746
747
748 it("should merge undefined and an object into one object", () => assertMergedResult([
749 {
750 },
751 {
752 languageOptions: {
753 sourceType: "module"
754 }
755 }
756 ], {
757 plugins: baseConfig.plugins,
758
759 languageOptions: {
760 sourceType: "module"
761 }
762 }));
763
764
765 });
766
767 describe("globals", () => {
768
769 it("should error when an unexpected value is found", async () => {
770
771 await assertInvalidConfig([
772 {
773 languageOptions: {
774 globals: "true"
775 }
776 }
777 ], "Expected an object.");
778 });
779
780 it("should error when an unexpected key value is found", async () => {
781
782 await assertInvalidConfig([
783 {
784 languageOptions: {
785 globals: {
786 foo: "truex"
787 }
788 }
789 }
790 ], "Key \"foo\": Expected \"readonly\", \"writable\", or \"off\".");
791 });
792
793 it("should error when a global has leading whitespace", async () => {
794
795 await assertInvalidConfig([
796 {
797 languageOptions: {
798 globals: {
799 " foo": "readonly"
800 }
801 }
802 }
803 ], /Global " foo" has leading or trailing whitespace/u);
804 });
805
806 it("should error when a global has trailing whitespace", async () => {
807
808 await assertInvalidConfig([
809 {
810 languageOptions: {
811 globals: {
812 "foo ": "readonly"
813 }
814 }
815 }
816 ], /Global "foo " has leading or trailing whitespace/u);
817 });
818
819 it("should merge two objects when second object has different keys", () => assertMergedResult([
820 {
821 languageOptions: {
822 globals: {
823 foo: "readonly"
824 }
825 }
826 },
827 {
828 languageOptions: {
829 globals: {
830 bar: "writable"
831 }
832 }
833 }
834 ], {
835 plugins: baseConfig.plugins,
836
837 languageOptions: {
838 globals: {
839 foo: "readonly",
840 bar: "writable"
841 }
842 }
843 }));
844
845 it("should merge two objects when second object has overrides", () => assertMergedResult([
846 {
847 languageOptions: {
848 globals: {
849 foo: null
850 }
851 }
852 },
853 {
854 languageOptions: {
855 globals: {
856 foo: "writeable"
857 }
858 }
859 }
860 ], {
861 plugins: baseConfig.plugins,
862
863 languageOptions: {
864 globals: {
865 foo: "writeable"
866 }
867 }
868 }));
869
870 it("should merge an object and undefined into one object", () => assertMergedResult([
871 {
872 languageOptions: {
873 globals: {
874 foo: "readable"
875 }
876 }
877 },
878 {
879 }
880 ], {
881 plugins: baseConfig.plugins,
882
883 languageOptions: {
884 globals: {
885 foo: "readable"
886 }
887 }
888 }));
889
890
891 it("should merge undefined and an object into one object", () => assertMergedResult([
892 {
893 },
894 {
895 languageOptions: {
896 globals: {
897 foo: "false"
898 }
899 }
900 }
901 ], {
902 plugins: baseConfig.plugins,
903
904 languageOptions: {
905 globals: {
906 foo: "false"
907 }
908 }
909 }));
910
911
912 });
913
914 describe("parser", () => {
915
916 it("should error when an unexpected value is found", async () => {
917
918 await assertInvalidConfig([
919 {
920 languageOptions: {
921 parser: true
922 }
923 }
924 ], "Expected an object or string.");
925 });
926
927 it("should error when an unexpected value is found", async () => {
928
929 await assertInvalidConfig([
930 {
931 languageOptions: {
932 parser: "true"
933 }
934 }
935 ], /Expected string in the form "pluginName\/objectName"/u);
936 });
937
938 it("should error when a plugin parser can't be found", async () => {
939
940 await assertInvalidConfig([
941 {
942 languageOptions: {
943 parser: "foo/bar"
944 }
945 }
946 ], "Key \"parser\": Could not find \"bar\" in plugin \"foo\".");
947 });
948
949 it("should error when a value doesn't have a parse() method", async () => {
950
951 await assertInvalidConfig([
952 {
953 languageOptions: {
954 parser: {}
955 }
956 }
957 ], "Expected object to have a parse() or parseForESLint() method.");
958 });
959
960 it("should merge two objects when second object has overrides", () => {
961
962 const parser = { parse() {} };
963 const stubParser = { parse() { } };
964
965 return assertMergedResult([
966 {
967 languageOptions: {
968 parser
969 }
970 },
971 {
972 plugins: {
973 "@foo/baz": {
974 parsers: {
975 bar: stubParser
976 }
977 }
978 },
979 languageOptions: {
980 parser: "@foo/baz/bar"
981 }
982 }
983 ], {
984 plugins: {
985 "@foo/baz": {
986 parsers: {
987 bar: stubParser
988 }
989 },
990 ...baseConfig.plugins
991 },
992 languageOptions: {
993 parser: stubParser
994 }
995 });
996 });
997
998 it("should merge an object and undefined into one object", () => {
999
1000 const stubParser = { parse() { } };
1001
1002 return assertMergedResult([
1003 {
1004 plugins: {
1005 foo: {
1006 parsers: {
1007 bar: stubParser
1008 }
1009 }
1010 },
1011
1012 languageOptions: {
1013 parser: "foo/bar"
1014 }
1015 },
1016 {
1017 }
1018 ], {
1019 plugins: {
1020 foo: {
1021 parsers: {
1022 bar: stubParser
1023 }
1024 },
1025 ...baseConfig.plugins
1026 },
1027
1028 languageOptions: {
1029 parser: stubParser
1030 }
1031 });
1032
1033 });
1034
1035
1036 it("should merge undefined and an object into one object", () => {
1037
1038 const stubParser = { parse() {} };
1039
1040 return assertMergedResult([
1041 {
1042 },
1043 {
1044 plugins: {
1045 foo: {
1046 parsers: {
1047 bar: stubParser
1048 }
1049 }
1050 },
1051
1052 languageOptions: {
1053 parser: "foo/bar"
1054 }
1055 }
1056 ], {
1057 plugins: {
1058 foo: {
1059 parsers: {
1060 bar: stubParser
1061 }
1062 },
1063 ...baseConfig.plugins
1064 },
1065
1066 languageOptions: {
1067 parser: stubParser
1068 }
1069 });
1070
1071 });
1072
1073 });
1074
1075
1076 describe("parserOptions", () => {
1077
1078 it("should error when an unexpected value is found", async () => {
1079
1080 await assertInvalidConfig([
1081 {
1082 languageOptions: {
1083 parserOptions: "true"
1084 }
1085 }
1086 ], "Expected an object.");
1087 });
1088
1089 it("should merge two objects when second object has different keys", () => assertMergedResult([
1090 {
1091 languageOptions: {
1092 parserOptions: {
1093 foo: "whatever"
1094 }
1095 }
1096 },
1097 {
1098 languageOptions: {
1099 parserOptions: {
1100 bar: "baz"
1101 }
1102 }
1103 }
1104 ], {
1105 plugins: baseConfig.plugins,
1106
1107 languageOptions: {
1108 parserOptions: {
1109 foo: "whatever",
1110 bar: "baz"
1111 }
1112 }
1113 }));
1114
1115 it("should deeply merge two objects when second object has different keys", () => assertMergedResult([
1116 {
1117 languageOptions: {
1118 parserOptions: {
1119 ecmaFeatures: {
1120 jsx: true
1121 }
1122 }
1123 }
1124 },
1125 {
1126 languageOptions: {
1127 parserOptions: {
1128 ecmaFeatures: {
1129 globalReturn: true
1130 }
1131 }
1132 }
1133 }
1134 ], {
1135 plugins: baseConfig.plugins,
1136
1137 languageOptions: {
1138 parserOptions: {
1139 ecmaFeatures: {
1140 jsx: true,
1141 globalReturn: true
1142 }
1143 }
1144 }
1145 }));
1146
1147 it("should deeply merge two objects when second object has missing key", () => assertMergedResult([
1148 {
1149 languageOptions: {
1150 parserOptions: {
1151 ecmaFeatures: {
1152 jsx: true
1153 }
1154 }
1155 }
1156 },
1157 {
1158 languageOptions: {
1159 ecmaVersion: 2021
1160 }
1161 }
1162 ], {
1163 plugins: baseConfig.plugins,
1164
1165 languageOptions: {
1166 ecmaVersion: 2021,
1167 parserOptions: {
1168 ecmaFeatures: {
1169 jsx: true
1170 }
1171 }
1172 }
1173 }));
1174
1175 it("should merge two objects when second object has overrides", () => assertMergedResult([
1176 {
1177 languageOptions: {
1178 parserOptions: {
1179 foo: "whatever"
1180 }
1181 }
1182 },
1183 {
1184 languageOptions: {
1185 parserOptions: {
1186 foo: "bar"
1187 }
1188 }
1189 }
1190 ], {
1191 plugins: baseConfig.plugins,
1192
1193 languageOptions: {
1194 parserOptions: {
1195 foo: "bar"
1196 }
1197 }
1198 }));
1199
1200 it("should merge an object and undefined into one object", () => assertMergedResult([
1201 {
1202 languageOptions: {
1203 parserOptions: {
1204 foo: "whatever"
1205 }
1206 }
1207 },
1208 {
1209 }
1210 ], {
1211 plugins: baseConfig.plugins,
1212
1213 languageOptions: {
1214 parserOptions: {
1215 foo: "whatever"
1216 }
1217 }
1218 }));
1219
1220
1221 it("should merge undefined and an object into one object", () => assertMergedResult([
1222 {
1223 },
1224 {
1225 languageOptions: {
1226 parserOptions: {
1227 foo: "bar"
1228 }
1229 }
1230 }
1231 ], {
1232 plugins: baseConfig.plugins,
1233
1234 languageOptions: {
1235 parserOptions: {
1236 foo: "bar"
1237 }
1238 }
1239 }));
1240
1241
1242 });
1243
1244
1245 });
1246
1247 describe("rules", () => {
1248
1249 it("should error when an unexpected value is found", async () => {
1250
1251 await assertInvalidConfig([
1252 {
1253 rules: true
1254 }
1255 ], "Expected an object.");
1256 });
1257
1258 it("should error when an invalid rule severity is set", async () => {
1259
1260 await assertInvalidConfig([
1261 {
1262 rules: {
1263 foo: true
1264 }
1265 }
1266 ], "Key \"rules\": Key \"foo\": Expected a string, number, or array.");
1267 });
1268
1269 it("should error when an invalid rule severity of the right type is set", async () => {
1270
1271 await assertInvalidConfig([
1272 {
1273 rules: {
1274 foo: 3
1275 }
1276 }
1277 ], "Key \"rules\": Key \"foo\": Expected severity of \"off\", 0, \"warn\", 1, \"error\", or 2.");
1278 });
1279
1280 it("should error when an invalid rule severity is set in an array", async () => {
1281
1282 await assertInvalidConfig([
1283 {
1284 rules: {
1285 foo: [true]
1286 }
1287 }
1288 ], "Key \"rules\": Key \"foo\": Expected severity of \"off\", 0, \"warn\", 1, \"error\", or 2.");
1289 });
1290
1291 it("should error when rule doesn't exist", async () => {
1292
1293 await assertInvalidConfig([
1294 {
1295 rules: {
1296 foox: [1, "bar"]
1297 }
1298 }
1299 ], /Key "rules": Key "foox": Could not find "foox" in plugin "@"./u);
1300 });
1301
1302 it("should error and suggest alternative when rule doesn't exist", async () => {
1303
1304 await assertInvalidConfig([
1305 {
1306 rules: {
1307 "test2/match": "error"
1308 }
1309 }
1310 ], /Key "rules": Key "test2\/match": Could not find "match" in plugin "test2"\. Did you mean "test1\/match"\?/u);
1311 });
1312
1313 it("should error when plugin for rule doesn't exist", async () => {
1314
1315 await assertInvalidConfig([
1316 {
1317 rules: {
1318 "doesnt-exist/match": "error"
1319 }
1320 }
1321 ], /Key "rules": Key "doesnt-exist\/match": Could not find plugin "doesnt-exist"\./u);
1322 });
1323
1324 it("should error when rule options don't match schema", async () => {
1325
1326 await assertInvalidConfig([
1327 {
1328 rules: {
1329 foo: [1, "bar"]
1330 }
1331 }
1332 ], /Value "bar" should be equal to one of the allowed values/u);
1333 });
1334
1335 it("should error when rule options don't match schema requiring at least one item", async () => {
1336
1337 await assertInvalidConfig([
1338 {
1339 rules: {
1340 foo2: 1
1341 }
1342 }
1343 ], /Value \[\] should NOT have fewer than 1 items/u);
1344 });
1345
1346 it("should merge two objects", () => assertMergedResult([
1347 {
1348 rules: {
1349 foo: 1,
1350 bar: "error"
1351 }
1352 },
1353 {
1354 rules: {
1355 baz: "warn",
1356 boom: 0
1357 }
1358 }
1359 ], {
1360 plugins: baseConfig.plugins,
1361
1362 rules: {
1363 foo: [1],
1364 bar: [2],
1365 baz: [1],
1366 boom: [0]
1367 }
1368 }));
1369
1370 it("should merge two objects when second object has simple overrides", () => assertMergedResult([
1371 {
1372 rules: {
1373 foo: [1, "always"],
1374 bar: "error"
1375 }
1376 },
1377 {
1378 rules: {
1379 foo: "error",
1380 bar: 0
1381 }
1382 }
1383 ], {
1384 plugins: baseConfig.plugins,
1385
1386 rules: {
1387 foo: [2, "always"],
1388 bar: [0]
1389 }
1390 }));
1391
1392 it("should merge two objects when second object has array overrides", () => assertMergedResult([
1393 {
1394 rules: {
1395 foo: 1,
1396 bar: "error"
1397 }
1398 },
1399 {
1400 rules: {
1401 foo: ["error", "never"],
1402 bar: ["warn", "foo"]
1403 }
1404 }
1405 ], {
1406 plugins: baseConfig.plugins,
1407 rules: {
1408 foo: [2, "never"],
1409 bar: [1, "foo"]
1410 }
1411 }));
1412
1413 it("should merge two objects and options when second object overrides without options", () => assertMergedResult([
1414 {
1415 rules: {
1416 foo: [1, "always"],
1417 bar: "error"
1418 }
1419 },
1420 {
1421 plugins: {
1422 "foo/baz/boom": {
1423 rules: {
1424 bang: {}
1425 }
1426 }
1427 },
1428 rules: {
1429 foo: ["error"],
1430 bar: 0,
1431 "foo/baz/boom/bang": "error"
1432 }
1433 }
1434 ], {
1435 plugins: {
1436 ...baseConfig.plugins,
1437 "foo/baz/boom": {
1438 rules: {
1439 bang: {}
1440 }
1441 }
1442 },
1443 rules: {
1444 foo: [2, "always"],
1445 bar: [0],
1446 "foo/baz/boom/bang": [2]
1447 }
1448 }));
1449
1450 it("should merge an object and undefined into one object", () => assertMergedResult([
1451 {
1452 rules: {
1453 foo: 0,
1454 bar: 1
1455 }
1456 },
1457 {
1458 }
1459 ], {
1460 plugins: baseConfig.plugins,
1461 rules: {
1462 foo: [0],
1463 bar: [1]
1464 }
1465 }));
1466
1467 it("should merge a rule that doesn't exist without error when the rule is off", () => assertMergedResult([
1468 {
1469 rules: {
1470 foo: 0,
1471 bar: 1
1472 }
1473 },
1474 {
1475 rules: {
1476 nonExistentRule: 0,
1477 nonExistentRule2: ["off", "bar"]
1478 }
1479 }
1480 ], {
1481 plugins: baseConfig.plugins,
1482 rules: {
1483 foo: [0],
1484 bar: [1],
1485 nonExistentRule: [0],
1486 nonExistentRule2: [0, "bar"]
1487 }
1488 }));
1489
1490 });
1491
1492 });
1493 });