@@ -149,12 +149,21 @@ describe('Tests for selecting rules', () => {
149149 expect ( ruleNamesFor ( selection7 , 'stubEngine2' ) ) . toEqual ( [ ] )
150150 } ) ;
151151
152- it ( 'When multiple selectors are provided, then they act as a union' , async ( ) => {
153- const selection : RuleSelection = await codeAnalyzer . selectRules ( [
154- 'Security' , // a tag
155- 'stubEngine2' , // an engine name
156- 'stub1RuleD' // a rule name
157- ] ) ;
152+ it . each ( [
153+ {
154+ case : 'multiple selectors are provided' ,
155+ selectors : [
156+ 'Security' , // a tag
157+ 'stubEngine2' , // an engine name
158+ 'stub1RuleD' // a rule name
159+ ]
160+ } ,
161+ {
162+ case : 'using a comma to join two rule selectors' ,
163+ selectors : [ 'Security,stubEngine2,stub1RuleD' ]
164+ }
165+ ] ) ( 'When $case, then it acts like a union' , async ( { selectors} ) => {
166+ const selection : RuleSelection = await codeAnalyzer . selectRules ( selectors ) ;
158167
159168 expect ( selection . getEngineNames ( ) ) . toEqual ( [ 'stubEngine1' , 'stubEngine2' ] ) ;
160169 expect ( ruleNamesFor ( selection , 'stubEngine1' ) ) . toEqual ( [ 'stub1RuleB' , 'stub1RuleD' ] ) ;
@@ -164,14 +173,93 @@ describe('Tests for selecting rules', () => {
164173 expect ( await codeAnalyzer . selectRules ( [ 'all' , 'Performance' , 'DoesNotExist' ] ) ) . toEqual ( await codeAnalyzer . selectRules ( [ 'all' ] ) ) ;
165174 } ) ;
166175
167- it ( 'When colons are used and multiple selectors are provided then we get correct union and intersection behavior' , async ( ) => {
168- const selection : RuleSelection = await codeAnalyzer . selectRules ( [ 'Recommended:Performance' , 'stubEngine2:2' , 'stubEngine2:DoesNotExist' ] ) ;
176+ it . each ( [
177+ {
178+ selector : 'Recommended:Performance,2' , // Equivalent to "(Recommended:Performance),2"
179+ engines : [ 'stubEngine1' , 'stubEngine2' ] ,
180+ stubEngine1Rules : [ 'stub1RuleB' , 'stub1RuleC' ] ,
181+ stubEngine2Rules : [ 'stub2RuleC' ] ,
182+ stubEngine3Rules : [ ]
183+ } ,
184+ {
185+ selector : '2,Recommended:Performance' , // Equivalent to "2,(Recommended:Performance),2"
186+ engines : [ 'stubEngine1' , 'stubEngine2' ] ,
187+ stubEngine1Rules : [ 'stub1RuleB' , 'stub1RuleC' ] ,
188+ stubEngine2Rules : [ 'stub2RuleC' ] ,
189+ stubEngine3Rules : [ ]
190+ } ,
191+ {
192+ selector : 'Recommended,3:Performance' , // Equivalent to "Recommended,(3:Performance)"
193+ engines : [ 'stubEngine1' , 'stubEngine2' , 'stubEngine3' ] ,
194+ stubEngine1Rules : [ 'stub1RuleA' , 'stub1RuleB' , 'stub1RuleC' , 'stub1RuleE' ] ,
195+ stubEngine2Rules : [ 'stub2RuleA' , 'stub2RuleC' ] ,
196+ stubEngine3Rules : [ 'stub3RuleA' ]
197+ } ,
198+ {
199+ selector : '3:Performance,Recommended' , // Equivalent to "(3:Performance),Recommended"
200+ engines : [ 'stubEngine1' , 'stubEngine2' , 'stubEngine3' ] ,
201+ stubEngine1Rules : [ 'stub1RuleA' , 'stub1RuleB' , 'stub1RuleC' , 'stub1RuleE' ] ,
202+ stubEngine2Rules : [ 'stub2RuleA' , 'stub2RuleC' ] ,
203+ stubEngine3Rules : [ 'stub3RuleA' ]
204+ }
205+ ] ) ( 'In the absence of parenthesis-defined ordering, commas are applied after colons. Case: $selector' , async ( { selector, engines, stubEngine1Rules, stubEngine2Rules, stubEngine3Rules} ) => {
206+ const selection : RuleSelection = await codeAnalyzer . selectRules ( [ selector ] ) ;
207+
208+ expect ( selection . getEngineNames ( ) ) . toEqual ( engines ) ;
209+ expect ( ruleNamesFor ( selection , 'stubEngine1' ) ) . toEqual ( stubEngine1Rules ) ;
210+ expect ( ruleNamesFor ( selection , 'stubEngine2' ) ) . toEqual ( stubEngine2Rules ) ;
211+ expect ( ruleNamesFor ( selection , 'stubEngine3' ) ) . toEqual ( stubEngine3Rules ) ;
212+ } ) ;
213+
214+ it . each ( [
215+ {
216+ case : 'colons are used and multiple selectors are provided' ,
217+ selectors : [ 'Recommended:Performance' , 'stubEngine2:2' , 'stubEngine2:DoesNotExist' ]
218+ } ,
219+ {
220+ case : 'colons and commas are nested via parentheses' ,
221+ selectors : [ '(Recommended:Performance),(stubEngine2:2),(stubEngine2:DoesNotExist)' ]
222+ }
223+ ] ) ( 'When $case, then we get correct union and intersection behavior' , async ( { selectors} ) => {
224+ const selection : RuleSelection = await codeAnalyzer . selectRules ( selectors ) ;
169225
170226 expect ( selection . getEngineNames ( ) ) . toEqual ( [ 'stubEngine1' , 'stubEngine2' ] ) ;
171227 expect ( ruleNamesFor ( selection , 'stubEngine1' ) ) . toEqual ( [ 'stub1RuleC' ] ) ;
172228 expect ( ruleNamesFor ( selection , 'stubEngine2' ) ) . toEqual ( [ 'stub2RuleC' ] ) ;
173229 } ) ;
174230
231+ it ( 'Parentheses cannot be empty' , async ( ) => {
232+ await expect ( codeAnalyzer . selectRules ( [ '()' ] ) ) . rejects . toThrow ( 'empty' ) ;
233+ } ) ;
234+
235+ it ( 'Redundant parentheses are accepted' , async ( ) => {
236+ const selection : RuleSelection = await codeAnalyzer . selectRules ( [ '((((((((stub1RuleC))))))))' ] ) ;
237+
238+ expect ( selection . getEngineNames ( ) ) . toEqual ( [ 'stubEngine1' ] ) ;
239+ expect ( ruleNamesFor ( selection , 'stubEngine1' ) ) . toEqual ( [ 'stub1RuleC' ] ) ;
240+ } )
241+
242+ it . each ( [
243+ { selector : 'a,b)' } ,
244+ { selector : '(a,b' } ,
245+ { selector : '((a,b)' } ,
246+ { selector : '(a),b)' } ,
247+ { selector : ')a,b)' } ,
248+ { selector : 'a,b(' }
249+ ] ) ( 'When parentheses are unbalanced, an error is thrown. Case: $selector' , async ( { selector} ) => {
250+ await expect ( codeAnalyzer . selectRules ( [ selector ] ) ) . rejects . toThrow ( 'looks incorrect' ) ;
251+ } ) ;
252+
253+ it . each ( [
254+ { selector : '2(a,b)' } ,
255+ { selector : '(a,b)2' } ,
256+ { selector : '2(a:b)' } ,
257+ { selector : '(a:b)2' }
258+ ] ) ( 'When parentheses are not accompanied by valid joiners, an error is thrown. Case: $selector' , async ( { selector} ) => {
259+ await expect ( codeAnalyzer . selectRules ( [ selector ] ) ) . rejects . toThrow ( 'looks incorrect' ) ;
260+ } ) ;
261+
262+
175263 it ( 'When selecting rules based on severity names instead of severity number, then we correctly return the rules' , async ( ) => {
176264 const selection : RuleSelection = await codeAnalyzer . selectRules ( [ 'High' , 'Recommended:Low' ] ) ;
177265
0 commit comments