@@ -4,29 +4,99 @@ import { rules } from "../../lib/index"
4
4
import assert from "assert"
5
5
6
6
describe ( "Don't crash even if with v flag." , ( ) => {
7
- const pattern = String . raw `^(a|b)(?:c|d)[e-f][[g--[h&&i]][j]\q{k}](?=l)(?!m)(?<=n)(?<!o)p+\1\b.\d\s\w\p{ASCII}$`
8
- const code = [
9
- ( p : string , flag : string ) => `export const ${ flag } = /${ p } /${ flag } ` ,
10
- ( p : string , flag : string ) =>
11
- `new RegExp(${ JSON . stringify ( p ) } , ${ JSON . stringify ( flag ) } )` ,
7
+ const elements = [
8
+ // Character
9
+ "a" ,
10
+ // CharacterClass
11
+ "[abc]" ,
12
+ "[^abc]" ,
13
+ // CharacterClassRange
14
+ "[a-z]" ,
15
+ "[^a-z]" ,
16
+ // EscapeCharacterSet
17
+ String . raw `\d` ,
18
+ String . raw `\D` ,
19
+ String . raw `\s` ,
20
+ String . raw `\S` ,
21
+ String . raw `\s` ,
22
+ String . raw `\W` ,
23
+ // UnicodePropertyCharacterSet
24
+ String . raw `\p{ASCII}` ,
25
+ String . raw `\P{ASCII}` ,
26
+ // ClassIntersection
27
+ `[a&&b]` ,
28
+ `[^a&&b]` ,
29
+ // ClassStringDisjunction
30
+ String . raw `[\q{a|b|c}]` ,
31
+ // ClassSubtraction
32
+ `[a--b]` ,
33
+ `[^a--b]` ,
12
34
]
13
- . flatMap ( ( f ) => [ f ( pattern , "v" ) , f ( pattern , "iv" ) ] )
35
+ const alternatives = [
36
+ // Alternative
37
+ "a|b" ,
38
+ // LookaheadAssertion
39
+ "(?=ab)" ,
40
+ "(?!ab)" ,
41
+ // LookbehindAssertion
42
+ `(?<=ab)` ,
43
+ `(?<!ab)` ,
44
+ // WordBoundaryAssertion
45
+ String . raw `\b` ,
46
+ String . raw `\B` ,
47
+ // AnyCharacterSet
48
+ "." ,
49
+ // Quantifier
50
+ `a?` ,
51
+ `a*` ,
52
+ `a+` ,
53
+ `a{1,2}` ,
54
+ `a??` ,
55
+ `a*?` ,
56
+ `a+?` ,
57
+ `a{1,2}?` ,
58
+ elements . join ( "" ) ,
59
+ `[${ elements . join ( "" ) } ]` ,
60
+ `[^${ elements . join ( "" ) } ]` ,
61
+ ]
62
+ const patternsWithGroup = [
63
+ // Group
64
+ `(?:${ alternatives . join ( "" ) } )` ,
65
+ // CapturingGroup
66
+ `(${ alternatives . join ( "" ) } )` ,
67
+ ]
68
+ const patternsWithBackreference = [
69
+ String . raw `(a)\1` ,
70
+ String . raw `(?<name>a)\k<name>` ,
71
+ ]
72
+ const patternWithEdgeAssertion = [
73
+ alternatives . join ( "" ) ,
74
+ ...patternsWithGroup ,
75
+ ...patternsWithBackreference ,
76
+ ] . map ( ( p ) => `^${ p } $` )
77
+ const patterns = [
78
+ alternatives . join ( "" ) ,
79
+ ...patternsWithGroup ,
80
+ ...patternWithEdgeAssertion ,
81
+ ]
82
+ const code = patterns
83
+ . flatMap ( ( p , i ) => [
84
+ `export const re${ i + 1 } = /${ p } /v` ,
85
+ `export const re${ i + 1 } i = /${ p } /iv` ,
86
+ ] )
14
87
. join ( ";\n" )
15
88
16
- const RULE_SPECIFIC : Record < string , string [ ] | number | undefined > = {
17
- "regexp/no-non-standard-flag" : Array ( 4 ) . fill (
18
- "Unexpected non-standard flag 'v'." ,
19
- ) ,
20
- "regexp/no-useless-assertions" : 20 ,
21
- "regexp/order-in-character-class" : 8 ,
22
- "regexp/prefer-named-capture-group" : Array ( 4 ) . fill (
23
- "Capture group '(a|b)' should be converted to a named or non-capturing group." ,
24
- ) ,
25
- "regexp/require-unicode-regexp" : Array ( 4 ) . fill ( "Use the 'u' flag." ) ,
26
- "regexp/sort-character-class-elements" : 8 ,
27
- "regexp/strict" : Array ( 4 ) . fill (
28
- "Invalid regular expression: /^(a|b)(?:c|d)[e-f][[g--[h&&i]][j]\\q{k}](?=l)(?!m)(?<=n)(?<!o)p+\\1\\b.\\d\\s\\w\\p{ASCII}$/: Range out of order in character class." ,
29
- ) ,
89
+ const RULE_SPECIFIC_HAS_ERROR : Record <
90
+ string ,
91
+ number | boolean | undefined
92
+ > = {
93
+ "regexp/no-empty-character-class" : true ,
94
+ "regexp/no-super-linear-backtracking" : true ,
95
+ "regexp/no-useless-assertions" : true ,
96
+ "regexp/order-in-character-class" : true ,
97
+ "regexp/prefer-named-capture-group" : true ,
98
+ "regexp/sort-character-class-elements" : true ,
99
+ "regexp/optimal-quantifier-concatenation" : true ,
30
100
}
31
101
32
102
for ( const key of Object . keys ( rules ) ) {
@@ -51,71 +121,27 @@ describe("Don't crash even if with v flag.", () => {
51
121
52
122
const resultVue = linter . verifyAndFix ( code , config , "test.js" )
53
123
54
- const expected = RULE_SPECIFIC [ ruleId ] ?? [ ]
55
- if ( Array . isArray ( expected ) ) {
124
+ const expected = RULE_SPECIFIC_HAS_ERROR [ ruleId ] ?? false
125
+ if ( expected === false ) {
126
+ assert . deepStrictEqual (
127
+ resultVue . messages . map ( ( m ) => m . message ) ,
128
+ [ ] ,
129
+ )
130
+ } else if ( typeof expected === "number" ) {
56
131
assert . deepStrictEqual (
57
132
resultVue . messages . map ( ( m ) => ( {
58
133
ruleId : m . ruleId ,
59
- message : m . message ,
60
- } ) ) ,
61
- expected . map ( ( message ) => ( {
62
- ruleId,
63
- message,
64
134
} ) ) ,
135
+ Array ( expected ) . fill ( { ruleId } ) ,
65
136
)
66
137
} else {
67
138
assert . deepStrictEqual (
68
139
resultVue . messages . map ( ( m ) => ( {
69
140
ruleId : m . ruleId ,
70
141
} ) ) ,
71
- Array ( expected ) . fill ( { ruleId } ) ,
142
+ Array ( resultVue . messages . length ) . fill ( { ruleId } ) ,
72
143
)
73
144
}
74
145
} )
75
146
}
76
147
} )
77
-
78
- // describe("Don't crash even if with unknown flag in core rules", () => {
79
- // const code = "var foo = /a/abcdefgg;\n new RegExp('a', 'abcdefgg')"
80
-
81
- // for (const ruleId of new Set([
82
- // ...Object.keys(configs.recommended.rules),
83
- // "no-empty-character-class",
84
- // ])) {
85
- // if (ruleId.startsWith("regexp/")) {
86
- // continue
87
- // }
88
-
89
- // it(ruleId, () => {
90
- // const linter = new Linter()
91
- // const config: Linter.Config = {
92
- // parser: "@typescript-eslint/parser",
93
- // parserOptions: {
94
- // ecmaVersion: 2020,
95
- // },
96
- // rules: {
97
- // [ruleId]: "error",
98
- // },
99
- // }
100
- // // @ts -expect-error -- ignore
101
- // linter.defineParser("@typescript-eslint/parser", parser)
102
- // const resultVue = linter.verifyAndFix(code, config, "test.js")
103
-
104
- // const msgs = resultVue.messages.map((m) => ({
105
- // ruleId: m.ruleId,
106
- // line: m.line,
107
- // }))
108
- // if (ruleId === "no-invalid-regexp") {
109
- // assert.deepStrictEqual(msgs, [
110
- // { ruleId: "no-invalid-regexp", line: 2 },
111
- // ])
112
- // } else if (ruleId === "prefer-regex-literals") {
113
- // assert.deepStrictEqual(msgs, [
114
- // { ruleId: "prefer-regex-literals", line: 2 },
115
- // ])
116
- // } else {
117
- // assert.deepStrictEqual(msgs, [])
118
- // }
119
- // })
120
- // }
121
- // })
0 commit comments