Skip to content

Commit

Permalink
feat(mock-doc): dispatch blur and focus events (#3449)
Browse files Browse the repository at this point in the history
for mock-doc, `blur()` and `focus()` methods will now dispatch an
event. created `MockFocusEvent` which extends a new 
`MockUIEvent`, which extends the existing `MockEvent`.
  • Loading branch information
marlon-ionic authored Jul 18, 2022
1 parent bd1b8c2 commit 15520b7
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 4 deletions.
26 changes: 26 additions & 0 deletions src/mock-doc/event.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { MockDocument } from './document';
import { MockElement } from './node';
import { NODE_NAMES } from './constants';
import { MockWindow } from './window';

export class MockEvent {
bubbles = false;
Expand Down Expand Up @@ -113,6 +114,31 @@ export class MockMouseEvent extends MockEvent {
}
}

export class MockUIEvent extends MockEvent {
detail: number | null = null;
view: MockWindow | null = null;

constructor(type: string, uiEventInitDic?: UIEventInit) {
super(type);

if (uiEventInitDic != null) {
Object.assign(this, uiEventInitDic);
}
}
}

export class MockFocusEvent extends MockUIEvent {
relatedTarget: EventTarget | null = null;

constructor(type: 'blur' | 'focus', focusEventInitDic?: FocusEventInit) {
super(type);

if (focusEventInitDic != null) {
Object.assign(this, focusEventInitDic);
}
}
}

export class MockEventListener {
type: string;
handler: (ev?: any) => void;
Expand Down
4 changes: 3 additions & 1 deletion src/mock-doc/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
MockTemplateElement,
MockTitleElement,
} from './element';
import { MockCustomEvent, MockEvent, MockKeyboardEvent, MockMouseEvent } from './event';
import { MockCustomEvent, MockEvent, MockFocusEvent, MockKeyboardEvent, MockMouseEvent } from './event';
import { MockHeaders } from './headers';
import { MockRequest, MockResponse } from './request-response';
import { MockDOMParser } from './parser';
Expand Down Expand Up @@ -148,6 +148,7 @@ const WINDOW_PROPS = [
'HTMLElement',
'Node',
'NodeList',
'FocusEvent',
'KeyboardEvent',
'MouseEvent',
];
Expand All @@ -156,6 +157,7 @@ const GLOBAL_CONSTRUCTORS: [string, any][] = [
['CustomEvent', MockCustomEvent],
['Event', MockEvent],
['Headers', MockHeaders],
['FocusEvent', MockFocusEvent],
['KeyboardEvent', MockKeyboardEvent],
['MouseEvent', MockMouseEvent],
['Request', MockRequest],
Expand Down
21 changes: 18 additions & 3 deletions src/mock-doc/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import { matches, selectAll, selectOne } from './selector';
import { MockAttr, MockAttributeMap, createAttributeProxy } from './attribute';
import { MockClassList } from './class-list';
import { MockCSSStyleDeclaration, createCSSStyleDeclaration } from './css-style-declaration';
import { MockEvent, addEventListener, dispatchEvent, removeEventListener, resetEventListeners } from './event';
import {
MockEvent,
addEventListener,
dispatchEvent,
removeEventListener,
resetEventListeners,
MockFocusEvent,
} from './event';
import { NODE_NAMES, NODE_TYPES } from './constants';
import { NON_ESCAPABLE_CONTENT, SerializeNodeToHtmlOptions, serializeNodeToHtml } from './serialize-node';
import { parseFragmentUtil } from './parse-util';
Expand Down Expand Up @@ -236,7 +243,10 @@ export class MockElement extends MockNode {
}

blur() {
/**/
dispatchEvent(
this,
new MockFocusEvent('blur', { relatedTarget: null, bubbles: true, cancelable: true, composed: true })
);
}

get shadowRoot() {
Expand Down Expand Up @@ -320,7 +330,12 @@ export class MockElement extends MockNode {
return this.children[0] || null;
}

focus(_options?: { preventScroll?: boolean }) {}
focus(_options?: { preventScroll?: boolean }) {
dispatchEvent(
this,
new MockFocusEvent('focus', { relatedTarget: null, bubbles: true, cancelable: true, composed: true })
);
}

getAttribute(attrName: string) {
if (attrName === 'style') {
Expand Down
43 changes: 43 additions & 0 deletions src/mock-doc/test/event.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,49 @@ describe('event', () => {
expect(ev.detail).toBe(88);
});

it('FocusEvent() requires type', () => {
expect(() => {
// @ts-ignore checking that it throws when not supplied required arguments
new win.FocusEvent();
}).toThrow();
});

const focusEventTypes: ('blur' | 'focus')[] = ['blur', 'focus'];
it.each(focusEventTypes)('creates a %s-type MockFocusEvent', (focusType) => {
const ev = new win.FocusEvent(focusType);
expect(ev.bubbles).toBe(false);
expect(ev.cancelBubble).toBe(false);
expect(ev.cancelable).toBe(false);
expect(ev.composed).toBe(false);
expect(ev.currentTarget).toBe(null);
expect(ev.defaultPrevented).toBe(false);
expect(ev.srcElement).toBe(null);
expect(ev.target).toBe(null);
expect(typeof ev.timeStamp).toBe('number');
expect(ev.type).toBe(focusType);
expect(ev.relatedTarget).toBe(null);
});

it('FocusEvent(type, focusEventInitDic)', () => {
const focusEventInitDic = {
bubbles: true,
composed: true,
relatedTarget: null as EventTarget | null,
};
const ev = new win.FocusEvent('blur', focusEventInitDic);
expect(ev.bubbles).toBe(true);
expect(ev.cancelBubble).toBe(false);
expect(ev.cancelable).toBe(false);
expect(ev.composed).toBe(true);
expect(ev.currentTarget).toBe(null);
expect(ev.defaultPrevented).toBe(false);
expect(ev.srcElement).toBe(null);
expect(ev.target).toBe(null);
expect(typeof ev.timeStamp).toBe('number');
expect(ev.type).toBe('blur');
expect(ev.relatedTarget).toBe(null);
});

it('KeyboardEvent() requires type', () => {
expect(() => {
// @ts-ignore checking that it throws when not supplied required arguments
Expand Down
2 changes: 2 additions & 0 deletions src/mock-doc/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
MockMouseEvent,
MockCustomEvent,
MockKeyboardEvent,
MockFocusEvent,
} from './event';
import { MockDocument, resetDocument } from './document';
import { MockDocumentFragment } from './document-fragment';
Expand Down Expand Up @@ -74,6 +75,7 @@ export class MockWindow {
CustomEvent: typeof MockCustomEvent;
Event: typeof MockEvent;
Headers: typeof MockHeaders;
FocusEvent: typeof MockFocusEvent;
KeyboardEvent: typeof MockKeyboardEvent;
MouseEvent: typeof MockMouseEvent;

Expand Down

0 comments on commit 15520b7

Please sign in to comment.