refactor(aio): reorganize search service for easier testing

This commit is contained in:
Peter Bacon Darwin 2017-03-02 12:20:26 +00:00 committed by Igor Minar
parent b8321e2f7d
commit b09ee424bf
4 changed files with 38 additions and 9 deletions

View File

@ -101,6 +101,9 @@ export class AppComponent implements OnInit {
}
ngOnInit() {
this.searchService.initWorker('app/search/search-worker.js');
this.searchService.loadIndex();
this.onResize(window.innerWidth);
}

View File

@ -0,0 +1,24 @@
import { ReflectiveInjector, NgZone } from '@angular/core';
import { SearchService } from './search.service';
xdescribe('SearchService', () => {
let injector: ReflectiveInjector;
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
SearchService,
{ provide: NgZone, useFactory: () => new NgZone({ enableLongStackTrace: false }) }
]);
});
describe('loadIndex', () => {
it('should send a "load-index" message to the worker', () => {});
it('should connect the `ready` property to the response to the "load-index" message', () => {});
});
describe('search', () => {
it('should send a "query-index" message to the worker', () => {});
it('should push the response to the `searchResults` observable', () => {});
});
});

View File

@ -4,7 +4,7 @@ Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
import { NgZone, Injectable } from '@angular/core';
import { NgZone, Injectable, Type } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/publishLast';
@ -16,7 +16,6 @@ export interface QueryResults {
results: Object[];
}
const SEARCH_WORKER_URL = 'app/search/search-worker.js';
@Injectable()
export class SearchService {
@ -25,8 +24,13 @@ export class SearchService {
private resultsSubject = new Subject<QueryResults>();
get searchResults() { return this.resultsSubject.asObservable(); }
constructor(private zone: NgZone) {
this.worker = new WebWorkerClient(SEARCH_WORKER_URL, zone);
constructor(private zone: NgZone) {}
initWorker(workerUrl) {
this.worker = new WebWorkerClient(new Worker(workerUrl), this.zone);
}
loadIndex() {
const ready = this.ready = this.worker.sendMessage<boolean>('load-index').publishLast();
// trigger the index to be loaded immediately
ready.connect();

View File

@ -14,18 +14,16 @@ export interface WebWorkerMessage {
}
export class WebWorkerClient {
worker: Worker;
private messageId = 0;
private nextId = 0;
constructor(url: string, private zone: NgZone) {
this.worker = new Worker(url);
constructor(private worker: Worker, private zone: NgZone) {
}
sendMessage<T>(type: string, payload?: any): Observable<T> {
return new Observable<T>(subscriber => {
const id = this.messageId++;
const id = this.nextId++;
const handleMessage = (response: MessageEvent) => {
const {type: responseType, id: responseId, payload: responsePayload} = response.data as WebWorkerMessage;