UNPKG

@harmowatch/ngx-redux-core

Version:

Decorator driven redux integration for Angular 2+

1,360 lines (1,357 loc) 54.3 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs/add/operator/toPromise'), require('rxjs/AsyncSubject'), require('rxjs/Observable'), require('@angular/core'), require('rxjs/BehaviorSubject'), require('rxjs/ReplaySubject'), require('rxjs/Subject'), require('@angular/common'), require('redux/index')) : typeof define === 'function' && define.amd ? define(['exports', 'rxjs/add/operator/toPromise', 'rxjs/AsyncSubject', 'rxjs/Observable', '@angular/core', 'rxjs/BehaviorSubject', 'rxjs/ReplaySubject', 'rxjs/Subject', '@angular/common', 'redux/index'], factory) : (factory((global['ngx-redux-core'] = {}),global.Rx.Observable.prototype,global.Rx,global.Rx,global.ng.core,global.Rx,global.Rx,global.Rx,global.ng.common,global.redux)); }(this, (function (exports,toPromise,AsyncSubject,Observable,core,BehaviorSubject,ReplaySubject,Subject,common,index) { 'use strict'; var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var ActionInterface = /** @class */ (function () { function ActionInterface() { } return ActionInterface; }()); var MetadataManager = /** @class */ (function () { function MetadataManager() { } /** * @template T * @param {?} target * @param {?} data * @return {?} */ MetadataManager.setActionMetadata = function (target, data) { MetadataManager.set(target, MetadataManager.ACTION_KEY, data); }; /** * @template T * @param {?} target * @return {?} */ MetadataManager.getActionMetadata = function (target) { return MetadataManager.get(target, MetadataManager.ACTION_KEY, MetadataManager.ACTION_DEFAULT); }; /** * @template T * @param {?} target * @param {?} data * @return {?} */ MetadataManager.setActionContextMetadata = function (target, data) { MetadataManager.set(target, MetadataManager.ACTION_CONTEXT_KEY, data); }; /** * @template T * @param {?} target * @return {?} */ MetadataManager.getActionContextMetadata = function (target) { return MetadataManager.get(target, MetadataManager.ACTION_CONTEXT_KEY, MetadataManager.ACTION_CONTEXT_DEFAULT); }; /** * @template T * @param {?} target * @param {?} data * @return {?} */ MetadataManager.setReducerMetadata = function (target, data) { MetadataManager.set(target, MetadataManager.REDUCER_KEY, data); }; /** * @template T * @param {?} target * @return {?} */ MetadataManager.getReducerMetadata = function (target) { return MetadataManager.get(target, MetadataManager.REDUCER_KEY, MetadataManager.REDUCER_DEFAULT); }; /** * @template T * @param {?} target * @param {?} data * @return {?} */ MetadataManager.setStateMetadata = function (target, data) { MetadataManager.set(target, MetadataManager.STATE_KEY, data); }; /** * @template T * @param {?} target * @return {?} */ MetadataManager.getStateMetadata = function (target) { return MetadataManager.get(target, MetadataManager.STATE_KEY, MetadataManager.STATE_DEFAULT); }; /** * @template D, T * @param {?} target * @param {?} key * @param {?} data * @return {?} */ MetadataManager.set = function (target, key, data) { Reflect['defineMetadata'](key, data, target); }; /** * @template D, T * @param {?} target * @param {?} key * @param {?} defaultData * @return {?} */ MetadataManager.get = function (target, key, defaultData) { defaultData = defaultData || /** @type {?} */ ({}); return Object.assign({}, defaultData, Reflect['getMetadata'](key, target)); }; return MetadataManager; }()); MetadataManager.ACTION_KEY = Symbol('@ReduxAction'); MetadataManager.ACTION_DEFAULT = { contextClazz: null, type: '', }; MetadataManager.ACTION_CONTEXT_KEY = Symbol('@ReduxActionContext'); MetadataManager.ACTION_CONTEXT_DEFAULT = { prefix: '', }; MetadataManager.REDUCER_KEY = Symbol('@ReduxReducer'); MetadataManager.REDUCER_DEFAULT = { reducers: [], }; MetadataManager.STATE_KEY = Symbol('@ReduxState'); MetadataManager.STATE_DEFAULT = { name: '', }; /** * @param {?} config * @return {?} */ function ReduxActionContext(config) { return function (constructor) { MetadataManager.setActionContextMetadata(constructor, config); return constructor; }; } var Registry = /** @class */ (function () { function Registry() { } /** * @return {?} */ Registry.reset = function () { Registry._store = new AsyncSubject.AsyncSubject(); Registry._reducers = []; }; /** * @param {?} store * @return {?} */ Registry.registerStore = function (store) { Registry._store.next(store); Registry._store.complete(); }; /** * @param {?} stateName * @param {?} types * @param {?} reducer * @return {?} */ Registry.registerReducer = function (stateName, types, reducer) { if (Array.isArray(types)) { types.forEach(function (type) { Registry._reducers.push({ reducer: reducer, stateName: stateName, type: type, }); }); } else { Registry._reducers.push({ reducer: reducer, stateName: stateName, type: /** @type {?} */ (types), }); } }; /** * @param {?} state * @return {?} */ Registry.registerState = function (state) { Registry.getStore().then(function (store) { var /** @type {?} */ stateConfig = MetadataManager.getStateMetadata(state.constructor); var /** @type {?} */ initState = state.getInitialState(); var /** @type {?} */ initStateToResolve = initState; if (initState instanceof Observable.Observable) { initStateToResolve = initState.toPromise(); } Promise.resolve(initStateToResolve).then(function (initialState) { store.dispatch({ payload: { initialValue: initialState, name: stateConfig.name, }, type: Registry.ACTION_REGISTER_STATE, }); }); }); }; /** * @param {?} type * @return {?} */ Registry.getReducerItemsByType = function (type) { return Registry._reducers .filter(function (reducerItem) { return getActionTypeByFunction(reducerItem.type) === type; }); }; /** * @return {?} */ Registry.getStore = function () { return new Promise(Registry._store.subscribe.bind(Registry._store)); }; return Registry; }()); Registry.ACTION_REGISTER_STATE = "ngx-redux://registerState"; Registry._store = new AsyncSubject.AsyncSubject(); Registry._reducers = []; /** * @param {?=} config * @return {?} */ function ReduxAction(config) { return function (target, propertyKey, descriptor) { config = Object.assign({ type: propertyKey, }, config || {}); var /** @type {?} */ originalFunction = descriptor.value; var /** @type {?} */ proxyFunction = function () { var /** @type {?} */ contextData = MetadataManager.getActionContextMetadata(target.constructor); var /** @type {?} */ type = getActionType(contextData.prefix, config.type); var /** @type {?} */ returnValue = originalFunction.apply(this, arguments); Promise.all([ Promise.resolve(returnValue), Registry.getStore(), ]).then(function (_e) { var payload = _e[0], store = _e[1]; store.dispatch({ payload: payload, type: type }); }); return returnValue; }; MetadataManager.setActionMetadata(proxyFunction, { contextClazz: target.constructor, type: config.type, }); descriptor.value = proxyFunction; }; } /** * @param {?} target * @return {?} */ function getActionTypeByFunction(target) { var _e = MetadataManager.getActionMetadata(target), type = _e.type, contextClazz = _e.contextClazz; var prefix = MetadataManager.getActionContextMetadata(contextClazz).prefix; return getActionType(prefix, type); } /** * @param {...?} rest * @return {?} */ function getActionType() { var rest = []; for (var _i = 0; _i < arguments.length; _i++) { rest[_i] = arguments[_i]; } return rest.filter(function (i) { return i.length > 0; }).join(''); } var ReduxModuleRootReducer = /** @class */ (function () { function ReduxModuleRootReducer() { } /** * @param {?} state * @param {?} action * @return {?} */ ReduxModuleRootReducer.reduce = function (state, action) { if (action.type === Registry.ACTION_REGISTER_STATE) { return ReduxModuleRootReducer.reduceRegisterState(state, /** @type {?} */ (action)); } return ReduxModuleRootReducer.reduceByRegisteredReducers(state, action); }; /** * @param {?} state * @param {?} action * @return {?} */ ReduxModuleRootReducer.reduceRegisterState = function (state, action) { var _e = action.payload, name = _e.name, initialValue = _e.initialValue; return Object.assign({}, state, (_f = {}, _f[name] = initialValue, _f)); var _f; }; /** * @param {?} state * @param {?} action * @return {?} */ ReduxModuleRootReducer.reduceByRegisteredReducers = function (state, action) { var /** @type {?} */ reducers = Registry.getReducerItemsByType(action.type); return reducers.reduce(function (stateToReduce, reducerItem) { var stateName = reducerItem.stateName, reducer = reducerItem.reducer; return Object.assign({}, stateToReduce, (_e = {}, _e[stateName] = reducer(stateToReduce[stateName], action), _e)); var _e; }, state); }; return ReduxModuleRootReducer; }()); /** * @template S, P * @param {?} types * @return {?} */ function ReduxReducer(types) { return function (target, propertyKey) { var /** @type {?} */ data = MetadataManager.getReducerMetadata(target.constructor); data.reducers.push({ types: types, reducer: target[propertyKey].bind(target) }); MetadataManager.setReducerMetadata(target.constructor, data); return target[propertyKey]; }; } var StateDefToken = /** @class */ (function (_super) { __extends(StateDefToken, _super); function StateDefToken() { return _super.call(this, 'StateDefToken') || this; } return StateDefToken; }(core.InjectionToken)); var ReduxStateSelectorSubjectType = {}; ReduxStateSelectorSubjectType.DEFAULT = 0; ReduxStateSelectorSubjectType.SUBJECT = 1; ReduxStateSelectorSubjectType.BEHAVIOR_SUBJECT = 2; ReduxStateSelectorSubjectType.REPLAY_SUBJECT = 3; ReduxStateSelectorSubjectType[ReduxStateSelectorSubjectType.DEFAULT] = "DEFAULT"; ReduxStateSelectorSubjectType[ReduxStateSelectorSubjectType.SUBJECT] = "SUBJECT"; ReduxStateSelectorSubjectType[ReduxStateSelectorSubjectType.BEHAVIOR_SUBJECT] = "BEHAVIOR_SUBJECT"; ReduxStateSelectorSubjectType[ReduxStateSelectorSubjectType.REPLAY_SUBJECT] = "REPLAY_SUBJECT"; var ReduxStateSelector = /** @class */ (function () { /** * @param {?} expression * @param {?=} context */ function ReduxStateSelector(expression, context) { this.expression = expression; this.context = context; if (!expression.startsWith(ReduxStateSelector.DELIMITER)) { if (!context) { throw new Error('You need to provide a state context if you want to use relativ selectors'); } this.expression = "/" + MetadataManager.getStateMetadata(context).name + "/" + this.expression; } } /** * @template S * @return {?} */ ReduxStateSelector.prototype.getObservable = function () { return this.getSubject().asObservable(); }; /** * @template S * @param {?} initialValue * @return {?} */ ReduxStateSelector.prototype.getBehaviorSubject = function (initialValue) { return /** @type {?} */ (this.getBySubjectType(ReduxStateSelectorSubjectType.BEHAVIOR_SUBJECT, initialValue)); }; /** * @template S * @return {?} */ ReduxStateSelector.prototype.getReplaySubject = function () { return /** @type {?} */ (this.getBySubjectType(ReduxStateSelectorSubjectType.REPLAY_SUBJECT)); }; /** * @template S * @return {?} */ ReduxStateSelector.prototype.getSubject = function () { return /** @type {?} */ (this.getBySubjectType(ReduxStateSelectorSubjectType.SUBJECT)); }; /** * @template S * @param {?} type * @param {?=} initialValue * @return {?} */ ReduxStateSelector.prototype.getBySubjectType = function (type, initialValue) { var _this = this; var /** @type {?} */ subject; switch (type) { case ReduxStateSelectorSubjectType.REPLAY_SUBJECT: subject = new ReplaySubject.ReplaySubject(); break; case ReduxStateSelectorSubjectType.SUBJECT: subject = new Subject.Subject(); break; default: subject = new BehaviorSubject.BehaviorSubject(initialValue || null); } Registry.getStore().then(function (store) { subject.next(_this.getValueFromState(store.getState())); store.subscribe(function () { return subject.next(_this.getValueFromState(store.getState())); }); }); return subject; }; /** * @template T, S * @param {?} state * @return {?} */ ReduxStateSelector.prototype.getValueFromState = function (state) { return this.expression.split(ReduxStateSelector.DELIMITER) .filter(ReduxStateSelector.isPropertyKeyValid) .reduce(function (previousValue, propertyKey) { if (!previousValue || !previousValue[propertyKey]) { return null; } return previousValue[propertyKey]; }, state); }; /** * @param {?} propertyKey * @return {?} */ ReduxStateSelector.isPropertyKeyValid = function (propertyKey) { return propertyKey !== ''; }; return ReduxStateSelector; }()); ReduxStateSelector.DELIMITER = '/'; var ReduxSelectPipe = /** @class */ (function () { /** * @param {?} stateDef */ function ReduxSelectPipe(stateDef) { this.stateDef = stateDef; } /** * @param {?} selector * @return {?} */ ReduxSelectPipe.prototype.transform = function (selector) { return new ReduxStateSelector(selector, this.stateDef.provider).getObservable(); }; return ReduxSelectPipe; }()); ReduxSelectPipe.decorators = [ { type: core.Pipe, args: [{ name: 'reduxSelect' },] }, ]; /** * @nocollapse */ ReduxSelectPipe.ctorParameters = function () { return [ { type: undefined, decorators: [{ type: core.Inject, args: [StateDefToken,] },] }, ]; }; /** * @param {?} expression * @param {?=} context * @return {?} */ function ReduxSelect(expression, context) { return function (target, propertyKey) { var /** @type {?} */ selector; Object.defineProperty(target, propertyKey, { configurable: true, enumerable: true, get: function () { if (!selector) { selector = new ReduxStateSelector(expression, context); } return selector.getObservable(); }, }); }; } /** * @param {?} config * @return {?} */ function ReduxState(config) { return function (constructor) { MetadataManager.setStateMetadata(constructor, config); return constructor; }; } var ReduxStore = /** @class */ (function (_super) { __extends(ReduxStore, _super); function ReduxStore() { return _super.call(this, 'ReduxStore') || this; } return ReduxStore; }(core.InjectionToken)); /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } /** * @license Angular v4.4.6 * (c) 2010-2017 Google, Inc. https://angular.io/ * License: MIT */ /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ /** * Fixture for debugging and testing a component. * * @stable */ var ComponentFixture = (function () { function ComponentFixture(componentRef, ngZone, _autoDetect) { var _this = this; this.componentRef = componentRef; this.ngZone = ngZone; this._autoDetect = _autoDetect; this._isStable = true; this._isDestroyed = false; this._resolve = null; this._promise = null; this._onUnstableSubscription = null; this._onStableSubscription = null; this._onMicrotaskEmptySubscription = null; this._onErrorSubscription = null; this.changeDetectorRef = componentRef.changeDetectorRef; this.elementRef = componentRef.location; this.debugElement = core.getDebugNode(this.elementRef.nativeElement); this.componentInstance = componentRef.instance; this.nativeElement = this.elementRef.nativeElement; this.componentRef = componentRef; this.ngZone = ngZone; if (ngZone) { // Create subscriptions outside the NgZone so that the callbacks run oustide // of NgZone. ngZone.runOutsideAngular(function () { _this._onUnstableSubscription = ngZone.onUnstable.subscribe({ next: function () { _this._isStable = false; } }); _this._onMicrotaskEmptySubscription = ngZone.onMicrotaskEmpty.subscribe({ next: function () { if (_this._autoDetect) { // Do a change detection run with checkNoChanges set to true to check // there are no changes on the second run. _this.detectChanges(true); } } }); _this._onStableSubscription = ngZone.onStable.subscribe({ next: function () { _this._isStable = true; // Check whether there is a pending whenStable() completer to resolve. if (_this._promise !== null) { // If so check whether there are no pending macrotasks before resolving. // Do this check in the next tick so that ngZone gets a chance to update the state of // pending macrotasks. scheduleMicroTask(function () { if (!ngZone.hasPendingMacrotasks) { if (_this._promise !== null) { _this._resolve(true); _this._resolve = null; _this._promise = null; } } }); } } }); _this._onErrorSubscription = ngZone.onError.subscribe({ next: function (error) { throw error; } }); }); } } ComponentFixture.prototype._tick = function (checkNoChanges) { this.changeDetectorRef.detectChanges(); if (checkNoChanges) { this.checkNoChanges(); } }; /** * Trigger a change detection cycle for the component. */ ComponentFixture.prototype.detectChanges = function (checkNoChanges) { var _this = this; if (checkNoChanges === void 0) { checkNoChanges = true; } if (this.ngZone != null) { // Run the change detection inside the NgZone so that any async tasks as part of the change // detection are captured by the zone and can be waited for in isStable. this.ngZone.run(function () { _this._tick(checkNoChanges); }); } else { // Running without zone. Just do the change detection. this._tick(checkNoChanges); } }; /** * Do a change detection run to make sure there were no changes. */ ComponentFixture.prototype.checkNoChanges = function () { this.changeDetectorRef.checkNoChanges(); }; /** * Set whether the fixture should autodetect changes. * * Also runs detectChanges once so that any existing change is detected. */ ComponentFixture.prototype.autoDetectChanges = function (autoDetect) { if (autoDetect === void 0) { autoDetect = true; } if (this.ngZone == null) { throw new Error('Cannot call autoDetectChanges when ComponentFixtureNoNgZone is set'); } this._autoDetect = autoDetect; this.detectChanges(); }; /** * Return whether the fixture is currently stable or has async tasks that have not been completed * yet. */ ComponentFixture.prototype.isStable = function () { return this._isStable && !this.ngZone.hasPendingMacrotasks; }; /** * Get a promise that resolves when the fixture is stable. * * This can be used to resume testing after events have triggered asynchronous activity or * asynchronous change detection. */ ComponentFixture.prototype.whenStable = function () { var _this = this; if (this.isStable()) { return Promise.resolve(false); } else if (this._promise !== null) { return this._promise; } else { this._promise = new Promise(function (res) { _this._resolve = res; }); return this._promise; } }; ComponentFixture.prototype._getRenderer = function () { if (this._renderer === undefined) { this._renderer = this.componentRef.injector.get(core.RendererFactory2, null); } return this._renderer; }; /** * Get a promise that resolves when the ui state is stable following animations. */ ComponentFixture.prototype.whenRenderingDone = function () { var renderer = this._getRenderer(); if (renderer && renderer.whenRenderingDone) { return renderer.whenRenderingDone(); } return this.whenStable(); }; /** * Trigger component destruction. */ ComponentFixture.prototype.destroy = function () { if (!this._isDestroyed) { this.componentRef.destroy(); if (this._onUnstableSubscription != null) { this._onUnstableSubscription.unsubscribe(); this._onUnstableSubscription = null; } if (this._onStableSubscription != null) { this._onStableSubscription.unsubscribe(); this._onStableSubscription = null; } if (this._onMicrotaskEmptySubscription != null) { this._onMicrotaskEmptySubscription.unsubscribe(); this._onMicrotaskEmptySubscription = null; } if (this._onErrorSubscription != null) { this._onErrorSubscription.unsubscribe(); this._onErrorSubscription = null; } this._isDestroyed = true; } }; return ComponentFixture; }()); function scheduleMicroTask(fn) { Zone.current.scheduleMicroTask('scheduleMicrotask', fn); } var ProxyZoneSpec = Zone['ProxyZoneSpec']; /** * Clears out the shared fake async zone for a test. * To be called in a global `beforeEach`. * * @experimental */ function resetFakeAsyncZone() { ProxyZoneSpec.assertPresent().resetDelegate(); } /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ /** * Injectable completer that allows signaling completion of an asynchronous test. Used internally. */ /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var AsyncTestCompleter = (function () { function AsyncTestCompleter() { var _this = this; this._promise = new Promise(function (res, rej) { _this._resolve = res; _this._reject = rej; }); } AsyncTestCompleter.prototype.done = function (value) { this._resolve(value); }; AsyncTestCompleter.prototype.fail = function (error, stackTrace) { this._reject(error); }; Object.defineProperty(AsyncTestCompleter.prototype, "promise", { get: function () { return this._promise; }, enumerable: true, configurable: true }); return AsyncTestCompleter; }()); /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ function unimplemented() { throw Error('unimplemented'); } /** * Special interface to the compiler only used by testing * * @experimental */ var TestingCompiler = (function (_super) { __extends(TestingCompiler, _super); function TestingCompiler() { return _super !== null && _super.apply(this, arguments) || this; } Object.defineProperty(TestingCompiler.prototype, "injector", { get: function () { throw unimplemented(); }, enumerable: true, configurable: true }); TestingCompiler.prototype.overrideModule = function (module, overrides) { throw unimplemented(); }; TestingCompiler.prototype.overrideDirective = function (directive, overrides) { throw unimplemented(); }; TestingCompiler.prototype.overrideComponent = function (component, overrides) { throw unimplemented(); }; TestingCompiler.prototype.overridePipe = function (directive, overrides) { throw unimplemented(); }; /** * Allows to pass the compile summary from AOT compilation to the JIT compiler, * so that it can use the code generated by AOT. */ TestingCompiler.prototype.loadAotSummaries = function (summaries) { throw unimplemented(); }; /** * Gets the component factory for the given component. * This assumes that the component has been compiled before calling this call using * `compileModuleAndAllComponents*`. */ TestingCompiler.prototype.getComponentFactory = function (component) { throw unimplemented(); }; return TestingCompiler; }(core.Compiler)); /** * A factory for creating a Compiler * * @experimental */ var TestingCompilerFactory = (function () { function TestingCompilerFactory() { } return TestingCompilerFactory; }()); /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var UNDEFINED = new Object(); /** * An abstract class for inserting the root test component element in a platform independent way. * * @experimental */ var TestComponentRenderer = (function () { function TestComponentRenderer() { } TestComponentRenderer.prototype.insertRootElement = function (rootElementId) { }; return TestComponentRenderer; }()); var _nextRootElementId = 0; /** * @experimental */ var ComponentFixtureAutoDetect = new core.InjectionToken('ComponentFixtureAutoDetect'); /** * @experimental */ var ComponentFixtureNoNgZone = new core.InjectionToken('ComponentFixtureNoNgZone'); /** * @whatItDoes Configures and initializes environment for unit testing and provides methods for * creating components and services in unit tests. * @description * * TestBed is the primary api for writing unit tests for Angular applications and libraries. * * @stable */ var TestBed = (function () { function TestBed() { this._instantiated = false; this._compiler = null; this._moduleRef = null; this._moduleFactory = null; this._compilerOptions = []; this._moduleOverrides = []; this._componentOverrides = []; this._directiveOverrides = []; this._pipeOverrides = []; this._providers = []; this._declarations = []; this._imports = []; this._schemas = []; this._activeFixtures = []; this._aotSummaries = function () { return []; }; this.platform = null; this.ngModule = null; } /** * Initialize the environment for testing with a compiler factory, a PlatformRef, and an * angular module. These are common to every test in the suite. * * This may only be called once, to set up the common providers for the current test * suite on the current platform. If you absolutely need to change the providers, * first use `resetTestEnvironment`. * * Test modules and platforms for individual platforms are available from * '@angular/<platform_name>/testing'. * * @experimental */ TestBed.initTestEnvironment = function (ngModule, platform, aotSummaries) { var testBed = getTestBed(); testBed.initTestEnvironment(ngModule, platform, aotSummaries); return testBed; }; /** * Reset the providers for the test injector. * * @experimental */ TestBed.resetTestEnvironment = function () { getTestBed().resetTestEnvironment(); }; TestBed.resetTestingModule = function () { getTestBed().resetTestingModule(); return TestBed; }; /** * Allows overriding default compiler providers and settings * which are defined in test_injector.js */ TestBed.configureCompiler = function (config) { getTestBed().configureCompiler(config); return TestBed; }; /** * Allows overriding default providers, directives, pipes, modules of the test injector, * which are defined in test_injector.js */ TestBed.configureTestingModule = function (moduleDef) { getTestBed().configureTestingModule(moduleDef); return TestBed; }; /** * Compile components with a `templateUrl` for the test's NgModule. * It is necessary to call this function * as fetching urls is asynchronous. */ TestBed.compileComponents = function () { return getTestBed().compileComponents(); }; TestBed.overrideModule = function (ngModule, override) { getTestBed().overrideModule(ngModule, override); return TestBed; }; TestBed.overrideComponent = function (component, override) { getTestBed().overrideComponent(component, override); return TestBed; }; TestBed.overrideDirective = function (directive, override) { getTestBed().overrideDirective(directive, override); return TestBed; }; TestBed.overridePipe = function (pipe, override) { getTestBed().overridePipe(pipe, override); return TestBed; }; TestBed.overrideTemplate = function (component, template) { getTestBed().overrideComponent(component, { set: { template: template, templateUrl: null } }); return TestBed; }; TestBed.overrideProvider = function (token, provider) { getTestBed().overrideProvider(token, provider); return TestBed; }; TestBed.deprecatedOverrideProvider = function (token, provider) { getTestBed().deprecatedOverrideProvider(token, provider); return TestBed; }; TestBed.get = function (token, notFoundValue) { if (notFoundValue === void 0) { notFoundValue = core.Injector.THROW_IF_NOT_FOUND; } return getTestBed().get(token, notFoundValue); }; TestBed.createComponent = function (component) { return getTestBed().createComponent(component); }; /** * Initialize the environment for testing with a compiler factory, a PlatformRef, and an * angular module. These are common to every test in the suite. * * This may only be called once, to set up the common providers for the current test * suite on the current platform. If you absolutely need to change the providers, * first use `resetTestEnvironment`. * * Test modules and platforms for individual platforms are available from * '@angular/<platform_name>/testing'. * * @experimental */ TestBed.prototype.initTestEnvironment = function (ngModule, platform, aotSummaries) { if (this.platform || this.ngModule) { throw new Error('Cannot set base providers because it has already been called'); } this.platform = platform; this.ngModule = ngModule; if (aotSummaries) { this._aotSummaries = aotSummaries; } }; /** * Reset the providers for the test injector. * * @experimental */ TestBed.prototype.resetTestEnvironment = function () { this.resetTestingModule(); this.platform = null; this.ngModule = null; this._aotSummaries = function () { return []; }; }; TestBed.prototype.resetTestingModule = function () { core.ɵclearProviderOverrides(); this._compiler = null; this._moduleOverrides = []; this._componentOverrides = []; this._directiveOverrides = []; this._pipeOverrides = []; this._moduleRef = null; this._moduleFactory = null; this._compilerOptions = []; this._providers = []; this._declarations = []; this._imports = []; this._schemas = []; this._instantiated = false; this._activeFixtures.forEach(function (fixture) { try { fixture.destroy(); } catch (e) { console.error('Error during cleanup of component', fixture.componentInstance); } }); this._activeFixtures = []; }; TestBed.prototype.configureCompiler = function (config) { this._assertNotInstantiated('TestBed.configureCompiler', 'configure the compiler'); this._compilerOptions.push(config); }; TestBed.prototype.configureTestingModule = function (moduleDef) { this._assertNotInstantiated('TestBed.configureTestingModule', 'configure the test module'); if (moduleDef.providers) { (_a = this._providers).push.apply(_a, moduleDef.providers); } if (moduleDef.declarations) { (_b = this._declarations).push.apply(_b, moduleDef.declarations); } if (moduleDef.imports) { (_c = this._imports).push.apply(_c, moduleDef.imports); } if (moduleDef.schemas) { (_d = this._schemas).push.apply(_d, moduleDef.schemas); } var _a, _b, _c, _d; }; TestBed.prototype.compileComponents = function () { var _this = this; if (this._moduleFactory || this._instantiated) { return Promise.resolve(null); } var moduleType = this._createCompilerAndModule(); return this._compiler.compileModuleAndAllComponentsAsync(moduleType) .then(function (moduleAndComponentFactories) { _this._moduleFactory = moduleAndComponentFactories.ngModuleFactory; }); }; TestBed.prototype._initIfNeeded = function () { if (this._instantiated) { return; } if (!this._moduleFactory) { try { var moduleType = this._createCompilerAndModule(); this._moduleFactory = this._compiler.compileModuleAndAllComponentsSync(moduleType).ngModuleFactory; } catch (e) { if (getComponentType(e)) { throw new Error("This test module uses the component " + core.ɵstringify(getComponentType(e)) + " which is using a \"templateUrl\" or \"styleUrls\", but they were never compiled. " + "Please call \"TestBed.compileComponents\" before your test."); } else { throw e; } } } var ngZone = new core.NgZone({ enableLongStackTrace: true }); var ngZoneInjector = core.ReflectiveInjector.resolveAndCreate([{ provide: core.NgZone, useValue: ngZone }], this.platform.injector); this._moduleRef = this._moduleFactory.create(ngZoneInjector); // ApplicationInitStatus.runInitializers() is marked @internal to core. So casting to any // before accessing it. this._moduleRef.injector.get(core.ApplicationInitStatus).runInitializers(); this._instantiated = true; }; TestBed.prototype._createCompilerAndModule = function () { var _this = this; var providers = this._providers.concat([{ provide: TestBed, useValue: this }]); var declarations = this._declarations; var imports = [this.ngModule, this._imports]; var schemas = this._schemas; var DynamicTestModule = (function () { function DynamicTestModule() { } return DynamicTestModule; }()); DynamicTestModule.decorators = [ { type: core.NgModule, args: [{ providers: providers, declarations: declarations, imports: imports, schemas: schemas },] }, ]; /** @nocollapse */ DynamicTestModule.ctorParameters = function () { return []; }; var compilerFactory = this.platform.injector.get(TestingCompilerFactory); this._compiler = compilerFactory.createTestingCompiler(this._compilerOptions.concat([{ useDebug: true }])); this._compiler.loadAotSummaries(this._aotSummaries); this._moduleOverrides.forEach(function (entry) { return _this._compiler.overrideModule(entry[0], entry[1]); }); this._componentOverrides.forEach(function (entry) { return _this._compiler.overrideComponent(entry[0], entry[1]); }); this._directiveOverrides.forEach(function (entry) { return _this._compiler.overrideDirective(entry[0], entry[1]); }); this._pipeOverrides.forEach(function (entry) { return _this._compiler.overridePipe(entry[0], entry[1]); }); return DynamicTestModule; }; TestBed.prototype._assertNotInstantiated = function (methodName, methodDescription) { if (this._instantiated) { throw new Error("Cannot " + methodDescription + " when the test module has already been instantiated. " + ("Make sure you are not using `inject` before `" + methodName + "`.")); } }; TestBed.prototype.get = function (token, notFoundValue) { if (notFoundValue === void 0) { notFoundValue = core.Injector.THROW_IF_NOT_FOUND; } this._initIfNeeded(); if (token === TestBed) { return this; } // Tests can inject things from the ng module and from the compiler, // but the ng module can't inject things from the compiler and vice versa. var result = this._moduleRef.injector.get(token, UNDEFINED); return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue) : result; }; TestBed.prototype.execute = function (tokens, fn, context) { var _this = this; this._initIfNeeded(); var params = tokens.map(function (t) { return _this.get(t); }); return fn.apply(context, params); }; TestBed.prototype.overrideModule = function (ngModule, override) { this._assertNotInstantiated('overrideModule', 'override module metadata'); this._moduleOverrides.push([ngModule, override]); }; TestBed.prototype.overrideComponent = function (component, override) { this._assertNotInstantiated('overrideComponent', 'override component metadata'); this._componentOverrides.push([component, override]); }; TestBed.prototype.overrideDirective = function (directive, override) { this._assertNotInstantiated('overrideDirective', 'override directive metadata'); this._directiveOverrides.push([directive, override]); }; TestBed.prototype.overridePipe = function (pipe, override) { this._assertNotInstantiated('overridePipe', 'override pipe metadata'); this._pipeOverrides.push([pipe, override]); }; TestBed.prototype.overrideProvider = function (token, provider) { this.overrideProviderImpl(token, provider); }; TestBed.prototype.deprecatedOverrideProvider = function (token, provider) { this.overrideProviderImpl(token, provider, /* deprecated */ true); }; TestBed.prototype.overrideProviderImpl = function (token, provider, deprecated) { if (deprecated === void 0) { deprecated = false; } var flags = 0; var value; if (provider.useFactory) { flags |= 1024 /* TypeFactoryProvider */; value = provider.useFactory; } else { flags |= 256 /* TypeValueProvider */; value = provider.useValue; } var deps = (provider.deps || []).map(function (dep) { var depFlags = 0; var depToken; if (Array.isArray(dep)) { dep.forEach(function (entry) { if (entry instanceof core.Optional) { depFlags |= 2 /* Optional */; } else if (entry instanceof core.SkipSelf) { depFlags |= 1 /* SkipSelf */; } else { depToken = entry; } }); } else { depToken = dep; } return [depFlags, depToken]; }); core.ɵoverrideProvider({ token: token, flags: flags, deps: deps, value: value, deprecatedBehavior: deprecated }); }; TestBed.prototype.createComponent = function (component) { var _this = this; this._initIfNeeded(); var componentFactory = this._compiler.getComponentFactory(component); if (!componentFactory) { throw new Error("Cannot create the component " + core.ɵstringify(component) + " as it was not imported into the testing module!"); } var noNgZone = this.get(ComponentFixtureNoNgZone, false); var autoDetect = this.get(ComponentFixtureAutoDetect, false); var ngZone = noNgZone ? null : this.get(core.NgZone, null); var testComponentRenderer = this.get(TestComponentRenderer); var rootElId = "root" + _nextRootElementId++; testComponentRenderer.insertRootElement(rootElId); var initComponent = function () { var componentRef = componentFactory.create(core.Injector.NULL, [], "#" + rootElId, _this._moduleRef); return new ComponentFixture(componentRef, ngZone, autoDetect); }; var fixture = !ngZone ? initComponent() : ngZone.run(initComponent); this._activeFixtures.push(fixture); return fixture; }; return TestBed; }()); var _testBed = null; /** * @experimental */ function getTestBed() { return _testBed = _testBed || new TestBed(); } /** * Allows injecting dependencies in `beforeEach()` and `it()`. * * Example: * * ``` * beforeEach(inject([Dependency, AClass], (dep, object) => { * // some code that uses `dep` and `object` * // ... * })); * * it('...', inject([AClass], (object) => { * object.doSomething(); * expect(...); * }) * ``` * * Notes: * - inject is currently a function because of some Traceur limitation the syntax should * eventually * becomes `it('...', @Inject (object: AClass, async: AsyncTestCompleter) => { ... });` * * @stable */ function inject(tokens, fn) { var testBed = getTestBed(); if (tokens.indexOf(AsyncTestCompleter) >= 0) { // Not using an arrow function to preserve context passed from call site return function () { var _this = this; // Return an async test method that returns a Promise if AsyncTestCompleter is one of // the injected tokens. return testBed.compileComponents().then(function () { var completer = testBed.get(AsyncTestCompleter); testBed.execute(tokens, fn, _this); return completer.promise; }); }; } else { // Not using an arrow function to preserve context passed from call site return function () { return testBed.execute(tokens, fn, this); }; } } /** * @experimental */ var InjectSetupWrapper = (function () { function InjectSetupWrapper(_moduleDef) { this._moduleDef = _moduleDef; } InjectSetupWrapper.prototype._addModule = function () { var moduleDef = this._moduleDef(); if (moduleDef) { getTestBed().configureTestingModule(moduleDef); } }; InjectSetupWrapper.prototype.inject = function (tokens, fn) { var self = this; // Not using an arrow function to preserve context passed from call site return function () { self._addModule(); return inject(tokens, fn).call(this); }; }; return InjectSetupWrapper; }()); function getComponentType(error) { return error[core.ɵERROR_COMPONENT_TYPE]; } /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ /** * Public Test Library for unit testing Angular applications. Assumes that you are running * with Jasmine, Mocha, or a similar framework which exports a beforeEach function and * allows tests to be asynchronous by either returning a promise or using a 'done' parameter. */ var _global$1 = (typeof window === 'undefined' ? global : window); // Reset the test providers and the fake async zone before each test. if (_global$1.beforeEach) { _global$1.beforeEach(function () { TestBed.resetTestingModule(); resetFakeAsyncZone(); }); } var ReduxTestingModule = /** @class */ (function () { function ReduxTestingModule() { Registry.reset(); Registry.registerStore(ReduxTestingModule.storeFactory()); } /** * @param {?} stateDef * @return {?} */ ReduxTestingModule.addStateDefinition = function (stateDef) { Registry.registerState(TestBed.get(stateDef.provider)); }; /** * @return {?} */ ReduxTestingModule.storeFactory = function () { return index.createStore(ReduxModuleRootReducer.reduce, {}); }; return ReduxTestingModule; }()); ReduxTestingModule.decorators = [ { type: core.NgModule, args: [{ declarations: [ ReduxSelectPipe, ], exports: [ ReduxSelectPipe, ], imports: [ common.CommonModule, ], },] }, ]; /** * @nocollapse */ ReduxTestingModule.ctorParameters = function () { return []; }; var ReduxModule = /** @class */ (function () { /** * @param {?=} stateDef * @param {?=} store * @param {?=} injector */ function ReduxModule(stateDef, store, injector) { if (stateDef === void