@@ -434,21 +434,62 @@ describe('Listbox', () => {
434434 ] ,
435435 } ) ;
436436
437- let orderedItems = listboxInstance . _collection . orderedItems ( ) ;
438- expect ( orderedItems . length ) . toBe ( 3 ) ;
439- expect ( orderedItems [ 0 ] . element . textContent ?. trim ( ) ) . toBe ( 'Item 1' ) ;
440- expect ( orderedItems [ 2 ] . element . textContent ?. trim ( ) ) . toBe ( 'Item 3' ) ;
437+ // Verify initial DOM order
438+ expect ( optionElements . length ) . toBe ( 3 ) ;
439+ expect ( optionElements [ 0 ] . textContent ?. trim ( ) ) . toBe ( 'Item 1' ) ;
440+ expect ( optionElements [ 2 ] . textContent ?. trim ( ) ) . toBe ( 'Item 3' ) ;
441441
442442 const testComponent = fixture . componentInstance as ListboxExample ;
443443 const items = testComponent . options ( ) . reverse ( ) ;
444444 testComponent . options . set ( [ ...items ] ) ;
445445 fixture . detectChanges ( ) ;
446446 await waitForMicrotasks ( ) ;
447447
448- orderedItems = listboxInstance . _collection . orderedItems ( ) ;
449- expect ( orderedItems . length ) . toBe ( 3 ) ;
450- expect ( orderedItems [ 0 ] . element . textContent ?. trim ( ) ) . toBe ( 'Item 3' ) ;
451- expect ( orderedItems [ 2 ] . element . textContent ?. trim ( ) ) . toBe ( 'Item 1' ) ;
448+ // Re-query elements to check new DOM order
449+ defineTestVariables ( fixture ) ;
450+
451+ expect ( optionElements . length ) . toBe ( 3 ) ;
452+ expect ( optionElements [ 0 ] . textContent ?. trim ( ) ) . toBe ( 'Item 3' ) ;
453+ expect ( optionElements [ 2 ] . textContent ?. trim ( ) ) . toBe ( 'Item 1' ) ;
454+ } ) ;
455+ } ) ;
456+
457+ describe ( 'Custom IDs' , ( ) => {
458+ let customIdFixture : ComponentFixture < ListboxCustomIdExample > ;
459+
460+ beforeEach ( ( ) => {
461+ TestBed . resetTestingModule ( ) ;
462+ TestBed . configureTestingModule ( {
463+ imports : [ ListboxCustomIdExample ] ,
464+ } ) ;
465+ customIdFixture = TestBed . createComponent ( ListboxCustomIdExample ) ;
466+ document . body . appendChild ( customIdFixture . nativeElement ) ;
467+ fixture = customIdFixture as any ;
468+ customIdFixture . detectChanges ( ) ;
469+ } ) ;
470+
471+ afterEach ( ( ) => {
472+ customIdFixture . nativeElement . remove ( ) ;
473+ } ) ;
474+
475+ it ( 'should use custom ID for option when provided' , async ( ) => {
476+ const optionEl = customIdFixture . nativeElement . querySelector ( '#custom-option-id' ) ;
477+ expect ( optionEl ) . toBeTruthy ( ) ;
478+ } ) ;
479+
480+ it ( 'should generate ID if not provided' , async ( ) => {
481+ const options = customIdFixture . debugElement
482+ . queryAll ( By . directive ( Option ) )
483+ . map ( ( debugEl : DebugElement ) => debugEl . nativeElement as HTMLElement ) ;
484+
485+ expect ( options [ 1 ] . id ) . toContain ( 'ng-option-' ) ;
486+ } ) ;
487+ } ) ;
488+
489+ describe ( 'Inert attribute' , ( ) => {
490+ it ( 'should set inert attribute on hard-disabled options' , ( ) => {
491+ setupListbox ( { disabledOptions : [ 0 ] , softDisabled : false } ) ;
492+ expect ( optionElements [ 0 ] . hasAttribute ( 'inert' ) ) . toBe ( true ) ;
452493 } ) ;
453494 } ) ;
454495
@@ -875,3 +916,15 @@ class ListboxExample {
875916 changeDetection : ChangeDetectionStrategy . Eager ,
876917} )
877918class DefaultListboxExample { }
919+
920+ @Component ( {
921+ template : `
922+ <ul ngListbox>
923+ <li ngOption value="1" id="custom-option-id">Item 1</li>
924+ <li ngOption value="2">Item 2</li>
925+ </ul>
926+ ` ,
927+ imports : [ Listbox , Option ] ,
928+ changeDetection : ChangeDetectionStrategy . Eager ,
929+ } )
930+ class ListboxCustomIdExample { }
0 commit comments