UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

239 lines (229 loc) 10.3 kB
import { Directionality } from '@angular/cdk/bidi'; import * as i0 from '@angular/core'; import { signal, makeEnvironmentProviders, NgZone, EventEmitter, Injectable } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { Subject } from 'rxjs'; /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ class MockDirectionality { value = 'ltr'; change = new Subject(); valueSignal = signal('ltr', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "valueSignal" }] : /* istanbul ignore next */ [])); } function provideMockDirectionality() { return makeEnvironmentProviders([{ provide: Directionality, useClass: MockDirectionality }]); } /** * Creates a `describe('RTL', ...)` block that verifies the component correctly toggles * an RTL CSS class when `Directionality.valueSignal` changes between 'ltr' and 'rtl'. * * Must be called at the top level of a spec file (outside any `describe` that has its own * `beforeEach` configuring TestBed), because it configures its own TestBed internally. * * @param componentFn Thunk returning the component class. Using a thunk avoids class hoisting * issues — class declarations defined below the call site would be `undefined` at registration time. * @param predicate A `By.directive(...)` or `By.css(...)` predicate to locate the element * that carries the RTL class. Use `By.css` when the RTL class is on a child element rather * than the component host. * @param classnamePrefix The class prefix (e.g. `'ant-alert'`). The test asserts the presence * of `${classnamePrefix}-rtl`. * @param options.detectChangesFn Custom change detection callback for components that need * imperative updates beyond `fixture.detectChanges()` (e.g. calling a private method). * @param options.providers Additional providers needed by the component (e.g. `provideNzIconsTesting()`). */ function testDirectionality(componentFn, predicate, classnamePrefix, options) { const rtlClass = `${classnamePrefix}-rtl`; describe('RTL', () => { let fixture; let dir; function detectChanges() { if (options?.detectChangesFn) { options.detectChangesFn(fixture); } else { fixture.detectChanges(); } } beforeEach(() => { TestBed.configureTestingModule({ providers: [provideMockDirectionality(), ...(options?.providers || [])] }); dir = TestBed.inject(Directionality); fixture = TestBed.createComponent(componentFn()); }); it('should className correct on dir change', async () => { detectChanges(); fixture.autoDetectChanges(); await fixture.whenStable(); const debugElement = fixture.debugElement.query(predicate); expect(debugElement).toBeTruthy(); expect(debugElement.nativeElement.classList.contains(rtlClass)).toBe(false); dir.valueSignal.set('rtl'); detectChanges(); await fixture.whenStable(); expect(debugElement.nativeElement.classList.contains(rtlClass)).toBe(true); dir.valueSignal.set('ltr'); detectChanges(); await fixture.whenStable(); expect(debugElement.nativeElement.classList.contains(rtlClass)).toBe(false); }); }); } /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ /** Creates a browser MouseEvent with the specified options. */ function createMouseEvent(type, x = 0, y = 0, button = 0) { const event = document.createEvent('MouseEvent'); event.initMouseEvent(type, true /* canBubble */, false /* cancelable */, window /* view */, 0 /* detail */, x /* screenX */, y /* screenY */, x /* clientX */, y /* clientY */, false /* ctrlKey */, false /* altKey */, false /* shiftKey */, false /* metaKey */, button /* button */, null /* relatedTarget */); // `initMouseEvent` doesn't allow us to pass the `buttons` and // defaults it to 0 which looks like a fake event. Object.defineProperty(event, 'buttons', { get: () => 1 }); return event; } /** Creates a browser TouchEvent with the specified pointer coordinates. */ function createTouchEvent(type, pageX = 0, pageY = 0) { // 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. const event = new UIEvent(type, { detail: 0, view: window }); const touchDetails = { pageX, pageY, clientX: pageX, clientY: pageY }; // 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] }, targetTouches: { value: [touchDetails] }, changedTouches: { value: [touchDetails] } }); return event; } /** Dispatches a keydown event from an element. */ function createKeyboardEvent(type, keyCode, target, key, ctrlKey, metaKey, shiftKey) { const event = document.createEvent('KeyboardEvent'); // Firefox does not support `initKeyboardEvent`, but supports `initKeyEvent`. if (event.initKeyEvent) { event.initKeyEvent(type, true, true, window, 0, 0, 0, 0, 0, keyCode); } else { event.initKeyboardEvent(type, true, true, window, 0, key, 0, '', false); } // 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, { keyCode: { get: () => keyCode }, key: { get: () => key }, target: { get: () => target }, ctrlKey: { get: () => ctrlKey }, metaKey: { get: () => metaKey }, shiftKey: { get: () => shiftKey } }); return event; } /** Creates a fake event object with any desired event type. */ function createFakeEvent(type, canBubble = true, cancelable = true) { const event = document.createEvent('Event'); event.initEvent(type, canBubble, cancelable); return event; } /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ /** Utility to dispatch any event on a Node. */ function dispatchEvent(node, event) { node.dispatchEvent(event); return event; } /** Shorthand to dispatch a fake event on a specified node. */ function dispatchFakeEvent(node, type, canBubble) { return dispatchEvent(node, createFakeEvent(type, canBubble)); } /** Shorthand to dispatch a keyboard event with a specified key code. */ function dispatchKeyboardEvent(node, type, keyCode, target) { return dispatchEvent(node, createKeyboardEvent(type, keyCode, target)); } /** Shorthand to dispatch a mouse event on the specified coordinates. */ function dispatchMouseEvent(node, type, x = 0, y = 0, event = createMouseEvent(type, x, y)) { return dispatchEvent(node, event); } /** Shorthand to dispatch a touch event on the specified coordinates. */ function dispatchTouchEvent(node, type, x = 0, y = 0) { return dispatchEvent(node, createTouchEvent(type, x, y)); } /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ /** * Mock synchronous NgZone implementation that can be used * to flush out `onStable` subscriptions in tests. * * via: https://github.com/angular/angular/blob/master/packages/core/testing/src/ng_zone_mock.ts * * @docs-private */ class MockNgZone extends NgZone { onStable = new EventEmitter(false); constructor() { super({ enableLongStackTrace: false }); } run(fn) { return fn(); } runOutsideAngular(fn) { return fn(); } simulateZoneExit() { this.onStable.emit(null); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MockNgZone, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MockNgZone }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MockNgZone, decorators: [{ type: Injectable }], ctorParameters: () => [] }); /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ /** * Focuses an input, sets its 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. */ function typeInElement(value, element) { element.focus(); element.value = value; dispatchFakeEvent(element, 'input'); } /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function nextAnimationFrame() { return sleep(16); } async function updateNonSignalsInput(fixture, ms) { fixture.changeDetectorRef.markForCheck(); if (typeof ms === 'number') { await sleep(ms); } await fixture.whenStable(); } /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ /** * Generated bundle index. Do not edit. */ export { MockNgZone, createFakeEvent, createKeyboardEvent, createMouseEvent, createTouchEvent, dispatchEvent, dispatchFakeEvent, dispatchKeyboardEvent, dispatchMouseEvent, dispatchTouchEvent, nextAnimationFrame, provideMockDirectionality, sleep, testDirectionality, typeInElement, updateNonSignalsInput }; //# sourceMappingURL=ng-zorro-antd-core-testing.mjs.map