@ngxs/store
Version:
286 lines (277 loc) • 10.6 kB
JavaScript
import { TestBed } from '@angular/core/testing';
import { ɵgetDOM as _getDOM, BrowserModule, ɵBrowserDomAdapter as _BrowserDomAdapter } from '@angular/platform-browser';
import * as i0 from '@angular/core';
import { DOCUMENT, destroyPlatform, VERSION, createPlatform, Injector, Component, NgModule, ApplicationRef, provideEnvironmentInitializer, inject, DestroyRef, Injectable } from '@angular/core';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { NgxsModule, Store, Actions, ActionStatus } from '@ngxs/store';
import { ReplaySubject, Subject, takeUntil } from 'rxjs';
function createRootElement() {
const document = TestBed.inject(DOCUMENT);
const root = _getDOM().createElement('app-root', document);
document.body.appendChild(root);
}
function removeRootElement() {
const root = document.getElementsByTagName('app-root').item(0);
try {
document.body.removeChild(root);
}
catch { }
}
function destroyPlatformBeforeBootstrappingTheNewOne(freshUrl) {
destroyPlatform();
resetLocationToUrl(freshUrl);
createRootElement();
}
// As we create our custom platform via `bootstrapModule`
// we have to destroy it after assetions and revert
// the previous one
function resetPlatformAfterBootstrapping() {
removeRootElement();
destroyPlatform();
const version = +VERSION.major;
// https://github.com/angular/angular/commit/e250db4f261741b04ee4cbad4dec41a8908a12aa
if (version < 14) {
createPlatform(TestBed.inject(Injector));
}
}
function resetLocationToUrl(freshUrl) {
window.history.replaceState({}, 'Test', freshUrl);
}
function freshPlatform(fn) {
let resolve = null;
let reject = null;
let whenDoneIsCalledPromise = null;
const hasDoneArgument = fn.length === 1;
if (hasDoneArgument) {
whenDoneIsCalledPromise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
});
}
return async function testWithAFreshPlatform() {
try {
const freshUrl = '/';
destroyPlatformBeforeBootstrappingTheNewOne(freshUrl);
if (hasDoneArgument) {
await fn((error) => {
if (error) {
reject(error);
}
else {
resolve();
}
});
await whenDoneIsCalledPromise;
}
else {
await fn();
}
}
finally {
resetPlatformAfterBootstrapping();
}
};
}
class NgxsTestComponent {
ngOnInit() { }
ngAfterViewInit() { }
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: NgxsTestComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
/** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.3", type: NgxsTestComponent, isStandalone: true, selector: "app-root", ngImport: i0, template: '', isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: NgxsTestComponent, decorators: [{
type: Component,
args: [{
selector: 'app-root',
template: ''
}]
}] });
class NgxsTestModule {
static ngDoBootstrap(app) {
app.bootstrap(NgxsTestComponent);
}
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: NgxsTestModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.3", ngImport: i0, type: NgxsTestModule, imports: [BrowserModule, NgxsTestComponent] });
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: NgxsTestModule, imports: [BrowserModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: NgxsTestModule, decorators: [{
type: NgModule,
args: [{
imports: [BrowserModule, NgxsTestComponent]
}]
}] });
function loggedError(message) {
return ['error', [expect.objectContaining({ message })]];
}
function skipConsoleLogging(fn, consoleRecorder = []) {
const consoleSpies = [
jest.spyOn(console, 'log').mockImplementation((...args) => {
consoleRecorder.push(['log', args]);
}),
jest.spyOn(console, 'warn').mockImplementation((...args) => {
consoleRecorder.push(['warn', args]);
}),
jest.spyOn(console, 'error').mockImplementation((...args) => {
consoleRecorder.push(['error', args]);
}),
jest.spyOn(console, 'info').mockImplementation((...args) => {
consoleRecorder.push(['info', args]);
})
];
function restoreSpies() {
consoleSpies.forEach(spy => spy.mockRestore());
}
let restoreSpyAsync = false;
try {
const returnValue = fn();
if (returnValue instanceof Promise) {
restoreSpyAsync = true;
return returnValue.finally(() => restoreSpies());
}
return returnValue;
}
finally {
if (!restoreSpyAsync) {
restoreSpies();
}
}
}
class NgxsTestBed {
static configureTestingStates(options) {
this.resetTestBed();
if (options.before) {
options.before();
}
skipConsoleLogging(() => TestBed.configureTestingModule({
imports: [
NgxsTestModule,
NgxsModule.forRoot(options.states || [], options.ngxsOptions || {}),
...(options.imports || [])
]
}).compileComponents());
NgxsTestBed.ngxsBootstrap();
return {
get store() {
return TestBed.inject(Store);
},
get getTestBed() {
return TestBed;
}
};
}
static ngxsBootstrap() {
NgxsTestBed.createRootNode();
NgxsTestModule.ngDoBootstrap(TestBed.inject(ApplicationRef));
}
static resetTestBed() {
TestBed.resetTestEnvironment();
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {
teardown: { destroyAfterEach: true }
});
}
static createRootNode(selector = 'app-root') {
const document = TestBed.inject(DOCUMENT);
const adapter = new _BrowserDomAdapter();
const root = adapter.createElement(selector);
document.body.appendChild(root);
}
}
class NgxsActionCollector {
/**
* Including this in your providers will
* set up the the action collector to start collecting actions
* from before NGXS initializes
* @example
* // In your providers declaration for your tests:
* {
* providers: [
* NgxsActionCollector.collectActions(),
* provideStore([MyState]),
* ],
* // ...
* }
* // and then in your test:
* const actionCollector = TestBed.inject(NgxsActionCollector);
* const actionsDispatched = actionCollector.dispatched;
* const action = actionsDispatched.find(
* (item) => item instanceof MyAction
* );
* expect(action).toBeDefined();
* @returns An environment initializer that starts the collector immediately
*/
static collectActions() {
return provideEnvironmentInitializer(() => {
inject(NgxsActionCollector).start();
});
}
_destroyed$ = new ReplaySubject(1);
_stopped$ = new Subject();
_started = false;
dispatched = [];
completed = [];
successful = [];
errored = [];
cancelled = [];
_actions$ = inject(Actions);
constructor() {
inject(DestroyRef).onDestroy(() => this._destroyed$.next());
}
start() {
if (this._started) {
return;
}
this._started = true;
this._actions$.pipe(takeUntil(this._destroyed$), takeUntil(this._stopped$)).subscribe({
next: (ctx) => {
switch (ctx?.status) {
case ActionStatus.Dispatched:
this.dispatched.push(ctx.action);
break;
case ActionStatus.Successful:
this.successful.push(ctx.action);
this.completed.push(ctx.action);
break;
case ActionStatus.Errored:
this.errored.push(ctx.action);
this.completed.push(ctx.action);
break;
case ActionStatus.Canceled:
this.cancelled.push(ctx.action);
this.completed.push(ctx.action);
break;
default:
break;
}
},
complete: () => {
this._started = false;
},
error: () => {
this._started = false;
}
});
}
reset() {
function clearArray(array) {
array.splice(0, array.length);
}
clearArray(this.dispatched);
clearArray(this.completed);
clearArray(this.successful);
clearArray(this.errored);
clearArray(this.cancelled);
}
stop() {
this._stopped$.next();
}
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: NgxsActionCollector, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: NgxsActionCollector, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: NgxsActionCollector, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [] });
/**
* Generated bundle index. Do not edit.
*/
export { NgxsActionCollector, NgxsTestBed, freshPlatform, loggedError, skipConsoleLogging };
//# sourceMappingURL=ngxs-store-internals-testing.mjs.map