fix(core): handle different DI token types in Chrome DevTools integration (#61333)

This small refactor makes the DI events reporting code more resiliant
with respect to finding names for different token types.

PR Close #61333
This commit is contained in:
Pawel Kozlowski
2025-05-14 14:54:30 +02:00
committed by Alex Rickabaugh
parent 56c0ef8eb7
commit d9d9e42c23
2 changed files with 66 additions and 6 deletions
@@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {InjectionToken} from '../../di';
import {isTypeProvider} from '../../di/provider_collection';
import {assertDefined, assertEqual} from '../../util/assert';
import {performanceMarkFeature} from '../../util/performance';
@@ -81,7 +80,6 @@ function measureEnd(
`Profiling error: expected to see ${startEvent} event but got ${top[0]}`,
);
// Expecting TypeScript error here as overloaded types are not supported yet in TS types
console.timeStamp(
entryName,
'Event_' + top[0] + '_' + top[1],
@@ -216,13 +214,12 @@ function getComponentMeasureName(instance: {}) {
}
function getProviderTokenMeasureName<T>(token: any) {
if (token instanceof InjectionToken) {
return token.toString();
} else if (isTypeProvider(token)) {
if (isTypeProvider(token)) {
return token.name;
} else {
} else if (token.provide != null) {
return getProviderTokenMeasureName(token.provide);
}
return token.toString();
}
/**
@@ -0,0 +1,63 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {enableProfiling} from '../../src/render3/debug/chrome_dev_tools_performance';
import {Component, HostAttributeToken, inject, Inject} from '../../src/core';
import {TestBed} from '../../testing';
describe('Chrome DevTools Performance integration', () => {
describe('DI perf events', () => {
it('should not crash when a HostAttributeToken is injected', () => {
@Component({
template: ``,
})
class MyCmp {
attr = inject(new HostAttributeToken('someAttr'), {optional: true});
}
spyOn(console, 'timeStamp');
const stopProfiling = enableProfiling();
try {
const fixture = TestBed.createComponent(MyCmp);
fixture.detectChanges();
expect((console.timeStamp as any).calls.all().length).not.toBe(0);
} finally {
stopProfiling();
}
});
it('should not crash when a string provider is injected', () => {
@Component({
template: ``,
providers: [
{
provide: 'foo',
useValue: 'bar',
},
],
})
class MyCmp {
constructor(@Inject('foo') foo: string) {}
}
spyOn(console, 'timeStamp');
const stopProfiling = enableProfiling();
try {
const fixture = TestBed.createComponent(MyCmp);
fixture.detectChanges();
expect((console.timeStamp as any).calls.all().length).not.toBe(0);
} finally {
stopProfiling();
}
});
});
});