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.
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:
to convert to standalone I used the new migration and it added these commented out lines and imports.
My Tests:
Again in this case all the migration did was change
declarationstoimportsThe 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
Please provide the environment you discovered this bug in (run
ng version)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.