From 4fe32724c64231eb08bd6c553b588a7de726e02d Mon Sep 17 00:00:00 2001 From: MG Date: Sat, 27 Mar 2021 22:18:37 +0100 Subject: [PATCH] feat(#315): ngMocks.trigger and ngMocks.click --- .github/workflows/ci.yaml | 140 ++++++++--------- .../mock-helper/events/mock-helper.click.ts | 5 + .../mock-helper/events/mock-helper.event.ts | 41 +++++ .../mock-helper/events/mock-helper.trigger.ts | 56 +++++++ .../format/mock-helper.format-html.ts | 1 + .../src/lib/mock-helper/mock-helper.object.ts | 6 + .../src/lib/mock-helper/mock-helper.ts | 28 ++++ tests/ng-mocks-trigger/blur.spec.ts | 146 ++++++++++++++++++ tests/ng-mocks-trigger/click.spec.ts | 135 ++++++++++++++++ tests/ng-mocks-trigger/focus.spec.ts | 121 +++++++++++++++ tests/ng-mocks-trigger/test.spec.ts | 90 +++++++++++ 11 files changed, 699 insertions(+), 70 deletions(-) create mode 100644 libs/ng-mocks/src/lib/mock-helper/events/mock-helper.click.ts create mode 100644 libs/ng-mocks/src/lib/mock-helper/events/mock-helper.event.ts create mode 100644 libs/ng-mocks/src/lib/mock-helper/events/mock-helper.trigger.ts create mode 100644 tests/ng-mocks-trigger/blur.spec.ts create mode 100644 tests/ng-mocks-trigger/click.spec.ts create mode 100644 tests/ng-mocks-trigger/focus.spec.ts create mode 100644 tests/ng-mocks-trigger/test.spec.ts diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 78249f9962..09274ee91d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -19,7 +19,7 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./node_modules + path: node_modules key: ${{ runner.os }}-root-v1-${{ hashFiles('./package-lock.json') }} - name: Install dependencies @@ -66,7 +66,7 @@ jobs: uses: actions/upload-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Artifacts uses: actions/upload-artifact@v2 @@ -112,7 +112,7 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./node_modules + path: node_modules key: ${{ runner.os }}-e2e-v1-${{ hashFiles('./package-lock.json') }} - name: Install dependencies @@ -140,7 +140,7 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./node_modules + path: node_modules key: ${{ runner.os }}-root-v1-${{ hashFiles('./package-lock.json') }} - name: Install dependencies @@ -181,7 +181,7 @@ jobs: id: a5es5 uses: actions/cache@v2 with: - path: ./e2e/a5es5/node_modules + path: e2e/a5es5/node_modules key: ${{ runner.os }}-a5es5-v1-${{ hashFiles('./e2e/a5es5/package-lock.json') }} - name: Install A5 es5 dependencies @@ -192,7 +192,7 @@ jobs: id: a5es2015 uses: actions/cache@v2 with: - path: ./e2e/a5es2015/node_modules + path: e2e/a5es2015/node_modules key: ${{ runner.os }}-a5es2015-v1-${{ hashFiles('./e2e/a5es2015/package-lock.json') }} - name: Install A5 es2015 dependencies @@ -203,7 +203,7 @@ jobs: id: a6 uses: actions/cache@v2 with: - path: ./e2e/a6/node_modules + path: e2e/a6/node_modules key: ${{ runner.os }}-a6-v1-${{ hashFiles('./e2e/a6/package-lock.json') }} - name: Install A6 dependencies @@ -214,7 +214,7 @@ jobs: id: a7 uses: actions/cache@v2 with: - path: ./e2e/a7/node_modules + path: e2e/a7/node_modules key: ${{ runner.os }}-a7-v1-${{ hashFiles('./e2e/a7/package-lock.json') }} - name: Install A7 dependencies @@ -225,7 +225,7 @@ jobs: id: a8 uses: actions/cache@v2 with: - path: ./e2e/a8/node_modules + path: e2e/a8/node_modules key: ${{ runner.os }}-a8-v1-${{ hashFiles('./e2e/a8/package-lock.json') }} - name: Install A8 dependencies @@ -236,7 +236,7 @@ jobs: id: a9 uses: actions/cache@v2 with: - path: ./e2e/a9/node_modules + path: e2e/a9/node_modules key: ${{ runner.os }}-a9-v1-${{ hashFiles('./e2e/a9/package-lock.json') }} - name: Install A9 dependencies @@ -247,7 +247,7 @@ jobs: id: a10 uses: actions/cache@v2 with: - path: ./e2e/a10/node_modules + path: e2e/a10/node_modules key: ${{ runner.os }}-a10-v1-${{ hashFiles('./e2e/a10/package-lock.json') }} - name: Install A10 dependencies @@ -258,7 +258,7 @@ jobs: id: a11 uses: actions/cache@v2 with: - path: ./e2e/a11/node_modules + path: e2e/a11/node_modules key: ${{ runner.os }}-a11-v1-${{ hashFiles('./e2e/a11/package-lock.json') }} - name: Install A11 dependencies @@ -269,7 +269,7 @@ jobs: id: a12 uses: actions/cache@v2 with: - path: ./e2e/a12/node_modules + path: e2e/a12/node_modules key: ${{ runner.os }}-a12-v1-${{ hashFiles('./e2e/a12/package-lock.json') }} - name: Install A12 dependencies @@ -280,7 +280,7 @@ jobs: id: am uses: actions/cache@v2 with: - path: ./e2e/am/node_modules + path: e2e/am/node_modules key: ${{ runner.os }}-am-v1-${{ hashFiles('./e2e/am/package-lock.json') }} - name: Install A Min dependencies @@ -303,14 +303,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a5es5/node_modules + path: e2e/a5es5/node_modules key: ${{ runner.os }}-a5es5-v1-${{ hashFiles('./e2e/a5es5/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a5es5 @@ -335,14 +335,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a5es2015/node_modules + path: e2e/a5es2015/node_modules key: ${{ runner.os }}-a5es2015-v1-${{ hashFiles('./e2e/a5es2015/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a5es2015 @@ -367,14 +367,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a6/node_modules + path: e2e/a6/node_modules key: ${{ runner.os }}-a6-v1-${{ hashFiles('./e2e/a6/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a6 @@ -399,14 +399,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a6/node_modules + path: e2e/a6/node_modules key: ${{ runner.os }}-a6-v1-${{ hashFiles('./e2e/a6/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a6 @@ -431,14 +431,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a7/node_modules + path: e2e/a7/node_modules key: ${{ runner.os }}-a7-v1-${{ hashFiles('./e2e/a7/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a7 @@ -463,14 +463,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a7/node_modules + path: e2e/a7/node_modules key: ${{ runner.os }}-a7-v1-${{ hashFiles('./e2e/a7/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a7 @@ -495,14 +495,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a8/node_modules + path: e2e/a8/node_modules key: ${{ runner.os }}-a8-v1-${{ hashFiles('./e2e/a8/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a8 @@ -527,14 +527,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a8/node_modules + path: e2e/a8/node_modules key: ${{ runner.os }}-a8-v1-${{ hashFiles('./e2e/a8/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a8 @@ -559,14 +559,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a9/node_modules + path: e2e/a9/node_modules key: ${{ runner.os }}-a9-v1-${{ hashFiles('./e2e/a9/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a9 @@ -591,14 +591,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a9/node_modules + path: e2e/a9/node_modules key: ${{ runner.os }}-a9-v1-${{ hashFiles('./e2e/a9/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a9 @@ -623,14 +623,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a9/node_modules + path: e2e/a9/node_modules key: ${{ runner.os }}-a9-v1-${{ hashFiles('./e2e/a9/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a9 @@ -655,14 +655,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a9/node_modules + path: e2e/a9/node_modules key: ${{ runner.os }}-a9-v1-${{ hashFiles('./e2e/a9/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a9 @@ -687,14 +687,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a10/node_modules + path: e2e/a10/node_modules key: ${{ runner.os }}-a10-v1-${{ hashFiles('./e2e/a10/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a10 @@ -719,14 +719,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a10/node_modules + path: e2e/a10/node_modules key: ${{ runner.os }}-a10-v1-${{ hashFiles('./e2e/a10/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a10 @@ -751,14 +751,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a10/node_modules + path: e2e/a10/node_modules key: ${{ runner.os }}-a10-v1-${{ hashFiles('./e2e/a10/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a10 @@ -783,14 +783,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a10/node_modules + path: e2e/a10/node_modules key: ${{ runner.os }}-a10-v1-${{ hashFiles('./e2e/a10/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a10 @@ -815,14 +815,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a11/node_modules + path: e2e/a11/node_modules key: ${{ runner.os }}-a11-v1-${{ hashFiles('./e2e/a11/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a11 @@ -847,14 +847,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a11/node_modules + path: e2e/a11/node_modules key: ${{ runner.os }}-a11-v1-${{ hashFiles('./e2e/a11/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a11 @@ -879,14 +879,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a11/node_modules + path: e2e/a11/node_modules key: ${{ runner.os }}-a11-v1-${{ hashFiles('./e2e/a11/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a11 @@ -911,14 +911,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a11/node_modules + path: e2e/a11/node_modules key: ${{ runner.os }}-a11-v1-${{ hashFiles('./e2e/a11/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a11 @@ -943,14 +943,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a12/node_modules + path: e2e/a12/node_modules key: ${{ runner.os }}-a12-v1-${{ hashFiles('./e2e/a12/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a12 @@ -975,14 +975,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a12/node_modules + path: e2e/a12/node_modules key: ${{ runner.os }}-a12-v1-${{ hashFiles('./e2e/a12/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a12 @@ -1007,14 +1007,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a12/node_modules + path: e2e/a12/node_modules key: ${{ runner.os }}-a12-v1-${{ hashFiles('./e2e/a12/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a12 @@ -1039,14 +1039,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/a12/node_modules + path: e2e/a12/node_modules key: ${{ runner.os }}-a12-v1-${{ hashFiles('./e2e/a12/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:a12 @@ -1071,14 +1071,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/am/node_modules + path: e2e/am/node_modules key: ${{ runner.os }}-am-v1-${{ hashFiles('./e2e/am/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:am @@ -1103,14 +1103,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/am/node_modules + path: e2e/am/node_modules key: ${{ runner.os }}-am-v1-${{ hashFiles('./e2e/am/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:am @@ -1135,14 +1135,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/am/node_modules + path: e2e/am/node_modules key: ${{ runner.os }}-am-v1-${{ hashFiles('./e2e/am/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:am @@ -1167,14 +1167,14 @@ jobs: id: cache uses: actions/cache@v2 with: - path: ./e2e/am/node_modules + path: e2e/am/node_modules key: ${{ runner.os }}-am-v1-${{ hashFiles('./e2e/am/package-lock.json') }} - name: Workspace uses: actions/download-artifact@v2 with: name: workspace - path: ./dist + path: dist - name: Spreading Build run: npm run s:am diff --git a/libs/ng-mocks/src/lib/mock-helper/events/mock-helper.click.ts b/libs/ng-mocks/src/lib/mock-helper/events/mock-helper.click.ts new file mode 100644 index 0000000000..0fd5ec9e4e --- /dev/null +++ b/libs/ng-mocks/src/lib/mock-helper/events/mock-helper.click.ts @@ -0,0 +1,5 @@ +import mockHelperTrigger from './mock-helper.trigger'; + +export default (selector: any, payload?: object) => { + mockHelperTrigger(selector, 'click', payload); +}; diff --git a/libs/ng-mocks/src/lib/mock-helper/events/mock-helper.event.ts b/libs/ng-mocks/src/lib/mock-helper/events/mock-helper.event.ts new file mode 100644 index 0000000000..fa214253b1 --- /dev/null +++ b/libs/ng-mocks/src/lib/mock-helper/events/mock-helper.event.ts @@ -0,0 +1,41 @@ +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 Event(event, init) + : /* istanbul ignore next */ customEvent; + +export default ( + event: string, + init?: EventInit, + overrides?: Partial, +): Event => { + const eventObj = eventCtor(event, { + bubbles: preventBubble.indexOf(event) === -1, + cancelable: true, + ...init, + }); + if (overrides) { + mockHelperStub(eventObj, overrides); + } + + return eventObj; +}; diff --git a/libs/ng-mocks/src/lib/mock-helper/events/mock-helper.trigger.ts b/libs/ng-mocks/src/lib/mock-helper/events/mock-helper.trigger.ts new file mode 100644 index 0000000000..8e749e2235 --- /dev/null +++ b/libs/ng-mocks/src/lib/mock-helper/events/mock-helper.trigger.ts @@ -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, +) => { + 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); +}; diff --git a/libs/ng-mocks/src/lib/mock-helper/format/mock-helper.format-html.ts b/libs/ng-mocks/src/lib/mock-helper/format/mock-helper.format-html.ts index d4d8c06194..ca3b68d575 100644 --- a/libs/ng-mocks/src/lib/mock-helper/format/mock-helper.format-html.ts +++ b/libs/ng-mocks/src/lib/mock-helper/format/mock-helper.format-html.ts @@ -8,6 +8,7 @@ const normalizeValue = (html: string | undefined): string => ? html .replace(new RegExp('\\s+', 'mg'), ' ') .replace(new RegExp('', 'mg'), '') + .replace(new RegExp('