From 44074499dc74465cf19d5378af6f1aa05fe585dd Mon Sep 17 00:00:00 2001 From: Sonu Kapoor Date: Mon, 14 Sep 2020 12:47:12 -0400 Subject: [PATCH] test(docs-infra): improve typeahead example and add unit test (#34190) This commit improves the typeahead example, by using the emitted input value. It also adds a unit test to ensure that the example is working as intended. PR Close #34190 --- .../src/typeahead.spec.ts | 72 +++++++++++++++++++ .../src/typeahead.ts | 42 +++++++---- 2 files changed, 100 insertions(+), 14 deletions(-) create mode 100644 aio/content/examples/practical-observable-usage/src/typeahead.spec.ts diff --git a/aio/content/examples/practical-observable-usage/src/typeahead.spec.ts b/aio/content/examples/practical-observable-usage/src/typeahead.spec.ts new file mode 100644 index 0000000000..285dd7e12e --- /dev/null +++ b/aio/content/examples/practical-observable-usage/src/typeahead.spec.ts @@ -0,0 +1,72 @@ +import { of } from 'rxjs'; +import { docRegionTypeahead } from './typeahead'; + +describe('typeahead', () => { + let document; + let ajax; + let triggertInputChange; + + beforeEach(() => { + jasmine.clock().install(); + const input = { + addEventListener: jasmine + .createSpy('addEvent') + .and.callFake((eventName: string, cb: (e) => void) => { + if (eventName === 'input') { + triggertInputChange = cb; + } + }), + removeEventListener: jasmine.createSpy('removeEvent'), + }; + + document = { getElementById: (id: string) => input }; + ajax = jasmine.createSpy('ajax').and.callFake((url: string) => of('foo bar')); + }); + + afterEach(() => { + jasmine.clock().uninstall(); + }); + + it('should make an ajax call to the corrent endpoint', () => { + docRegionTypeahead(document, ajax); + triggertInputChange({ target: { value: 'foo' } }); + jasmine.clock().tick(11); + expect(ajax).toHaveBeenCalledWith('/api/endpoint?search=foo'); + }); + + it('should not make an ajax call, when the input length < 3', () => { + docRegionTypeahead(document, ajax); + triggertInputChange({ target: { value: '' } }); + jasmine.clock().tick(11); + expect(ajax).not.toHaveBeenCalled(); + triggertInputChange({ target: { value: 'fo' } }); + jasmine.clock().tick(11); + expect(ajax).not.toHaveBeenCalled(); + }); + + it('should not make an ajax call for intermediate values when debouncing', () => { + docRegionTypeahead(document, ajax); + triggertInputChange({ target: { value: 'foo' } }); + jasmine.clock().tick(9); + triggertInputChange({ target: { value: 'bar' } }); + jasmine.clock().tick(9); + triggertInputChange({ target: { value: 'baz' } }); + jasmine.clock().tick(9); + triggertInputChange({ target: { value: 'qux' } }); + expect(ajax).not.toHaveBeenCalled(); + jasmine.clock().tick(10); + expect(ajax).toHaveBeenCalledTimes(1); + expect(ajax).toHaveBeenCalledWith('/api/endpoint?search=qux'); + }); + + it('should not make an ajax call, when the input value has not changed', () => { + docRegionTypeahead(document, ajax); + triggertInputChange({ target: { value: 'foo' } }); + jasmine.clock().tick(11); + expect(ajax).toHaveBeenCalled(); + ajax.calls.reset(); + triggertInputChange({ target: { value: 'foo' } }); + jasmine.clock().tick(11); + expect(ajax).not.toHaveBeenCalled(); + }); +}); diff --git a/aio/content/examples/practical-observable-usage/src/typeahead.ts b/aio/content/examples/practical-observable-usage/src/typeahead.ts index 153ab7f23e..adbddd66c4 100644 --- a/aio/content/examples/practical-observable-usage/src/typeahead.ts +++ b/aio/content/examples/practical-observable-usage/src/typeahead.ts @@ -1,18 +1,32 @@ -import { fromEvent } from 'rxjs'; -import { ajax } from 'rxjs/ajax'; -import { debounceTime, distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators'; +/* + Because of how the code is merged together using the doc regions, + we need to indent the imports with the function below. +*/ +// #docplaster +// #docregion + import { fromEvent } from 'rxjs'; + import { ajax } from 'rxjs/ajax'; + import { debounceTime, distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators'; +// #enddocregion +/* tslint:disable:no-shadowed-variable */ +/* tslint:disable:align */ +export function docRegionTypeahead(document, ajax) { + // #docregion + const searchBox = document.getElementById('search-box'); -const searchBox = document.getElementById('search-box'); + const typeahead = fromEvent(searchBox, 'input').pipe( + map((e: KeyboardEvent) => (e.target as HTMLInputElement).value), + filter(text => text.length > 2), + debounceTime(10), + distinctUntilChanged(), + switchMap(searchTerm => ajax(`/api/endpoint?search=${searchTerm}`)) + ); -const typeahead = fromEvent(searchBox, 'input').pipe( - map((e: KeyboardEvent) => (e.target as HTMLInputElement).value), - filter(text => text.length > 2), - debounceTime(10), - distinctUntilChanged(), - switchMap(() => ajax('/api/endpoint')) -); + typeahead.subscribe(data => { + // Handle the data from the API + }); -typeahead.subscribe(data => { - // Handle the data from the API -}); + // #enddocregion + return typeahead; +}