UNPKG

@terminus/ngx-tools

Version:

[![CircleCI][circle-badge]][circle-link] [![codecov][codecov-badge]][codecov-project] [![semantic-release][semantic-release-badge]][semantic-release] [![MIT License][license-image]][license-url] <br> [![NPM version][npm-version-image]][npm-url] [![Github

488 lines (464 loc) 16.5 kB
import { __decorate, __assign, __awaiter, __generator, __spread } from 'tslib'; import { Injectable } from '@angular/core'; import { noop } from '@terminus/ngx-tools/utilities'; import { TestBed, async } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; /** * A mock of the Angular ChangeDetectorRefMock class */ var ChangeDetectorRefMock = /** @class */ (function () { function ChangeDetectorRefMock() { this.markForCheck = noop; this.detach = noop; this.detectChanges = noop; this.checkNoChanges = noop; this.reattach = noop; } ChangeDetectorRefMock = __decorate([ Injectable() ], ChangeDetectorRefMock); return ChangeDetectorRefMock; }()); /** * Default stubbed items for `nativeElement` */ var defaults = { innerText: 'foo', style: {}, classList: { add: noop, remove: noop, }, }; /** * A mock of the Angular ElementRef class */ var ElementRefMock = /** @class */ (function () { function ElementRefMock(nativeElementAdditions) { this.nativeElement = __assign(__assign({}, defaults), nativeElementAdditions || {}); } return ElementRefMock; }()); /** * A mock of the Angular Renderer */ var rendererMock = { setElementStyle: noop, setElementClass: noop, selectRootElement: noop, createElement: noop, createViewRoot: noop, createText: noop, setElementProperty: noop, setElementAttribute: noop, setText: noop, setBindingDebugInfo: noop, createTemplateAnchor: noop, projectNodes: noop, attachViewAfter: noop, detachView: noop, destroyView: noop, listen: noop, listenGlobal: noop, invokeElementMethod: noop, animate: noop, }; /** * A mock of the Angular Renderer2 */ var Renderer2Mock = /** @class */ (function () { function Renderer2Mock() { } Renderer2Mock.prototype.addClass = function () { }; Renderer2Mock.prototype.appendChild = function () { }; Renderer2Mock.prototype.createComment = function () { }; Object.defineProperty(Renderer2Mock.prototype, "data", { get: function () { return this._data; }, set: function (v) { this._data = v; }, enumerable: true, configurable: true }); Renderer2Mock.prototype.destroy = function () { }; Renderer2Mock.prototype.destroyNode = function () { }; Renderer2Mock.prototype.insertBefore = function () { }; Renderer2Mock.prototype.nextSibling = function () { }; Renderer2Mock.prototype.parentNode = function () { }; Renderer2Mock.prototype.removeAttribute = function () { }; Renderer2Mock.prototype.removeChild = function () { }; Renderer2Mock.prototype.removeClass = function () { }; Renderer2Mock.prototype.removeStyle = function () { }; Renderer2Mock.prototype.setAttribute = function () { }; Renderer2Mock.prototype.setProperty = function () { }; Renderer2Mock.prototype.setStyle = function () { }; Renderer2Mock.prototype.setValue = function () { }; Renderer2Mock.prototype.animate = function () { }; Renderer2Mock.prototype.attachViewAfter = function () { }; Renderer2Mock.prototype.createElement = function () { }; Renderer2Mock.prototype.createTemplateAnchor = function () { }; Renderer2Mock.prototype.createText = function () { }; Renderer2Mock.prototype.createViewRoot = function () { }; Renderer2Mock.prototype.destroyView = function () { }; Renderer2Mock.prototype.detachView = function () { }; Renderer2Mock.prototype.invokeElementMethod = function () { }; Renderer2Mock.prototype.listen = function () { return noop; }; Renderer2Mock.prototype.listenGlobal = function () { return noop; }; Renderer2Mock.prototype.projectNodes = function () { }; Renderer2Mock.prototype.selectRootElement = function () { }; Renderer2Mock.prototype.setBindingDebugInfo = function () { }; Renderer2Mock.prototype.setElementAttribute = function () { }; Renderer2Mock.prototype.setElementClass = function () { }; Renderer2Mock.prototype.setElementProperty = function () { }; Renderer2Mock.prototype.setElementStyle = function () { }; Renderer2Mock.prototype.setText = function () { }; return Renderer2Mock; }()); /** * Create an instance of the TestBed and compile components * * @param configureFn - The configuration function for the TestBed * @param compilerOptions * @returns A promise-wrapped TestBed instance */ function configureTestBedWhitespace(configureFn, compilerOptions) { if (compilerOptions === void 0) { compilerOptions = {}; } var compilerConfig = __assign({ preserveWhitespaces: false }, compilerOptions); var configuredTestBed = TestBed.configureCompiler(compilerConfig); configureFn(configuredTestBed); return configuredTestBed.compileComponents().then(function () { return configuredTestBed; }); } /** * Set up the TestBed without resetting the TestBed for every test * * https://github.com/angular/angular/issues/12409 * * @param moduleDef - The module definition */ function configureTestBedWithoutReset(moduleDef) { var resetTestingModule = TestBed.resetTestingModule; var preventAngularFromResetting = function () { TestBed.resetTestingModule = function () { return TestBed; }; return TestBed.resetTestingModule; }; var allowAngularToReset = function () { TestBed.resetTestingModule = resetTestingModule; return TestBed.resetTestingModule; }; // eslint-disable-next-line no-undef beforeAll(async(function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: resetTestingModule(); preventAngularFromResetting(); TestBed.configureTestingModule(moduleDef); return [4 /*yield*/, TestBed.compileComponents()]; case 1: _a.sent(); return [2 /*return*/]; } }); }); })); // eslint-disable-next-line no-undef afterAll(function () { return allowAngularToReset(); }); } /** * Create a TestBed fixture with a single component registered * * @param component - The test component * @param providers - Any providers to register to the test module * @param imports - Any items to import to the test module * @returns The test fixture * * @example * const myComponent = createComponent(MyComponent); * const myComponent = createComponent(MyComponent, MyProviders, MyImports); */ function createComponent(component, providers, // eslint-disable-next-line @typescript-eslint/no-explicit-any imports) { if (providers === void 0) { providers = []; } if (imports === void 0) { imports = []; } TestBed.configureTestingModule({ imports: __spread(imports), declarations: [component], providers: __spread(providers), }).compileComponents(); return TestBed.createComponent(component); } /** * Creates a fake event object with any desired event type. * * @param type - The event type * @param canBubble - Define if the event can bubble up the DOM * @param cancelable * @returns The event * * @example * createFakeEvent('focus'); * createFakeEvent('focus', false, false); */ function createFakeEvent(type, canBubble, cancelable) { if (canBubble === void 0) { canBubble = true; } if (cancelable === void 0) { cancelable = true; } var event = document.createEvent('Event'); event.initEvent(type, canBubble, cancelable); return event; } /** * Dispatches a keydown event from an element. * * @param type - The event type * @param key - The KeyCode type * @param target - The target element * @returns The event * * @example * createKeyboardEvent('keydown', ENTER, myInputNativeElement); */ function createKeyboardEvent(type, key, target) { // NOTE: Cannot 'type' the event here due to the note about FireFox below // eslint-disable-next-line @typescript-eslint/no-explicit-any var event = document.createEvent('KeyboardEvent'); event.initEvent(type, true, false); var originalPreventDefault = event.preventDefault; // NOTE: Webkit Browsers don't set the keyCode when calling the init function. // See related bug https://bugs.webkit.org/show_bug.cgi?id=16735 Object.defineProperties(event, { code: { get: function () { return key.code; } }, key: { get: function () { return key.code; } }, keyCode: { get: function () { return key.keyCode; } }, target: { get: function () { return target; } }, }); // NOTE: IE won't set `defaultPrevented` on synthetic events so we need to do it manually. event.preventDefault = function () { Object.defineProperty(event, 'defaultPrevented', { get: function () { return true; } }); // FIXME: Not sure why this `as any` is needed now // eslint-disable-next-line @typescript-eslint/no-explicit-any return originalPreventDefault.apply(this, arguments); }; return event; } /** * Create a browser MouseEvent with the specified options * * @param type - The event type * @param x - The location on the X axis * @param y - The location on the Y axis * @returns The event * * @example * createMouseEvent('click'); * createMouseEvent('click', 212, 433); */ function createMouseEvent(type, x, y) { if (x === void 0) { x = 0; } if (y === void 0) { y = 0; } var event = document.createEvent('MouseEvent'); /* eslint-disable line-comment-position */ event.initMouseEvent(type, false, // canBubble false, // cancelable window, // view 0, // detail x, // screenX y, // screenY x, // clientX y, // clientY false, // ctrlKey false, // altKey false, // shiftKey false, // metaKey 0, // button null); /* eslint-enable line-comment-position */ return event; } /** * Creates a browser TouchEvent with the specified pointer coordinates. * * @param type - The touch event type * @param pageX - The location on the X axis * @param pageY - The location on the Y axis * * @example * createTouchEvent('touchstart'); * createTouchEvent('touchstart', 212, 433); */ function createTouchEvent(type, pageX, pageY) { if (pageX === void 0) { pageX = 0; } if (pageY === void 0) { pageY = 0; } // NOTE: In favor of creating events that work for most of the browsers, the event is created // as a basic UI Event. The necessary details for the event will be set manually. var event = document.createEvent('UIEvent'); var touchDetails = { pageX: pageX, pageY: pageY, }; event.initEvent(type, true, true); // NOTE: Most of the browsers don't have a "initTouchEvent" method that can be used to define the touch details. Object.defineProperties(event, { touches: { value: [touchDetails] } }); return event; } /** * Utility to dispatch any event on a Node. * * @param node - The Node that should dispatch the event * @param event - The event to be dispatched * @returns The dispatched event * * @example * dispatchEvent(myNativeElement, 'blur'); */ function dispatchEvent(node, event) { node.dispatchEvent(event); return event; } /** * Shorthand to dispatch a fake event on a specified node. * * @param node - The Node that should dispatch the fake event * @param type - The event type * @param canBubble - Define if the event can bubble up the DOM * @returns The event * * @example * dispatchFakeEvent(myNativeElement, 'mousedown'); * dispatchFakeEvent(myNativeElement, 'mousedown', true); */ var dispatchFakeEvent = function (node, type, canBubble) { return dispatchEvent(node, createFakeEvent(type, canBubble)); }; /** * Shorthand to dispatch a keyboard event with a specified key code * * @param node - The Node that should dispatch the keyboard event * @param type - The event type * @param key - The KeycodesConst type (contains code and keyCode) * @param target - The target event element * @returns The keyboard event * * @example * dispatchKeyboardEvent(myNativeElement, 'keyup', ENTER); * dispatchKeyboardEvent(myNativeElement, 'keyup', ENTER, myTargetElement); */ var dispatchKeyboardEvent = function (node, type, key, target) { return dispatchEvent(node, createKeyboardEvent(type, key, target)); }; /** * Shorthand to dispatch a mouse event on the specified coordinates. * * @param node - The Node that should dispatch the mouse event * @param type - The event type * @param x - The location on the X axis * @param y - The location on the Y axis * @param event - The event * @returns The mouse event * * @example * dispatchMouseEvent(myNativeElement, 'mousedown'); * dispatchMouseEvent(myNativeElement, 'mousedown', 10, 10, myCustomEvent); */ var dispatchMouseEvent = function (node, type, x, y, event) { if (x === void 0) { x = 0; } if (y === void 0) { y = 0; } if (event === void 0) { event = createMouseEvent(type, x, y); } return dispatchEvent(node, event); }; /** * Shorthand to dispatch a touch event on the specified coordinates. * * @param node - The Node that should dispatch the touch event * @param type - The event type * @param x - The location on the X axis * @param y - The location on the Y axis * @returns The touch event * * @example * dispatchTouchEvent(myNativeElement, 'touchstart'); * dispatchTouchEvent(myNativeElement, 'touchstart', 10, 10); */ var dispatchTouchEvent = function (node, type, x, y) { if (x === void 0) { x = 0; } if (y === void 0) { y = 0; } return dispatchEvent(node, createTouchEvent(type, x, y)); }; /** * Reusable expect statement to check for the nativeElement * * NOTE: This helper only accesses the 1st-level child within a component. * * @param fixture - The test fixture * @returns expect statement * * @example * test('My test', () => { * expectNativeEl(myEl); * }); */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function expectNativeEl(fixture) { fixture.detectChanges(); // eslint-disable-next-line no-undef return expect(fixture.debugElement.children[0].nativeElement); } /** * Return a component's instance from within a ComponentFixture * * @param fixture - The component fixture * @param component - The component to find * @returns The instance of the found component * * @example * const myItem = getChildComponentInstanceFromFixture(myFixture, MyComponent); */ function getChildComponentInstanceFromFixture(fixture, component) { var debugElForDumbComponent = fixture.debugElement.query(By.directive(component)); return debugElForDumbComponent.injector.get(component); } /** * Helper to query a fixture for a selector * * @param fixture - The test fixture * @param selector - The selector to query for * @returns The query result * * @example * const myItem = queryFor(myFixture, '.my-class'); */ var queryFor = function (fixture, selector) { return fixture.debugElement.query(By.css(selector)); }; /** * Focuses an input, sets it's value and dispatches the `input` event, simulating the user typing. * * @param value - Value to be set on the input. * @param element - Element onto which to set the value. * * @example * typeInElement('test@test.com', myEmailInputElement); */ function typeInElement(value, element) { element.focus(); element.value = value; dispatchFakeEvent(element, 'input'); } /** * Gets a RegExp used to detect an angular wrapped error message. * * See https://github.com/angular/angular/issues/8348 * * @param e - The error * @returns The regex */ function wrappedErrorMessage(e) { var escapedMessage = e.message.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'); return new RegExp(escapedMessage); } /** * Generated bundle index. Do not edit. */ export { ChangeDetectorRefMock, ElementRefMock, Renderer2Mock, configureTestBedWhitespace, configureTestBedWithoutReset, createComponent, createFakeEvent, createKeyboardEvent, createMouseEvent, createTouchEvent, dispatchEvent, dispatchFakeEvent, dispatchKeyboardEvent, dispatchMouseEvent, dispatchTouchEvent, expectNativeEl, getChildComponentInstanceFromFixture, queryFor, rendererMock, typeInElement, wrappedErrorMessage }; //# sourceMappingURL=terminus-ngx-tools-testing.js.map