diff --git a/src/material/autocomplete/autocomplete.spec.ts b/src/material/autocomplete/autocomplete.spec.ts index 369b5f66f922..5284c4ff922d 100644 --- a/src/material/autocomplete/autocomplete.spec.ts +++ b/src/material/autocomplete/autocomplete.spec.ts @@ -37,18 +37,18 @@ import { waitForAsync, } from '@angular/core/testing'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {AsyncPipe} from '@angular/common'; import {By} from '@angular/platform-browser'; import {Observable, Subject, Subscription} from 'rxjs'; import {map, startWith} from 'rxjs/operators'; -import {MATERIAL_ANIMATIONS, MatOption, MatOptionSelectionChange} from '../core'; -import {MatFormField, MatFormFieldModule} from '../form-field'; +import {MATERIAL_ANIMATIONS, MatOptgroup, MatOption, MatOptionSelectionChange} from '../core'; +import {MatFormField} from '../form-field'; import {MatInputModule} from '../input'; import { MAT_AUTOCOMPLETE_DEFAULT_OPTIONS, MAT_AUTOCOMPLETE_SCROLL_STRATEGY, MatAutocomplete, MatAutocompleteDefaultOptions, - MatAutocompleteModule, MatAutocompleteOrigin, MatAutocompleteSelectedEvent, MatAutocompleteTrigger, @@ -61,23 +61,13 @@ describe('MatAutocomplete', () => { // Creates a test component fixture. function createComponent(component: Type, providers: Provider[] = []) { TestBed.configureTestingModule({ - imports: [ - MatAutocompleteModule, - MatFormFieldModule, - MatInputModule, - FormsModule, - ReactiveFormsModule, - OverlayModule, - ], providers: [ ...providers, {provide: MATERIAL_ANIMATIONS, useValue: {animationsDisabled: true}}, ], - declarations: [component], }); overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement(); - return TestBed.createComponent(component); } @@ -4022,7 +4012,16 @@ const SIMPLE_AUTOCOMPLETE_TEMPLATE = ` `; -@Component({template: SIMPLE_AUTOCOMPLETE_TEMPLATE, standalone: false}) +@Component({ + template: SIMPLE_AUTOCOMPLETE_TEMPLATE, + imports: [ + MatAutocomplete, + MatAutocompleteTrigger, + MatOption, + MatInputModule, + ReactiveFormsModule, + ], +}) class SimpleAutocomplete implements OnDestroy { stateCtrl = new FormControl<{name: string; code: string} | string | null>(null); filteredStates: any[]; @@ -4081,27 +4080,40 @@ class SimpleAutocomplete implements OnDestroy { @Component({ template: SIMPLE_AUTOCOMPLETE_TEMPLATE, encapsulation: ViewEncapsulation.ShadowDom, - standalone: false, + imports: [ + MatAutocomplete, + MatAutocompleteTrigger, + MatOption, + MatInputModule, + ReactiveFormsModule, + ], }) class SimpleAutocompleteShadowDom extends SimpleAutocomplete {} @Component({ template: ` @if (isVisible) { - - - -} + + + + } @for (option of filteredOptions | async; track option) { - - {{option}} - -} + + {{option}} + + } `, - standalone: false, + imports: [ + MatAutocomplete, + MatAutocompleteTrigger, + MatOption, + MatInputModule, + ReactiveFormsModule, + AsyncPipe, + ], }) class NgIfAutocomplete { optionCtrl = new FormControl(''); @@ -4139,7 +4151,7 @@ class NgIfAutocomplete { } `, - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, MatInputModule], }) class AutocompleteWithoutForms { filteredStates: any[]; @@ -4169,7 +4181,7 @@ class AutocompleteWithoutForms { } `, - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, MatInputModule, FormsModule], }) class AutocompleteWithNgModel { filteredStates: any[]; @@ -4201,7 +4213,7 @@ class AutocompleteWithNgModel { } `, - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, MatInputModule, FormsModule], }) class AutocompleteWithNumbers { selectedNumber: number; @@ -4221,7 +4233,13 @@ class AutocompleteWithNumbers { } `, - standalone: false, + imports: [ + MatAutocomplete, + MatAutocompleteTrigger, + MatOption, + MatInputModule, + ReactiveFormsModule, + ], }) class AutocompleteWithOnPushDelay implements OnInit { @ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger; @@ -4244,7 +4262,7 @@ class AutocompleteWithOnPushDelay implements OnInit { } `, - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, ReactiveFormsModule, AsyncPipe], }) class AutocompleteWithNativeInput { optionCtrl = new FormControl(''); @@ -4268,7 +4286,7 @@ class AutocompleteWithNativeInput { @Component({ template: ``, - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, ReactiveFormsModule], }) class AutocompleteWithoutPanel { @ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger; @@ -4293,7 +4311,14 @@ class AutocompleteWithoutPanel { } `, - standalone: false, + imports: [ + MatAutocomplete, + MatAutocompleteTrigger, + MatOptgroup, + MatOption, + MatInputModule, + FormsModule, + ], }) class AutocompleteWithGroups { @ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger; @@ -4334,7 +4359,14 @@ class AutocompleteWithGroups { } `, - standalone: false, + imports: [ + MatAutocomplete, + MatAutocompleteTrigger, + MatOptgroup, + MatOption, + MatInputModule, + FormsModule, + ], }) class AutocompleteWithIndirectGroups extends AutocompleteWithGroups {} @@ -4352,7 +4384,7 @@ class AutocompleteWithIndirectGroups extends AutocompleteWithGroups {} } `, - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, MatInputModule, FormsModule], }) class AutocompleteWithSelectEvent { selectedState: string; @@ -4368,7 +4400,7 @@ class AutocompleteWithSelectEvent { `, - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, ReactiveFormsModule], }) class PlainAutocompleteInputWithFormControl { formControl = new FormControl(''); @@ -4386,7 +4418,7 @@ class PlainAutocompleteInputWithFormControl { } `, - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, MatInputModule, FormsModule], }) class AutocompleteWithNumberInputAndNgModel { selectedValue: number; @@ -4419,7 +4451,14 @@ class AutocompleteWithNumberInputAndNgModel { } `, - standalone: false, + imports: [ + MatAutocomplete, + MatAutocompleteTrigger, + MatAutocompleteOrigin, + MatOption, + MatInputModule, + FormsModule, + ], }) class AutocompleteWithDifferentOrigin { @ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger; @@ -4434,7 +4473,7 @@ class AutocompleteWithDifferentOrigin { `, - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, FormsModule], }) class AutocompleteWithNativeAutocompleteAttribute { value: string; @@ -4442,7 +4481,7 @@ class AutocompleteWithNativeAutocompleteAttribute { @Component({ template: '', - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption], }) class InputWithoutAutocompleteAndDisabled {} @@ -4458,7 +4497,7 @@ class InputWithoutAutocompleteAndDisabled {} } `, - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, MatInputModule], }) class AutocompleteWithActivatedEvent { states = ['California', 'West Virginia', 'Florida']; @@ -4470,7 +4509,6 @@ class AutocompleteWithActivatedEvent { } @Component({ - selector: 'autocomplete-inside-a-modal', template: ` `, - standalone: false, + imports: [ + MatAutocomplete, + MatAutocompleteTrigger, + MatOption, + MatInputModule, + ReactiveFormsModule, + OverlayModule, + ], }) class AutocompleteInsideAModal { foods = [ @@ -4506,7 +4551,6 @@ class AutocompleteInsideAModal { } @Component({ - selector: 'autocomplete-without-options', template: ` @@ -4515,7 +4559,7 @@ class AutocompleteInsideAModal { `, - standalone: false, + imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, MatInputModule], }) class AutocompleteWithoutOptions { @ViewChild(MatAutocompleteTrigger, {static: true}) trigger: MatAutocompleteTrigger; diff --git a/src/material/autocomplete/autocomplete.zone.spec.ts b/src/material/autocomplete/autocomplete.zone.spec.ts index 7db6661f9b77..67fec2070ad6 100644 --- a/src/material/autocomplete/autocomplete.zone.spec.ts +++ b/src/material/autocomplete/autocomplete.zone.spec.ts @@ -1,4 +1,3 @@ -import {OverlayModule} from '@angular/cdk/overlay'; import {dispatchFakeEvent} from '@angular/cdk/testing/private'; import { Component, @@ -12,10 +11,10 @@ import { provideZoneChangeDetection, } from '@angular/core'; import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing'; -import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {FormControl, ReactiveFormsModule} from '@angular/forms'; import {Subscription} from 'rxjs'; import {MATERIAL_ANIMATIONS, MatOption} from '../core'; -import {MatFormField, MatFormFieldModule} from '../form-field'; +import {MatFormField} from '../form-field'; import {MatInputModule} from '../input'; import {MatAutocomplete} from './autocomplete'; import {MatAutocompleteTrigger} from './autocomplete-trigger'; @@ -25,20 +24,11 @@ describe('MatAutocomplete Zone.js integration', () => { // Creates a test component fixture. function createComponent(component: Type, providers: Provider[] = []) { TestBed.configureTestingModule({ - imports: [ - MatAutocompleteModule, - MatFormFieldModule, - MatInputModule, - FormsModule, - ReactiveFormsModule, - OverlayModule, - ], providers: [ provideZoneChangeDetection(), ...providers, {provide: MATERIAL_ANIMATIONS, useValue: {animationsDisabled: true}}, ], - declarations: [component], }); return TestBed.createComponent(component); @@ -91,41 +81,42 @@ describe('MatAutocomplete Zone.js integration', () => { })); }); -const SIMPLE_AUTOCOMPLETE_TEMPLATE = ` - - @if (hasLabel) { - State - } - - - - @for (state of filteredStates; track state) { - - {{ state.code }}: {{ state.name }} - - } - -`; - -@Component({template: SIMPLE_AUTOCOMPLETE_TEMPLATE, standalone: false}) +@Component({ + template: ` + + @if (hasLabel) { + State + } + + + + @for (state of filteredStates; track state) { + + {{ state.code }}: {{ state.name }} + + } + + `, + imports: [MatAutocompleteModule, MatInputModule, ReactiveFormsModule], +}) class SimpleAutocomplete implements OnDestroy { stateCtrl = new FormControl<{name: string; code: string} | string | null>(null); filteredStates: any[]; diff --git a/src/material/grid-list/grid-list.spec.ts b/src/material/grid-list/grid-list.spec.ts index 69ddea756bea..3843d639a0fc 100644 --- a/src/material/grid-list/grid-list.spec.ts +++ b/src/material/grid-list/grid-list.spec.ts @@ -1,41 +1,32 @@ import {provideFakeDirectionality} from '@angular/cdk/testing/private'; -import {Component, DebugElement, Type, ViewChild} from '@angular/core'; -import {ComponentFixture, TestBed} from '@angular/core/testing'; +import {Component, DebugElement, ViewChild} from '@angular/core'; +import {TestBed} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; import {MatGridTile, MatGridTileText} from './grid-tile'; import {MatGridList, MatGridListModule} from './index'; describe('MatGridList', () => { - function createComponent(componentType: Type): ComponentFixture { - TestBed.configureTestingModule({ - imports: [MatGridListModule], - declarations: [componentType], - }); - - return TestBed.createComponent(componentType); - } - it('should throw error if cols is not defined', () => { - const fixture = createComponent(GridListWithoutCols); + const fixture = TestBed.createComponent(GridListWithoutCols); expect(() => fixture.detectChanges()).toThrowError(/must pass in number of columns/); }); it('should throw error if rowHeight ratio is invalid', () => { expect(() => { - const fixture = createComponent(GridListWithInvalidRowHeightRatio); + const fixture = TestBed.createComponent(GridListWithInvalidRowHeightRatio); fixture.detectChanges(); }).toThrowError(/invalid ratio given for row-height/); }); it('should throw error if tile colspan is wider than total cols', () => { - const fixture = createComponent(GridListWithTooWideColspan); + const fixture = TestBed.createComponent(GridListWithTooWideColspan); expect(() => fixture.detectChanges()).toThrowError(/tile with colspan 5 is wider than grid/); }); it('should not throw when setting the `rowHeight` programmatically before init', () => { - const fixture = createComponent(GridListWithUnspecifiedRowHeight); + const fixture = TestBed.createComponent(GridListWithUnspecifiedRowHeight); const gridList = fixture.debugElement.query(By.directive(MatGridList))!; expect(() => { @@ -48,7 +39,7 @@ describe('MatGridList', () => { }); it('should preserve value when zero is set as row height', () => { - const fixture = createComponent(GridListWithUnspecifiedRowHeight); + const fixture = TestBed.createComponent(GridListWithUnspecifiedRowHeight); const gridList = fixture.debugElement.query(By.directive(MatGridList))!.componentInstance; gridList.rowHeight = 0; @@ -56,7 +47,7 @@ describe('MatGridList', () => { }); it('should set the columns to zero if a negative number is passed in', () => { - const fixture = createComponent(GridListWithDynamicCols); + const fixture = TestBed.createComponent(GridListWithDynamicCols); fixture.detectChanges(); expect(fixture.componentInstance.gridList.cols).toBe(2); @@ -71,7 +62,7 @@ describe('MatGridList', () => { }); it('should default to 1:1 row height if undefined ', () => { - const fixture = createComponent(GridListWithUnspecifiedRowHeight); + const fixture = TestBed.createComponent(GridListWithUnspecifiedRowHeight); fixture.detectChanges(); const tile = fixture.debugElement.query(By.directive(MatGridTile))!; @@ -84,7 +75,7 @@ describe('MatGridList', () => { }); it('should use a ratio row height if passed in', () => { - const fixture = createComponent(GirdListWithRowHeightRatio); + const fixture = TestBed.createComponent(GirdListWithRowHeightRatio); fixture.componentInstance.rowHeight = '4:1'; fixture.changeDetectorRef.markForCheck(); @@ -107,7 +98,7 @@ describe('MatGridList', () => { }); it('should divide row height evenly in "fit" mode', () => { - const fixture = createComponent(GridListWithFitRowHeightMode); + const fixture = TestBed.createComponent(GridListWithFitRowHeightMode); fixture.componentInstance.totalHeight = '300px'; fixture.changeDetectorRef.markForCheck(); @@ -126,7 +117,7 @@ describe('MatGridList', () => { }); it('should use the fixed row height if passed in', () => { - const fixture = createComponent(GridListWithFixedRowHeightMode); + const fixture = TestBed.createComponent(GridListWithFixedRowHeightMode); fixture.componentInstance.rowHeight = '100px'; fixture.changeDetectorRef.markForCheck(); @@ -143,7 +134,7 @@ describe('MatGridList', () => { }); it('should default to pixels if row height units are missing', () => { - const fixture = createComponent(GridListWithUnitlessFixedRowHeight); + const fixture = TestBed.createComponent(GridListWithUnitlessFixedRowHeight); fixture.detectChanges(); const tile = fixture.debugElement.query(By.directive(MatGridTile))!; @@ -151,7 +142,7 @@ describe('MatGridList', () => { }); it('should default gutter size to 1px', () => { - const fixture = createComponent(GridListWithUnspecifiedGutterSize); + const fixture = TestBed.createComponent(GridListWithUnspecifiedGutterSize); fixture.detectChanges(); const tiles = fixture.debugElement.queryAll(By.css('mat-grid-tile')); @@ -166,7 +157,7 @@ describe('MatGridList', () => { }); it('should be able to set the gutter size to zero', () => { - const fixture = createComponent(GridListWithUnspecifiedGutterSize); + const fixture = TestBed.createComponent(GridListWithUnspecifiedGutterSize); const gridList = fixture.debugElement.query(By.directive(MatGridList))!; gridList.componentInstance.gutterSize = 0; @@ -185,7 +176,7 @@ describe('MatGridList', () => { }); it('should lay out the tiles correctly for a nested grid list', () => { - const fixture = createComponent(NestedGridList); + const fixture = TestBed.createComponent(NestedGridList); fixture.detectChanges(); const innerTiles = fixture.debugElement.queryAll( @@ -198,7 +189,7 @@ describe('MatGridList', () => { }); it('should set the gutter size if passed', () => { - const fixture = createComponent(GridListWithGutterSize); + const fixture = TestBed.createComponent(GridListWithGutterSize); fixture.detectChanges(); const tiles = fixture.debugElement.queryAll(By.css('mat-grid-tile')); @@ -213,7 +204,7 @@ describe('MatGridList', () => { }); it('should use pixels if gutter units are missing', () => { - const fixture = createComponent(GridListWithUnitlessGutterSize); + const fixture = TestBed.createComponent(GridListWithUnitlessGutterSize); fixture.detectChanges(); const tiles = fixture.debugElement.queryAll(By.css('mat-grid-tile')); @@ -228,7 +219,7 @@ describe('MatGridList', () => { }); it('should allow alternate units for the gutter size', () => { - const fixture = createComponent(GridListWithUnspecifiedGutterSize); + const fixture = TestBed.createComponent(GridListWithUnspecifiedGutterSize); const gridList = fixture.debugElement.query(By.directive(MatGridList))!; gridList.componentInstance.gutterSize = '10%'; @@ -242,7 +233,7 @@ describe('MatGridList', () => { }); it('should set the correct list height in ratio mode', () => { - const fixture = createComponent(GridListWithRatioHeightAndMulipleRows); + const fixture = TestBed.createComponent(GridListWithRatioHeightAndMulipleRows); fixture.detectChanges(); const list = fixture.debugElement.query(By.directive(MatGridList))!; @@ -254,7 +245,7 @@ describe('MatGridList', () => { }); it('should set the correct list height in fixed mode', () => { - const fixture = createComponent(GridListWithFixRowHeightAndMultipleRows); + const fixture = TestBed.createComponent(GridListWithFixRowHeightAndMultipleRows); fixture.detectChanges(); const list = fixture.debugElement.query(By.directive(MatGridList))!; @@ -262,7 +253,7 @@ describe('MatGridList', () => { }); it('should allow adjustment of tile colspan', () => { - const fixture = createComponent(GridListWithColspanBinding); + const fixture = TestBed.createComponent(GridListWithColspanBinding); fixture.componentInstance.colspan = 2; fixture.changeDetectorRef.markForCheck(); @@ -278,7 +269,7 @@ describe('MatGridList', () => { }); it('should allow adjustment of tile rowspan', () => { - const fixture = createComponent(GridListWithRowspanBinding); + const fixture = TestBed.createComponent(GridListWithRowspanBinding); fixture.componentInstance.rowspan = 2; fixture.changeDetectorRef.markForCheck(); @@ -294,7 +285,7 @@ describe('MatGridList', () => { }); it('should lay out tiles correctly for a complex layout', () => { - const fixture = createComponent(GridListWithComplexLayout); + const fixture = TestBed.createComponent(GridListWithComplexLayout); fixture.componentInstance.tiles = [ {cols: 3, rows: 1}, @@ -329,7 +320,7 @@ describe('MatGridList', () => { }); it('should lay out tiles correctly', () => { - const fixture = createComponent(GridListWithLayout); + const fixture = TestBed.createComponent(GridListWithLayout); fixture.detectChanges(); const tiles = fixture.debugElement.queryAll(By.css('mat-grid-tile')); @@ -361,7 +352,7 @@ describe('MatGridList', () => { }); it('should lay out tiles correctly when single cell to be placed at the beginning', () => { - const fixture = createComponent(GridListWithSingleCellAtBeginning); + const fixture = TestBed.createComponent(GridListWithSingleCellAtBeginning); fixture.detectChanges(); const tiles = fixture.debugElement.queryAll(By.css('mat-grid-tile')); @@ -387,7 +378,7 @@ describe('MatGridList', () => { }); it('should add not add any classes to footers without lines', () => { - const fixture = createComponent(GridListWithFootersWithoutLines); + const fixture = TestBed.createComponent(GridListWithFootersWithoutLines); fixture.detectChanges(); const footer = fixture.debugElement.query(By.directive(MatGridTileText))!; @@ -395,7 +386,7 @@ describe('MatGridList', () => { }); it('should add class to footers with two lines', () => { - const fixture = createComponent(GridListWithFooterContainingTwoLines); + const fixture = TestBed.createComponent(GridListWithFooterContainingTwoLines); fixture.detectChanges(); const footer = fixture.debugElement.query(By.directive(MatGridTileText))!; @@ -403,7 +394,7 @@ describe('MatGridList', () => { }); it('should add class to footers with two indirect descendant lines', () => { - const fixture = createComponent(GridListWithFooterContainingTwoIndirectDescendantLines); + const fixture = TestBed.createComponent(GridListWithFooterContainingTwoIndirectDescendantLines); fixture.detectChanges(); const footer = fixture.debugElement.query(By.directive(MatGridTileText))!; @@ -411,7 +402,7 @@ describe('MatGridList', () => { }); it('should not use calc() that evaluates to 0', () => { - const fixture = createComponent(GirdListWithRowHeightRatio); + const fixture = TestBed.createComponent(GirdListWithRowHeightRatio); fixture.componentInstance.rowHeight = '4:1'; fixture.changeDetectorRef.markForCheck(); @@ -424,7 +415,7 @@ describe('MatGridList', () => { }); it('should reset the old styles when switching to a new tile styler', () => { - const fixture = createComponent(GirdListWithRowHeightRatio); + const fixture = TestBed.createComponent(GirdListWithRowHeightRatio); fixture.componentInstance.rowHeight = '4:1'; fixture.changeDetectorRef.markForCheck(); @@ -459,7 +450,7 @@ describe('MatGridList', () => { }); it('should ensure that all tiles are inside the grid when there are no matching gaps', () => { - const fixture = createComponent(GridListWithoutMatchingGap); + const fixture = TestBed.createComponent(GridListWithoutMatchingGap); const tiles = fixture.debugElement.queryAll(By.css('mat-grid-tile')); fixture.detectChanges(); @@ -469,7 +460,7 @@ describe('MatGridList', () => { }); it('should default to LTR if empty directionality is given', () => { - const fixture = createComponent(GridListWithEmptyDirectionality); + const fixture = TestBed.createComponent(GridListWithEmptyDirectionality); const tile: HTMLElement = fixture.debugElement.query(By.css('mat-grid-tile'))!.nativeElement; fixture.detectChanges(); @@ -478,7 +469,7 @@ describe('MatGridList', () => { }); it('should set `right` styles for RTL', () => { - const fixture = createComponent(GridListWithRtl); + const fixture = TestBed.createComponent(GridListWithRtl); const tile: HTMLElement = fixture.debugElement.query(By.css('mat-grid-tile'))!.nativeElement; fixture.detectChanges(); @@ -487,7 +478,7 @@ describe('MatGridList', () => { }); it('should lay out the tiles if they are not direct descendants of the list', () => { - const fixture = createComponent(GridListWithIndirectTileDescendants); + const fixture = TestBed.createComponent(GridListWithIndirectTileDescendants); fixture.detectChanges(); const tile = fixture.debugElement.query(By.directive(MatGridTile))!; @@ -499,7 +490,7 @@ describe('MatGridList', () => { }); it('should throw if an invalid value is set as the `rowHeight`', () => { - const fixture = createComponent(GridListWithUnspecifiedRowHeight); + const fixture = TestBed.createComponent(GridListWithUnspecifiedRowHeight); const gridList = fixture.debugElement.query(By.directive(MatGridList))!; expect(() => { @@ -543,22 +534,25 @@ function getComputedLeft(element: DebugElement): number { return elementRect.left - bodyRect.left; } -@Component({template: '', standalone: false}) +@Component({template: '', imports: [MatGridListModule]}) class GridListWithoutCols {} @Component({ template: '', - standalone: false, + imports: [MatGridListModule], }) class GridListWithInvalidRowHeightRatio {} @Component({ template: '', - standalone: false, + imports: [MatGridListModule], }) class GridListWithTooWideColspan {} -@Component({template: '', standalone: false}) +@Component({ + template: '', + imports: [MatGridListModule], +}) class GridListWithDynamicCols { @ViewChild(MatGridList) gridList: MatGridList; cols = 2; @@ -571,7 +565,7 @@ class GridListWithDynamicCols { `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithUnspecifiedRowHeight {} @@ -582,7 +576,7 @@ class GridListWithUnspecifiedRowHeight {} `, - standalone: false, + imports: [MatGridListModule], }) class GirdListWithRowHeightRatio { rowHeight: string; @@ -594,7 +588,7 @@ class GirdListWithRowHeightRatio { `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithFitRowHeightMode { totalHeight: string; @@ -605,7 +599,7 @@ class GridListWithFitRowHeightMode { `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithFixedRowHeightMode { rowHeight: string; @@ -616,7 +610,7 @@ class GridListWithFixedRowHeightMode { `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithUnitlessFixedRowHeight { rowHeight: string; @@ -631,7 +625,7 @@ class GridListWithUnitlessFixedRowHeight { `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithUnspecifiedGutterSize {} @@ -644,7 +638,7 @@ class GridListWithUnspecifiedGutterSize {} `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithGutterSize {} @@ -657,7 +651,7 @@ class GridListWithGutterSize {} `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithUnitlessGutterSize {} @@ -669,7 +663,7 @@ class GridListWithUnitlessGutterSize {} `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithRatioHeightAndMulipleRows {} @@ -679,7 +673,7 @@ class GridListWithRatioHeightAndMulipleRows {} `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithFixRowHeightAndMultipleRows {} @@ -690,7 +684,7 @@ class GridListWithFixRowHeightAndMultipleRows {} `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithColspanBinding { colspan: number; @@ -701,7 +695,7 @@ class GridListWithColspanBinding { `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithRowspanBinding { rowspan: number; @@ -719,7 +713,7 @@ class GridListWithRowspanBinding { } `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithComplexLayout { tiles: any[]; @@ -736,7 +730,7 @@ class GridListWithComplexLayout { `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithLayout {} @@ -750,7 +744,7 @@ class GridListWithLayout {} `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithSingleCellAtBeginning {} @@ -763,7 +757,7 @@ class GridListWithSingleCellAtBeginning {} `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithFootersWithoutLines {} @@ -777,7 +771,7 @@ class GridListWithFootersWithoutLines {} `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithFooterContainingTwoLines {} @@ -793,7 +787,7 @@ class GridListWithFooterContainingTwoLines {} `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithFooterContainingTwoIndirectDescendantLines {} @@ -806,21 +800,21 @@ class GridListWithFooterContainingTwoIndirectDescendantLines {} 4 `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithoutMatchingGap {} @Component({ template: `Hello`, providers: [provideFakeDirectionality('ltr')], - standalone: false, + imports: [MatGridListModule], }) class GridListWithEmptyDirectionality {} @Component({ template: `Hello`, providers: [provideFakeDirectionality('rtl')], - standalone: false, + imports: [MatGridListModule], }) class GridListWithRtl {} @@ -835,7 +829,7 @@ class GridListWithRtl {} `, - standalone: false, + imports: [MatGridListModule], }) class GridListWithIndirectTileDescendants {} @@ -853,6 +847,6 @@ class GridListWithIndirectTileDescendants {} `, - standalone: false, + imports: [MatGridListModule], }) class NestedGridList {} diff --git a/src/material/input/input.spec.ts b/src/material/input/input.spec.ts index 4b29f4f3a61f..ec85a54598e2 100644 --- a/src/material/input/input.spec.ts +++ b/src/material/input/input.spec.ts @@ -5,8 +5,6 @@ import { Component, Directive, ErrorHandler, - Provider, - Type, ViewChild, } from '@angular/core'; import {ComponentFixture, TestBed, fakeAsync, flush, tick} from '@angular/core/testing'; @@ -25,18 +23,35 @@ import { MAT_FORM_FIELD_DEFAULT_OPTIONS, MatFormField, MatFormFieldAppearance, - MatFormFieldModule, SubscriptSizing, getMatFormFieldDuplicatedHintError, getMatFormFieldMissingControlError, } from '../form-field'; -import {MatIconModule} from '../icon'; import {By} from '@angular/platform-browser'; import {MAT_INPUT_VALUE_ACCESSOR, MatInput, MatInputModule} from './index'; describe('MatMdcInput without forms', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + // Custom error handler that re-throws the error. Errors happening within + // change detection phase will be reported through the handler and thrown + // in Ivy. Since we do not want to pollute the "console.error", but rather + // just rely on the actual error interrupting the test, we re-throw here. + { + provide: ErrorHandler, + useValue: { + handleError: (err: any) => { + throw err; + }, + }, + }, + ], + }); + }); + it('should default to floating labels', fakeAsync(() => { - let fixture = createComponent(MatInputWithLabel); + const fixture = TestBed.createComponent(MatInputWithLabel); fixture.detectChanges(); let formField = fixture.debugElement.query(By.directive(MatFormField))! @@ -47,12 +62,15 @@ describe('MatMdcInput without forms', () => { })); it('should default to global floating label type', fakeAsync(() => { - let fixture = createComponent(MatInputWithLabel, [ - { - provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, - useValue: {floatLabel: 'always'}, - }, - ]); + TestBed.resetTestingModule().configureTestingModule({ + providers: [ + { + provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, + useValue: {floatLabel: 'always'}, + }, + ], + }); + const fixture = TestBed.createComponent(MatInputWithLabel); fixture.detectChanges(); let formField = fixture.debugElement.query(By.directive(MatFormField))! @@ -63,7 +81,7 @@ describe('MatMdcInput without forms', () => { })); it('should not be treated as empty if type is date', fakeAsync(() => { - const fixture = createComponent(MatInputDateTestController); + const fixture = TestBed.createComponent(MatInputDateTestController); fixture.detectChanges(); if (getSupportedInputTypes().has('date')) { @@ -75,7 +93,7 @@ describe('MatMdcInput without forms', () => { })); it('should be treated as empty if type is date on unsupported browser', fakeAsync(() => { - const fixture = createComponent(MatInputDateTestController); + const fixture = TestBed.createComponent(MatInputDateTestController); fixture.detectChanges(); if (!getSupportedInputTypes().has('date')) { @@ -87,7 +105,7 @@ describe('MatMdcInput without forms', () => { })); it('should treat text input type as empty at init', fakeAsync(() => { - let fixture = createComponent(MatInputTextTestController); + const fixture = TestBed.createComponent(MatInputTextTestController); fixture.detectChanges(); const formField = fixture.debugElement.query(By.directive(MatFormField))! @@ -97,7 +115,7 @@ describe('MatMdcInput without forms', () => { })); it('should treat password input type as empty at init', fakeAsync(() => { - let fixture = createComponent(MatInputPasswordTestController); + const fixture = TestBed.createComponent(MatInputPasswordTestController); fixture.detectChanges(); const formField = fixture.debugElement.query(By.directive(MatFormField))! @@ -107,7 +125,7 @@ describe('MatMdcInput without forms', () => { })); it('should treat number input type as empty at init', fakeAsync(() => { - let fixture = createComponent(MatInputNumberTestController); + const fixture = TestBed.createComponent(MatInputNumberTestController); fixture.detectChanges(); const formField = fixture.debugElement.query(By.directive(MatFormField))! @@ -117,7 +135,7 @@ describe('MatMdcInput without forms', () => { })); it('should not be empty after input entered', fakeAsync(() => { - let fixture = createComponent(MatInputTextTestController); + const fixture = TestBed.createComponent(MatInputTextTestController); fixture.detectChanges(); let inputEl = fixture.debugElement.query(By.css('input'))!; @@ -134,7 +152,7 @@ describe('MatMdcInput without forms', () => { })); it('should update the placeholder when input entered', fakeAsync(() => { - let fixture = createComponent(MatInputWithStaticLabel); + const fixture = TestBed.createComponent(MatInputWithStaticLabel); fixture.detectChanges(); const inputEl = fixture.debugElement.query(By.css('input'))!; @@ -157,7 +175,7 @@ describe('MatMdcInput without forms', () => { })); it('should not be empty when the value set before view init', fakeAsync(() => { - let fixture = createComponent(MatInputWithValueBinding); + const fixture = TestBed.createComponent(MatInputWithValueBinding); fixture.detectChanges(); const formField = fixture.debugElement.query(By.directive(MatFormField))! .componentInstance as MatFormField; @@ -171,7 +189,7 @@ describe('MatMdcInput without forms', () => { })); it('should add id', fakeAsync(() => { - let fixture = createComponent(MatInputTextTestController); + const fixture = TestBed.createComponent(MatInputTextTestController); fixture.detectChanges(); const inputElement: HTMLInputElement = fixture.debugElement.query( @@ -186,7 +204,7 @@ describe('MatMdcInput without forms', () => { })); it('should add aria-required reflecting the required state', fakeAsync(() => { - const fixture = createComponent(MatInputWithRequired); + const fixture = TestBed.createComponent(MatInputWithRequired); fixture.detectChanges(); const inputElement: HTMLInputElement = fixture.debugElement.query( @@ -207,7 +225,7 @@ describe('MatMdcInput without forms', () => { })); it('should not overwrite existing id', fakeAsync(() => { - let fixture = createComponent(MatInputWithId); + const fixture = TestBed.createComponent(MatInputWithId); fixture.detectChanges(); const inputElement: HTMLInputElement = fixture.debugElement.query( @@ -222,14 +240,14 @@ describe('MatMdcInput without forms', () => { })); it("validates there's only one hint label per side", () => { - let fixture = createComponent(MatInputInvalidHintTestController); + const fixture = TestBed.createComponent(MatInputInvalidHintTestController); expect(() => fixture.detectChanges()).toThrowError( wrappedErrorMessage(getMatFormFieldDuplicatedHintError('start')), ); }); it("validates there's only one hint label per side (attribute)", () => { - let fixture = createComponent(MatInputInvalidHint2TestController); + const fixture = TestBed.createComponent(MatInputInvalidHint2TestController); expect(() => fixture.detectChanges()).toThrowError( wrappedErrorMessage(getMatFormFieldDuplicatedHintError('start')), @@ -237,7 +255,7 @@ describe('MatMdcInput without forms', () => { }); it('validates that matInput child is present', fakeAsync(() => { - let fixture = createComponent(MatInputMissingMatInputTestController); + const fixture = TestBed.createComponent(MatInputMissingMatInputTestController); expect(() => fixture.detectChanges()).toThrowError( wrappedErrorMessage(getMatFormFieldMissingControlError()), @@ -245,7 +263,7 @@ describe('MatMdcInput without forms', () => { })); it('validates that matInput child is present after initialization', fakeAsync(() => { - let fixture = createComponent(MatInputWithNgIf); + const fixture = TestBed.createComponent(MatInputWithNgIf); expect(() => fixture.detectChanges()).not.toThrowError( wrappedErrorMessage(getMatFormFieldMissingControlError()), @@ -260,7 +278,7 @@ describe('MatMdcInput without forms', () => { })); it('validates the type', fakeAsync(() => { - let fixture = createComponent(MatInputInvalidTypeTestController); + const fixture = TestBed.createComponent(MatInputInvalidTypeTestController); // Technically this throws during the OnChanges detection phase, // so the error is really a ChangeDetectionError and it becomes @@ -273,7 +291,7 @@ describe('MatMdcInput without forms', () => { })); it('supports hint labels attribute', fakeAsync(() => { - let fixture = createComponent(MatInputHintLabelTestController); + const fixture = TestBed.createComponent(MatInputHintLabelTestController); fixture.detectChanges(); // If the hint label is empty, expect no label. @@ -286,7 +304,7 @@ describe('MatMdcInput without forms', () => { })); it('sets an id on hint labels', fakeAsync(() => { - let fixture = createComponent(MatInputHintLabelTestController); + const fixture = TestBed.createComponent(MatInputHintLabelTestController); fixture.componentInstance.label = 'label'; fixture.changeDetectorRef.markForCheck(); @@ -298,7 +316,7 @@ describe('MatMdcInput without forms', () => { })); it('supports hint labels elements', fakeAsync(() => { - let fixture = createComponent(MatInputHintLabel2TestController); + const fixture = TestBed.createComponent(MatInputHintLabel2TestController); fixture.detectChanges(); // In this case, we should have an empty . @@ -313,7 +331,7 @@ describe('MatMdcInput without forms', () => { })); it('sets an id on the hint element', fakeAsync(() => { - let fixture = createComponent(MatInputHintLabel2TestController); + const fixture = TestBed.createComponent(MatInputHintLabel2TestController); fixture.componentInstance.label = 'label'; fixture.changeDetectorRef.markForCheck(); @@ -325,7 +343,7 @@ describe('MatMdcInput without forms', () => { })); it('supports label required star', fakeAsync(() => { - const fixture = createComponent(MatInputLabelRequiredTestComponent); + const fixture = TestBed.createComponent(MatInputLabelRequiredTestComponent); fixture.detectChanges(); const label = fixture.debugElement.query(By.css('label'))!; @@ -335,7 +353,7 @@ describe('MatMdcInput without forms', () => { })); it('should show the required star when using a FormControl', fakeAsync(() => { - const fixture = createComponent(MatInputWithRequiredFormControl); + const fixture = TestBed.createComponent(MatInputWithRequiredFormControl); fixture.detectChanges(); const label = fixture.debugElement.query(By.css('label'))!; @@ -345,7 +363,7 @@ describe('MatMdcInput without forms', () => { })); it('should show the required star when FormControl is reassigned', fakeAsync(() => { - const fixture = createComponent(MatInputWithRequiredAssignableFormControl); + const fixture = TestBed.createComponent(MatInputWithRequiredAssignableFormControl); fixture.detectChanges(); // should have star by default @@ -362,7 +380,7 @@ describe('MatMdcInput without forms', () => { })); it('should show the required star when required validator is toggled', fakeAsync(() => { - const fixture = createComponent(MatInputWithRequiredAssignableFormControl); + const fixture = TestBed.createComponent(MatInputWithRequiredAssignableFormControl); fixture.detectChanges(); // should have star by default @@ -387,7 +405,7 @@ describe('MatMdcInput without forms', () => { })); it('should not hide the required star if input is disabled', () => { - const fixture = createComponent(MatInputLabelRequiredTestComponent); + const fixture = TestBed.createComponent(MatInputLabelRequiredTestComponent); fixture.componentInstance.disabled = true; fixture.changeDetectorRef.markForCheck(); @@ -400,7 +418,7 @@ describe('MatMdcInput without forms', () => { }); it('hide label required star when set to hide the required marker', fakeAsync(() => { - const fixture = createComponent(MatInputLabelRequiredTestComponent); + const fixture = TestBed.createComponent(MatInputLabelRequiredTestComponent); fixture.detectChanges(); const label = fixture.debugElement.query(By.css('label'))!; @@ -417,7 +435,7 @@ describe('MatMdcInput without forms', () => { })); it('supports the disabled attribute as binding', fakeAsync(() => { - const fixture = createComponent(MatInputWithDisabled); + const fixture = TestBed.createComponent(MatInputWithDisabled); fixture.detectChanges(); const wrapperEl = fixture.debugElement.query( @@ -441,7 +459,7 @@ describe('MatMdcInput without forms', () => { })); it('should be able to set an input as being disabled and interactive', fakeAsync(() => { - const fixture = createComponent(MatInputWithDisabled); + const fixture = TestBed.createComponent(MatInputWithDisabled); fixture.componentInstance.disabled = true; fixture.detectChanges(); @@ -462,7 +480,7 @@ describe('MatMdcInput without forms', () => { })); it('should not float the label when disabled and disabledInteractive are set', fakeAsync(() => { - const fixture = createComponent(MatInputTextTestController); + const fixture = TestBed.createComponent(MatInputTextTestController); fixture.componentInstance.disabled = fixture.componentInstance.disabledInteractive = true; fixture.detectChanges(); @@ -482,7 +500,7 @@ describe('MatMdcInput without forms', () => { })); it('should float the label when disabledInteractive is set and the input has a value', fakeAsync(() => { - const fixture = createComponent(MatInputWithDynamicLabel); + const fixture = TestBed.createComponent(MatInputWithDynamicLabel); fixture.componentInstance.shouldFloat = 'auto'; fixture.componentInstance.disabled = fixture.componentInstance.disabledInteractive = true; fixture.detectChanges(); @@ -500,7 +518,7 @@ describe('MatMdcInput without forms', () => { })); it('supports the disabled attribute as binding for select', fakeAsync(() => { - const fixture = createComponent(MatInputSelect); + const fixture = TestBed.createComponent(MatInputSelect); fixture.detectChanges(); const wrapperEl = fixture.debugElement.query( @@ -524,7 +542,7 @@ describe('MatMdcInput without forms', () => { })); it('should add a class to the form field if it has a native select', fakeAsync(() => { - const fixture = createComponent(MatInputSelect); + const fixture = TestBed.createComponent(MatInputSelect); fixture.detectChanges(); const formField = fixture.debugElement.query(By.css('.mat-mdc-form-field'))!.nativeElement; @@ -533,7 +551,7 @@ describe('MatMdcInput without forms', () => { })); it('supports the required attribute as binding', fakeAsync(() => { - let fixture = createComponent(MatInputWithRequired); + const fixture = TestBed.createComponent(MatInputWithRequired); fixture.detectChanges(); let inputEl = fixture.debugElement.query(By.css('input'))!.nativeElement; @@ -548,7 +566,7 @@ describe('MatMdcInput without forms', () => { })); it('supports the required attribute as binding for select', fakeAsync(() => { - const fixture = createComponent(MatInputSelect); + const fixture = TestBed.createComponent(MatInputSelect); fixture.detectChanges(); const selectEl = fixture.debugElement.query(By.css('select'))!.nativeElement; @@ -563,7 +581,7 @@ describe('MatMdcInput without forms', () => { })); it('supports the type attribute as binding', fakeAsync(() => { - let fixture = createComponent(MatInputWithType); + const fixture = TestBed.createComponent(MatInputWithType); fixture.detectChanges(); let inputEl = fixture.debugElement.query(By.css('input'))!.nativeElement; @@ -578,7 +596,7 @@ describe('MatMdcInput without forms', () => { })); it('supports textarea', fakeAsync(() => { - let fixture = createComponent(MatInputTextareaWithBindings); + const fixture = TestBed.createComponent(MatInputTextareaWithBindings); fixture.detectChanges(); const textarea: HTMLTextAreaElement = fixture.nativeElement.querySelector('textarea'); @@ -586,7 +604,7 @@ describe('MatMdcInput without forms', () => { })); it('supports select', fakeAsync(() => { - const fixture = createComponent(MatInputSelect); + const fixture = TestBed.createComponent(MatInputSelect); fixture.detectChanges(); const nativeSelect: HTMLTextAreaElement = fixture.nativeElement.querySelector('select'); @@ -594,7 +612,7 @@ describe('MatMdcInput without forms', () => { })); it('sets the aria-describedby when a hintLabel is set', fakeAsync(() => { - let fixture = createComponent(MatInputHintLabelTestController); + const fixture = TestBed.createComponent(MatInputHintLabelTestController); fixture.componentInstance.label = 'label'; fixture.changeDetectorRef.markForCheck(); @@ -608,7 +626,7 @@ describe('MatMdcInput without forms', () => { })); it('supports user binding to aria-describedby', fakeAsync(() => { - let fixture = createComponent(MatInputWithSubscriptAndAriaDescribedBy); + const fixture = TestBed.createComponent(MatInputWithSubscriptAndAriaDescribedBy); fixture.componentInstance.label = 'label'; fixture.changeDetectorRef.markForCheck(); @@ -646,7 +664,7 @@ describe('MatMdcInput without forms', () => { })); it('sets the aria-describedby to the id of the mat-hint', fakeAsync(() => { - let fixture = createComponent(MatInputHintLabel2TestController); + const fixture = TestBed.createComponent(MatInputHintLabel2TestController); fixture.componentInstance.label = 'label'; fixture.changeDetectorRef.markForCheck(); @@ -659,7 +677,7 @@ describe('MatMdcInput without forms', () => { })); it('sets the aria-describedby with multiple mat-hint instances', fakeAsync(() => { - let fixture = createComponent(MatInputMultipleHintTestController); + const fixture = TestBed.createComponent(MatInputMultipleHintTestController); fixture.componentInstance.startId = 'start'; fixture.componentInstance.endId = 'end'; @@ -672,7 +690,7 @@ describe('MatMdcInput without forms', () => { })); it('should preserve aria-describedby set directly in the DOM', fakeAsync(() => { - const fixture = createComponent(MatInputHintLabel2TestController); + const fixture = TestBed.createComponent(MatInputHintLabel2TestController); const input = fixture.nativeElement.querySelector('input'); input.setAttribute('aria-describedby', 'custom'); fixture.componentInstance.label = 'label'; @@ -684,7 +702,7 @@ describe('MatMdcInput without forms', () => { })); it('should set a class on the hint element based on its alignment', fakeAsync(() => { - const fixture = createComponent(MatInputMultipleHintTestController); + const fixture = TestBed.createComponent(MatInputMultipleHintTestController); fixture.componentInstance.startId = 'start'; fixture.componentInstance.endId = 'end'; @@ -699,7 +717,7 @@ describe('MatMdcInput without forms', () => { })); it('sets the aria-describedby when a hintLabel is set, in addition to a mat-hint', fakeAsync(() => { - let fixture = createComponent(MatInputMultipleHintMixedTestController); + const fixture = TestBed.createComponent(MatInputMultipleHintMixedTestController); fixture.detectChanges(); @@ -716,7 +734,7 @@ describe('MatMdcInput without forms', () => { })); it('should float when floatLabel is set to default and text is entered', fakeAsync(() => { - let fixture = createComponent(MatInputWithDynamicLabel); + const fixture = TestBed.createComponent(MatInputWithDynamicLabel); fixture.detectChanges(); let inputEl = fixture.debugElement.query(By.css('input'))!.nativeElement; @@ -741,7 +759,7 @@ describe('MatMdcInput without forms', () => { })); it('should always float the label when floatLabel is set to always', fakeAsync(() => { - let fixture = createComponent(MatInputWithDynamicLabel); + const fixture = TestBed.createComponent(MatInputWithDynamicLabel); fixture.detectChanges(); let inputEl = fixture.debugElement.query(By.css('input'))!.nativeElement; @@ -761,7 +779,7 @@ describe('MatMdcInput without forms', () => { })); it('should float labels when select has value', fakeAsync(() => { - const fixture = createComponent(MatInputSelect); + const fixture = TestBed.createComponent(MatInputSelect); fixture.detectChanges(); const labelEl = fixture.debugElement.query(By.css('label'))!.nativeElement; @@ -769,7 +787,7 @@ describe('MatMdcInput without forms', () => { })); it('should mark a multi-select as being inline', fakeAsync(() => { - const fixture = createComponent(MatInputSelect); + const fixture = TestBed.createComponent(MatInputSelect); fixture.detectChanges(); const select: HTMLSelectElement = fixture.nativeElement.querySelector('select'); @@ -784,7 +802,7 @@ describe('MatMdcInput without forms', () => { })); it('should mark a select with a size as being inline', fakeAsync(() => { - const fixture = createComponent(MatInputSelect); + const fixture = TestBed.createComponent(MatInputSelect); fixture.detectChanges(); const select: HTMLSelectElement = fixture.nativeElement.querySelector('select'); @@ -803,7 +821,7 @@ describe('MatMdcInput without forms', () => { })); it('should not float the label if the selectedIndex is negative', fakeAsync(() => { - const fixture = createComponent(MatInputSelect); + const fixture = TestBed.createComponent(MatInputSelect); fixture.detectChanges(); const labelEl = fixture.debugElement.query(By.css('label'))!.nativeElement; @@ -819,7 +837,7 @@ describe('MatMdcInput without forms', () => { })); it('should not float labels when select has no value, no option label, no option innerHtml', fakeAsync(() => { - const fixture = createComponent(MatInputSelectWithNoLabelNoValue); + const fixture = TestBed.createComponent(MatInputSelectWithNoLabelNoValue); fixture.detectChanges(); const labelEl = fixture.debugElement.query(By.css('label'))!.nativeElement; @@ -827,7 +845,7 @@ describe('MatMdcInput without forms', () => { })); it('should floating labels when select has no value but has option label', fakeAsync(() => { - const fixture = createComponent(MatInputSelectWithLabel); + const fixture = TestBed.createComponent(MatInputSelectWithLabel); fixture.detectChanges(); const labelEl = fixture.debugElement.query(By.css('label'))!.nativeElement; @@ -835,7 +853,7 @@ describe('MatMdcInput without forms', () => { })); it('should floating labels when select has no value but has option innerHTML', fakeAsync(() => { - const fixture = createComponent(MatInputSelectWithInnerHtml); + const fixture = TestBed.createComponent(MatInputSelectWithInnerHtml); fixture.detectChanges(); const labelEl = fixture.debugElement.query(By.css('label'))!.nativeElement; @@ -843,12 +861,12 @@ describe('MatMdcInput without forms', () => { })); it('should not throw if a native select does not have options', fakeAsync(() => { - const fixture = createComponent(MatInputSelectWithoutOptions); + const fixture = TestBed.createComponent(MatInputSelectWithoutOptions); expect(() => fixture.detectChanges()).not.toThrow(); })); it('should be able to toggle the floating label programmatically', fakeAsync(() => { - const fixture = createComponent(MatInputWithId); + const fixture = TestBed.createComponent(MatInputWithId); fixture.detectChanges(); @@ -868,7 +886,7 @@ describe('MatMdcInput without forms', () => { })); it('should not have prefix and suffix elements when none are specified', fakeAsync(() => { - let fixture = createComponent(MatInputWithId); + const fixture = TestBed.createComponent(MatInputWithId); fixture.detectChanges(); let prefixEl = fixture.debugElement.query(By.css('.mat-mdc-form-field-prefix')); @@ -879,7 +897,7 @@ describe('MatMdcInput without forms', () => { })); it('should add prefix and suffix elements when specified', fakeAsync(() => { - const fixture = createComponent(MatInputWithPrefixAndSuffix); + const fixture = TestBed.createComponent(MatInputWithPrefixAndSuffix); fixture.detectChanges(); const textPrefixEl = fixture.debugElement.query(By.css('.mat-mdc-form-field-text-prefix'))!; @@ -898,7 +916,7 @@ describe('MatMdcInput without forms', () => { })); it('should allow ng-container as prefix and suffix', () => { - const fixture = createComponent(InputWithNgContainerPrefixAndSuffix); + const fixture = TestBed.createComponent(InputWithNgContainerPrefixAndSuffix); fixture.detectChanges(); const textPrefixEl = fixture.debugElement.query(By.css('.mat-mdc-form-field-text-prefix'))!; @@ -913,7 +931,7 @@ describe('MatMdcInput without forms', () => { }); it('should update empty class when value changes programmatically and OnPush', fakeAsync(() => { - let fixture = createComponent(MatInputOnPush); + const fixture = TestBed.createComponent(MatInputOnPush); fixture.detectChanges(); let component = fixture.componentInstance; @@ -928,7 +946,7 @@ describe('MatMdcInput without forms', () => { })); it('should set the focused class when the input is focused', fakeAsync(() => { - let fixture = createComponent(MatInputTextTestController); + const fixture = TestBed.createComponent(MatInputTextTestController); fixture.detectChanges(); let input = fixture.debugElement @@ -945,7 +963,7 @@ describe('MatMdcInput without forms', () => { })); it('should remove the focused class if the input becomes disabled while focused', fakeAsync(() => { - const fixture = createComponent(MatInputTextTestController); + const fixture = TestBed.createComponent(MatInputTextTestController); fixture.detectChanges(); const input = fixture.debugElement @@ -967,7 +985,7 @@ describe('MatMdcInput without forms', () => { })); it('should only show the native control placeholder, when there is a label, on focus', () => { - const fixture = createComponent(MatInputWithLabelAndPlaceholder); + const fixture = TestBed.createComponent(MatInputWithLabelAndPlaceholder); fixture.detectChanges(); const container = fixture.debugElement.query(By.css('mat-form-field'))!.nativeElement; @@ -985,7 +1003,7 @@ describe('MatMdcInput without forms', () => { }); it('should always show the native control placeholder when floatLabel is set to "always"', () => { - const fixture = createComponent(MatInputWithLabelAndPlaceholder); + const fixture = TestBed.createComponent(MatInputWithLabelAndPlaceholder); fixture.componentInstance.floatLabel = 'always'; fixture.changeDetectorRef.markForCheck(); @@ -997,7 +1015,7 @@ describe('MatMdcInput without forms', () => { }); it('should not add the `placeholder` attribute if there is no placeholder', () => { - const fixture = createComponent(MatInputWithoutPlaceholder); + const fixture = TestBed.createComponent(MatInputWithoutPlaceholder); fixture.detectChanges(); const input = fixture.debugElement.query(By.css('input'))!.nativeElement; @@ -1005,7 +1023,7 @@ describe('MatMdcInput without forms', () => { }); it('should not add the native select class if the control is not a native select', () => { - const fixture = createComponent(MatInputWithId); + const fixture = TestBed.createComponent(MatInputWithId); fixture.detectChanges(); const formField = fixture.debugElement.query(By.css('.mat-mdc-form-field'))!.nativeElement; @@ -1013,7 +1031,7 @@ describe('MatMdcInput without forms', () => { }); it('should preserve the native placeholder on a non-legacy appearance', fakeAsync(() => { - const fixture = createComponent(MatInputWithLabelAndPlaceholder); + const fixture = TestBed.createComponent(MatInputWithLabelAndPlaceholder); fixture.componentInstance.floatLabel = 'auto'; fixture.componentInstance.appearance = 'outline'; fixture.changeDetectorRef.markForCheck(); @@ -1028,7 +1046,7 @@ describe('MatMdcInput without forms', () => { 'should use the native input value when determining whether ' + 'the element is empty with a custom accessor', fakeAsync(() => { - let fixture = createComponent(MatInputWithCustomAccessor, [], [], [CustomMatInputAccessor]); + const fixture = TestBed.createComponent(MatInputWithCustomAccessor); fixture.detectChanges(); let formField = fixture.debugElement.query(By.directive(MatFormField))! .componentInstance as MatFormField; @@ -1043,7 +1061,7 @@ describe('MatMdcInput without forms', () => { ); it('should default the form field color to primary', fakeAsync(() => { - const fixture = createComponent(MatInputWithColor); + const fixture = TestBed.createComponent(MatInputWithColor); fixture.detectChanges(); const formField = fixture.nativeElement.querySelector('.mat-mdc-form-field'); @@ -1051,7 +1069,7 @@ describe('MatMdcInput without forms', () => { })); it('should be able to change the form field color', fakeAsync(() => { - const fixture = createComponent(MatInputWithColor); + const fixture = TestBed.createComponent(MatInputWithColor); fixture.componentInstance.color = 'accent'; fixture.changeDetectorRef.markForCheck(); fixture.detectChanges(); @@ -1066,7 +1084,7 @@ describe('MatMdcInput without forms', () => { })); it('should set a class on the input depending on whether it is in a form field', fakeAsync(() => { - const fixture = createComponent(MatInputInsideOutsideFormField); + const fixture = TestBed.createComponent(MatInputInsideOutsideFormField); fixture.detectChanges(); const inFormField = fixture.nativeElement.querySelector('.inside'); @@ -1085,7 +1103,7 @@ describe('MatMdcInput with forms', () => { let inputEl: HTMLInputElement; beforeEach(fakeAsync(() => { - fixture = createComponent(MatInputWithFormErrorMessages); + fixture = TestBed.createComponent(MatInputWithFormErrorMessages); fixture.detectChanges(); testComponent = fixture.componentInstance; containerEl = fixture.debugElement.query(By.css('.mat-mdc-form-field'))!.nativeElement; @@ -1177,7 +1195,7 @@ describe('MatMdcInput with forms', () => { fixture.destroy(); TestBed.resetTestingModule(); - let groupFixture = createComponent(MatInputWithFormGroupErrorMessages); + let groupFixture = TestBed.createComponent(MatInputWithFormGroupErrorMessages); let component: MatInputWithFormGroupErrorMessages; groupFixture.detectChanges(); @@ -1325,7 +1343,7 @@ describe('MatMdcInput with forms', () => { describe('custom error behavior', () => { it('should display an error message when a custom error matcher returns true', fakeAsync(() => { - let fixture = createComponent(InputInFormGroup); + const fixture = TestBed.createComponent(InputInFormGroup); fixture.detectChanges(); let component = fixture.componentInstance; @@ -1355,13 +1373,15 @@ describe('MatMdcInput with forms', () => { })); it('should display an error message when global error matcher returns true', fakeAsync(() => { - let fixture = createComponent(MatInputWithFormErrorMessages, [ - { - provide: ErrorStateMatcher, - useValue: {isErrorState: () => true}, - }, - ]); - + TestBed.configureTestingModule({ + providers: [ + { + provide: ErrorStateMatcher, + useValue: {isErrorState: () => true}, + }, + ], + }); + const fixture = TestBed.createComponent(MatInputWithFormErrorMessages); fixture.detectChanges(); let containerEl = fixture.debugElement.query(By.css('.mat-mdc-form-field'))!.nativeElement; @@ -1378,12 +1398,15 @@ describe('MatMdcInput with forms', () => { })); it('should display an error message when using ShowOnDirtyErrorStateMatcher', fakeAsync(() => { - let fixture = createComponent(MatInputWithFormErrorMessages, [ - { - provide: ErrorStateMatcher, - useClass: ShowOnDirtyErrorStateMatcher, - }, - ]); + TestBed.configureTestingModule({ + providers: [ + { + provide: ErrorStateMatcher, + useClass: ShowOnDirtyErrorStateMatcher, + }, + ], + }); + const fixture = TestBed.createComponent(MatInputWithFormErrorMessages); fixture.detectChanges(); let containerEl = fixture.debugElement.query(By.css('.mat-mdc-form-field'))!.nativeElement; @@ -1413,7 +1436,7 @@ describe('MatMdcInput with forms', () => { }); it('should update the value when using FormControl.setValue', () => { - let fixture = createComponent(MatInputWithFormControl); + const fixture = TestBed.createComponent(MatInputWithFormControl); fixture.detectChanges(); let input = fixture.debugElement @@ -1428,7 +1451,7 @@ describe('MatMdcInput with forms', () => { }); it('should display disabled styles when using FormControl.disable()', fakeAsync(() => { - const fixture = createComponent(MatInputWithFormControl); + const fixture = TestBed.createComponent(MatInputWithFormControl); fixture.detectChanges(); const formFieldEl = fixture.debugElement.query(By.css('.mat-mdc-form-field'))!.nativeElement; @@ -1450,7 +1473,7 @@ describe('MatMdcInput with forms', () => { })); it('should not treat the number 0 as empty', fakeAsync(() => { - let fixture = createComponent(MatInputZeroTestController); + const fixture = TestBed.createComponent(MatInputZeroTestController); fixture.detectChanges(); flush(); @@ -1463,7 +1486,7 @@ describe('MatMdcInput with forms', () => { })); it('should update when the form field value is patched without emitting', fakeAsync(() => { - const fixture = createComponent(MatInputWithFormControl); + const fixture = TestBed.createComponent(MatInputWithFormControl); fixture.detectChanges(); let formField = fixture.debugElement.query(By.directive(MatFormField))! @@ -1478,7 +1501,7 @@ describe('MatMdcInput with forms', () => { })); it('should update notch size after changing appearance to outline', fakeAsync(() => { - const fixture = createComponent(MatInputWithAppearance); + const fixture = TestBed.createComponent(MatInputWithAppearance); fixture.detectChanges(); tick(16); @@ -1502,76 +1525,90 @@ describe('MatMdcInput with forms', () => { describe('MatFormField default options', () => { it('should be fill appearance if no default options provided', () => { - const fixture = createComponent(MatInputWithAppearance); + const fixture = TestBed.createComponent(MatInputWithAppearance); fixture.detectChanges(); expect(fixture.componentInstance.formField.appearance).toBe('fill'); }); it('should be fill appearance if empty default options provided', () => { - const fixture = createComponent(MatInputWithAppearance, [ - { - provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, - useValue: {}, - }, - ]); + TestBed.configureTestingModule({ + providers: [ + { + provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, + useValue: {}, + }, + ], + }); + const fixture = TestBed.createComponent(MatInputWithAppearance); fixture.detectChanges(); expect(fixture.componentInstance.formField.appearance).toBe('fill'); }); it('should be able to change the default appearance', () => { - const fixture = createComponent(MatInputWithAppearance, [ - { - provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, - useValue: {appearance: 'outline'}, - }, - ]); + TestBed.configureTestingModule({ + providers: [ + { + provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, + useValue: {appearance: 'outline'}, + }, + ], + }); + const fixture = TestBed.createComponent(MatInputWithAppearance); fixture.detectChanges(); expect(fixture.componentInstance.formField.appearance).toBe('outline'); }); it('should default hideRequiredMarker to false', () => { - const fixture = createComponent(MatInputWithAppearance, [ - { - provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, - useValue: {}, - }, - ]); + TestBed.configureTestingModule({ + providers: [ + { + provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, + useValue: {}, + }, + ], + }); + const fixture = TestBed.createComponent(MatInputWithAppearance); fixture.detectChanges(); expect(fixture.componentInstance.formField.hideRequiredMarker).toBe(false); }); it('should be able to change the default value of hideRequiredMarker and appearance', () => { - const fixture = createComponent(MatInputWithAppearance, [ - { - provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, - useValue: { - hideRequiredMarker: true, - appearance: 'outline', + TestBed.configureTestingModule({ + providers: [ + { + provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, + useValue: { + hideRequiredMarker: true, + appearance: 'outline', + }, }, - }, - ]); - + ], + }); + const fixture = TestBed.createComponent(MatInputWithAppearance); fixture.detectChanges(); expect(fixture.componentInstance.formField.hideRequiredMarker).toBe(true); expect(fixture.componentInstance.formField.appearance).toBe('outline'); }); it('should be able to change the default color', () => { - const fixture = createComponent(MatInputSimple, [ - { - provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, - useValue: {color: 'accent'}, - }, - ]); + TestBed.configureTestingModule({ + providers: [ + { + provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, + useValue: {color: 'accent'}, + }, + ], + }); + const fixture = TestBed.createComponent(MatInputSimple); fixture.detectChanges(); const formField = fixture.nativeElement.querySelector('.mat-mdc-form-field'); expect(formField.classList).toContain('mat-accent'); }); it('defaults subscriptSizing to false', () => { - const fixture = createComponent(MatInputWithSubscriptSizing); + const fixture = TestBed.createComponent(MatInputWithSubscriptSizing); fixture.detectChanges(); const subscriptElement = fixture.nativeElement.querySelector( @@ -1594,14 +1631,15 @@ describe('MatFormField default options', () => { }); it('changes the default value of subscriptSizing (undefined input)', () => { - const fixture = createComponent(MatInputWithSubscriptSizing, [ - { - provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, - useValue: { - subscriptSizing: 'dynamic', + TestBed.configureTestingModule({ + providers: [ + { + provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, + useValue: {subscriptSizing: 'dynamic'}, }, - }, - ]); + ], + }); + const fixture = TestBed.createComponent(MatInputWithSubscriptSizing); fixture.detectChanges(); expect(fixture.componentInstance.formField.subscriptSizing).toBe('dynamic'); @@ -1613,14 +1651,15 @@ describe('MatFormField default options', () => { }); it('changes the default value of subscriptSizing (no input)', () => { - const fixture = createComponent(MatInputWithAppearance, [ - { - provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, - useValue: { - subscriptSizing: 'dynamic', + TestBed.configureTestingModule({ + providers: [ + { + provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, + useValue: {subscriptSizing: 'dynamic'}, }, - }, - ]); + ], + }); + const fixture = TestBed.createComponent(MatInputWithAppearance); fixture.detectChanges(); expect(fixture.componentInstance.formField.subscriptSizing).toBe('dynamic'); @@ -1634,7 +1673,7 @@ describe('MatFormField default options', () => { describe('MatFormField without label', () => { it('should not float the label when no label is defined.', () => { - let fixture = createComponent(MatInputWithoutDefinedLabel); + const fixture = TestBed.createComponent(MatInputWithoutDefinedLabel); fixture.detectChanges(); const inputEl = fixture.debugElement.query(By.css('input'))!; @@ -1650,7 +1689,7 @@ describe('MatFormField without label', () => { }); it('should not float the label when the label is removed after it has been shown', () => { - let fixture = createComponent(MatInputWithCondictionalLabel); + const fixture = TestBed.createComponent(MatInputWithCondictionalLabel); fixture.detectChanges(); const inputEl = fixture.debugElement.query(By.css('input'))!; const formField = fixture.debugElement.query(By.directive(MatFormField))! @@ -1672,7 +1711,7 @@ describe('MatFormField without label', () => { }); it('should float the label when the label is not removed', () => { - let fixture = createComponent(MatInputWithCondictionalLabel); + const fixture = TestBed.createComponent(MatInputWithCondictionalLabel); fixture.detectChanges(); const inputEl = fixture.debugElement.query(By.css('input'))!; const formField = fixture.debugElement.query(By.directive(MatFormField))! @@ -1689,60 +1728,13 @@ describe('MatFormField without label', () => { }); }); -function configureTestingModule( - component: Type, - options: { - providers?: Provider[]; - imports?: any[]; - declarations?: any[]; - } = {}, -) { - const {providers = [], imports = [], declarations = []} = options; - TestBed.configureTestingModule({ - imports: [ - FormsModule, - MatFormFieldModule, - MatIconModule, - MatInputModule, - ReactiveFormsModule, - ...imports, - ], - declarations: [component, ...declarations], - providers: [ - // Custom error handler that re-throws the error. Errors happening within - // change detection phase will be reported through the handler and thrown - // in Ivy. Since we do not want to pollute the "console.error", but rather - // just rely on the actual error interrupting the test, we re-throw here. - { - provide: ErrorHandler, - useValue: { - handleError: (err: any) => { - throw err; - }, - }, - }, - ...providers, - ], - }); -} - -function createComponent( - component: Type, - providers: Provider[] = [], - imports: any[] = [], - declarations: any[] = [], -): ComponentFixture { - configureTestingModule(component, {providers, imports, declarations}); - return TestBed.createComponent(component); -} - @Component({ template: ` Label `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithId { floatLabel: 'always' | 'auto' = 'auto'; @@ -1754,7 +1746,7 @@ class MatInputWithId { `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithDisabled { disabled = false; @@ -1763,7 +1755,7 @@ class MatInputWithDisabled { @Component({ template: ``, - standalone: false, + imports: [MatInputModule], }) class MatInputWithRequired { required: boolean; @@ -1771,7 +1763,7 @@ class MatInputWithRequired { @Component({ template: ``, - standalone: false, + imports: [MatInputModule], }) class MatInputWithType { type: string; @@ -1783,7 +1775,7 @@ class MatInputWithType { hello `, - standalone: false, + imports: [MatInputModule], }) class MatInputLabelRequiredTestComponent { hideRequiredMarker: boolean = false; @@ -1795,7 +1787,7 @@ class MatInputLabelRequiredTestComponent { `, - standalone: false, + imports: [MatInputModule, ReactiveFormsModule], }) class MatInputWithFormControl { formControl = new FormControl(''); @@ -1803,7 +1795,7 @@ class MatInputWithFormControl { @Component({ template: `{{label}}`, - standalone: false, + imports: [MatInputModule], }) class MatInputHintLabel2TestController { label: string = ''; @@ -1814,7 +1806,7 @@ class MatInputHintLabel2TestController { `, - standalone: false, + imports: [MatInputModule], }) class MatInputHintLabelTestController { label: string = ''; @@ -1828,7 +1820,7 @@ class MatInputHintLabelTestController { Some error } `, - standalone: false, + imports: [MatInputModule, ReactiveFormsModule], }) class MatInputWithSubscriptAndAriaDescribedBy { label: string = ''; @@ -1839,7 +1831,7 @@ class MatInputWithSubscriptAndAriaDescribedBy { @Component({ template: ``, - standalone: false, + imports: [MatInputModule], }) class MatInputInvalidTypeTestController { t = 'file'; @@ -1851,7 +1843,7 @@ class MatInputInvalidTypeTestController { World `, - standalone: false, + imports: [MatInputModule], }) class MatInputInvalidHint2TestController {} @@ -1862,7 +1854,7 @@ class MatInputInvalidHint2TestController {} Hello World `, - standalone: false, + imports: [MatInputModule], }) class MatInputInvalidHintTestController {} @@ -1873,7 +1865,7 @@ class MatInputInvalidHintTestController {} Hello World `, - standalone: false, + imports: [MatInputModule], }) class MatInputMultipleHintTestController { startId: string; @@ -1886,7 +1878,7 @@ class MatInputMultipleHintTestController { World `, - standalone: false, + imports: [MatInputModule], }) class MatInputMultipleHintMixedTestController {} @@ -1895,7 +1887,7 @@ class MatInputMultipleHintMixedTestController {} `, - standalone: false, + imports: [MatInputModule], }) class MatInputDateTestController {} @@ -1910,7 +1902,7 @@ class MatInputDateTestController {} [disabled]="disabled" [disabledInteractive]="disabledInteractive"> `, - standalone: false, + imports: [MatInputModule], }) class MatInputTextTestController { disabled = false; @@ -1922,7 +1914,7 @@ class MatInputTextTestController { `, - standalone: false, + imports: [MatInputModule], }) class MatInputPasswordTestController {} @@ -1931,7 +1923,7 @@ class MatInputPasswordTestController {} `, - standalone: false, + imports: [MatInputModule], }) class MatInputNumberTestController {} @@ -1940,7 +1932,7 @@ class MatInputNumberTestController {} `, - standalone: false, + imports: [MatInputModule, FormsModule], }) class MatInputZeroTestController { value = 0; @@ -1951,7 +1943,7 @@ class MatInputZeroTestController { `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithValueBinding { value: string = 'Initial'; @@ -1963,7 +1955,7 @@ class MatInputWithValueBinding { `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithStaticLabel {} @@ -1977,7 +1969,7 @@ class MatInputWithStaticLabel {} [disabled]="disabled" [disabledInteractive]="disabledInteractive"> `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithDynamicLabel { shouldFloat: 'always' | 'auto' = 'always'; @@ -1991,7 +1983,7 @@ class MatInputWithDynamicLabel { `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithoutDefinedLabel {} @@ -2003,7 +1995,7 @@ class MatInputWithoutDefinedLabel {} } `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithCondictionalLabel { hasLabel = true; @@ -2015,7 +2007,7 @@ class MatInputWithCondictionalLabel { `, - standalone: false, + imports: [MatInputModule], }) class MatInputTextareaWithBindings { rows: number = 4; @@ -2025,7 +2017,7 @@ class MatInputTextareaWithBindings { @Component({ template: ``, - standalone: false, + imports: [MatInputModule], }) class MatInputMissingMatInputTestController {} @@ -2041,7 +2033,7 @@ class MatInputMissingMatInputTestController {} `, - standalone: false, + imports: [MatInputModule, ReactiveFormsModule, FormsModule], }) class MatInputWithFormErrorMessages { @ViewChild('form') form: NgForm; @@ -2064,7 +2056,7 @@ class MatInputWithFormErrorMessages { `, - standalone: false, + imports: [MatInputModule, ReactiveFormsModule], }) class InputInFormGroup { formGroup = new FormGroup({ @@ -2088,7 +2080,7 @@ class InputInFormGroup { `, - standalone: false, + imports: [MatInputModule, ReactiveFormsModule], }) class MatInputWithFormGroupErrorMessages { @ViewChild(FormGroupDirective) formGroupDirective: FormGroupDirective; @@ -2107,7 +2099,7 @@ class MatInputWithFormGroupErrorMessages { favorite `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithPrefixAndSuffix {} @@ -2119,7 +2111,7 @@ class MatInputWithPrefixAndSuffix {} } `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithNgIf { renderInput = true; @@ -2133,7 +2125,7 @@ class MatInputWithNgIf { `, - standalone: false, + imports: [MatInputModule, ReactiveFormsModule], }) class MatInputOnPush { formControl = new FormControl(''); @@ -2146,7 +2138,7 @@ class MatInputOnPush { `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithLabel {} @@ -2157,7 +2149,7 @@ class MatInputWithLabel {} `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithLabelAndPlaceholder { floatLabel: FloatLabelType; @@ -2171,7 +2163,7 @@ class MatInputWithLabelAndPlaceholder { `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithAppearance { @ViewChild(MatFormField) formField: MatFormField; @@ -2185,7 +2177,7 @@ class MatInputWithAppearance { `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithSubscriptSizing { @ViewChild(MatFormField) formField: MatFormField; @@ -2198,7 +2190,7 @@ class MatInputWithSubscriptSizing { `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithoutPlaceholder {} @@ -2213,7 +2205,7 @@ class MatInputWithoutPlaceholder {} `, - standalone: false, + imports: [MatInputModule], }) class MatInputSelect { disabled: boolean; @@ -2231,7 +2223,7 @@ class MatInputSelect { `, - standalone: false, + imports: [MatInputModule], }) class MatInputSelectWithNoLabelNoValue {} @@ -2246,7 +2238,7 @@ class MatInputSelectWithNoLabelNoValue {} `, - standalone: false, + imports: [MatInputModule], }) class MatInputSelectWithLabel {} @@ -2261,29 +2253,10 @@ class MatInputSelectWithLabel {} `, - standalone: false, + imports: [MatInputModule], }) class MatInputSelectWithInnerHtml {} -@Component({ - template: ` - - - `, - standalone: false, -}) -class MatInputWithCustomAccessor {} - -@Component({ - template: ` - - - `, - standalone: false, -}) -class MatInputSelectWithoutOptions {} - /** Custom component that never has a value. Used for testing the `MAT_INPUT_VALUE_ACCESSOR`. */ @Directive({ selector: 'input[customInputAccessor]', @@ -2293,7 +2266,6 @@ class MatInputSelectWithoutOptions {} useExisting: CustomMatInputAccessor, }, ], - standalone: false, }) class CustomMatInputAccessor { get value() { @@ -2303,12 +2275,31 @@ class CustomMatInputAccessor { private _value = null; } +@Component({ + template: ` + + + `, + imports: [MatInputModule, CustomMatInputAccessor], +}) +class MatInputWithCustomAccessor {} + +@Component({ + template: ` + + + `, + imports: [MatInputModule], +}) +class MatInputSelectWithoutOptions {} + @Component({ template: ` `, - standalone: false, + imports: [MatInputModule], }) class MatInputWithColor { color: ThemePalette; @@ -2322,7 +2313,7 @@ class MatInputWithColor { `, - standalone: false, + imports: [MatInputModule], }) class MatInputInsideOutsideFormField {} @@ -2332,7 +2323,7 @@ class MatInputInsideOutsideFormField {} Hello `, - standalone: false, + imports: [MatInputModule, ReactiveFormsModule], }) class MatInputWithRequiredFormControl { formControl = new FormControl('', [Validators.required]); @@ -2344,7 +2335,7 @@ class MatInputWithRequiredFormControl { `, - standalone: false, + imports: [MatInputModule], }) class MatInputSimple {} @@ -2358,7 +2349,7 @@ class MatInputSimple {} icon-suffix `, - standalone: false, + imports: [MatInputModule], }) class InputWithNgContainerPrefixAndSuffix {} @@ -2368,7 +2359,7 @@ class InputWithNgContainerPrefixAndSuffix {} Hello `, - standalone: false, + imports: [MatInputModule, ReactiveFormsModule], }) class MatInputWithRequiredAssignableFormControl { formControl = new FormControl('', [Validators.required]); diff --git a/src/material/menu/menu.spec.ts b/src/material/menu/menu.spec.ts index 231f2a5e949f..b2f150e3d139 100644 --- a/src/material/menu/menu.spec.ts +++ b/src/material/menu/menu.spec.ts @@ -1,5 +1,5 @@ import {FocusMonitor} from '@angular/cdk/a11y'; -import {Direction} from '@angular/cdk/bidi'; +import {Direction, Directionality} from '@angular/cdk/bidi'; import { DOWN_ARROW, END, @@ -23,11 +23,9 @@ import { OnDestroy, Output, provideCheckNoChangesConfig, - Provider, QueryList, signal, TemplateRef, - Type, ViewChild, ViewChildren, } from '@angular/core'; @@ -50,6 +48,7 @@ import {MatMenu, MatMenuItem, MatMenuModule} from './index'; import { MAT_MENU_DEFAULT_OPTIONS, MAT_MENU_SCROLL_STRATEGY, + MatMenuContent, MatMenuPanel, MatMenuTrigger, MenuPositionX, @@ -60,35 +59,22 @@ const MENU_PANEL_TOP_PADDING = 8; describe('MatMenu', () => { let overlayContainerElement: HTMLElement; - let focusMonitor: FocusMonitor; - let viewportRuler: ViewportRuler; - - function createComponent( - component: Type, - providers: Provider[] = [], - declarations: any[] = [], - imports: Type[] = [], - ): ComponentFixture { + + beforeEach(() => { TestBed.configureTestingModule({ - providers: [ - provideCheckNoChangesConfig({exhaustive: false}), - ...providers, - {provide: MATERIAL_ANIMATIONS, useValue: {animationsDisabled: true}}, - ], - imports: [MatMenuModule, ...imports], - declarations: [component, ...declarations], + providers: [{provide: MATERIAL_ANIMATIONS, useValue: {animationsDisabled: true}}], }); overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement(); - focusMonitor = TestBed.inject(FocusMonitor); - viewportRuler = TestBed.inject(ViewportRuler); - const fixture = TestBed.createComponent(component); window.scroll(0, 0); - return fixture; - } + }); + + afterEach(() => { + window.scroll(0, 0); + }); it('should aria-controls the menu panel', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); @@ -99,7 +85,7 @@ describe('MatMenu', () => { })); it('should set aria-haspopup based on whether a menu is assigned', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerElement = fixture.componentInstance.triggerEl.nativeElement; @@ -113,7 +99,7 @@ describe('MatMenu', () => { })); it('should open the menu as an idempotent operation', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); expect(overlayContainerElement.textContent).toBe(''); expect(() => { @@ -128,7 +114,7 @@ describe('MatMenu', () => { })); it('should close the menu when a click occurs outside the menu', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -141,7 +127,7 @@ describe('MatMenu', () => { })); it('should be able to remove the backdrop', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.menu.hasBackdrop = false; @@ -153,7 +139,7 @@ describe('MatMenu', () => { })); it('should set the correct aria-haspopup value on the trigger element', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerElement = fixture.componentInstance.triggerEl.nativeElement; @@ -161,7 +147,7 @@ describe('MatMenu', () => { })); it('should be able to remove the backdrop on repeat openings', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -188,7 +174,7 @@ describe('MatMenu', () => { })); it('should restore focus to the trigger when the menu was opened by keyboard', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -206,7 +192,7 @@ describe('MatMenu', () => { })); it('should not restore focus to the trigger if focus restoration is disabled', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -228,7 +214,7 @@ describe('MatMenu', () => { })); it('should be able to move focus in the closed event', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); const instance = fixture.componentInstance; fixture.detectChanges(); const triggerEl = instance.triggerEl.nativeElement; @@ -250,7 +236,7 @@ describe('MatMenu', () => { })); it('should restore focus to the trigger immediately once the menu is closed', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -273,7 +259,9 @@ describe('MatMenu', () => { it('should move focus to another item if the active item is destroyed', fakeAsync(() => { // TODO(crisbeto): figure out why NoopAnimationsModule is necessary // here and our token isn't enough. Likely indicates an issue. - const fixture = createComponent(MenuWithRepeatedItems, [], [FakeIcon], [NoopAnimationsModule]); + TestBed.resetTestingModule().configureTestingModule({imports: [NoopAnimationsModule]}); + overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement(); + const fixture = TestBed.createComponent(MenuWithRepeatedItems); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -295,7 +283,7 @@ describe('MatMenu', () => { })); it('should be able to set a custom class on the backdrop', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.componentInstance.backdropClass = 'custom-backdrop'; fixture.detectChanges(); @@ -309,11 +297,16 @@ describe('MatMenu', () => { })); it('should be able to set a custom class on the overlay panel', fakeAsync(() => { - const optionsProvider = { - provide: MAT_MENU_DEFAULT_OPTIONS, - useValue: {overlayPanelClass: 'custom-panel-class'}, - }; - const fixture = createComponent(SimpleMenu, [optionsProvider], [FakeIcon]); + TestBed.resetTestingModule().configureTestingModule({ + providers: [ + { + provide: MAT_MENU_DEFAULT_OPTIONS, + useValue: {overlayPanelClass: 'custom-panel-class'}, + }, + ], + }); + overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement(); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -326,12 +319,16 @@ describe('MatMenu', () => { })); it('should be able to set a custom classes on the overlay panel', fakeAsync(() => { - const optionsProvider = { - provide: MAT_MENU_DEFAULT_OPTIONS, - useValue: {overlayPanelClass: ['custom-panel-class-1', 'custom-panel-class-2']}, - }; - const fixture = createComponent(SimpleMenu, [optionsProvider], [FakeIcon]); - + TestBed.resetTestingModule().configureTestingModule({ + providers: [ + { + provide: MAT_MENU_DEFAULT_OPTIONS, + useValue: {overlayPanelClass: ['custom-panel-class-1', 'custom-panel-class-2']}, + }, + ], + }); + overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement(); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); @@ -344,7 +341,7 @@ describe('MatMenu', () => { })); it('should restore focus to the root trigger when the menu was opened by mouse', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -362,7 +359,7 @@ describe('MatMenu', () => { })); it('should restore focus to the root trigger when the menu was opened by touch', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -380,7 +377,7 @@ describe('MatMenu', () => { })); it('should scroll the panel to the top on open, when it is scrollable', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); // Add 50 items to make the menu scrollable @@ -400,7 +397,8 @@ describe('MatMenu', () => { })); it('should set the proper focus origin when restoring focus after opening by keyboard', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const focusMonitor = TestBed.inject(FocusMonitor); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -418,7 +416,8 @@ describe('MatMenu', () => { })); it('should set the proper focus origin when restoring focus after opening by mouse', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const focusMonitor = TestBed.inject(FocusMonitor); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -437,7 +436,8 @@ describe('MatMenu', () => { })); it('should set proper focus origin when right clicking on trigger, before opening by keyboard', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const focusMonitor = TestBed.inject(FocusMonitor); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -461,7 +461,8 @@ describe('MatMenu', () => { })); it('should set the proper focus origin when restoring focus after opening by touch', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const focusMonitor = TestBed.inject(FocusMonitor); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -481,7 +482,7 @@ describe('MatMenu', () => { })); it('should close the menu when pressing ESCAPE', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -496,7 +497,7 @@ describe('MatMenu', () => { })); it('should not close the menu when pressing ESCAPE with a modifier', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -512,7 +513,7 @@ describe('MatMenu', () => { })); it('should open a custom menu', () => { - const fixture = createComponent(CustomMenu, [], [CustomMenuPanel]); + const fixture = TestBed.createComponent(CustomMenu); fixture.detectChanges(); expect(overlayContainerElement.textContent).toBe(''); expect(() => { @@ -525,8 +526,11 @@ describe('MatMenu', () => { }); it('should set the panel direction based on the trigger direction', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [provideFakeDirectionality('rtl')], [FakeIcon]); - + TestBed.resetTestingModule().configureTestingModule({ + providers: [provideFakeDirectionality('rtl')], + }); + overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement(); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); @@ -540,8 +544,11 @@ describe('MatMenu', () => { it('should update the panel direction if the trigger direction changes', fakeAsync(() => { const dir = signal('rtl'); - const fixture = createComponent(SimpleMenu, [provideFakeDirectionality(dir)], [FakeIcon]); - + TestBed.resetTestingModule().configureTestingModule({ + providers: [provideFakeDirectionality(dir)], + }); + const fixture = TestBed.createComponent(SimpleMenu); + overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement(); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); @@ -568,7 +575,7 @@ describe('MatMenu', () => { })); it('should transfer any custom classes from the host to the overlay', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.componentInstance.panelClass = 'custom-one custom-two'; fixture.detectChanges(); @@ -587,7 +594,7 @@ describe('MatMenu', () => { })); it('should set the "menu" role on the overlay panel', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); @@ -602,7 +609,7 @@ describe('MatMenu', () => { })); it('should forward ARIA attributes to the menu panel', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); const instance = fixture.componentInstance; fixture.detectChanges(); instance.trigger.openMenu(); @@ -637,7 +644,7 @@ describe('MatMenu', () => { })); it('should set the "menuitem" role on the items by default', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); @@ -650,7 +657,7 @@ describe('MatMenu', () => { })); it('should be able to set an alternate role on the menu items', fakeAsync(() => { - const fixture = createComponent(MenuWithCheckboxItems); + const fixture = TestBed.createComponent(MenuWithCheckboxItems); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); @@ -663,7 +670,7 @@ describe('MatMenu', () => { })); it('should not change focus origin if origin not specified for menu items', fakeAsync(() => { - const fixture = createComponent(MenuWithCheckboxItems); + const fixture = TestBed.createComponent(MenuWithCheckboxItems); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); @@ -687,32 +694,32 @@ describe('MatMenu', () => { })); it('should not throw an error on destroy', () => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); expect(fixture.destroy.bind(fixture)).not.toThrow(); }); it('should be able to extract the menu item text', () => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); expect(fixture.componentInstance.items.first.getLabel()).toBe('Item'); }); it('should filter out icon nodes when figuring out the label', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const items = fixture.componentInstance.items.toArray(); expect(items[2].getLabel()).toBe('Item with an icon'); })); it('should get the label of an item if the text is not in a direct descendant node', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const items = fixture.componentInstance.items.toArray(); expect(items[3].getLabel()).toBe('Item with text inside span'); })); it('should set the proper focus origin when opening by mouse', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); spyOn(fixture.componentInstance.items.first, 'focus').and.callThrough(); @@ -727,7 +734,7 @@ describe('MatMenu', () => { })); it('should set the proper focus origin when opening by touch', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); spyOn(fixture.componentInstance.items.first, 'focus').and.callThrough(); @@ -742,7 +749,7 @@ describe('MatMenu', () => { })); it('should set the proper origin when calling focusFirstItem after the opening sequence has started', () => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); spyOn(fixture.componentInstance.items.first, 'focus').and.callThrough(); @@ -756,17 +763,18 @@ describe('MatMenu', () => { it('should close the menu when using the CloseScrollStrategy', fakeAsync(() => { const scrolledSubject = new Subject(); - const fixture = createComponent( - SimpleMenu, - [ + TestBed.resetTestingModule().configureTestingModule({ + providers: [ {provide: ScrollDispatcher, useFactory: () => ({scrolled: () => scrolledSubject})}, { provide: MAT_MENU_SCROLL_STRATEGY, useFactory: () => () => createCloseScrollStrategy(TestBed.inject(Injector)), }, ], - [FakeIcon], - ); + }); + overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement(); + + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const trigger = fixture.componentInstance.trigger; @@ -782,7 +790,7 @@ describe('MatMenu', () => { })); it('should switch to keyboard focus when using the keyboard after opening using the mouse', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.triggerEl.nativeElement.click(); @@ -812,7 +820,7 @@ describe('MatMenu', () => { })); it('should set the keyboard focus origin when opened using the keyboard', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const trigger = fixture.componentInstance.triggerEl.nativeElement; @@ -834,7 +842,7 @@ describe('MatMenu', () => { })); it('should toggle the aria-expanded attribute on the trigger', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -854,7 +862,7 @@ describe('MatMenu', () => { })); it('should toggle aria-expanded on the trigger in an OnPush component', fakeAsync(() => { - const fixture = createComponent(SimpleMenuOnPush, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenuOnPush); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -875,14 +883,14 @@ describe('MatMenu', () => { it('should throw if assigning a menu that contains the trigger', fakeAsync(() => { expect(() => { - const fixture = createComponent(InvalidRecursiveMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(InvalidRecursiveMenu); fixture.detectChanges(); tick(500); }).toThrowError(/menu cannot contain its own trigger/); })); it('should be able to swap out a menu after the first time it is opened', fakeAsync(() => { - const fixture = createComponent(DynamicPanelMenu); + const fixture = TestBed.createComponent(DynamicPanelMenu); fixture.detectChanges(); expect(overlayContainerElement.textContent).toBe(''); @@ -915,7 +923,7 @@ describe('MatMenu', () => { })); it('should focus the first item when pressing home', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -943,7 +951,7 @@ describe('MatMenu', () => { })); it('should not focus the first item when pressing home with a modifier key', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -970,7 +978,7 @@ describe('MatMenu', () => { })); it('should focus the last item when pressing end', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -991,7 +999,7 @@ describe('MatMenu', () => { })); it('should not focus the last item when pressing end with a modifier key', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -1014,7 +1022,7 @@ describe('MatMenu', () => { })); it('should respect the DOM order, rather than insertion order, when moving focus using the arrow keys', fakeAsync(() => { - let fixture = createComponent(SimpleMenuWithRepeater); + let fixture = TestBed.createComponent(SimpleMenuWithRepeater); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -1043,7 +1051,7 @@ describe('MatMenu', () => { })); it('should sync the focus order when an item is focused programmatically', fakeAsync(() => { - const fixture = createComponent(SimpleMenuWithRepeater); + const fixture = TestBed.createComponent(SimpleMenuWithRepeater); // Add some more items to work with. for (let i = 0; i < 5; i++) { @@ -1076,7 +1084,7 @@ describe('MatMenu', () => { })); it('should open submenus when the menu is inside an OnPush component', fakeAsync(() => { - const fixture = createComponent(LazyMenuWithOnPush); + const fixture = TestBed.createComponent(LazyMenuWithOnPush); fixture.detectChanges(); // Open the top-level menu @@ -1096,7 +1104,7 @@ describe('MatMenu', () => { })); it('should focus the menu panel if all items are disabled', fakeAsync(() => { - const fixture = createComponent(SimpleMenuWithRepeater, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenuWithRepeater); fixture.componentInstance.items.forEach(item => (item.disabled = true)); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -1109,7 +1117,7 @@ describe('MatMenu', () => { })); it('should focus the menu panel if all items are disabled inside lazy content', fakeAsync(() => { - const fixture = createComponent(SimpleMenuWithRepeaterInLazyContent, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenuWithRepeaterInLazyContent); fixture.componentInstance.items.forEach(item => (item.disabled = true)); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -1122,13 +1130,13 @@ describe('MatMenu', () => { })); it('should clear the static aria-label from the menu host', fakeAsync(() => { - const fixture = createComponent(StaticAriaLabelMenu); + const fixture = TestBed.createComponent(StaticAriaLabelMenu); fixture.detectChanges(); expect(fixture.nativeElement.querySelector('mat-menu').hasAttribute('aria-label')).toBe(false); })); it('should clear the static aria-labelledby from the menu host', fakeAsync(() => { - const fixture = createComponent(StaticAriaLabelledByMenu); + const fixture = TestBed.createComponent(StaticAriaLabelledByMenu); fixture.detectChanges(); expect(fixture.nativeElement.querySelector('mat-menu').hasAttribute('aria-labelledby')).toBe( false, @@ -1136,7 +1144,7 @@ describe('MatMenu', () => { })); it('should clear the static aria-describedby from the menu host', fakeAsync(() => { - const fixture = createComponent(StaticAriaDescribedbyMenu); + const fixture = TestBed.createComponent(StaticAriaDescribedbyMenu); fixture.detectChanges(); expect(fixture.nativeElement.querySelector('mat-menu').hasAttribute('aria-describedby')).toBe( false, @@ -1144,7 +1152,7 @@ describe('MatMenu', () => { })); it('should be able to move focus inside the `open` event', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.menuOpened.subscribe(() => { @@ -1159,7 +1167,7 @@ describe('MatMenu', () => { })); it('should default to the "below" and "after" positions', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); @@ -1171,7 +1179,8 @@ describe('MatMenu', () => { })); it('should keep the panel in the viewport when more items are added while open', () => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const viewportRuler = TestBed.inject(ViewportRuler); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const triggerEl = fixture.componentInstance.triggerEl.nativeElement; @@ -1195,8 +1204,7 @@ describe('MatMenu', () => { describe('lazy rendering', () => { it('should be able to render the menu content lazily', fakeAsync(() => { - const fixture = createComponent(SimpleLazyMenu); - + const fixture = TestBed.createComponent(SimpleLazyMenu); fixture.detectChanges(); fixture.componentInstance.triggerEl.nativeElement.click(); fixture.detectChanges(); @@ -1214,27 +1222,16 @@ describe('MatMenu', () => { })); it('should detach the lazy content when the menu is closed', fakeAsync(() => { - let destroyCount = 0; - - // Note: for some reason doing `spyOn(item, 'ngOnDestroy')` doesn't work, even though a - // `console.log` shows that the `ngOnDestroy` gets called. We work around it with a custom - // directive that increments a counter. - @Directive({selector: '[mat-menu-item]', standalone: false}) - class DestroyChecker implements OnDestroy { - ngOnDestroy(): void { - destroyCount++; - } - } - - const fixture = createComponent(SimpleLazyMenu, undefined, [DestroyChecker]); + const fixture = TestBed.createComponent(SimpleLazyMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); tick(500); fixture.detectChanges(); + const checkers = fixture.componentInstance.destroyCheckers.toArray(); expect(fixture.componentInstance.items.length).toBe(2); - expect(destroyCount).toBe(0); + expect(checkers.map(d => d.destroyed)).toEqual([false, false]); fixture.componentInstance.trigger.closeMenu(); fixture.detectChanges(); @@ -1244,11 +1241,13 @@ describe('MatMenu', () => { expect(fixture.componentInstance.items.length) .withContext('Expected items to be removed from query list') .toBe(0); - expect(destroyCount).withContext('Expected ngOnDestroy to have been called').toBe(2); + expect(checkers.map(d => d.destroyed)) + .withContext('Expected ngOnDestroy to have been called') + .toEqual([true, true]); })); it('should focus the first menu item when opening a lazy menu via keyboard', () => { - const fixture = createComponent(SimpleLazyMenu); + const fixture = TestBed.createComponent(SimpleLazyMenu); fixture.detectChanges(); // A click without a mousedown before it is considered a keyboard open. @@ -1261,8 +1260,7 @@ describe('MatMenu', () => { }); it('should be able to open the same menu with a different context', fakeAsync(() => { - const fixture = createComponent(LazyMenuWithContext); - + const fixture = TestBed.createComponent(LazyMenuWithContext); fixture.detectChanges(); fixture.componentInstance.triggerOne.openMenu(); fixture.detectChanges(); @@ -1290,7 +1288,7 @@ describe('MatMenu', () => { let trigger: HTMLElement; beforeEach(fakeAsync(() => { - fixture = createComponent(PositionedMenu); + fixture = TestBed.createComponent(PositionedMenu); fixture.detectChanges(); trigger = fixture.componentInstance.triggerEl.nativeElement; @@ -1405,7 +1403,7 @@ describe('MatMenu', () => { describe('fallback positions', () => { it('should fall back to "before" mode if "after" mode would not fit on screen', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const trigger = fixture.componentInstance.triggerEl.nativeElement; @@ -1439,7 +1437,7 @@ describe('MatMenu', () => { })); it('should fall back to "above" mode if "below" mode would not fit on screen', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const trigger = fixture.componentInstance.triggerEl.nativeElement; @@ -1467,7 +1465,7 @@ describe('MatMenu', () => { })); it('should re-position menu on both axes if both defaults would not fit', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const trigger = fixture.componentInstance.triggerEl.nativeElement; @@ -1496,7 +1494,7 @@ describe('MatMenu', () => { })); it('should re-position a menu with custom position set', fakeAsync(() => { - const fixture = createComponent(PositionedMenu); + const fixture = TestBed.createComponent(PositionedMenu); fixture.detectChanges(); const trigger = fixture.componentInstance.triggerEl.nativeElement; @@ -1545,7 +1543,7 @@ describe('MatMenu', () => { readonly trigger: HTMLElement; constructor(ctor: {new (): T}, inputs: {[key: string]: any} = {}) { - this.fixture = createComponent(ctor); + this.fixture = TestBed.createComponent(ctor); Object.keys(inputs).forEach( key => ((this.fixture.componentInstance as any)[key] = inputs[key]), ); @@ -1636,7 +1634,7 @@ describe('MatMenu', () => { describe('animations', () => { it('should enable ripples on items by default', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -1650,7 +1648,7 @@ describe('MatMenu', () => { })); it('should disable ripples on disabled items', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -1664,7 +1662,7 @@ describe('MatMenu', () => { })); it('should disable ripples if disableRipple is set', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); @@ -1683,7 +1681,7 @@ describe('MatMenu', () => { let fixture: ComponentFixture; beforeEach(fakeAsync(() => { - fixture = createComponent(SimpleMenu, [], [FakeIcon]); + fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); @@ -1740,23 +1738,37 @@ describe('MatMenu', () => { let fixture: ComponentFixture; let instance: NestedMenu; let overlay: HTMLElement; - let compileTestComponent = (direction: Direction = 'ltr') => { - fixture = createComponent(NestedMenu, [provideFakeDirectionality(direction)]); - + let direction: Direction; + + beforeEach(() => { + direction = 'ltr'; + TestBed.resetTestingModule().configureTestingModule({ + providers: [ + provideCheckNoChangesConfig({exhaustive: false}), + { + provide: Directionality, + useValue: { + get value() { + return direction; + }, + }, + }, + ], + }); + overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement(); + fixture = TestBed.createComponent(NestedMenu); fixture.detectChanges(); instance = fixture.componentInstance; overlay = overlayContainerElement; - }; + }); it('should set the `triggersSubmenu` flags on the triggers', fakeAsync(() => { - compileTestComponent(); expect(instance.rootTrigger.triggersSubmenu()).toBe(false); expect(instance.levelOneTrigger.triggersSubmenu()).toBe(true); expect(instance.levelTwoTrigger.triggersSubmenu()).toBe(true); })); it('should set the `parentMenu` on the sub-menu instances', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); tick(500); @@ -1775,7 +1787,7 @@ describe('MatMenu', () => { })); it('should pass the layout direction the nested menus', fakeAsync(() => { - compileTestComponent('rtl'); + direction = 'rtl'; instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); @@ -1793,7 +1805,6 @@ describe('MatMenu', () => { })); it('should emit an event when the hover state of the menu items changes', fakeAsync(() => { - compileTestComponent(); instance.rootTrigger.openMenu(); fixture.detectChanges(); tick(500); @@ -1818,7 +1829,6 @@ describe('MatMenu', () => { })); it('should toggle a nested menu when its trigger is hovered', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); expect(overlay.querySelectorAll('.mat-mdc-menu-panel').length) @@ -1854,7 +1864,6 @@ describe('MatMenu', () => { })); it('should close all the open sub-menus when the hover state is changed at the root', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); @@ -1884,7 +1893,6 @@ describe('MatMenu', () => { })); it('should close submenu when hovering over disabled sibling item', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); tick(500); @@ -1914,7 +1922,6 @@ describe('MatMenu', () => { })); it('should not open submenu when hovering over disabled trigger', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); tick(500); @@ -1940,7 +1947,6 @@ describe('MatMenu', () => { })); it('should open a nested menu when its trigger is clicked', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); tick(500); @@ -1965,7 +1971,6 @@ describe('MatMenu', () => { })); it('should open and close a nested menu with arrow keys in ltr', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); expect(overlay.querySelectorAll('.mat-mdc-menu-panel').length) @@ -1988,7 +1993,7 @@ describe('MatMenu', () => { })); it('should open and close a nested menu with the arrow keys in rtl', fakeAsync(() => { - compileTestComponent('rtl'); + direction = 'rtl'; instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); expect(overlay.querySelectorAll('.mat-mdc-menu-panel').length) @@ -2011,7 +2016,6 @@ describe('MatMenu', () => { })); it('should not do anything with the arrow keys for a top-level menu', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); tick(500); @@ -2034,7 +2038,6 @@ describe('MatMenu', () => { })); it('should close all of the menus when the backdrop is clicked', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); tick(500); @@ -2067,7 +2070,6 @@ describe('MatMenu', () => { })); it('should shift focus between the sub-menus', fakeAsync(() => { - compileTestComponent(); instance.rootTrigger.openMenu(); fixture.detectChanges(); tick(500); @@ -2110,7 +2112,6 @@ describe('MatMenu', () => { })); it('should restore focus to a nested trigger when navigating via the keyboard', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); @@ -2131,7 +2132,6 @@ describe('MatMenu', () => { })); it('should position the sub-menu to the right edge of the trigger in ltr', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.style.position = 'fixed'; instance.rootTriggerEl.nativeElement.style.left = '50px'; instance.rootTriggerEl.nativeElement.style.top = '200px'; @@ -2151,7 +2151,6 @@ describe('MatMenu', () => { })); it('should fall back to aligning to the left edge of the trigger in ltr', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.style.position = 'fixed'; instance.rootTriggerEl.nativeElement.style.right = '10px'; instance.rootTriggerEl.nativeElement.style.top = '200px'; @@ -2171,7 +2170,7 @@ describe('MatMenu', () => { })); it('should position the sub-menu to the left edge of the trigger in rtl', fakeAsync(() => { - compileTestComponent('rtl'); + direction = 'rtl'; instance.rootTriggerEl.nativeElement.style.position = 'fixed'; instance.rootTriggerEl.nativeElement.style.left = '50%'; instance.rootTriggerEl.nativeElement.style.top = '200px'; @@ -2191,7 +2190,7 @@ describe('MatMenu', () => { })); it('should fall back to aligning to the right edge of the trigger in rtl', fakeAsync(() => { - compileTestComponent('rtl'); + direction = 'rtl'; instance.rootTriggerEl.nativeElement.style.position = 'fixed'; instance.rootTriggerEl.nativeElement.style.left = '10px'; instance.rootTriggerEl.nativeElement.style.top = '200px'; @@ -2211,7 +2210,6 @@ describe('MatMenu', () => { })); it('should account for custom padding when offsetting the sub-menu', () => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.style.position = 'fixed'; instance.rootTriggerEl.nativeElement.style.left = '10px'; instance.rootTriggerEl.nativeElement.style.top = '200px'; @@ -2231,7 +2229,6 @@ describe('MatMenu', () => { }); it('should close all of the menus when an item is clicked', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); @@ -2255,7 +2252,6 @@ describe('MatMenu', () => { })); it('should close all of the menus when the user tabs away', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); @@ -2279,7 +2275,6 @@ describe('MatMenu', () => { })); it('should set a class on the menu items that trigger a sub-menu', fakeAsync(() => { - compileTestComponent(); instance.rootTrigger.openMenu(); fixture.detectChanges(); tick(500); @@ -2299,8 +2294,6 @@ describe('MatMenu', () => { })); it('should not change focus origin if origin not specified for trigger', fakeAsync(() => { - compileTestComponent(); - instance.levelOneTrigger.openMenu(); fixture.detectChanges(); tick(500); @@ -2318,7 +2311,6 @@ describe('MatMenu', () => { })); it('should close all of the menus when the root is closed programmatically', fakeAsync(() => { - compileTestComponent(); instance.rootTrigger.openMenu(); fixture.detectChanges(); @@ -2342,7 +2334,6 @@ describe('MatMenu', () => { })); it('should toggle a nested menu when its trigger is added after init', fakeAsync(() => { - compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); tick(500); @@ -2371,7 +2362,6 @@ describe('MatMenu', () => { })); it('should prevent the default mousedown action if the menu item opens a sub-menu', fakeAsync(() => { - compileTestComponent(); instance.rootTrigger.openMenu(); fixture.detectChanges(); tick(500); @@ -2388,7 +2378,7 @@ describe('MatMenu', () => { })); it('should handle the items being rendered in a repeater', fakeAsync(() => { - const repeaterFixture = createComponent(NestedMenuRepeater); + const repeaterFixture = TestBed.createComponent(NestedMenuRepeater); overlay = overlayContainerElement; expect(() => repeaterFixture.detectChanges()).not.toThrow(); @@ -2409,7 +2399,7 @@ describe('MatMenu', () => { })); it('should be able to trigger the same nested menu from different triggers', fakeAsync(() => { - const repeaterFixture = createComponent(NestedMenuRepeater); + const repeaterFixture = TestBed.createComponent(NestedMenuRepeater); overlay = overlayContainerElement; repeaterFixture.detectChanges(); @@ -2439,7 +2429,7 @@ describe('MatMenu', () => { })); it('should close the initial menu if the user moves away while animating', fakeAsync(() => { - const repeaterFixture = createComponent(NestedMenuRepeater); + const repeaterFixture = TestBed.createComponent(NestedMenuRepeater); overlay = overlayContainerElement; repeaterFixture.detectChanges(); @@ -2468,7 +2458,7 @@ describe('MatMenu', () => { 'should be able to open a submenu through an item that is not a direct descendant ' + 'of the panel', fakeAsync(() => { - const nestedFixture = createComponent(SubmenuDeclaredInsideParentMenu); + const nestedFixture = TestBed.createComponent(SubmenuDeclaredInsideParentMenu); overlay = overlayContainerElement; nestedFixture.detectChanges(); @@ -2493,7 +2483,7 @@ describe('MatMenu', () => { 'should not close when hovering over a menu item inside a sub-menu panel that is declared' + 'inside the root menu', fakeAsync(() => { - const nestedFixture = createComponent(SubmenuDeclaredInsideParentMenu); + const nestedFixture = TestBed.createComponent(SubmenuDeclaredInsideParentMenu); overlay = overlayContainerElement; nestedFixture.detectChanges(); @@ -2523,8 +2513,6 @@ describe('MatMenu', () => { ); it('should not re-focus a child menu trigger when hovering another trigger', fakeAsync(() => { - compileTestComponent(); - dispatchFakeEvent(instance.rootTriggerEl.nativeElement, 'mousedown'); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); @@ -2551,7 +2539,7 @@ describe('MatMenu', () => { }); it('should have a focus indicator', fakeAsync(() => { - const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); fixture.componentInstance.trigger.openMenu(); fixture.detectChanges(); @@ -2577,7 +2565,6 @@ describe('MatMenu default overrides', () => { }, {provide: MATERIAL_ANIMATIONS, useValue: {animationsDisabled: true}}, ], - declarations: [SimpleMenu, FakeIcon], }); })); @@ -2621,9 +2608,15 @@ const SIMPLE_MENU_TEMPLATE = ` `; +@Component({ + selector: 'mat-icon', + template: '', +}) +class FakeIcon {} + @Component({ template: SIMPLE_MENU_TEMPLATE, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem, FakeIcon], }) class SimpleMenu { @ViewChild(MatMenuTrigger) trigger: MatMenuTrigger; @@ -2643,7 +2636,7 @@ class SimpleMenu { @Component({ template: SIMPLE_MENU_TEMPLATE, changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem, FakeIcon], }) class SimpleMenuOnPush extends SimpleMenu {} @@ -2654,7 +2647,7 @@ class SimpleMenuOnPush extends SimpleMenu {} `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class PositionedMenu { @ViewChild(MatMenuTrigger) trigger: MatMenuTrigger; @@ -2674,7 +2667,7 @@ interface TestableMenu { `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class OverlapMenu implements TestableMenu { @Input() overlapTrigger: boolean; @@ -2691,7 +2684,7 @@ class OverlapMenu implements TestableMenu { `, exportAs: 'matCustomMenu', - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class CustomMenuPanel implements MatMenuPanel { direction: Direction; @@ -2714,7 +2707,7 @@ class CustomMenuPanel implements MatMenuPanel { `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem, CustomMenuPanel], }) class CustomMenu { @ViewChild(MatMenuTrigger) trigger: MatMenuTrigger; @@ -2766,7 +2759,7 @@ class CustomMenu { `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class NestedMenu { @ViewChild('root') rootMenu: MatMenu; @@ -2805,7 +2798,7 @@ class NestedMenu { `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class NestedMenuRepeater { @ViewChild('rootTriggerEl') rootTriggerEl: ElementRef; @@ -2826,18 +2819,23 @@ class NestedMenuRepeater { `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class SubmenuDeclaredInsideParentMenu { @ViewChild('rootTriggerEl') rootTriggerEl: ElementRef; } -@Component({ - selector: 'mat-icon', - template: '', - standalone: false, -}) -class FakeIcon {} +// Note: for some reason doing `spyOn(item, 'ngOnDestroy')` doesn't work, even though a +// `console.log` shows that the `ngOnDestroy` gets called. We work around it with a custom +// directive that flips a flag. +@Directive({selector: '[mat-menu-item]'}) +class DestroyChecker implements OnDestroy { + destroyed = false; + + ngOnDestroy(): void { + this.destroyed = true; + } +} @Component({ template: ` @@ -2850,12 +2848,13 @@ class FakeIcon {} `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem, MatMenuContent, DestroyChecker], }) class SimpleLazyMenu { @ViewChild(MatMenuTrigger) trigger: MatMenuTrigger; @ViewChild('triggerEl') triggerEl: ElementRef; @ViewChildren(MatMenuItem) items: QueryList; + @ViewChildren(DestroyChecker) destroyCheckers: QueryList; } @Component({ @@ -2876,7 +2875,7 @@ class SimpleLazyMenu { `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem, MatMenuContent], }) class LazyMenuWithContext { @ViewChild('triggerOne') triggerOne: MatMenuTrigger; @@ -2894,7 +2893,7 @@ class LazyMenuWithContext { `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class DynamicPanelMenu { @ViewChild(MatMenuTrigger) trigger: MatMenuTrigger; @@ -2911,7 +2910,7 @@ class DynamicPanelMenu { `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class MenuWithCheckboxItems { @ViewChild(MatMenuTrigger) trigger: MatMenuTrigger; @@ -2926,7 +2925,7 @@ class MenuWithCheckboxItems { } `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class SimpleMenuWithRepeater { @ViewChild(MatMenuTrigger) trigger: MatMenuTrigger; @@ -2949,7 +2948,7 @@ class SimpleMenuWithRepeater { `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem, MatMenuContent], }) class SimpleMenuWithRepeaterInLazyContent { @ViewChild(MatMenuTrigger) trigger: MatMenuTrigger; @@ -2977,7 +2976,7 @@ class SimpleMenuWithRepeaterInLazyContent { `, changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem, MatMenuContent], }) class LazyMenuWithOnPush { @ViewChild('triggerEl', {read: ElementRef}) rootTrigger: ElementRef; @@ -2990,25 +2989,25 @@ class LazyMenuWithOnPush { `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class InvalidRecursiveMenu {} @Component({ template: '', - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class StaticAriaLabelMenu {} @Component({ template: '', - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class StaticAriaLabelledByMenu {} @Component({ template: '', - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class StaticAriaDescribedbyMenu {} @@ -3021,7 +3020,7 @@ class StaticAriaDescribedbyMenu {} } `, - standalone: false, + imports: [MatMenuTrigger, MatMenu, MatMenuItem], }) class MenuWithRepeatedItems { @ViewChild(MatMenuTrigger, {static: false}) trigger: MatMenuTrigger; diff --git a/src/material/select/select.spec.ts b/src/material/select/select.spec.ts index c2574ea65c34..67252a5885bd 100644 --- a/src/material/select/select.spec.ts +++ b/src/material/select/select.spec.ts @@ -33,7 +33,6 @@ import { ElementRef, Injector, OnInit, - Provider, QueryList, ViewChild, ViewChildren, @@ -42,14 +41,7 @@ import { provideCheckNoChangesConfig, signal, } from '@angular/core'; -import { - ComponentFixture, - TestBed, - fakeAsync, - flush, - tick, - waitForAsync, -} from '@angular/core/testing'; +import {ComponentFixture, TestBed, fakeAsync, flush, tick} from '@angular/core/testing'; import { ControlValueAccessor, FormBuilder, @@ -64,11 +56,16 @@ import { import {By} from '@angular/platform-browser'; import {Subject, Subscription} from 'rxjs'; import {map} from 'rxjs/operators'; -import {ErrorStateMatcher, MATERIAL_ANIMATIONS, MatOption, MatOptionSelectionChange} from '../core'; +import { + ErrorStateMatcher, + MATERIAL_ANIMATIONS, + MatOptgroup, + MatOption, + MatOptionSelectionChange, +} from '../core'; import {FloatLabelType, MAT_FORM_FIELD_DEFAULT_OPTIONS, MatFormFieldModule} from '../form-field'; import {MAT_SELECT_CONFIG, MatSelectConfig} from '../select'; -import {MatSelectModule} from './index'; -import {MAT_SELECT_SCROLL_STRATEGY, MatSelect} from './select'; +import {MAT_SELECT_SCROLL_STRATEGY, MatSelect, MatSelectTrigger} from './select'; import { getMatSelectDynamicMultipleError, getMatSelectNonArrayValueError, @@ -83,23 +80,9 @@ describe('MatSelect', () => { let dir: WritableSignal; let scrolledSubject = new Subject(); - /** - * Configures the test module for MatSelect with the given declarations. This is broken out so - * that we're only compiling the necessary test components for each test in order to speed up - * overall test time. - * @param declarations Components to declare for this block - * @param providers Additional providers for this block - */ - function configureMatSelectTestingModule(declarations: any[], providers: Provider[] = []) { + beforeEach(() => { dir = signal('ltr'); TestBed.configureTestingModule({ - imports: [ - MatFormFieldModule, - MatSelectModule, - ReactiveFormsModule, - FormsModule, - OverlayModule, - ], providers: [ provideCheckNoChangesConfig({exhaustive: false}), {provide: MATERIAL_ANIMATIONS, useValue: {animationsDisabled: true}}, @@ -110,28 +93,13 @@ describe('MatSelect', () => { scrolled: () => scrolledSubject, }), }, - ...providers, ], - declarations: declarations, }); overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement(); - } + }); describe('core', () => { - beforeEach(waitForAsync(() => { - configureMatSelectTestingModule([ - BasicSelect, - SelectInsideAModal, - MultiSelect, - SelectWithGroups, - SelectWithGroupsAndNgContainer, - SelectWithFormFieldLabel, - SelectWithChangeEvent, - SelectInsideDynamicFormGroup, - ]); - })); - describe('accessibility', () => { describe('for select', () => { let fixture: ComponentFixture; @@ -1448,11 +1416,6 @@ describe('MatSelect', () => { // Need to recreate the testing module, because the issue we're // testing for only happens when animations are enabled. TestBed.resetTestingModule(); - TestBed.configureTestingModule({ - imports: [MatFormFieldModule, MatSelectModule], - declarations: [BasicSelect], - }); - fixture = TestBed.createComponent(BasicSelect); fixture.detectChanges(); const select = fixture.componentInstance.select; @@ -1781,8 +1744,6 @@ describe('MatSelect', () => { TestBed.resetTestingModule(); TestBed.configureTestingModule({ - imports: [MatFormFieldModule, MatSelectModule], - declarations: [BasicSelect], providers: [ { provide: MAT_SELECT_SCROLL_STRATEGY, @@ -2708,8 +2669,6 @@ describe('MatSelect', () => { }); describe('when initialized without options', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectInitWithoutOptions]))); - it('should select the proper option when option list is initialized later', fakeAsync(() => { const fixture = TestBed.createComponent(SelectInitWithoutOptions); const instance = fixture.componentInstance; @@ -2731,8 +2690,6 @@ describe('MatSelect', () => { }); describe('with a selectionChange event handler', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectWithChangeEvent]))); - let fixture: ComponentFixture; let trigger: HTMLElement; @@ -2775,8 +2732,6 @@ describe('MatSelect', () => { }); describe('with ngModel', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([NgModelSelect]))); - it('should disable itself when control is disabled using the property', fakeAsync(() => { const fixture = TestBed.createComponent(NgModelSelect); fixture.detectChanges(); @@ -2827,8 +2782,6 @@ describe('MatSelect', () => { }); describe('with ngIf', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([NgIfSelect]))); - it('should handle nesting in an ngIf', fakeAsync(() => { const fixture = TestBed.createComponent(NgIfSelect); fixture.detectChanges(); @@ -2861,8 +2814,6 @@ describe('MatSelect', () => { }); describe('with multiple mat-select elements in one view', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([ManySelects]))); - let fixture: ComponentFixture; let triggers: DebugElement[]; let options: NodeListOf; @@ -2908,8 +2859,6 @@ describe('MatSelect', () => { }); describe('with floatLabel', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([FloatLabelSelect]))); - it('should be able to always float the label', () => { const fixture = TestBed.createComponent(FloatLabelSelect); fixture.detectChanges(); @@ -2929,9 +2878,7 @@ describe('MatSelect', () => { it('should default to global floating label type', () => { TestBed.resetTestingModule(); TestBed.configureTestingModule({ - imports: [MatFormFieldModule, MatSelectModule, ReactiveFormsModule, FormsModule], providers: [{provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: {floatLabel: 'always'}}], - declarations: [FloatLabelSelect], }); const fixture = TestBed.createComponent(FloatLabelSelect); @@ -2965,9 +2912,6 @@ describe('MatSelect', () => { }); describe('with a sibling component that throws an error', () => { - beforeEach(waitForAsync(() => - configureMatSelectTestingModule([SelectWithErrorSibling, ThrowsErrorOnInit]))); - it('should not crash the browser when a sibling throws an error on init', () => { // Note that this test can be considered successful if the error being thrown didn't // end up crashing the testing setup altogether. @@ -2978,8 +2922,6 @@ describe('MatSelect', () => { }); describe('with tabindex', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectWithPlainTabindex]))); - it('should be able to set the tabindex via the native attribute', () => { const fixture = TestBed.createComponent(SelectWithPlainTabindex); fixture.detectChanges(); @@ -2990,8 +2932,6 @@ describe('MatSelect', () => { }); describe('change events', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectWithPlainTabindex]))); - it('should complete the stateChanges stream on destroy', () => { const fixture = TestBed.createComponent(SelectWithPlainTabindex); fixture.detectChanges(); @@ -3009,8 +2949,6 @@ describe('MatSelect', () => { }); describe('when initially hidden', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([BasicSelectInitiallyHidden]))); - it('should set the width of the overlay if the element was hidden initially', fakeAsync(() => { const fixture = TestBed.createComponent(BasicSelectInitiallyHidden); fixture.detectChanges(); @@ -3032,8 +2970,6 @@ describe('MatSelect', () => { }); describe('with no placeholder', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([BasicSelectNoPlaceholder]))); - it('should set the width of the overlay if there is no placeholder', fakeAsync(() => { const fixture = TestBed.createComponent(BasicSelectNoPlaceholder); @@ -3050,8 +2986,6 @@ describe('MatSelect', () => { }); describe('with theming', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([BasicSelectWithTheming]))); - let fixture: ComponentFixture; beforeEach(() => { @@ -3073,8 +3007,6 @@ describe('MatSelect', () => { }); describe('when invalid inside a form', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([InvalidSelectInForm]))); - it('should not throw SelectionModel errors in addition to ngModel errors', () => { const fixture = TestBed.createComponent(InvalidSelectInForm); @@ -3088,8 +3020,6 @@ describe('MatSelect', () => { }); describe('with ngModel using compareWith', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([NgModelCompareWithSelect]))); - let fixture: ComponentFixture; let instance: NgModelCompareWithSelect; @@ -3157,8 +3087,6 @@ describe('MatSelect', () => { }); describe(`when the select's value is accessed on initialization`, () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectEarlyAccessSibling]))); - it('should not throw when trying to access the selected value on init in the view', () => { expect(() => { TestBed.createComponent(SelectEarlyAccessSibling).detectChanges(); @@ -3187,8 +3115,6 @@ describe('MatSelect', () => { }); describe('with ngIf and mat-label', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectWithNgIfAndLabel]))); - it('should not throw when using ngIf on a select with an associated label', () => { expect(() => { const fixture = TestBed.createComponent(SelectWithNgIfAndLabel); @@ -3198,8 +3124,6 @@ describe('MatSelect', () => { }); describe('inside of a form group', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectInsideFormGroup]))); - let fixture: ComponentFixture; let testComponent: SelectInsideFormGroup; let select: HTMLElement; @@ -3311,10 +3235,7 @@ describe('MatSelect', () => { }; fixture.destroy(); - TestBed.resetTestingModule().configureTestingModule({ - imports: [MatSelectModule, ReactiveFormsModule, FormsModule], - declarations: [SelectInsideFormGroup], providers: [{provide: ErrorStateMatcher, useValue: errorStateMatcher}], }); @@ -3350,8 +3271,6 @@ describe('MatSelect', () => { }); describe('with custom error behavior', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([CustomErrorBehaviorSelect]))); - it('should be able to override the error matching behavior via an @Input', () => { const fixture = TestBed.createComponent(CustomErrorBehaviorSelect); const component = fixture.componentInstance; @@ -3372,9 +3291,6 @@ describe('MatSelect', () => { }); describe('with preselected array values', () => { - beforeEach(waitForAsync(() => - configureMatSelectTestingModule([SingleSelectWithPreselectedArrayValues]))); - it('should be able to preselect an array value in single-selection mode', fakeAsync(() => { const fixture = TestBed.createComponent(SingleSelectWithPreselectedArrayValues); fixture.detectChanges(); @@ -3389,9 +3305,6 @@ describe('MatSelect', () => { }); describe('with custom value accessor', () => { - beforeEach(waitForAsync(() => - configureMatSelectTestingModule([CompWithCustomSelect, CustomSelectAccessor]))); - it('should support use inside a custom value accessor', () => { const fixture = TestBed.createComponent(CompWithCustomSelect); spyOn(fixture.componentInstance.customAccessor, 'writeValue'); @@ -3405,8 +3318,6 @@ describe('MatSelect', () => { }); describe('with a falsy value', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([FalsyValueSelect]))); - it('should be able to programmatically select a falsy option', fakeAsync(() => { const fixture = TestBed.createComponent(FalsyValueSelect); @@ -3426,9 +3337,6 @@ describe('MatSelect', () => { }); describe('with OnPush', () => { - beforeEach(waitForAsync(() => - configureMatSelectTestingModule([BasicSelectOnPush, BasicSelectOnPushPreselected]))); - it('should set the trigger text based on the value when initialized', fakeAsync(() => { const fixture = TestBed.createComponent(BasicSelectOnPushPreselected); @@ -3469,8 +3377,6 @@ describe('MatSelect', () => { }); describe('with custom trigger', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectWithCustomTrigger]))); - it('should allow the user to customize the label', () => { const fixture = TestBed.createComponent(SelectWithCustomTrigger); fixture.detectChanges(); @@ -3487,8 +3393,6 @@ describe('MatSelect', () => { }); describe('when reseting the value by setting null or undefined', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([ResetValuesSelect]))); - let fixture: ComponentFixture; let trigger: HTMLElement; let formField: HTMLElement; @@ -3583,8 +3487,6 @@ describe('MatSelect', () => { }); describe('allowing selection of nullable options', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([ResetValuesSelect]))); - let fixture: ComponentFixture; let trigger: HTMLElement; let formField: HTMLElement; @@ -3684,7 +3586,6 @@ describe('MatSelect', () => { let trigger: HTMLElement; beforeEach(() => { - configureMatSelectTestingModule([SelectWithResetOptionAndFormControl]); fixture = TestBed.createComponent(SelectWithResetOptionAndFormControl); fixture.detectChanges(); trigger = fixture.debugElement.query(By.css('.mat-mdc-select-trigger'))!.nativeElement; @@ -3736,13 +3637,6 @@ describe('MatSelect', () => { }); describe('without Angular forms', () => { - beforeEach(waitForAsync(() => - configureMatSelectTestingModule([ - BasicSelectWithoutForms, - BasicSelectWithoutFormsPreselected, - BasicSelectWithoutFormsMultiple, - ]))); - it('should set the value when options are clicked', fakeAsync(() => { const fixture = TestBed.createComponent(BasicSelectWithoutForms); @@ -4086,8 +3980,6 @@ describe('MatSelect', () => { }); describe('with option centering disabled', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectWithoutOptionCentering]))); - let fixture: ComponentFixture; let trigger: HTMLElement; @@ -4119,8 +4011,6 @@ describe('MatSelect', () => { }); describe('positioning', () => { - beforeEach(waitForAsync(() => configureMatSelectTestingModule([BasicSelect]))); - let fixture: ComponentFixture; let trigger: HTMLElement; let formField: HTMLElement; @@ -4172,9 +4062,6 @@ describe('MatSelect', () => { }); describe('with multiple selection', () => { - beforeEach(waitForAsync(() => - configureMatSelectTestingModule([MultiSelect, MultiSelectWithLotsOfOptions]))); - let fixture: ComponentFixture; let testInstance: MultiSelect; let trigger: HTMLElement; @@ -4643,9 +4530,9 @@ describe('MatSelect', () => { }); it('should be able to provide default values through an injection token', fakeAsync(() => { - configureMatSelectTestingModule( - [NgModelSelect], - [ + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + providers: [ { provide: MAT_SELECT_CONFIG, useValue: { @@ -4656,7 +4543,7 @@ describe('MatSelect', () => { } as MatSelectConfig, }, ], - ); + }); const fixture = TestBed.createComponent(NgModelSelect); fixture.detectChanges(); const select = fixture.componentInstance.select; @@ -4672,15 +4559,15 @@ describe('MatSelect', () => { it('should be able to hide checkmark icon through an injection token', () => { const matSelectConfig: MatSelectConfig = {hideSingleSelectionIndicator: true}; - configureMatSelectTestingModule( - [NgModelSelect], - [ + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + providers: [ { provide: MAT_SELECT_CONFIG, useValue: matSelectConfig, }, ], - ); + }); const fixture = TestBed.createComponent(NgModelSelect); fixture.detectChanges(); const select = fixture.componentInstance.select; @@ -4705,7 +4592,6 @@ describe('MatSelect', () => { }); it('should not not throw if the select is inside an ng-container with ngIf', () => { - configureMatSelectTestingModule([SelectInNgContainer]); const fixture = TestBed.createComponent(SelectInNgContainer); expect(() => fixture.detectChanges()).not.toThrow(); }); @@ -4714,9 +4600,6 @@ describe('MatSelect', () => { let fixture: ComponentFixture; let host: HTMLElement; - beforeEach(waitForAsync(() => - configureMatSelectTestingModule([BasicSelectWithFirstAndLastOptionDisabled]))); - beforeEach(fakeAsync(() => { fixture = TestBed.createComponent(BasicSelectWithFirstAndLastOptionDisabled); @@ -4762,7 +4645,6 @@ describe('MatSelect', () => { }); @Component({ - selector: 'basic-select', template: `
@@ -4787,7 +4669,7 @@ describe('MatSelect', () => {
`, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class BasicSelect { foods: any[] = [ @@ -4821,7 +4703,6 @@ class BasicSelect { } @Component({ - selector: 'ng-model-select', template: ` @@ -4831,7 +4712,7 @@ class BasicSelect { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, FormsModule], }) class NgModelSelect { foods: any[] = [ @@ -4846,7 +4727,6 @@ class NgModelSelect { } @Component({ - selector: 'many-selects', template: ` @@ -4861,12 +4741,11 @@ class NgModelSelect { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class ManySelects {} @Component({ - selector: 'ng-if-select', template: ` @if (isShowing) {
@@ -4880,7 +4759,7 @@ class ManySelects {}
} `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class NgIfSelect { isShowing = false; @@ -4895,7 +4774,6 @@ class NgIfSelect { } @Component({ - selector: 'select-with-change-event', template: ` @@ -4905,7 +4783,7 @@ class NgIfSelect { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class SelectWithChangeEvent { foods: string[] = [ @@ -4923,7 +4801,6 @@ class SelectWithChangeEvent { } @Component({ - selector: 'select-init-without-options', template: ` @@ -4933,7 +4810,7 @@ class SelectWithChangeEvent { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class SelectInitWithoutOptions { foods: any[]; @@ -4952,8 +4829,8 @@ class SelectInitWithoutOptions { } @Component({ - selector: 'custom-select-accessor', template: ``, + selector: 'custom-select-accessor', providers: [ { provide: NG_VALUE_ACCESSOR, @@ -4961,7 +4838,7 @@ class SelectInitWithoutOptions { multi: true, }, ], - standalone: false, + imports: [MatSelect, MatFormFieldModule], }) class CustomSelectAccessor implements ControlValueAccessor { @ViewChild(MatSelect) select: MatSelect; @@ -4972,7 +4849,6 @@ class CustomSelectAccessor implements ControlValueAccessor { } @Component({ - selector: 'comp-with-custom-select', template: ``, providers: [ { @@ -4981,7 +4857,7 @@ class CustomSelectAccessor implements ControlValueAccessor { multi: true, }, ], - standalone: false, + imports: [CustomSelectAccessor, MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class CompWithCustomSelect { ctrl = new FormControl('initial value'); @@ -4989,32 +4865,29 @@ class CompWithCustomSelect { } @Component({ - selector: 'select-infinite-loop', + template: '', + selector: 'throws-error-on-init', +}) +class ThrowsErrorOnInit implements OnInit { + ngOnInit() { + throw Error('Oh no!'); + } +} + +@Component({ template: ` `, - standalone: false, + imports: [ThrowsErrorOnInit, MatSelect, MatOption, MatFormFieldModule, FormsModule], }) class SelectWithErrorSibling { value: string; } @Component({ - selector: 'throws-error-on-init', - template: '', - standalone: false, -}) -class ThrowsErrorOnInit implements OnInit { - ngOnInit() { - throw Error('Oh no!'); - } -} - -@Component({ - selector: 'basic-select-on-push', changeDetection: ChangeDetectionStrategy.OnPush, template: ` @@ -5025,7 +4898,7 @@ class ThrowsErrorOnInit implements OnInit { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class BasicSelectOnPush { foods: any[] = [ @@ -5037,7 +4910,6 @@ class BasicSelectOnPush { } @Component({ - selector: 'basic-select-on-push-preselected', changeDetection: ChangeDetectionStrategy.OnPush, template: ` @@ -5048,7 +4920,7 @@ class BasicSelectOnPush { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class BasicSelectOnPushPreselected { @ViewChild(MatSelect) select: MatSelect; @@ -5061,7 +4933,6 @@ class BasicSelectOnPushPreselected { } @Component({ - selector: 'floating-label-select', template: ` Select a food @@ -5072,7 +4943,7 @@ class BasicSelectOnPushPreselected { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class FloatLabelSelect { floatLabel: FloatLabelType | null = 'auto'; @@ -5088,7 +4959,6 @@ class FloatLabelSelect { } @Component({ - selector: 'multi-select', template: ` `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class MultiSelect { foods: any[] = [ @@ -5120,14 +4990,12 @@ class MultiSelect { } @Component({ - selector: 'select-with-plain-tabindex', template: ``, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class SelectWithPlainTabindex {} @Component({ - selector: 'select-early-sibling-access', template: ` @@ -5136,12 +5004,11 @@ class SelectWithPlainTabindex {}
} `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class SelectEarlyAccessSibling {} @Component({ - selector: 'basic-select-initially-hidden', template: ` @@ -5149,14 +5016,13 @@ class SelectEarlyAccessSibling {} `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class BasicSelectInitiallyHidden { isVisible = false; } @Component({ - selector: 'basic-select-no-placeholder', template: ` @@ -5164,12 +5030,11 @@ class BasicSelectInitiallyHidden { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class BasicSelectNoPlaceholder {} @Component({ - selector: 'basic-select-with-theming', template: ` @@ -5178,7 +5043,7 @@ class BasicSelectNoPlaceholder {} `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class BasicSelectWithTheming { @ViewChild(MatSelect) select: MatSelect; @@ -5186,7 +5051,6 @@ class BasicSelectWithTheming { } @Component({ - selector: 'reset-values-select', template: ` Select a food @@ -5198,7 +5062,7 @@ class BasicSelectWithTheming { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class ResetValuesSelect { foods: any[] = [ @@ -5225,7 +5089,7 @@ class ResetValuesSelect {
`, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class FalsyValueSelect { foods: any[] = [ @@ -5237,7 +5101,6 @@ class FalsyValueSelect { } @Component({ - selector: 'select-with-groups', template: ` @@ -5252,7 +5115,7 @@ class FalsyValueSelect { `, - standalone: false, + imports: [MatSelect, MatOption, MatOptgroup, MatFormFieldModule, ReactiveFormsModule], }) class SelectWithGroups { control = new FormControl(''); @@ -5296,7 +5159,6 @@ class SelectWithGroups { } @Component({ - selector: 'select-with-groups', template: ` @@ -5310,7 +5172,7 @@ class SelectWithGroups { `, - standalone: false, + imports: [MatSelect, MatOption, MatOptgroup, MatFormFieldModule, ReactiveFormsModule], }) class SelectWithGroupsAndNgContainer { control = new FormControl(''); @@ -5330,7 +5192,7 @@ class SelectWithGroupsAndNgContainer { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, FormsModule], }) class InvalidSelectInForm { value: any; @@ -5351,7 +5213,7 @@ class InvalidSelectInForm { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class SelectInsideFormGroup { @ViewChild(FormGroupDirective) formGroupDirective: FormGroupDirective; @@ -5376,7 +5238,7 @@ class SelectInsideFormGroup { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class BasicSelectWithoutForms { selectedFood: string | null; @@ -5399,7 +5261,7 @@ class BasicSelectWithoutForms { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class BasicSelectWithoutFormsPreselected { selectedFood = 'pizza-1'; @@ -5421,7 +5283,7 @@ class BasicSelectWithoutFormsPreselected { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class BasicSelectWithoutFormsMultiple { selectedFoods: string[]; @@ -5435,7 +5297,6 @@ class BasicSelectWithoutFormsMultiple { } @Component({ - selector: 'select-with-custom-trigger', template: ` @@ -5448,7 +5309,7 @@ class BasicSelectWithoutFormsMultiple { `, - standalone: false, + imports: [MatSelect, MatSelectTrigger, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class SelectWithCustomTrigger { foods: any[] = [ @@ -5459,7 +5320,6 @@ class SelectWithCustomTrigger { } @Component({ - selector: 'ng-model-compare-with', template: ` `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, FormsModule], }) class NgModelCompareWithSelect { foods: {value: string; viewValue: string}[] = [ @@ -5517,7 +5377,7 @@ class NgModelCompareWithSelect { } `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class CustomErrorBehaviorSelect { @ViewChild(MatSelect) select: MatSelect; @@ -5539,7 +5399,7 @@ class CustomErrorBehaviorSelect { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, FormsModule], }) class SingleSelectWithPreselectedArrayValues { foods: any[] = [ @@ -5555,7 +5415,6 @@ class SingleSelectWithPreselectedArrayValues { } @Component({ - selector: 'select-without-option-centering', template: ` @@ -5565,7 +5424,7 @@ class SingleSelectWithPreselectedArrayValues { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class SelectWithoutOptionCentering { foods: any[] = [ @@ -5584,22 +5443,6 @@ class SelectWithoutOptionCentering { @ViewChildren(MatOption) options: QueryList; } -@Component({ - template: ` - - Select a thing - - - A thing - - - `, - standalone: false, -}) -class SelectWithFormFieldLabel { - placeholder: string; -} - @Component({ template: ` @@ -5611,7 +5454,7 @@ class SelectWithFormFieldLabel { } `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class SelectWithNgIfAndLabel { showSelect = true; @@ -5627,7 +5470,7 @@ class SelectWithNgIfAndLabel { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, FormsModule], }) class MultiSelectWithLotsOfOptions { items = new Array(100).fill(0).map((_, i) => i); @@ -5643,7 +5486,6 @@ class MultiSelectWithLotsOfOptions { } @Component({ - selector: 'basic-select-with-reset', template: ` @@ -5654,7 +5496,7 @@ class MultiSelectWithLotsOfOptions { `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class SelectWithResetOptionAndFormControl { @ViewChild(MatSelect) select: MatSelect; @@ -5663,7 +5505,6 @@ class SelectWithResetOptionAndFormControl { } @Component({ - selector: 'select-with-placeholder-in-ngcontainer-with-ngIf', template: ` @if (true) { @@ -5675,7 +5516,7 @@ class SelectWithResetOptionAndFormControl { } `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule], }) class SelectInNgContainer {} @@ -5689,7 +5530,7 @@ class SelectInNgContainer {} `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class SelectInsideDynamicFormGroup { private _formBuilder = inject(FormBuilder); @@ -5711,7 +5552,6 @@ class SelectInsideDynamicFormGroup { } } @Component({ - selector: 'basic-select', template: `
@@ -5735,7 +5575,7 @@ class SelectInsideDynamicFormGroup {
`, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, ReactiveFormsModule], }) class BasicSelectWithFirstAndLastOptionDisabled { foods: any[] = [ @@ -5767,7 +5607,6 @@ class BasicSelectWithFirstAndLastOptionDisabled { } @Component({ - selector: 'select-inside-a-modal', template: ` `, - standalone: false, + imports: [MatSelect, MatOption, MatFormFieldModule, FormsModule, OverlayModule], }) class SelectInsideAModal { foods = [ diff --git a/src/material/slider/slider.spec.ts b/src/material/slider/slider.spec.ts index 0c2db2b63fba..48b45d9f0362 100644 --- a/src/material/slider/slider.spec.ts +++ b/src/material/slider/slider.spec.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.dev/license */ -import {BidiModule} from '@angular/cdk/bidi'; import {Platform} from '@angular/cdk/platform'; import { dispatchEvent, @@ -40,11 +39,7 @@ describe('MatSlider', () => { let platform: Platform; function createComponent(component: Type, providers: Provider[] = []): ComponentFixture { - TestBed.configureTestingModule({ - imports: [FormsModule, MatSliderModule, ReactiveFormsModule, BidiModule], - providers: [...providers], - declarations: [component], - }); + TestBed.configureTestingModule({providers}); platform = TestBed.inject(Platform); return TestBed.createComponent(component); } @@ -1730,7 +1725,7 @@ const SLIDER_STYLES = ['.mat-mdc-slider { width: 300px; }']; `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class StandardSlider {} @@ -1742,7 +1737,7 @@ class StandardSlider {} `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class StandardRangeSlider {} @@ -1753,7 +1748,7 @@ class StandardRangeSlider {} `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class DisabledSlider {} @@ -1765,7 +1760,7 @@ class DisabledSlider {} `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class DisabledRangeSlider {} @@ -1776,7 +1771,7 @@ class DisabledRangeSlider {} `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class SliderWithMinAndMax { min = 25; @@ -1791,7 +1786,7 @@ class SliderWithMinAndMax { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class RangeSliderWithMinAndMax { min = 25; @@ -1805,7 +1800,7 @@ class RangeSliderWithMinAndMax { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class SliderWithValue {} @@ -1817,7 +1812,7 @@ class SliderWithValue {} `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class RangeSliderWithValue {} @@ -1828,7 +1823,7 @@ class RangeSliderWithValue {} `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class SliderWithStep { step = 25; @@ -1842,7 +1837,7 @@ class SliderWithStep { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class RangeSliderWithStep { step = 25; @@ -1855,7 +1850,7 @@ class RangeSliderWithStep { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class DiscreteSliderWithDisplayWith { displayWith(v: number) { @@ -1871,7 +1866,7 @@ class DiscreteSliderWithDisplayWith { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class DiscreteRangeSliderWithDisplayWith { displayWith(v: number) { @@ -1886,7 +1881,7 @@ class DiscreteRangeSliderWithDisplayWith { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class SliderWithOneWayBinding { value = 50; @@ -1900,7 +1895,7 @@ class SliderWithOneWayBinding { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class RangeSliderWithOneWayBinding { startValue = 25; @@ -1914,7 +1909,7 @@ class RangeSliderWithOneWayBinding { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule, FormsModule], }) class SliderWithNgModel { @ViewChild(MatSlider) slider: MatSlider; @@ -1929,7 +1924,7 @@ class SliderWithNgModel { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule, FormsModule], }) class RangeSliderWithNgModel { @ViewChild(MatSlider) slider: MatSlider; @@ -1946,7 +1941,7 @@ class RangeSliderWithNgModel { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule, FormsModule], }) class RangeSliderWithNgModelEdgeCase { @ViewChild(MatSlider) slider: MatSlider; @@ -1960,7 +1955,7 @@ class RangeSliderWithNgModelEdgeCase { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule, ReactiveFormsModule], }) class SliderWithFormControl { control = new FormControl(0); @@ -1973,7 +1968,7 @@ class SliderWithFormControl { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule, ReactiveFormsModule], }) class RangeSliderWithFormControl { startInputControl = new FormControl(0); @@ -1987,7 +1982,7 @@ class RangeSliderWithFormControl { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class SliderWithTwoWayBinding { value = 0; @@ -2001,7 +1996,7 @@ class SliderWithTwoWayBinding { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class RangeSliderWithTwoWayBinding { @ViewChild(MatSlider) slider: MatSlider; @@ -2017,7 +2012,7 @@ class RangeSliderWithTwoWayBinding { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class SliderWithTickMarks { @ViewChild(MatSlider) slider: MatSlider; @@ -2031,7 +2026,7 @@ class SliderWithTickMarks { `, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule], }) class RangeSliderWithTickMarks { @ViewChild(MatSlider) slider: MatSlider; @@ -2047,7 +2042,7 @@ class RangeSliderWithTickMarks {
`, styles: SLIDER_STYLES, - standalone: false, + imports: [MatSliderModule, ReactiveFormsModule], }) class SliderWithFormGroup { readonly MIN = 0; diff --git a/src/material/tooltip/tooltip.spec.ts b/src/material/tooltip/tooltip.spec.ts index 5dbc7574c5e8..a83129363c43 100644 --- a/src/material/tooltip/tooltip.spec.ts +++ b/src/material/tooltip/tooltip.spec.ts @@ -53,17 +53,6 @@ describe('MatTooltip', () => { dir = signal('ltr'); TestBed.configureTestingModule({ - imports: [ - MatTooltipModule, - OverlayModule, - BasicTooltipDemo, - ScrollableTooltipDemo, - OnPushTooltipDemo, - DynamicTooltipsDemo, - TooltipOnTextFields, - TooltipOnDraggableElement, - DataBoundAriaLabelTooltip, - ], providers: [provideFakeDirectionality(dir)], }); @@ -161,7 +150,6 @@ describe('MatTooltip', () => { it('should be able to override the default show and hide delays', fakeAsync(() => { TestBed.resetTestingModule().configureTestingModule({ - imports: [MatTooltipModule, OverlayModule, BasicTooltipDemo], providers: [ { provide: MAT_TOOLTIP_DEFAULT_OPTIONS, @@ -196,8 +184,6 @@ describe('MatTooltip', () => { it('should be able to override the default position', fakeAsync(() => { TestBed.resetTestingModule().configureTestingModule({ - imports: [MatTooltipModule, OverlayModule], - declarations: [TooltipDemoWithoutPositionBinding], providers: [ { provide: MAT_TOOLTIP_DEFAULT_OPTIONS, @@ -223,8 +209,6 @@ describe('MatTooltip', () => { it('should be able to define a default (global) tooltip class', fakeAsync(() => { TestBed.resetTestingModule().configureTestingModule({ - declarations: [TooltipDemoWithoutTooltipClassBinding], - imports: [MatTooltipModule, OverlayModule], providers: [ { provide: MAT_TOOLTIP_DEFAULT_OPTIONS, @@ -250,8 +234,6 @@ describe('MatTooltip', () => { it('should be able to provide tooltip class over the custom default one', fakeAsync(() => { TestBed.resetTestingModule().configureTestingModule({ - declarations: [TooltipDemoWithTooltipClassBinding], - imports: [MatTooltipModule, OverlayModule], providers: [ { provide: MAT_TOOLTIP_DEFAULT_OPTIONS, @@ -282,11 +264,7 @@ describe('MatTooltip', () => { return; } - TestBed.resetTestingModule().configureTestingModule({ - imports: [MatTooltipModule, OverlayModule], - declarations: [WideTooltipDemo], - }); - + TestBed.resetTestingModule(); const wideFixture = TestBed.createComponent(WideTooltipDemo); wideFixture.detectChanges(); tooltipDirective = wideFixture.debugElement @@ -315,8 +293,6 @@ describe('MatTooltip', () => { } TestBed.resetTestingModule().configureTestingModule({ - imports: [MatTooltipModule, OverlayModule], - declarations: [WideTooltipDemo], providers: [ { provide: MAT_TOOLTIP_DEFAULT_OPTIONS, @@ -347,8 +323,6 @@ describe('MatTooltip', () => { it('should be able to disable tooltip interactivity', fakeAsync(() => { TestBed.resetTestingModule().configureTestingModule({ - imports: [MatTooltipModule, OverlayModule], - declarations: [TooltipDemoWithoutPositionBinding], providers: [ { provide: MAT_TOOLTIP_DEFAULT_OPTIONS, @@ -1583,7 +1557,6 @@ describe('MatTooltip', () => { }); @Component({ - selector: 'app', template: ` @if (showButton) { @@ -1709,9 +1679,8 @@ class TooltipOnDraggableElement { } @Component({ - selector: 'app', template: ``, - standalone: false, + imports: [MatTooltip], }) class TooltipDemoWithoutPositionBinding { message: any = initialTooltipMessage; @@ -1720,9 +1689,8 @@ class TooltipDemoWithoutPositionBinding { } @Component({ - selector: 'app', template: ``, - standalone: false, + imports: [MatTooltip], }) class TooltipDemoWithoutTooltipClassBinding { message = initialTooltipMessage; @@ -1731,11 +1699,10 @@ class TooltipDemoWithoutTooltipClassBinding { } @Component({ - selector: 'app', template: ` `, - standalone: false, + imports: [MatTooltip], }) class TooltipDemoWithTooltipClassBinding { message: any = initialTooltipMessage; @@ -1744,10 +1711,9 @@ class TooltipDemoWithTooltipClassBinding { } @Component({ - selector: 'app', styles: `button { width: 500px; height: 500px; }`, template: ``, - standalone: false, + imports: [MatTooltip], }) class WideTooltipDemo { message = 'Test';