@@ -233,6 +233,33 @@ describe('Validation Rules', () => {
233233 expect ( result . valid ) . toBe ( true ) ;
234234 } ) ;
235235
236+ it ( 'should detect duplicate toString where last occurrence wins' , async ( ) => {
237+ const rule = new DisallowedIdentifierRule ( { disallowed : [ 'constructor' ] } ) ;
238+ const validator = new JSAstValidator ( [ rule ] ) ;
239+
240+ const result = await validator . validate ( 'obj[{toString: () => "safe", toString: () => "constructor"}]' , {
241+ rules : { 'disallowed-identifier' : true } ,
242+ } ) ;
243+ expect ( result . valid ) . toBe ( false ) ;
244+ expect ( result . issues [ 0 ] . code ) . toBe ( 'DISALLOWED_IDENTIFIER' ) ;
245+ expect ( result . issues [ 0 ] . data ?. [ 'identifier' ] ) . toBe ( 'constructor' ) ;
246+ } ) ;
247+
248+ it ( 'should detect multi-return getter with disallowed identifier in later return' , async ( ) => {
249+ const rule = new DisallowedIdentifierRule ( { disallowed : [ 'constructor' ] } ) ;
250+ const validator = new JSAstValidator ( [ rule ] ) ;
251+
252+ const result = await validator . validate (
253+ "obj[{get toString(){ if(true) return () => 'x'; return () => 'constructor' }}]" ,
254+ {
255+ rules : { 'disallowed-identifier' : true } ,
256+ } ,
257+ ) ;
258+ expect ( result . valid ) . toBe ( false ) ;
259+ expect ( result . issues [ 0 ] . code ) . toBe ( 'DISALLOWED_IDENTIFIER' ) ;
260+ expect ( result . issues [ 0 ] . data ?. [ 'identifier' ] ) . toBe ( 'constructor' ) ;
261+ } ) ;
262+
236263 it ( 'should allow safe template literal' , async ( ) => {
237264 const rule = new DisallowedIdentifierRule ( { disallowed : [ 'constructor' ] } ) ;
238265 const validator = new JSAstValidator ( [ rule ] ) ;
0 commit comments