Skip to content

Commit 17f2628

Browse files
committed
test(core): add test validating that component destroy does not depend on the injector
While developing this feature, I attempted to inject a service during component destruction (to call `SharedStylesHost.prototype.removeHost`), however this broke some Material use cases which seem to destroy the injector before the component. Whether this constraint was intended or not, I believe we currently live in a world where component destruction cannot depend on its injection, so I'm enforcing this in a test to be clear about that constraint. This is not intended to imply that this is a _good_ constraint or that we _want_ this to be the case, but it does represent the reality we currently exist in.
1 parent 5b5a4f0 commit 17f2628

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

packages/core/test/acceptance/view_container_ref_spec.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,46 @@ describe('ViewContainerRef', () => {
732732
});
733733
});
734734

735+
describe('destroy', () => {
736+
// NOTE: We may not necessarily _want_ this to be the case, but it does seem to be necessary
737+
// for some amount of Angular code out there. We may want to consider lifting this constraint.
738+
it('should not throw if the injector is destroyed before a view is removed', () => {
739+
@Component({
740+
template: 'View Content',
741+
standalone: false,
742+
})
743+
class DynamicComponent {}
744+
745+
@Component({
746+
template: '<ng-container #vcr></ng-container>',
747+
standalone: false,
748+
})
749+
class App {
750+
@ViewChild('vcr', {read: ViewContainerRef, static: true})
751+
vcr!: ViewContainerRef;
752+
}
753+
754+
TestBed.configureTestingModule({declarations: [App, DynamicComponent]});
755+
756+
const envInjector = createEnvironmentInjector([], TestBed.inject(EnvironmentInjector));
757+
const fixture = TestBed.createComponent(App);
758+
fixture.detectChanges();
759+
760+
const componentRef = fixture.componentInstance.vcr.createComponent(DynamicComponent, {
761+
environmentInjector: envInjector,
762+
});
763+
fixture.detectChanges();
764+
765+
// Destroy the environment injector first
766+
envInjector.destroy();
767+
768+
// Should be able to destroy the component afterwards.
769+
expect(() => {
770+
componentRef.destroy();
771+
}).not.toThrow();
772+
});
773+
});
774+
735775
describe('length', () => {
736776
it('should return the number of embedded views', () => {
737777
TestBed.configureTestingModule({declarations: [EmbeddedViewInsertionComp, VCRefDirective]});

0 commit comments

Comments
 (0)