/
githubmirror
/
angular
Обзор
Документация
Войти
/
githubmirror
/
angular
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
packages/core/test/acceptance/tracing_spec.ts
183 строки
5 KB
Matthieu Riegler
refactor(core): Migrate more tests off `fakeAsync`
29 июл 2026, 18:46
29 июл 2026, 18:46
c1025a0
Код
Авторство
О чём код?
/*! * @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 { afterEveryRender, Component, provideZoneChangeDetection, signal, ɵTracingAction as TracingAction, ɵTracingService as TracingService, ɵTracingSnapshot as TracingSnapshot, } from '../../src/core'; import {TestBed} from '../../testing'; describe('TracingService', () => { beforeEach(() => { TestBed.configureTestingModule({ providers: [provideZoneChangeDetection()], }); }); let actions: TracingAction[]; let listeners: {event: string; handler: Function}[]; let fakeSnapshot: TracingSnapshot; let mockTracingService: TracingService<TracingSnapshot>; let clickCount: number; let createdComponents: (string | null)[]; beforeEach(() => { actions = []; listeners = []; clickCount = 0; createdComponents = []; fakeSnapshot = { run: <T>(action: TracingAction, fn: () => T): T => { actions.push(action); return fn(); }, dispose() {}, }; mockTracingService = { snapshot: jasmine.createSpy('snapshot').and.returnValue(fakeSnapshot), wrapEventListener: jasmine .createSpy('wrapEventListener') .and.callFake((_element, event: string, handler: Function) => { if (event === 'click') { const originalHandler = handler; handler = function (this: unknown) { clickCount++; originalHandler.apply(this, arguments); }; } listeners.push({event, handler}); return handler; }), componentCreate: (name, fn) => { createdComponents.push(name); return fn(); }, }; }); it('should take a snapshot after change detection', () => { TestBed.configureTestingModule({ providers: [{provide: TracingService, useValue: mockTracingService}], }); @Component({template: ''}) class App {} const fixture = TestBed.createComponent(App); expect(mockTracingService.snapshot).not.toHaveBeenCalled(); fixture.changeDetectorRef.markForCheck(); fixture.detectChanges(); expect(mockTracingService.snapshot).toHaveBeenCalledTimes(1); expect(actions).toEqual([TracingAction.CHANGE_DETECTION]); fixture.changeDetectorRef.markForCheck(); fixture.detectChanges(); expect(mockTracingService.snapshot).toHaveBeenCalledTimes(2); expect(actions).toEqual([TracingAction.CHANGE_DETECTION, TracingAction.CHANGE_DETECTION]); }); it('should take a snapshot after `afterRender`', async () => { TestBed.configureTestingModule({ providers: [{provide: TracingService, useValue: mockTracingService}], }); @Component({template: ''}) class App { constructor() { afterEveryRender(() => {}); } } const fixture = TestBed.createComponent(App); fixture.changeDetectorRef.markForCheck(); fixture.detectChanges(); expect(mockTracingService.snapshot).toHaveBeenCalledTimes(4); expect(actions).toEqual([ TracingAction.CHANGE_DETECTION, TracingAction.CHANGE_DETECTION, TracingAction.AFTER_NEXT_RENDER, ]); }); it('should be able to wrap event listeners through the tracing service', async () => { TestBed.configureTestingModule({ providers: [{provide: TracingService, useValue: mockTracingService}], }); @Component({template: '<button (click)="noop()"></button> <span (mousedown)="noop()"></span>'}) class App { noop() {} } const fixture = TestBed.createComponent(App); await fixture.whenStable(); expect(listeners).toEqual([ {event: 'click', handler: jasmine.any(Function)}, {event: 'mousedown', handler: jasmine.any(Function)}, ]); expect(clickCount).toBe(0); fixture.nativeElement.querySelector('button').click(); await fixture.whenStable(); expect(clickCount).toBe(1); }); it('should trace component creations', () => { TestBed.configureTestingModule({ providers: [{provide: TracingService, useValue: mockTracingService}], }); @Component({template: 'hello', selector: 'grandchild'}) class GrandChild {} @Component({template: 'extra', selector: 'extra'}) class Extra {} @Component({ template: '<grandchild/>', selector: 'child', imports: [GrandChild], }) class Child {} @Component({ template: ` <child /> <child /> @if (showExtra()) { <extra /> }`, imports: [Child, Extra], }) class App { showExtra = signal(false); } const fixture = TestBed.createComponent(App); fixture.detectChanges(); expect(createdComponents).toEqual(['App', 'Child', 'Child', 'GrandChild', 'GrandChild']); fixture.componentInstance.showExtra.set(true); fixture.detectChanges(); expect(createdComponents).toEqual([ 'App', 'Child', 'Child', 'GrandChild', 'GrandChild', 'Extra', ]); }); });