refactor(aio): reorganize search service for easier testing
This commit is contained in:
parent
b8321e2f7d
commit
b09ee424bf
|
@ -101,6 +101,9 @@ export class AppComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
this.searchService.initWorker('app/search/search-worker.js');
|
||||||
|
this.searchService.loadIndex();
|
||||||
|
|
||||||
this.onResize(window.innerWidth);
|
this.onResize(window.innerWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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', () => {});
|
||||||
|
});
|
||||||
|
});
|
|
@ -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
|
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 { Observable } from 'rxjs/Observable';
|
||||||
import { Subject } from 'rxjs/Subject';
|
import { Subject } from 'rxjs/Subject';
|
||||||
import 'rxjs/add/operator/publishLast';
|
import 'rxjs/add/operator/publishLast';
|
||||||
|
@ -16,7 +16,6 @@ export interface QueryResults {
|
||||||
results: Object[];
|
results: Object[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const SEARCH_WORKER_URL = 'app/search/search-worker.js';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SearchService {
|
export class SearchService {
|
||||||
|
@ -25,8 +24,13 @@ export class SearchService {
|
||||||
private resultsSubject = new Subject<QueryResults>();
|
private resultsSubject = new Subject<QueryResults>();
|
||||||
get searchResults() { return this.resultsSubject.asObservable(); }
|
get searchResults() { return this.resultsSubject.asObservable(); }
|
||||||
|
|
||||||
constructor(private zone: NgZone) {
|
constructor(private zone: NgZone) {}
|
||||||
this.worker = new WebWorkerClient(SEARCH_WORKER_URL, zone);
|
|
||||||
|
initWorker(workerUrl) {
|
||||||
|
this.worker = new WebWorkerClient(new Worker(workerUrl), this.zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadIndex() {
|
||||||
const ready = this.ready = this.worker.sendMessage<boolean>('load-index').publishLast();
|
const ready = this.ready = this.worker.sendMessage<boolean>('load-index').publishLast();
|
||||||
// trigger the index to be loaded immediately
|
// trigger the index to be loaded immediately
|
||||||
ready.connect();
|
ready.connect();
|
||||||
|
|
|
@ -14,18 +14,16 @@ export interface WebWorkerMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WebWorkerClient {
|
export class WebWorkerClient {
|
||||||
worker: Worker;
|
private nextId = 0;
|
||||||
private messageId = 0;
|
|
||||||
|
|
||||||
constructor(url: string, private zone: NgZone) {
|
constructor(private worker: Worker, private zone: NgZone) {
|
||||||
this.worker = new Worker(url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage<T>(type: string, payload?: any): Observable<T> {
|
sendMessage<T>(type: string, payload?: any): Observable<T> {
|
||||||
|
|
||||||
return new Observable<T>(subscriber => {
|
return new Observable<T>(subscriber => {
|
||||||
|
|
||||||
const id = this.messageId++;
|
const id = this.nextId++;
|
||||||
|
|
||||||
const handleMessage = (response: MessageEvent) => {
|
const handleMessage = (response: MessageEvent) => {
|
||||||
const {type: responseType, id: responseId, payload: responsePayload} = response.data as WebWorkerMessage;
|
const {type: responseType, id: responseId, payload: responsePayload} = response.data as WebWorkerMessage;
|
||||||
|
|
Loading…
Reference in New Issue