Skip to content

Commit

Permalink
docs(docs-infra): change the testing guide due to deprecation (#44674)
Browse files Browse the repository at this point in the history
The jasmine used in the docs is

```typescript
expect(<variableName>).<matcher>(predicate, failOutput)
```

The new version should be

```typescript
expect(<variableName>).withContext(failOutput).<matcher>(predicate)
```

So, this commit mainly focuses on changing the former to latter with
format below

```typescript
expect(<variableName>)
  .withContext(failOutput)
  .<matcher>(predicate)
```

And for RxJs, see https://rxjs.dev/deprecations/subscribe-arguments.

> For example someone could name functions poorly and confuse the next
reader: `source$.subscribe(doSomething, doSomethingElse, lol)` with that
signature, you have to know unapparent details about subscribe, where
using a partial observer solves that neatly: `source$.subscribe({ next:
doSomething, error: doSomethingElse, complete: lol }`).

This commit also does this conversion.

Last, remove the unused imported `async` from file
`twain.component.marbles.spec.ts`.

PR Close #44674
  • Loading branch information
shejialuo authored and dylhunn committed Jan 13, 2022
1 parent c2da290 commit 6e04815
Show file tree
Hide file tree
Showing 16 changed files with 468 additions and 208 deletions.
Expand Up @@ -170,11 +170,15 @@ class Page {
}

function expectPathToBe(path: string, expectationFailOutput?: any) {
expect(location.path()).toEqual(path, expectationFailOutput || 'location.path()');
expect(location.path())
.withContext(expectationFailOutput || 'location.path()')
.toEqual(path);
}

