@@ -16,6 +16,9 @@ import {
1616 NODE_SELECTOR_NTH ,
1717 NODE_SELECTOR_NTH_OF ,
1818 NODE_SELECTOR_LANG ,
19+ ATTR_FLAG_NONE ,
20+ ATTR_FLAG_CASE_INSENSITIVE ,
21+ ATTR_FLAG_CASE_SENSITIVE ,
1922} from './arena'
2023
2124// Tests using the exported parse_selector() function
@@ -520,6 +523,99 @@ describe('SelectorParser', () => {
520523 // Content now stores just the attribute name
521524 expect ( getNodeContent ( arena , source , child ) ) . toBe ( 'data-test' )
522525 } )
526+
527+ it ( 'should parse attribute with case-insensitive flag' , ( ) => {
528+ const { arena, rootNode, source } = parseSelectorInternal ( '[type="text" i]' )
529+
530+ expect ( rootNode ) . not . toBeNull ( )
531+ if ( ! rootNode ) return
532+
533+ const selectorWrapper = arena . get_first_child ( rootNode )
534+ const child = arena . get_first_child ( selectorWrapper )
535+ expect ( arena . get_type ( child ) ) . toBe ( NODE_SELECTOR_ATTRIBUTE )
536+ expect ( getNodeText ( arena , source , child ) ) . toBe ( '[type="text" i]' )
537+ expect ( getNodeContent ( arena , source , child ) ) . toBe ( 'type' )
538+ expect ( arena . get_attr_flags ( child ) ) . toBe ( ATTR_FLAG_CASE_INSENSITIVE )
539+ } )
540+
541+ it ( 'should parse attribute with case-sensitive flag' , ( ) => {
542+ const { arena, rootNode, source } = parseSelectorInternal ( '[type="text" s]' )
543+
544+ expect ( rootNode ) . not . toBeNull ( )
545+ if ( ! rootNode ) return
546+
547+ const selectorWrapper = arena . get_first_child ( rootNode )
548+ const child = arena . get_first_child ( selectorWrapper )
549+ expect ( arena . get_type ( child ) ) . toBe ( NODE_SELECTOR_ATTRIBUTE )
550+ expect ( getNodeText ( arena , source , child ) ) . toBe ( '[type="text" s]' )
551+ expect ( getNodeContent ( arena , source , child ) ) . toBe ( 'type' )
552+ expect ( arena . get_attr_flags ( child ) ) . toBe ( ATTR_FLAG_CASE_SENSITIVE )
553+ } )
554+
555+ it ( 'should parse attribute with uppercase case-insensitive flag' , ( ) => {
556+ const { arena, rootNode, source } = parseSelectorInternal ( '[type="text" I]' )
557+
558+ expect ( rootNode ) . not . toBeNull ( )
559+ if ( ! rootNode ) return
560+
561+ const selectorWrapper = arena . get_first_child ( rootNode )
562+ const child = arena . get_first_child ( selectorWrapper )
563+ expect ( arena . get_type ( child ) ) . toBe ( NODE_SELECTOR_ATTRIBUTE )
564+ expect ( arena . get_attr_flags ( child ) ) . toBe ( ATTR_FLAG_CASE_INSENSITIVE )
565+ } )
566+
567+ it ( 'should parse attribute with whitespace before flag' , ( ) => {
568+ const { arena, rootNode, source } = parseSelectorInternal ( '[type="text" i]' )
569+
570+ expect ( rootNode ) . not . toBeNull ( )
571+ if ( ! rootNode ) return
572+
573+ const selectorWrapper = arena . get_first_child ( rootNode )
574+ const child = arena . get_first_child ( selectorWrapper )
575+ expect ( arena . get_type ( child ) ) . toBe ( NODE_SELECTOR_ATTRIBUTE )
576+ expect ( arena . get_attr_flags ( child ) ) . toBe ( ATTR_FLAG_CASE_INSENSITIVE )
577+ } )
578+
579+ it ( 'should parse attribute without flag' , ( ) => {
580+ const { arena, rootNode, source } = parseSelectorInternal ( '[type="text"]' )
581+
582+ expect ( rootNode ) . not . toBeNull ( )
583+ if ( ! rootNode ) return
584+
585+ const selectorWrapper = arena . get_first_child ( rootNode )
586+ const child = arena . get_first_child ( selectorWrapper )
587+ expect ( arena . get_type ( child ) ) . toBe ( NODE_SELECTOR_ATTRIBUTE )
588+ expect ( arena . get_attr_flags ( child ) ) . toBe ( ATTR_FLAG_NONE )
589+ } )
590+
591+ it ( 'should handle flag with various operators' , ( ) => {
592+ // Test with ^= operator
593+ const test1 = parseSelectorInternal ( '[class^="btn" i]' )
594+ if ( ! test1 . rootNode ) throw new Error ( 'Expected rootNode' )
595+ const wrapper1 = test1 . arena . get_first_child ( test1 . rootNode )
596+ if ( ! wrapper1 ) throw new Error ( 'Expected wrapper1' )
597+ const child1 = test1 . arena . get_first_child ( wrapper1 )
598+ if ( ! child1 ) throw new Error ( 'Expected child1' )
599+ expect ( test1 . arena . get_attr_flags ( child1 ) ) . toBe ( ATTR_FLAG_CASE_INSENSITIVE )
600+
601+ // Test with $= operator
602+ const test2 = parseSelectorInternal ( '[class$="btn" s]' )
603+ if ( ! test2 . rootNode ) throw new Error ( 'Expected rootNode' )
604+ const wrapper2 = test2 . arena . get_first_child ( test2 . rootNode )
605+ if ( ! wrapper2 ) throw new Error ( 'Expected wrapper2' )
606+ const child2 = test2 . arena . get_first_child ( wrapper2 )
607+ if ( ! child2 ) throw new Error ( 'Expected child2' )
608+ expect ( test2 . arena . get_attr_flags ( child2 ) ) . toBe ( ATTR_FLAG_CASE_SENSITIVE )
609+
610+ // Test with ~= operator
611+ const test3 = parseSelectorInternal ( '[class~="active" i]' )
612+ if ( ! test3 . rootNode ) throw new Error ( 'Expected rootNode' )
613+ const wrapper3 = test3 . arena . get_first_child ( test3 . rootNode )
614+ if ( ! wrapper3 ) throw new Error ( 'Expected wrapper3' )
615+ const child3 = test3 . arena . get_first_child ( wrapper3 )
616+ if ( ! child3 ) throw new Error ( 'Expected child3' )
617+ expect ( test3 . arena . get_attr_flags ( child3 ) ) . toBe ( ATTR_FLAG_CASE_INSENSITIVE )
618+ } )
523619 } )
524620
525621 describe ( 'Combinators' , ( ) => {
0 commit comments