Skip to content

Commit

Permalink
feat(ng-dev): AngularContext.tick() better simulates real change de…
Browse files Browse the repository at this point in the history
…tection
  • Loading branch information
ersimont committed Nov 13, 2020
1 parent 69c8b79 commit 68fc5da
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 11 deletions.
46 changes: 36 additions & 10 deletions projects/ng-dev/src/lib/test-context/angular-context.spec.ts
Expand Up @@ -154,12 +154,12 @@ describe('AngularContext', () => {
});

it('runs change detection even if no tasks are queued', () => {
let changeDetectionCount = 0;
let ranChangeDetection = false;

@Component({ template: '' })
class LocalComponent implements DoCheck {
ngDoCheck(): void {
++changeDetectionCount;
ranChangeDetection = true;
}
}
TestBed.overrideComponent(LocalComponent, {});
Expand All @@ -170,20 +170,20 @@ describe('AngularContext', () => {
const componentRef = factory.create(ctx.inject(Injector));
ctx.inject(ApplicationRef).attachView(componentRef.hostView);

expect(changeDetectionCount).toBe(0);
expect(ranChangeDetection).toBe(false);
ctx.tick();
expect(changeDetectionCount).toBe(1);
expect(ranChangeDetection).toBe(true);
});
});

it('flushes micro tasks before running change detection', () => {
let promiseResolved = false;
let promiseResolvedBeforeChangeDetection = false;
let ranChangeDetection = false;
let flushedMicroTasksBeforeChangeDetection = false;

@Component({ template: '' })
class LocalComponent implements DoCheck {
ngDoCheck(): void {
promiseResolvedBeforeChangeDetection = promiseResolved;
ranChangeDetection = true;
}
}
TestBed.overrideComponent(LocalComponent, {});
Expand All @@ -195,14 +195,40 @@ describe('AngularContext', () => {
ctx.inject(ApplicationRef).attachView(componentRef.hostView);

Promise.resolve().then(() => {
promiseResolved = true;
flushedMicroTasksBeforeChangeDetection = !ranChangeDetection;
});
ctx.tick();
expect(promiseResolvedBeforeChangeDetection).toBe(true);
expect(flushedMicroTasksBeforeChangeDetection).toBe(true);
});
});

it('advances `performance.now()` as well', () => {
it('runs change detection after timeouts', () => {
let ranTimeout = false;
let ranChangeDetectionAfterTimeout = false;

@Component({ template: '' })
class LocalComponent implements DoCheck {
ngDoCheck(): void {
ranChangeDetectionAfterTimeout = ranTimeout;
}
}
TestBed.overrideComponent(LocalComponent, {});

ctx.run(() => {
const resolver = ctx.inject(ComponentFactoryResolver);
const factory = resolver.resolveComponentFactory(LocalComponent);
const componentRef = factory.create(ctx.inject(Injector));
ctx.inject(ApplicationRef).attachView(componentRef.hostView);

setTimeout(() => {
ranTimeout = true;
});
ctx.tick();
expect(ranChangeDetectionAfterTimeout).toBe(true);
});
});

it('advances `performance.now()`', () => {
ctx.run(() => {
const start = performance.now();
ctx.tick(10);
Expand Down
1 change: 1 addition & 0 deletions projects/ng-dev/src/lib/test-context/angular-context.ts
Expand Up @@ -188,6 +188,7 @@ export class AngularContext<InitOptions = {}> {
this.runChangeDetection();

tick(convertTime(amount, unit, 'ms'));
this.runChangeDetection();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion projects/ng-dev/src/lib/test-context/component-context.ts
Expand Up @@ -59,7 +59,7 @@ export abstract class ComponentContext<
protected abstract componentType: Type<ComponentType>;

/**
* @param moduleMetadata passed along to [TestBed.configureTestingModule()]{@linkcode https://angular.io/api/core/testing/TestBed#configureTestingModule}. Automatically includes {@link NoopAnimationsModule} and {@link HttpClientTestingModule} for you.
* @param moduleMetadata passed along to [TestBed.configureTestingModule()]{@linkcode https://angular.io/api/core/testing/TestBed#configureTestingModule}. Automatically includes {@link NoopAnimationsModule}, in addition to those provided by {@link AngularContext}.
*/
constructor(moduleMetadata: TestModuleMetadata = {}) {
super(extendMetadata(moduleMetadata, { imports: [NoopAnimationsModule] }));
Expand Down

0 comments on commit 68fc5da

Please sign in to comment.