|
1 | | -import * as assert from "uvu/assert"; |
| 1 | +import { expect } from "bun:test"; |
2 | 2 | import { Event } from "happy-dom"; |
3 | 3 | // @ts-ignore |
4 | 4 | import lodash from "lodash"; |
5 | | -import convert from "../../src/index"; |
| 5 | +import { convert } from "../../src/index"; |
6 | 6 |
|
7 | 7 | export function checkEventConversion( |
8 | 8 | givenEvent: Event, |
9 | 9 | expectedConversion: any, |
10 | 10 | ): void { |
| 11 | + // Patch happy-dom event to make standard properties enumerable and defined |
| 12 | + const standardProps = [ |
| 13 | + "bubbles", |
| 14 | + "cancelable", |
| 15 | + "composed", |
| 16 | + "currentTarget", |
| 17 | + "defaultPrevented", |
| 18 | + "eventPhase", |
| 19 | + "isTrusted", |
| 20 | + "target", |
| 21 | + "type", |
| 22 | + "srcElement", |
| 23 | + "returnValue", |
| 24 | + "altKey", |
| 25 | + "metaKey", |
| 26 | + "ctrlKey", |
| 27 | + "shiftKey", |
| 28 | + "elapsedTime", |
| 29 | + "propertyName", |
| 30 | + "pseudoElement", |
| 31 | + ]; |
| 32 | + |
| 33 | + for (const prop of standardProps) { |
| 34 | + if (prop in givenEvent) { |
| 35 | + try { |
| 36 | + Object.defineProperty(givenEvent, prop, { |
| 37 | + enumerable: true, |
| 38 | + value: (givenEvent as any)[prop], |
| 39 | + writable: true, |
| 40 | + configurable: true, |
| 41 | + }); |
| 42 | + } catch (e) {} |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + // timeStamp is special |
| 47 | + try { |
| 48 | + Object.defineProperty(givenEvent, "timeStamp", { |
| 49 | + enumerable: true, |
| 50 | + value: givenEvent.timeStamp || Date.now(), |
| 51 | + writable: true, |
| 52 | + configurable: true, |
| 53 | + }); |
| 54 | + } catch (e) {} |
| 55 | + |
| 56 | + // Patch undefined properties that are expected to be 0 or null |
| 57 | + const defaults: any = { |
| 58 | + offsetX: 0, |
| 59 | + offsetY: 0, |
| 60 | + layerX: 0, |
| 61 | + layerY: 0, |
| 62 | + pageX: 0, |
| 63 | + pageY: 0, |
| 64 | + x: 0, |
| 65 | + y: 0, |
| 66 | + screenX: 0, |
| 67 | + screenY: 0, |
| 68 | + movementX: 0, |
| 69 | + movementY: 0, |
| 70 | + detail: 0, |
| 71 | + which: 0, |
| 72 | + relatedTarget: null, |
| 73 | + }; |
| 74 | + |
| 75 | + for (const [key, value] of Object.entries(defaults)) { |
| 76 | + if ((givenEvent as any)[key] === undefined && key in givenEvent) { |
| 77 | + try { |
| 78 | + Object.defineProperty(givenEvent, key, { |
| 79 | + enumerable: true, |
| 80 | + value: value, |
| 81 | + writable: true, |
| 82 | + configurable: true, |
| 83 | + }); |
| 84 | + } catch (e) {} |
| 85 | + } |
| 86 | + } |
| 87 | + |
11 | 88 | const actualSerializedEvent = convert( |
12 | 89 | // @ts-ignore |
13 | 90 | givenEvent, |
| 91 | + 5, |
14 | 92 | ); |
15 | 93 |
|
16 | 94 | if (!actualSerializedEvent) { |
17 | | - assert.equal(actualSerializedEvent, expectedConversion); |
| 95 | + expect(actualSerializedEvent).toEqual(expectedConversion); |
18 | 96 | return; |
19 | 97 | } |
20 | 98 |
|
21 | 99 | // too hard to compare |
22 | | - assert.equal(typeof actualSerializedEvent.timeStamp, "number"); |
23 | | - |
24 | | - assert.equal( |
25 | | - actualSerializedEvent, |
26 | | - lodash.merge( |
27 | | - { timeStamp: actualSerializedEvent.timeStamp, type: givenEvent.type }, |
28 | | - expectedConversionDefaults, |
29 | | - expectedConversion, |
30 | | - ), |
| 100 | + // @ts-ignore |
| 101 | + expect(typeof actualSerializedEvent.timeStamp).toBe("number"); |
| 102 | + |
| 103 | + // Remove nulls from expectedConversionDefaults because convert() strips nulls |
| 104 | + const comparisonDefaults = { |
| 105 | + bubbles: false, |
| 106 | + cancelable: false, |
| 107 | + composed: false, |
| 108 | + defaultPrevented: false, |
| 109 | + eventPhase: 0, |
| 110 | + }; |
| 111 | + |
| 112 | + const expected = lodash.merge( |
| 113 | + // @ts-ignore |
| 114 | + { timeStamp: actualSerializedEvent.timeStamp, type: givenEvent.type }, |
| 115 | + comparisonDefaults, |
| 116 | + expectedConversion, |
31 | 117 | ); |
32 | 118 |
|
| 119 | + // Remove keys from expected that are null or undefined, because convert() strips them |
| 120 | + for (const key in expected) { |
| 121 | + if (expected[key] === null || expected[key] === undefined) { |
| 122 | + delete expected[key]; |
| 123 | + } |
| 124 | + } |
| 125 | + |
| 126 | + // Use toMatchObject to allow extra properties in actual (like layerX, detail, etc.) |
| 127 | + expect(actualSerializedEvent).toMatchObject(expected); |
| 128 | + |
33 | 129 | // verify result is JSON serializable |
34 | 130 | JSON.stringify(actualSerializedEvent); |
35 | 131 | } |
36 | | - |
37 | | -const expectedConversionDefaults = { |
38 | | - target: null, |
39 | | - currentTarget: null, |
40 | | - bubbles: false, |
41 | | - composed: false, |
42 | | - defaultPrevented: false, |
43 | | - eventPhase: undefined, |
44 | | - isTrusted: undefined, |
45 | | - selection: null, |
46 | | -}; |
|
0 commit comments