@harmowatch/ngx-redux-core
Version:
Decorator driven redux integration for Angular 2+
1,360 lines (1,357 loc) • 54.3 kB
JavaScript
(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