From 8422633b8ab070d3321b7f9d557677773695e8aa Mon Sep 17 00:00:00 2001 From: Sonu Kapoor Date: Sat, 19 Sep 2020 12:41:59 -0400 Subject: [PATCH] test(docs-infra): add missing unit tests for backoff example (#38896) This commit adds the missing unit test for the backoff example. PR Close #38896 --- .../src/backoff.spec.ts | 70 +++++++++++++++++++ .../practical-observable-usage/src/backoff.ts | 20 ++++-- 2 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 aio/content/examples/practical-observable-usage/src/backoff.spec.ts diff --git a/aio/content/examples/practical-observable-usage/src/backoff.spec.ts b/aio/content/examples/practical-observable-usage/src/backoff.spec.ts new file mode 100644 index 0000000000..0390a476d1 --- /dev/null +++ b/aio/content/examples/practical-observable-usage/src/backoff.spec.ts @@ -0,0 +1,70 @@ +import { interval } from 'rxjs'; +import { tap } from 'rxjs/operators'; +import { backoff } from './backoff'; + +describe('backoff()', () => { + beforeEach(() => jasmine.clock().install()); + afterEach(() => jasmine.clock().uninstall()); + + it('should retry in case of error', () => { + const mockConsole = {log: jasmine.createSpy('log')}; + const source = interval(10).pipe( + tap(i => { + if (i > 0) { + throw new Error('Test error'); + } + }), + backoff(3, 100), + ); + source.subscribe({ + next: v => mockConsole.log(`Emitted: ${v}`), + error: e => mockConsole.log(`Errored: ${e.message || e}`), + complete: () => mockConsole.log('Completed'), + }); + + // Initial try: + // Errors on second emission and schedules retrying (with delay). + jasmine.clock().tick(10); + expect(mockConsole.log.calls.allArgs()).toEqual([['Emitted: 0']]); + + jasmine.clock().tick(10); + expect(mockConsole.log.calls.allArgs()).toEqual([['Emitted: 0']]); + mockConsole.log.calls.reset(); + + // First re-attempt after 100ms: + // Errors again on second emission and schedules retrying (with larger delay). + jasmine.clock().tick(100); + expect(mockConsole.log).not.toHaveBeenCalled(); + + jasmine.clock().tick(10); + expect(mockConsole.log.calls.allArgs()).toEqual([['Emitted: 0']]); + + jasmine.clock().tick(10); + expect(mockConsole.log.calls.allArgs()).toEqual([['Emitted: 0']]); + mockConsole.log.calls.reset(); + + // Second re-attempt after 400ms: + // Errors again on second emission and schedules retrying (with even larger delay). + jasmine.clock().tick(400); + expect(mockConsole.log).not.toHaveBeenCalled(); + + jasmine.clock().tick(10); + expect(mockConsole.log.calls.allArgs()).toEqual([['Emitted: 0']]); + + jasmine.clock().tick(10); + expect(mockConsole.log.calls.allArgs()).toEqual([['Emitted: 0']]); + mockConsole.log.calls.reset(); + + // Third re-attempt after 900ms: + // Errors again on second emission and gives up (no retrying). + jasmine.clock().tick(900); + expect(mockConsole.log).not.toHaveBeenCalled(); + + jasmine.clock().tick(10); + expect(mockConsole.log.calls.allArgs()).toEqual([['Emitted: 0']]); + mockConsole.log.calls.reset(); + + jasmine.clock().tick(10); + expect(mockConsole.log.calls.allArgs()).toEqual([['Errored: Test error']]); + }); +}); diff --git a/aio/content/examples/practical-observable-usage/src/backoff.ts b/aio/content/examples/practical-observable-usage/src/backoff.ts index 677ed0b2a4..68d724d097 100644 --- a/aio/content/examples/practical-observable-usage/src/backoff.ts +++ b/aio/content/examples/practical-observable-usage/src/backoff.ts @@ -1,9 +1,10 @@ -// TODO: Add unit tests for this file. +// #docplaster +// #docregion import { of, pipe, range, throwError, timer, zip } from 'rxjs'; import { ajax } from 'rxjs/ajax'; import { map, mergeMap, retryWhen } from 'rxjs/operators'; -function backoff(maxTries, delay) { +export function backoff(maxTries, delay) { return pipe( retryWhen(attempts => zip(range(1, maxTries + 1), attempts).pipe( @@ -15,10 +16,17 @@ function backoff(maxTries, delay) { ); } +// #enddocregion +/* + This function declaration is necessary to ensure that it does not get called + when running the unit tests. It will not get rendered into the docs. + The indentation needs to start in the leftmost level position as well because of how + the docplaster combines the different regions together. +*/ +function docRegionAjaxCall() { +// #docregion ajax('/api/endpoint') .pipe(backoff(3, 250)) - .subscribe(data => handleData(data)); - -function handleData(data) { - // ... + .subscribe(function handleData(data) { /* ... */ }); +// #enddocregion }