-
Notifications
You must be signed in to change notification settings - Fork 27k
Description
Which @angular/* package(s) are the source of the bug?
core
Is this a regression?
Yes
Description
I have a relatively simple component that recursively nests on itself to build a node tree of div tags with various css classes and inner text based on a configuration object. When I convert this component to a standalone component, my tests fail with NG0300 but the new component works fine in the application. I'm assuming I am doing something wrong in configuring the testing module or that there is some bug in it but I'm unable to find documentation covering this case. The full component:
import { Input, Component, forwardRef } from '@angular/core';
import { NgFor, NgIf, NgClass } from '@angular/common';
export interface Node {
cssClasses?: string;
text?: string;
nodes?: Node[];
}
@Component({
selector: '[app-nester]',
template: `<ng-container *ngFor="let node of nodes">
<ng-container>
<ng-container *ngIf="node.text as text">
<div [ngClass]="node.cssClasses!">{{ text }}</div>
</ng-container>
<ng-container *ngIf="node.nodes as nodes">
<div [ngClass]="node.cssClasses!" app-nester [nodes]="node.nodes"></div>
</ng-container>
</ng-container>
</ng-container> `,
// standalone: true,
// imports: [NgFor, NgIf, NgClass, forwardRef(() => NesterComponent)],
})
export class NesterComponent {
@Input() nodes: Node[] | null = null;
}to convert to standalone I used the new migration and it added these commented out lines and imports.
My Tests:
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { NesterComponent } from './nester.component';
describe('NesterComponent', () => {
let component: NesterComponent;
let fixture: ComponentFixture<NesterComponent>;
// remove for standalone version
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ declarations: [NesterComponent] }).compileComponents();
}));
// standalone version from migration:
// beforeEach(waitForAsync(() => {
// TestBed.configureTestingModule({ imports: [NesterComponent] }).compileComponents();
// }));
beforeEach(() => {
fixture = TestBed.createComponent(NesterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeDefined();
});
it('should render text', () => {
component.nodes = [
{ cssClasses: 'test1', text: 'test1' },
{
cssClasses: 'test2',
nodes: [{ cssClasses: 'not in result' }, { text: 'test4' }],
},
{
cssClasses: 'test5',
nodes: [],
},
];
fixture.detectChanges();
expect(fixture.nativeElement).toMatchSnapshot();
});
});Again in this case all the migration did was change declarations to imports
The above functions and test passes... however if I switch it to the standalone version of both files then the test fails (as far as I can tell it still works though, this is just a test problem).
Please provide a link to a minimal reproduction of the bug
No response
Please provide the exception or error you saw
FAIL src/app/shared/nester/nester.component.spec.ts (13.262 s)
NesterComponent
√ should create (322 ms)
× should render text (826 ms)
● NesterComponent › should render text
NG0300: Multiple components match node with tagname div: NesterComponent and NesterComponent. Find more at https://angular.io/errors/NG0300
at throwMultipleComponentError (node_modules/@angular/core/fesm2022/core.mjs:10251:11)
at findDirectiveDefMatches (node_modules/@angular/core/fesm2022/core.mjs:11580:29)
at resolveDirectives (node_modules/@angular/core/fesm2022/core.mjs:11380:29)
at elementStartFirstCreatePass (node_modules/@angular/core/fesm2022/core.mjs:15137:5)
at ɵɵelementStart (node_modules/@angular/core/fesm2022/core.mjs:15173:9)
at ɵɵelement (node_modules/@angular/core/fesm2022/core.mjs:15254:5)
at NesterComponent_ng_container_0_ng_container_1_ng_container_2_Template (ng:/NesterComponent.js:25:5)
at executeTemplate (node_modules/@angular/core/fesm2022/core.mjs:10890:17)
at renderView (node_modules/@angular/core/fesm2022/core.mjs:12078:13)
at TemplateRef2.createEmbeddedViewImpl (node_modules/@angular/core/fesm2022/core.mjs:22877:9)
at ViewContainerRef2.createEmbeddedView (node_modules/@angular/core/fesm2022/core.mjs:23142:37)
at _NgIf._updateView (node_modules/@angular/common/fesm2022/common.mjs:3316:45)
at _NgIf.set ngIf [as ngIf] (node_modules/@angular/common/fesm2022/common.mjs:3289:14)
at writeToDirectiveInput (node_modules/@angular/core/fesm2022/core.mjs:11766:33)
at setInputsForProperty (node_modules/@angular/core/fesm2022/core.mjs:12000:9)
at elementPropertyInternal (node_modules/@angular/core/fesm2022/core.mjs:11302:9)
at ɵɵproperty (node_modules/@angular/core/fesm2022/core.mjs:15115:9)
at NesterComponent_ng_container_0_ng_container_1_Template (ng:/NesterComponent.js:48:5)
at ReactiveLViewConsumer.runInContext (node_modules/@angular/core/fesm2022/core.mjs:10345:13)
at executeTemplate (node_modules/@angular/core/fesm2022/core.mjs:10885:22)
at refreshView (node_modules/@angular/core/fesm2022/core.mjs:12395:13)
at refreshEmbeddedViews (node_modules/@angular/core/fesm2022/core.mjs:12506:17)
at refreshView (node_modules/@angular/core/fesm2022/core.mjs:12419:9)
at refreshEmbeddedViews (node_modules/@angular/core/fesm2022/core.mjs:12506:17)
at refreshView (node_modules/@angular/core/fesm2022/core.mjs:12419:9)
at refreshComponent (node_modules/@angular/core/fesm2022/core.mjs:12542:13)
at refreshChildComponents (node_modules/@angular/core/fesm2022/core.mjs:12589:9)
at refreshView (node_modules/@angular/core/fesm2022/core.mjs:12445:13)
at detectChangesInternal (node_modules/@angular/core/fesm2022/core.mjs:12337:9)
at RootViewRef.detectChanges (node_modules/@angular/core/fesm2022/core.mjs:12867:9)
at ComponentFixture._tick (node_modules/@angular/core/fesm2022/testing.mjs:126:32)
at node_modules/@angular/core/fesm2022/testing.mjs:139:22
at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (node_modules/zone.js/bundles/zone.umd.js:416:30)
at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (node_modules/zone.js/bundles/zone-testing.umd.js:300:43)
at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (node_modules/zone.js/bundles/zone.umd.js:415:56)
at Object.onInvoke (node_modules/@angular/core/fesm2022/core.mjs:26108:33)
at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (node_modules/zone.js/bundles/zone.umd.js:415:56)
at Zone.Object.<anonymous>.Zone.run (node_modules/zone.js/bundles/zone.umd.js:173:47)
at NgZone.run (node_modules/@angular/core/fesm2022/core.mjs:25962:28)
at ComponentFixture.detectChanges (node_modules/@angular/core/fesm2022/testing.mjs:138:25)
at src/app/shared/nester/nester.component.spec.ts:37:13
at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (node_modules/zone.js/bundles/zone.umd.js:416:30)
at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (node_modules/zone.js/bundles/zone-testing.umd.js:300:43)
at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (node_modules/zone.js/bundles/zone.umd.js:415:56)
at Zone.Object.<anonymous>.Zone.run (node_modules/zone.js/bundles/zone.umd.js:173:47)
at Object.wrappedFunc (node_modules/zone.js/bundles/zone-testing.umd.js:780:34)
Please provide the environment you discovered this bug in (run ng version)
Angular CLI: 16.0.2
Node: 18.16.0
Package Manager: npm 9.5.1
OS: win32 x64
Angular: 16.0.2
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, router
Package Version
@angular-devkit/architect 0.1502.6
@angular-devkit/build-angular 16.0.2
@angular-devkit/core 15.2.6
@angular-devkit/schematics 16.0.2
@angular/cdk 16.0.1
@angular/material 16.0.1
@schematics/angular 16.0.2
rxjs 7.8.1
typescript 5.0.4
Anything else?
It would be nice if https://angular.io/guide/testing-components-basics said something about standalone components. And/Or if https://angular.io/guide/standalone-components or https://angular.io/guide/standalone-migration covered testing at all.