transform(docObs: any, args: List<any> = null): any { if (!this._subscription) { var self = this; this._subscription = ObservableWrapper.subscribe(docObs, value => { self._updateLatestValue(value); }); return null; } if (!this._isUpdated) { return this._latestReturnedValue; } this._isUpdated = false; this._latestReturnedValue = this._latestValue; return WrappedValue.wrap(this._latestValue); }
.then((_) => { ObservableWrapper.subscribe<string>(eventBus, (ev) => { if (ev.startsWith('parent activate')) { completer.resolve(true); } }); rtr.navigateByUrl('/parent-activate/child-activate') .then((_) => { fixture.detectChanges(); expect(fixture.debugElement.nativeElement).toHaveText('parent {activate cmp}'); expect(log).toEqual([ 'parent activate: null -> /parent-activate', 'activate: null -> /child-activate' ]); async.done(); }); });
it('should append an svg as child of self', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { let html = '<div class="logo" logo></div>'; ObservableWrapper.subscribe(backend.connections, (connection: MockConnection) => { // console.log(connection); connection.mockRespond(response) }); tcb .overrideTemplate(Test, html) .createAsync(Test) .then((rootTC) => { rootTC.detectChanges(); let logo: Element = DOM.querySelector(rootTC.nativeElement, '.logo'); let prefixSelector = isNativeShadowDOMSupported ? '* /deep/ ' : ''; // soon use '>>>' https://www.chromestatus.com/features/6750456638341120 // console.log(logo.firstChild, prefixSelector); // expect(logo.querySelector(prefixSelector + 'svg')).not.toBe(null); async.done(); }); }));
.then((_) => { fixture.detectChanges(); expect(fixture.debugElement.nativeElement).toHaveText('routerCanDeactivate {A}'); expect(log).toEqual([]); ObservableWrapper.subscribe<string>(eventBus, (ev) => { if (ev.startsWith('routerCanDeactivate')) { completer.resolve(false); } }); rtr.navigateByUrl('/a').then((_) => { fixture.detectChanges(); expect(fixture.debugElement.nativeElement).toHaveText('routerCanDeactivate {A}'); expect(log).toEqual(['routerCanDeactivate: /can-deactivate -> /a']); async.done(); }); });
it("should fire an event every time a control is updated", inject([AsyncTestCompleter], (async) => { var loggedValues = []; ObservableWrapper.subscribe(g.valueChanges, (value) => { ListWrapper.push(loggedValues, value); if (loggedValues.length == 2) { expect(loggedValues).toEqual([{ "one": "new1", "two": "old2" }, { "one": "new1", "two": "new2" }]); async.done(); } }); c1.updateValue("new1"); c2.updateValue("new2"); }));
inject([AsyncTestCompleter], (async) => { // the only practical use-case to run a callback inside the zone is // change detection after "onTurnDone". That's the only case tested. var turnDone = false; ObservableWrapper.subscribe(_zone.onTurnDone, (_) => { _log.add('onTurnDone'); if (turnDone) return; _zone.run(() => { microTask(() => {}); }); turnDone = true; }); macroTask(() => { _zone.run(_log.fn('run')); }); macroTask(() => { expect(_log.result()).toEqual('run; onTurnDone; onTurnDone'); async.done(); }, resultTimer); }), testTimeout);
inject([AsyncTestCompleter], (async) => { ObservableWrapper.subscribe(_zone.onEventDone, (_) => { _log.add('onEventDone'); // If not implemented correctly, this time will cause another digest, // which is not what we want. TimerWrapper.setTimeout(() => { _log.add('asyncTask'); }, 5); }); logOnTurnDone(); macroTask(() => { _zone.run(_log.fn('run')); }); macroTask(() => { TimerWrapper.setTimeout(() => { expect(_log.result()).toEqual('run; onTurnDone; onEventDone; asyncTask'); async.done(); }, 50); }); }), testTimeout);
inject([AsyncTestCompleter], (async) => { runNgZoneNoLog(() => macroTask(_log.fn('run'))); // the only practical use-case to run a callback inside the zone is // change detection after "onMicrotaskEmpty". That's the only case tested. var turnDone = false; ObservableWrapper.subscribe(_zone.onMicrotaskEmpty, (_) => { _log.add('onMyMicrotaskEmpty'); if (turnDone) return; _zone.run(() => { scheduleMicroTask(() => {}); }); turnDone = true; }); macroTask(() => { expect(_log.result()) .toEqual('onUnstable; run; onMicrotaskEmpty; onMyMicrotaskEmpty; ' + 'onMicrotaskEmpty; onMyMicrotaskEmpty; onStable'); async.done(); }, resultTimer); }), testTimeout);
it('should ignore load/callback when disposed', inject([AsyncTestCompleter], async => { var connection = new JSONPConnection(sampleRequest, new MockBrowserJsonp()); let spy = new SpyObject(); let loadSpy = spy.spy('load'); let errorSpy = spy.spy('error'); let returnSpy = spy.spy('cancelled'); ObservableWrapper.subscribe(connection.response, loadSpy, errorSpy, returnSpy); connection.dispose(); expect(connection.readyState).toBe(ReadyStates.CANCELLED); connection.finished('Fake data'); existingScripts[0].dispatchEvent('load'); TimerWrapper.setTimeout(() => { expect(loadSpy).not.toHaveBeenCalled(); expect(errorSpy).not.toHaveBeenCalled(); expect(returnSpy).toHaveBeenCalled(); async.done(); }, 10); }));
it('should call onEventDone once at the end of event', inject([AsyncTestCompleter], (async) => { // The test is set up in a way that causes the zone loop to run onTurnDone twice // then verified that onEventDone is only called once at the end logOnEventDone(); var times = 0; ObservableWrapper.subscribe(_zone.onTurnDone, (_) => { times++; _log.add(`onTurnDone ${times}`); if (times < 2) { // Scheduling a microtask causes a second digest _zone.run(() => { microTask(() => {}); }); } }); macroTask(() => { _zone.run(_log.fn('run')); }); macroTask(() => { expect(_log.result()).toEqual('run; onTurnDone 1; onTurnDone 2; onEventDone'); async.done(); }, resultTimer); }), testTimeout);