shallow-render
Version:
Shallow rendering test utility for Angular
369 lines • 15.1 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Shallow = void 0;
const common_1 = require("@angular/common");
const forms_1 = require("@angular/forms");
const platform_browser_1 = require("@angular/platform-browser");
const renderer_1 = require("./models/renderer");
const test_setup_1 = require("./models/test-setup");
require("./test-frameworks/shallow-matchers");
const mock_statics_1 = require("./tools/mock-statics");
const create_service_1 = require("./tools/create-service");
const clear_angular_cache_1 = require("./tools/clear-angular-cache");
/**
* Test setup wrapper. This class tracks all the test module configurations including
* mocks and providers. When the test setup is complete, you can render with the `render` method.
*/
class Shallow {
/**
* Instruct *all* shallow-render tests to prevent mocking of a particular:
* * Service
* * Directive
* * Component
* * Module
* * InjectionToken
* * PipeTransform
*
* NOTE: Designed to be used in a global test setup
* If you wish to avoid mocking for a specific test (or test file) @see Shallow#dontMock
*/
static neverMock(...things) {
this._neverMock.push(...things);
return Shallow;
}
/**
* Instruct *all* shallow-render tests to always add providers to the test module.
* This is useful to mimic the
* Module.forRoot() pattern where dynamic injectables are provided at the app
* root level. You can `alwaysProvide` root-only injectables to all your specs
* with this method.
*
* NOTE: Designed to be used in a global test setup
* If you wish to add a provider for a specific test (or test file) @see Shallow#provide
*
* https://getsaf.github.io/shallow-render/#global-providers-with-alwaysprovide
*/
static alwaysProvide(...providers) {
this._alwaysProvide.push(...providers);
return Shallow;
}
/**
* Instruct *all* shallow-render tests to always mock an injectable in a particular way.
*
* NOTE: Designed to be used in a global test setup
* If you wish to add a provider for a specific test (or test file) @see Shallow#mock
*
*
* @example
* Shallow.alwaysMock(MyService, {fetchItems: () => Promise.resolve(['one', 'two', 'three'])});
*
* @link https://getsaf.github.io/shallow-render/#global-mocks-with-alwaysmock
*/
static alwaysMock(thing, stubs) {
const mock = Shallow._alwaysMock.get(thing) || {};
this._alwaysMock.set(thing, Object.assign(Object.assign({}, mock), stubs));
return Shallow;
}
/**
* Instruct *all* shallow-render tests to always mock pipes.
*
* NOTE: Designed to be used in a global test setup
* If you wish to mock a pipe for a specific test (or test file) @see Shallow#mockPipe
*
* @link https://getsaf.github.io/shallow-render/#mocking-pipes-with-mockpipe
*/
static alwaysMockPipe(pipe, transform) {
this._alwaysMockPipes.set(pipe, transform);
return this;
}
/**
* Instruct *all* shallow-render tests to replace references to one module with another module.
*
* This can be useful to automatically inject "test" modules in your tests.
*
* @example
* Shallow.alwaysReplaceModule(HTTPClientModule, HTTPClientTestingModule);
*
* NOTE: Designed to be used in a global test setup
* If you wish to replace modules for a specific test (or test file) @see Shallow#replaceModule
*
* @link https://getsaf.github.io/shallow-render/#replace-a-module-with-a-test-module
*/
static alwaysReplaceModule(originalModule, replacementModule) {
this._alwaysReplaceModule.set(originalModule, replacementModule);
return Shallow;
}
/**
* Instruct *all* shallow-render tests to import a given `AngularModule`.
*
* NOTE: Designed to be used in a global test setup
* If you wish to import modules for a specific test (or test file) @see Shallow#import
*/
static alwaysImport(...imports) {
this._alwaysImport.push(...imports);
return Shallow;
}
/**
* Instruct *all* shallow-render tests to always render templates associated with
* mocked structural directives. The default behavior is not to render structural directives
* until the user specifically enables the directive in their test.
*
* @see Shallow.alwaysWithStructuralDirective
* @see Rendering#renderStructuralDirective
*
* NOTE: Designed to be used in a global test setup
* If you wish to control structural directives manually in a specific test (or test file) @see Rendering#renderStructuralDirective
*
* @link https://getsaf.github.io/shallow-render/#structural-directives
*/
static alwaysRenderStructuralDirectives() {
this._alwaysRenderStructuralDirectives = true;
return Shallow;
}
/**
* Instruct *all* shallow-render tests to enforce the default render state of a given directive.
*
* This can be useful when you have certain structural directives that are commonly desired to be
* have their contents rendered in your tests.
*
* --or--
*
* If you want to render all structural directives by default but toggle certain ones off.
*
* @see Shallow.alwaysRenderStructuralDirectives
* @see Rendering#renderStructuralDirective
*
* NOTE: Designed to be used in a global test setup
* If you wish to control structural directives manually in a specific test (or test file) @see Rendering#renderStructuralDirective
*
* @link https://getsaf.github.io/shallow-render/#structural-directives
*/
static alwaysWithStructuralDirective(directive, renderContents = true) {
this._alwaysWithStructuralDirectives.set(directive, renderContents);
return Shallow;
}
constructor(testComponentOrService, testModule) {
this.setup = new test_setup_1.TestSetup(testComponentOrService, testModule);
this.setup.dontMock.push(...Shallow._neverMock);
this.setup.providers.unshift(...Shallow._alwaysProvide);
this.setup.imports.push(...Shallow._alwaysImport);
this.setup.alwaysRenderStructuralDirectives = Shallow._alwaysRenderStructuralDirectives;
Shallow._alwaysMock.forEach((value, key) => this.setup.mocks.set(key, value));
Shallow._alwaysMockPipes.forEach((value, key) => this.setup.mockPipes.set(key, value));
Shallow._alwaysReplaceModule.forEach((value, key) => this.setup.moduleReplacements.set(key, value));
Shallow._alwaysWithStructuralDirectives.forEach((value, key) => this.setup.withStructuralDirectives.set(key, value));
}
/**
* Enforce the default render state of a given directive's contents.
*
* Note: If you wish to control structural directives globally @see Shallow.alwaysWithStructuralDirective
*
* @link https://getsaf.github.io/shallow-render/#structural-directives
*/
withStructuralDirective(directive, renderContents = true) {
this.setup.withStructuralDirectives.set(directive, renderContents);
return this;
}
/**
* Adds a component/directive to the test module's `declarations` array.
*
* NOTE: Generally speaking, your declarations should be supplied in your modules. Use of this function
* should be taken with caution because it can mask issues with missing declarations in your modules.
*/
declare(...declarations) {
this.setup.declarations.push(...declarations);
return this;
}
/**
* Adds a provider to the test module's `providers` array.
*
* Can be useful to supply Singleton services (aka: services that are `providedIn: 'root'`).
*
* Providers can match any structure allowed Angular's module system
*
* @example
* shallow.pro({ provide: MyService, useClass: MyMockService });
*
* @link https://getsaf.github.io/shallow-render/#use-a-manual-mock-instance-or-class
*/
provide(...providers) {
this.setup.providers.unshift(...providers);
return this;
}
/**
* Adds a pre-defined and pre-mocked provider to the test module. Useful when you have
* a test-double service that you wish to use instead of a given service:
*
* Providers can match any structure allowed Angular's module system
*
* @example
* shallow.provideMock({ provide: MyService, useClass: MyMockService });
*
* @link https://getsaf.github.io/shallow-render/#use-a-manual-mock-instance-or-class
*/
provideMock(...providers) {
this.setup.providers.unshift(...providers);
this.setup.dontMock.push(...providers);
return this;
}
/**
* Instructs shallow to avoid mocking a particular injectable in a test.
*
* This can be any of the following types:
* * Service
* * Directive
* * Component
* * Module
* * InjectionToken
* * PipeTransform
*
* @example
* // While testing a ListComponent, you may want to use the *real* child component too
* shallow.dontMock(ListItemComponent)
*
* @link https://getsaf.github.io/shallow-render/#skip-mocking-with-dontmock
*/
dontMock(...things) {
this.setup.dontMock.push(...things);
return this;
}
/**
* Provides mock functions and properties to your test module for a given injectable.
*
* @example
* shallow.mock(MyService, {fetchItems: () => Promise.resolve(['one', 'two', 'three'])});
*
* @link https://getsaf.github.io/shallow-render/#mocking
*/
mock(thingToMock, stubs) {
const mock = this.setup.mocks.get(thingToMock);
if (typeof mock === 'object') {
this.setup.mocks.set(thingToMock, Object.assign(Object.assign({}, mock), stubs));
}
else {
this.setup.mocks.set(thingToMock, stubs);
}
return this;
}
/**
* Allows mocking static properties (or properties of plain JS objects) in your test.
*
* Note: These mocks are reset after your test completes so there is no data-bleed between tests.
*
* @example
* shallow.mockStatic(STATIC_STATUS_CONFIG, {customStatus: 'Mock Status Value Here'});
*
* @link https://getsaf.github.io/shallow-render/#static-function-mocks
*/
mockStatic(obj, stubs) {
mock_statics_1.InvalidStaticPropertyMockError.checkMockForStaticProperties(stubs);
const mock = this.setup.staticMocks.get(obj) || {};
this.setup.staticMocks.set(obj, Object.assign(Object.assign({}, mock), stubs));
return this;
}
/**
* Mocks a pipe to transform in a specific way for your test.
*
* By default, all pipes are mocked to simply return the same value that was input as their output
*
* @example
* // Fake the translate pipe to do simple text reversal
* shallow.mockPipe(TranslatePipe, input => input.split('').reverse().join(''));
*
* @link https://getsaf.github.io/shallow-render/#mocking-pipes-with-mockpipe
*/
mockPipe(pipe, transform) {
this.setup.mockPipes.set(pipe, transform);
return this;
}
/**
* Replace any reference to a module with a different module
*
* This can be useful to automatically inject "test" modules in your tests.
*
* NOTE: If you wish to replace modules globally @see Shallow.alwaysReplaceModule
*
* @example
* shallow.replaceModule(HTTPClientModule, HTTPClientTestingModule);
*
* @link https://getsaf.github.io/shallow-render/#replace-a-module-with-a-test-module
*/
replaceModule(originalModule, replacementModule) {
this.setup.moduleReplacements.set(originalModule, replacementModule);
return this;
}
/**
* Adds imports to the TestModule
*
* Note: If you wish to import modules globally @see Shallow#import
*/
import(...imports) {
this.setup.imports.push(...imports);
return this;
}
render(htmlOrRenderOptions, renderOptions) {
return __awaiter(this, void 0, void 0, function* () {
const renderer = new renderer_1.Renderer(this.setup);
if (typeof htmlOrRenderOptions === 'string') {
return renderer.render(htmlOrRenderOptions, renderOptions);
}
else if (htmlOrRenderOptions !== undefined) {
return renderer.render(htmlOrRenderOptions);
}
else {
return renderer.render();
}
});
}
/**
* Creates an instance of a service for testing.
*
* Services can be tested in a similar manner as components.
*
* @example
* const shallow = new Shallow(MyService, MyModule).mock(DependentService, {get: () => 'mocked!'})
* const {instance} = shallow.createService;
*
* @link https://getsaf.github.io/shallow-render/#testing-services
*/
createService() {
return (0, create_service_1.createService)(this.setup);
}
}
exports.Shallow = Shallow;
/**
* When `true`, Angular DepsTracker cache will be reset after
* each test.
*
* Defaults to `false` for `jest` runners.
*/
Shallow.autoResetAngularCache = typeof jest === 'undefined';
Shallow._neverMock = [];
Shallow._alwaysProvide = [];
Shallow._alwaysMock = new Map();
// eslint-disable-next-line @typescript-eslint/ban-types
Shallow._alwaysMockPipes = new Map();
Shallow._alwaysReplaceModule = new Map();
Shallow._alwaysImport = [];
Shallow._alwaysRenderStructuralDirectives = false;
Shallow._alwaysWithStructuralDirectives = new Map();
Shallow.neverMock(common_1.CommonModule, platform_browser_1.BrowserModule, forms_1.FormsModule, forms_1.ReactiveFormsModule, platform_browser_1.HAMMER_GESTURE_CONFIG);
if (typeof jest === 'undefined') {
// Karma runs in one browser instance which can result in a buildup
// of mock test modules in the DepsTracker cache over the entire run.
afterEach(() => {
if (Shallow.autoResetAngularCache) {
(0, clear_angular_cache_1.clearAngularCache)();
}
});
}
//# sourceMappingURL=shallow.js.map