Skip to content

Commit

Permalink
feat(#315): ngMocks.trigger and ngMocks.click
Browse files Browse the repository at this point in the history
  • Loading branch information
satanTime committed Mar 27, 2021
1 parent 93d5813 commit b92b7a5
Show file tree
Hide file tree
Showing 12 changed files with 878 additions and 70 deletions.
140 changes: 70 additions & 70 deletions .github/workflows/ci.yaml

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions libs/ng-mocks/src/lib/mock-helper/events/mock-helper.click.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import mockHelperTrigger from './mock-helper.trigger';

export default (selector: any, payload?: object) => {
mockHelperTrigger(selector, 'click', payload);
};
162 changes: 162 additions & 0 deletions libs/ng-mocks/src/lib/mock-helper/events/mock-helper.event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import mockHelperStub from '../mock-helper.stub';

/**
* @see https://developer.mozilla.org/de/docs/Web/Events
*/
const preventBubble = ['focus', 'blur', 'load', 'unload', 'change', 'reset', 'scroll'];

// istanbul ignore next
function customEvent(event: string, params?: EventInit) {
const initParams = {
bubbles: false,
cancelable: false,
...params,
};
const eventObj = document.createEvent('CustomEvent');
eventObj.initCustomEvent(event, initParams.bubbles, initParams.cancelable, null);

return eventObj;
}

const eventCtor =
typeof (Event as any) === 'function'
? (event: string, init?: EventInit): Event => new CustomEvent(event, init)
: /* istanbul ignore next */ customEvent;

const keyMap: Record<string, object> = {
alt: {
altKey: true,
code: 'AltLeft',
key: 'Alt',
location: 1,
which: 18,
},
arrowdown: {
code: 'ArrowDown',
key: 'ArrowDown',
location: 0,
which: 40,
},
arrowleft: {
code: 'ArrowLeft',
key: 'ArrowLeft',
location: 0,
which: 37,
},
arrowright: {
code: 'ArrowRight',
key: 'ArrowRight',
location: 0,
which: 39,
},
arrowup: {
code: 'ArrowUp',
key: 'ArrowUp',
location: 0,
which: 38,
},
backspace: {
code: 'Backspace',
key: 'Backspace',
location: 0,
which: 8,
},
control: {
code: 'ControlLeft',
ctrlKey: true,
key: 'Control',
location: 1,
which: 17,
},
enter: {
code: 'Enter',
key: 'Enter',
location: 0,
which: 13,
},
esc: {
code: 'Escape',
key: 'Escape',
location: 0,
which: 27,
},
meta: {
code: 'MetaLeft',
key: 'Meta',
location: 1,
metaKey: true,
which: 91,
},
shift: {
code: 'ShiftLeft',
key: 'Shift',
location: 1,
shiftKey: true,
which: 16,
},
space: {
code: 'Space',
key: ' ',
location: 0,
which: 32,
},
tab: {
code: 'Tab',
key: 'Tab',
location: 0,
which: 9,
},
};
for (let f = 1; f <= 12; f += 1) {
keyMap[`f${f}`] = {
code: `F${f}`,
key: `F${f}`,
location: 0,
which: f + 111,
};
}

const applyPayload = (event: Event, payload?: string): void => {
const keyData: object = {};
for (const key of payload ? payload.split('.') : []) {
let map = keyMap[key];
if (!map && key.length === 1) {
map = {
code: `Key${key.toUpperCase()}`,
key,
which: key.charCodeAt(0),
};
}

if (!map) {
throw new Error(`Unknown event part ${key}`);
}

mockHelperStub(keyData, map);
}

if (payload) {
mockHelperStub(event, keyData);
}
};

export default (
event: string,
init?: EventInit,
overrides?: Partial<UIEvent | KeyboardEvent | MouseEvent | TouchEvent | Event>,
): Event => {
const dot = event.indexOf('.');
const [eventName, eventPayload] = dot === -1 ? [event] : [event.substr(0, dot), event.substr(dot + 1)];
const eventObj = eventCtor(eventName, {
bubbles: preventBubble.indexOf(event) === -1,
cancelable: true,
...init,
});
applyPayload(eventObj, eventPayload);

if (overrides) {
mockHelperStub(eventObj, overrides);
}

return eventObj;
};
56 changes: 56 additions & 0 deletions libs/ng-mocks/src/lib/mock-helper/events/mock-helper.trigger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { DebugElement } from '@angular/core';

import mockHelperStub from '../mock-helper.stub';

import mockHelperEvent from './mock-helper.event';

/**
* @see https://developer.mozilla.org/de/docs/Web/Events
*/
const preventBubble = ['focus', 'blur', 'load', 'unload', 'change', 'reset', 'scroll'];

const toEventObj = (
event: string | UIEvent | KeyboardEvent | MouseEvent | TouchEvent | Event,
debugElement?: DebugElement | null,
): Event => {
const eventObj =
typeof event === 'string'
? mockHelperEvent(event, {
bubbles: preventBubble.indexOf(event) === -1,
cancelable: true,
})
: event;
if (!eventObj.target && debugElement) {
mockHelperStub(eventObj, {
target: debugElement.nativeElement,
});
}

return eventObj;
};

export default (
debugElement: DebugElement | undefined | null,
eventName: string | UIEvent | KeyboardEvent | MouseEvent | TouchEvent | Event,
payload?: Partial<UIEvent | KeyboardEvent | MouseEvent | TouchEvent | Event>,
) => {
if (!debugElement) {
throw new Error(
`Cannot trigger ${typeof eventName === 'string' ? eventName : eventName.type} event undefined element`,
);
}

// nothing to emit on disabled elements
if (debugElement.nativeElement.disabled) {
return;
}

const callback = (event: Event) => {
if (payload) {
mockHelperStub(event, payload);
}
};
debugElement.nativeElement.addEventListener(eventName, callback, true);
debugElement.nativeElement.dispatchEvent(toEventObj(eventName, debugElement));
debugElement.nativeElement.removeEventListener(eventName, callback, true);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const normalizeValue = (html: string | undefined): string =>
? html
.replace(new RegExp('\\s+', 'mg'), ' ')
.replace(new RegExp('<!--.*?-->', 'mg'), '')
.replace(new RegExp('<!--.*?', 'mg'), '')
.replace(new RegExp('\\s+', 'mg'), ' ')
.replace(new RegExp('>\\s+<', 'mg'), '><')
: '';
Expand Down
6 changes: 6 additions & 0 deletions libs/ng-mocks/src/lib/mock-helper/mock-helper.object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import mockHelperReveal from './crawl/mock-helper.reveal';
import mockHelperRevealAll from './crawl/mock-helper.reveal-all';
import mockHelperChange from './cva/mock-helper.change';
import mockHelperTouch from './cva/mock-helper.touch';
import mockHelperClick from './events/mock-helper.click';
import mockHelperEvent from './events/mock-helper.event';
import mockHelperTrigger from './events/mock-helper.trigger';
import mockHelperFormatHtml from './format/mock-helper.format-html';
import mockHelperFormatText from './format/mock-helper.format-text';
import mockHelperAutoSpy from './mock-helper.auto-spy';
Expand Down Expand Up @@ -34,8 +37,10 @@ import mockHelperFindTemplateRefs from './template-ref/mock-helper.find-template
export default {
autoSpy: mockHelperAutoSpy,
change: mockHelperChange,
click: mockHelperClick,
crawl: mockHelperCrawl,
defaultMock: mockHelperDefaultMock,
event: mockHelperEvent,
faster: mockHelperFaster,
find: mockHelperFind,
findAll: mockHelperFindAll,
Expand Down Expand Up @@ -64,4 +69,5 @@ export default {
stubMember: mockHelperStubMember,
throwOnConsole: mockHelperThrowOnConsole,
touch: mockHelperTouch,
trigger: mockHelperTrigger,
};
28 changes: 28 additions & 0 deletions libs/ng-mocks/src/lib/mock-helper/mock-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ export const ngMocks: {
*/
change(el: DebugNode, value: any): void;

/**
* @see https://ng-mocks.sudo.eu/api/ngMocks/click
*/
click(debugElement: MockedDebugElement | undefined | null, payload?: Partial<MouseEvent>): void;

/**
* @see https://ng-mocks.sudo.eu/api/ngMocks/crawl
*/
Expand Down Expand Up @@ -63,6 +68,15 @@ export const ngMocks: {
*/
defaultMock<T>(def: AnyType<T>, handler?: (value: T, injector: Injector) => void | Partial<T>): void;

/**
* @see https://ng-mocks.sudo.eu/api/ngMocks/event
*/
event(
event: string,
init?: EventInit,
overrides?: Partial<UIEvent | KeyboardEvent | MouseEvent | TouchEvent | Event>,
): Event;

/**
* @see https://ng-mocks.sudo.eu/api/ngMocks/faster
*/
Expand Down Expand Up @@ -492,4 +506,18 @@ export const ngMocks: {
* @see https://ng-mocks.sudo.eu/api/ngMocks/touch
*/
touch(el: DebugNode): void;

/**
* @see https://ng-mocks.sudo.eu/api/ngMocks/trigger
*/
trigger(debugElement: MockedDebugElement | undefined | null, event: Event): void;

/**
* @see https://ng-mocks.sudo.eu/api/ngMocks/trigger
*/
trigger(
debugElement: MockedDebugElement | undefined | null,
event: string,
payload?: Partial<UIEvent | KeyboardEvent | MouseEvent | TouchEvent>,
): void;
} = mockHelperObject;
Loading

0 comments on commit b92b7a5

Please sign in to comment.