function expectElementOf(type: Type<any>): any {
const el = fixture.debugElement.query(By.directive(type));
expect(el).toBeTruthy('expected an element for ' + type.name);
expect(el)
.withContext(`expected an element for ${type.name}`)
.toBeTruthy();
return el;
}
8 changes: 6 additions & 2 deletions aio/content/examples/testing/src/app/app.component.spec.ts
Expand Up @@ -121,7 +121,9 @@ function tests() {

// #docregion tests
it('can get RouterLinks from template', () => {
expect(routerLinks.length).toBe(3, 'should have 3 routerLinks');
expect(routerLinks.length)
.withContext('should have 3 routerLinks')
.toBe(3);
expect(routerLinks[0].linkParams).toBe('/dashboard');
expect(routerLinks[1].linkParams).toBe('/heroes');
expect(routerLinks[2].linkParams).toBe('/about');
Expand All @@ -131,7 +133,9 @@ function tests() {
const heroesLinkDe = linkDes[1]; // heroes link DebugElement
const heroesLink = routerLinks[1]; // heroes link directive

expect(heroesLink.navigatedTo).toBeNull('should not have navigated yet');
expect(heroesLink.navigatedTo)
.withContext('should not have navigated yet')
.toBeNull();

heroesLinkDe.triggerEventHandler('click', null);
fixture.detectChanges();
Expand Down
Expand Up @@ -23,27 +23,31 @@ describe('DashboardComponent class only', () => {
});

it('should NOT have heroes before calling OnInit', () => {
expect(comp.heroes.length).toBe(0,
'should not have heroes before OnInit');
expect(comp.heroes.length)
.withContext('should not have heroes before OnInit')
.toBe(0);
});

it('should NOT have heroes immediately after OnInit', () => {
comp.ngOnInit(); // ngOnInit -> getHeroes
expect(comp.heroes.length).toBe(0,
'should not have heroes until service promise resolves');
expect(comp.heroes.length)
.withContext('should not have heroes until service promise resolves')
.toBe(0);
});

it('should HAVE heroes after HeroService gets them', (done: DoneFn) => {
comp.ngOnInit(); // ngOnInit -> getHeroes
heroService.lastResult // the one from getHeroes
.subscribe(
() => {
.subscribe({
next: () => {
// throw new Error('deliberate error'); // see it fail gracefully
expect(comp.heroes.length).toBeGreaterThan(0,
'should have heroes after service promise resolves');
done();
},
done.fail);
expect(comp.heroes.length)
.withContext('should have heroes after service promise resolves')
.toBeGreaterThan(0);
done();
},
error: done.fail
});
});

it('should tell ROUTER to navigate by hero id', () => {
Expand All @@ -53,7 +57,9 @@ describe('DashboardComponent class only', () => {
comp.gotoDetail(hero);

const navArgs = spy.calls.mostRecent().args[0];
expect(navArgs).toBe('/heroes/42', 'should nav to HeroDetail for Hero 42');
expect(navArgs)
.withContext('should nav to HeroDetail for Hero 42')
.toBe('/heroes/42');
});

});
Expand Up @@ -87,13 +87,17 @@ function compileAndCreate() {
function tests(heroClick: () => void) {

it('should NOT have heroes before ngOnInit', () => {
expect(comp.heroes.length).toBe(0, 'should not have heroes before ngOnInit');
expect(comp.heroes.length)
.withContext('should not have heroes before ngOnInit')
.toBe(0);
});

it('should NOT have heroes immediately after ngOnInit', () => {
fixture.detectChanges(); // runs initial lifecycle hooks

expect(comp.heroes.length).toBe(0, 'should not have heroes until service promise resolves');
expect(comp.heroes.length)
.withContext('should not have heroes until service promise resolves')
.toBe(0);
});

describe('after get dashboard heroes', () => {
Expand All @@ -109,14 +113,17 @@ function tests(heroClick: () => void) {

it('should HAVE heroes', () => {
expect(comp.heroes.length)
.toBeGreaterThan(0, 'should have heroes after service promise resolves');
.withContext('should have heroes after service promise resolves')
.toBeGreaterThan(0);
});

it('should DISPLAY heroes', () => {
// Find and examine the displayed heroes
// Look for them in the DOM by css class
const heroes = fixture.nativeElement.querySelectorAll('dashboard-hero');
expect(heroes.length).toBe(4, 'should display 4 heroes');
expect(heroes.length)
.withContext('should display 4 heroes')
.toBe(4);
});

// #docregion navigate-test
Expand All @@ -129,7 +136,9 @@ function tests(heroClick: () => void) {

// expecting to navigate to id of the component's first hero
const id = comp.heroes[0].id;
expect(navArgs).toBe('/heroes/' + id, 'should nav to HeroDetail for first hero');
expect(navArgs)
.withContext('should nav to HeroDetail for first hero')
.toBe('/heroes/' + id);
});
// #enddocregion navigate-test
});
Expand Down
17 changes: 13 additions & 4 deletions aio/content/examples/testing/src/app/demo/async-helper.spec.ts
Expand Up @@ -11,7 +11,9 @@ describe('Angular async helper', () => {
});

afterEach(() => {
expect(actuallyDone).toBe(true, 'actuallyDone should be true');
expect(actuallyDone)
.withContext('actuallyDone should be true')
.toBe(true);
});

it('should run normal test', () => {
Expand Down Expand Up @@ -59,17 +61,24 @@ describe('Angular async helper', () => {
// Use done. Can also use async or fakeAsync.
it('should run async test with successful delayed Observable', (done: DoneFn) => {
const source = of(true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err), done);
source.subscribe({
next: val => actuallyDone = true,
error: err => fail(err),
complete: done});
});

it('should run async test with successful delayed Observable', waitForAsync(() => {
const source = of(true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err));
source.subscribe({
next: val => actuallyDone = true,
error: err => fail(err)});
}));

it('should run async test with successful delayed Observable', fakeAsync(() => {
const source = of(true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err));
source.subscribe({
next: val => actuallyDone = true,
error: err => fail(err)});

tick(10);
}));
Expand Down
32 changes: 23 additions & 9 deletions aio/content/examples/testing/src/app/demo/demo.spec.ts
Expand Up @@ -74,9 +74,11 @@ describe('demo (no TestBed):', () => {
masterService = new MasterService(valueServiceSpy);

expect(masterService.getValue())
.toBe(stubValue, 'service returned stub value');
.withContext('service returned stub value')
.toBe(stubValue);
expect(valueServiceSpy.getValue.calls.count())
.toBe(1, 'spy method was called once');
.withContext('spy method was called once')
.toBe(1);
expect(valueServiceSpy.getValue.calls.mostRecent().returnValue)
.toBe(stubValue);
});
Expand All @@ -90,9 +92,11 @@ describe('demo (no TestBed):', () => {
const { masterService, stubValue, valueServiceSpy } = setup();
// #enddocregion no-before-each-setup-call
expect(masterService.getValue())
.toBe(stubValue, 'service returned stub value');
.withContext('service returned stub value')
.toBe(stubValue);
expect(valueServiceSpy.getValue.calls.count())
.toBe(1, 'spy method was called once');
.withContext('spy method was called once')
.toBe(1);
expect(valueServiceSpy.getValue.calls.mostRecent().returnValue)
.toBe(stubValue);
});
Expand Down Expand Up @@ -131,18 +135,28 @@ describe('demo (no TestBed):', () => {
describe('LightswitchComp', () => {
it('#clicked() should toggle #isOn', () => {
const comp = new LightswitchComponent();
expect(comp.isOn).toBe(false, 'off at first');
expect(comp.isOn)
.withContext('off at first')
.toBe(false);
comp.clicked();
expect(comp.isOn).toBe(true, 'on after click');
expect(comp.isOn)
.withContext('on after click')
.toBe(true);
comp.clicked();
expect(comp.isOn).toBe(false, 'off after second click');
expect(comp.isOn)
.withContext('off after second click')
.toBe(false);
});

it('#clicked() should set #message to "is on"', () => {
const comp = new LightswitchComponent();
expect(comp.message).toMatch(/is off/i, 'off at first');
expect(comp.message)
.withContext('off at first')
.toMatch(/is off/i);
comp.clicked();
expect(comp.message).toMatch(/is on/i, 'on after clicked');
expect(comp.message)
.withContext('on after clicked')
.toMatch(/is on/i);
});
});
// #enddocregion Lightswitch
Expand Down

0 comments on commit 6e04815

Please sign in to comment.