@rokkit/helpers 1.0.0-next.101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/dist/src/index.d.ts +1 -0
  3. package/dist/src/matchers/action.d.ts +27 -0
  4. package/dist/src/matchers/array.d.ts +10 -0
  5. package/dist/src/matchers/dataset.d.ts +10 -0
  6. package/dist/src/matchers/event.d.ts +10 -0
  7. package/dist/src/matchers/index.d.ts +4 -0
  8. package/dist/src/matchers/internal.d.ts +1 -0
  9. package/dist/src/mocks/animate.d.ts +1 -0
  10. package/dist/src/mocks/element.d.ts +56 -0
  11. package/dist/src/mocks/index.d.ts +2 -0
  12. package/dist/src/mocks/match-media.d.ts +30 -0
  13. package/dist/src/mocks/resize-observer.d.ts +9 -0
  14. package/dist/src/simulators/touch.d.ts +16 -0
  15. package/dist/vitest.config.d.ts +1 -0
  16. package/package.json +35 -0
  17. package/spec/index.spec.js +14 -0
  18. package/spec/matchers/action.spec.js +102 -0
  19. package/spec/matchers/array.spec.js +33 -0
  20. package/spec/matchers/dataset.spec.js +32 -0
  21. package/spec/matchers/event.spec.js +35 -0
  22. package/spec/matchers/index.spec.js +15 -0
  23. package/spec/mocks/animate.spec.js +24 -0
  24. package/spec/mocks/element.spec.js +136 -0
  25. package/spec/mocks/index.spec.js +16 -0
  26. package/spec/mocks/match-media.spec.js +75 -0
  27. package/spec/mocks/resize-observer.spec.js +52 -0
  28. package/spec/simulator.spec.js +96 -0
  29. package/src/components/MockItem.svelte +5 -0
  30. package/src/index.js +1 -0
  31. package/src/matchers/action.js +88 -0
  32. package/src/matchers/array.js +16 -0
  33. package/src/matchers/dataset.js +18 -0
  34. package/src/matchers/event.js +18 -0
  35. package/src/matchers/index.js +4 -0
  36. package/src/matchers/internal.js +9 -0
  37. package/src/mocks/animate.js +26 -0
  38. package/src/mocks/element.js +83 -0
  39. package/src/mocks/index.js +7 -0
  40. package/src/mocks/match-media.js +90 -0
  41. package/src/mocks/resize-observer.js +25 -0
  42. package/src/simulators/touch.js +67 -0
  43. package/tsconfig.build.json +11 -0
  44. package/vitest.config.js +2 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Jerry Thomas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ export * from "./simulators/touch";
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Checks if all the given events are registered by the action and cleaned up on destroy.
3
+ *
4
+ * @param {*} action
5
+ * @param {Object<string,any>} options
6
+ * @param {string|Array<string>} events
7
+ * @returns
8
+ */
9
+ export function toUseHandlersFor(action: any, options: {
10
+ [x: string]: any;
11
+ }, events: string | Array<string>): {
12
+ message: () => string;
13
+ pass: boolean;
14
+ };
15
+ /**
16
+ * Verifies that only the specified events are triggered. Expects an object of spies with key as event names.
17
+ *
18
+ * @param {Object<string,any>} handler : Object with keys as event names and values as spies
19
+ * @param {string|Array<string>} events : An event name or an array of event names
20
+ * @returns
21
+ */
22
+ export function toOnlyTrigger(handler: {
23
+ [x: string]: any;
24
+ }, events: string | Array<string>): {
25
+ message: () => string;
26
+ pass: boolean;
27
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Verify that an array contains all of the expected values
3
+ *
4
+ * @param {Array} received - the array to inspect
5
+ * @param {Array} expected - the values to check for
6
+ */
7
+ export function toIncludeAll(received: any[], expected: any[]): {
8
+ message: () => string;
9
+ pass: boolean;
10
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Check if the element has valid data attributes
3
+ *
4
+ * @param {HTMLElement} received - HTML element to be checked
5
+ * @param {Object} expected - data to be compared
6
+ */
7
+ export function toHaveValidData(received: HTMLElement, expected: Object): {
8
+ message: () => string;
9
+ pass: any;
10
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Verify that a spy event has been dispatched with data in event detail
3
+ *
4
+ * @param {Function} spy - the event handler to inspect
5
+ * @param {Object} data - data expected inthe event detail
6
+ */
7
+ export function toHaveBeenDispatchedWith(spy: Function, data: Object): {
8
+ message: () => string;
9
+ pass: boolean;
10
+ };
@@ -0,0 +1,4 @@
1
+ export * from "./array";
2
+ export * from "./action";
3
+ export * from "./dataset";
4
+ export * from "./event";
@@ -0,0 +1 @@
1
+ export function getMessage(actual: any, expected: any, pass: any, condition?: string): string;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Creates an array of elements with the specified size
3
+ *
4
+ * @param {number} count
5
+ * @param {number} size
6
+ * @param {string} [prop='offsetHeight']
7
+ * @returns {Array<Object<string, number>>}
8
+ */
9
+ export function elementsWithSize(count: number, size: number, prop?: string): Array<{
10
+ [x: string]: number;
11
+ }>;
12
+ /**
13
+ * Creates an array of elements with mixed sizes
14
+ *
15
+ * @param {Array<{count: number, size: number}>} data
16
+ * @param {string} prop
17
+ * @returns {Array<Object<string, number>>}
18
+ */
19
+ export function mixedSizeElements(data: Array<{
20
+ count: number;
21
+ size: number;
22
+ }>, prop: string): Array<{
23
+ [x: string]: number;
24
+ }>;
25
+ /**
26
+ * Creates a mock node with functions to add and remove event handlers
27
+ *
28
+ * @param {Array<string} events
29
+ * @returns {{node: HTMLElement, listeners: Object<string, integer>}}
30
+ */
31
+ export function getMockNode(events: Array<string>): {
32
+ node: HTMLElement;
33
+ listeners: {
34
+ [x: string]: integer;
35
+ };
36
+ };
37
+ /**
38
+ * @typedef {Object} NestedItem
39
+ * @property {string} name
40
+ * @property {string} [dataPath]
41
+ * @property {string} [id]
42
+ * @property {Array<NestedItem>} [children]
43
+ */
44
+ /**
45
+ * Creates a nested HTML element structure using the provided data
46
+ *
47
+ * @param {NestedItem} item
48
+ * @returns {HTMLElement}
49
+ */
50
+ export function createNestedElement(item: NestedItem): HTMLElement;
51
+ export type NestedItem = {
52
+ name: string;
53
+ dataPath?: string | undefined;
54
+ id?: string | undefined;
55
+ children?: NestedItem[] | undefined;
56
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./match-media";
2
+ export * from "./element";
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Updates the media query matches
3
+ * @returns {void}
4
+ */
5
+ export function updateMedia(): void;
6
+ /**
7
+ * Mocks the window.matchMedia function
8
+ * @param {string} query
9
+ * @returns {Object}
10
+ */
11
+ export const matchMediaMock: import("vitest").Mock<(...args: any[]) => any>;
12
+ export type MediaQuery = {
13
+ "min-width"?: integer;
14
+ "max-width"?: integer;
15
+ "min-height"?: integer;
16
+ "max-height"?: integer;
17
+ width?: integer;
18
+ height?: integer;
19
+ orientation?: integer;
20
+ "aspect-ratio"?: integer;
21
+ "min-aspect-ratio"?: integer;
22
+ "max-aspect-ratio"?: integer;
23
+ resolution?: integer;
24
+ "min-resolution"?: integer;
25
+ "max-resolution"?: integer;
26
+ scan?: integer;
27
+ grid?: integer;
28
+ update?: integer;
29
+ "overflow-block"?: integer;
30
+ };
@@ -0,0 +1,9 @@
1
+ export class ResizeObserver {
2
+ constructor(callback: any);
3
+ callback: any;
4
+ elements: Map<any, any>;
5
+ observe(element: any): void;
6
+ unobserve(element: any): void;
7
+ disconnect(): void;
8
+ simulateResize(element: any, contentRect: any): void;
9
+ }
@@ -0,0 +1,16 @@
1
+ export function simulateMouseEvent(x: any, y: any): {
2
+ clientX: any;
3
+ clientY: any;
4
+ stopPropagation: import("vitest").Mock<(...args: any[]) => any>;
5
+ preventDefault: import("vitest").Mock<(...args: any[]) => any>;
6
+ };
7
+ export function simulateTouchEvent(clientX: any, clientY: any): {
8
+ touches: {
9
+ clientX: any;
10
+ clientY: any;
11
+ }[];
12
+ preventDefault: import("vitest").Mock<(...args: any[]) => any>;
13
+ stopPropagation: import("vitest").Mock<(...args: any[]) => any>;
14
+ };
15
+ export function simulateTouchSwipe(node: any, distance: any, delay?: number): void;
16
+ export function simulateMouseSwipe(node: any, distance: any, delay?: number): void;
@@ -0,0 +1 @@
1
+ export default defineConfig;
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@rokkit/helpers",
3
+ "version": "1.0.0-next.101",
4
+ "description": "Custom matchers for vitest.",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "keywords": [
9
+ "vitest",
10
+ "matchers",
11
+ "validators",
12
+ "svelte"
13
+ ],
14
+ "author": "Jerry Thomas<me@jerrythomas.name>",
15
+ "license": "MIT",
16
+ "type": "module",
17
+ "exports": {
18
+ "./package.json": "./package.json",
19
+ "./mocks": "./src/mocks/index.js",
20
+ "./matchers": "./src/matchers/index.js",
21
+ "./simulators": "./src/simulators/index.js",
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./src/index.js"
25
+ }
26
+ },
27
+ "dependencies": {
28
+ "@vitest/expect": "^2.1.8",
29
+ "ramda": "^0.30.1"
30
+ },
31
+ "scripts": {
32
+ "clean": "rm -rf dist",
33
+ "build": "pnpm clean && pnpm prepublishOnly"
34
+ }
35
+ }
@@ -0,0 +1,14 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ // skipcq: JS-C1003 - Importing all components for verification
3
+ import * as functions from '../src'
4
+
5
+ describe('functions', () => {
6
+ it('should contain all exported functions', () => {
7
+ expect(Object.keys(functions)).toEqual([
8
+ 'simulateMouseEvent',
9
+ 'simulateTouchEvent',
10
+ 'simulateTouchSwipe',
11
+ 'simulateMouseSwipe'
12
+ ])
13
+ })
14
+ })
@@ -0,0 +1,102 @@
1
+ import { describe, it, expect, vi, afterEach } from 'vitest'
2
+ import { toOnlyTrigger, toUseHandlersFor } from '../../src/matchers/action'
3
+
4
+ describe('action', () => {
5
+ describe('toOnlyTrigger', () => {
6
+ const handler = {
7
+ a: vi.fn(),
8
+ b: vi.fn(),
9
+ c: vi.fn()
10
+ }
11
+
12
+ expect.extend({ toOnlyTrigger })
13
+ afterEach(() => {
14
+ vi.resetAllMocks()
15
+ })
16
+
17
+ it('should pass if only the specified events are triggered', () => {
18
+ let result = toOnlyTrigger(handler, 'a')
19
+ expect(result.pass).toBe(false)
20
+ expect(result.message()).toBe(
21
+ 'Expected only [a] to be called once and the other handlers to not be called'
22
+ )
23
+ expect(handler).not.toOnlyTrigger('a')
24
+
25
+ handler.a()
26
+ result = toOnlyTrigger(handler, 'a')
27
+ expect(result.pass).toBe(true)
28
+ expect(result.message()).toBe(
29
+ 'Expected other handlers besides [a] to be called, but none were'
30
+ )
31
+ expect(handler).toOnlyTrigger('a')
32
+
33
+ handler.b()
34
+ result = toOnlyTrigger(handler, ['a', 'b'])
35
+ expect(result.pass).toBe(true)
36
+ expect(result.message()).toBe(
37
+ 'Expected other handlers besides [a, b] to be called, but none were'
38
+ )
39
+ expect(handler).toOnlyTrigger(['a', 'b'])
40
+ })
41
+
42
+ it('should fail if no/other events are triggered', () => {
43
+ let result = toOnlyTrigger(handler, ['a', 'b'])
44
+ expect(result.pass).toBe(false)
45
+
46
+ handler.c()
47
+ result = toOnlyTrigger(handler, ['a', 'b'])
48
+ expect(result.pass).toBe(false)
49
+ expect(result.message()).toBe(
50
+ 'Expected only [a, b] to be called once and the other handlers to not be called'
51
+ )
52
+ expect(handler).not.toOnlyTrigger(['a', 'b'])
53
+ })
54
+
55
+ it('should fail if event is not in handler', () => {
56
+ const result = toOnlyTrigger(handler, ['x'])
57
+ expect(result.pass).toBe(false)
58
+ expect(result.message()).toBe('Expected events from [a, b, c] but got unexpected events [x]')
59
+ expect(handler).not.toOnlyTrigger(['a', 'b'])
60
+ })
61
+ })
62
+
63
+ describe('toUseHandlersFor', () => {
64
+ const mockAction = (node, options) => {
65
+ const handler = vi.fn()
66
+ node.addEventListener('click', handler)
67
+ if (options.touch) node.addEventListener('touchstart', handler)
68
+ return {
69
+ destroy: () => {
70
+ node.removeEventListener('click', handler)
71
+ if (options.touch) node.removeEventListener('touchstart', handler)
72
+ }
73
+ }
74
+ }
75
+ expect.extend({ toUseHandlersFor })
76
+
77
+ it('should pass if all events are registered and cleanued up', () => {
78
+ let result = toUseHandlersFor(mockAction, {}, 'click')
79
+ expect(result.pass).toBe(true)
80
+ expect(result.message()).toBe(
81
+ 'Expected action not to manage handlers for [click] but result is [{"event":"click","created":true,"destroyed":true,"pass":true}]'
82
+ )
83
+ expect(mockAction).toUseHandlersFor({}, 'click')
84
+
85
+ result = toUseHandlersFor(mockAction, { touch: true }, ['click', 'touchstart'])
86
+ expect(result.pass).toBe(true)
87
+ expect(result.message()).toBe(
88
+ 'Expected action not to manage handlers for [click,touchstart] but result is [{"event":"click","created":true,"destroyed":true,"pass":true},{"event":"touchstart","created":true,"destroyed":true,"pass":true}]'
89
+ )
90
+ expect(mockAction).toUseHandlersFor({ touch: true }, ['click', 'touchstart'])
91
+ })
92
+
93
+ it('should fail if all events are not registered or not cleaned up', () => {
94
+ const result = toUseHandlersFor(mockAction, {}, ['click', 'touchstart'])
95
+ expect(result.pass).toBe(false)
96
+ expect(result.message()).toBe(
97
+ 'Expected action to manage handlers for [click,touchstart] but result is [{"event":"click","created":true,"destroyed":true,"pass":true},{"event":"touchstart","created":false,"destroyed":true,"pass":false}]'
98
+ )
99
+ expect(mockAction).not.toUseHandlersFor({}, ['click', 'touchstart'])
100
+ })
101
+ })
102
+ })
@@ -0,0 +1,33 @@
1
+ import { describe, it, expect, vi, afterEach } from 'vitest'
2
+ import { toIncludeAll } from '../../src/matchers/array'
3
+
4
+ describe('event', () => {
5
+ describe('toIncludeAll', () => {
6
+ expect.extend({ toIncludeAll })
7
+ afterEach(() => {
8
+ vi.resetAllMocks()
9
+ })
10
+
11
+ it('should pass if the array includes all the values', () => {
12
+ const input = [1, 2, 3]
13
+ const expected = [1, 2]
14
+ const result = toIncludeAll(input, expected)
15
+ expect(result.pass).toBe(true)
16
+ expect(result.message()).toBe(
17
+ `expected ${JSON.stringify(input)} to not include all of ${JSON.stringify(expected)}`
18
+ )
19
+ expect(input).toIncludeAll(expected)
20
+ })
21
+
22
+ it('should fail if the array does not include all the values', () => {
23
+ const input = [1, 2, 3]
24
+ const expected = [1, 2, 4]
25
+ const result = toIncludeAll(input, expected)
26
+ expect(result.pass).toBe(false)
27
+ expect(result.message()).toBe(
28
+ `expected ${JSON.stringify(input)} to include all of ${JSON.stringify(expected)}`
29
+ )
30
+ expect(input).not.toIncludeAll(expected)
31
+ })
32
+ })
33
+ })
@@ -0,0 +1,32 @@
1
+ import { describe, it, expect, vi, afterEach } from 'vitest'
2
+ import { toHaveValidData } from '../../src/matchers/dataset'
3
+
4
+ describe('event', () => {
5
+ describe('toHaveValidData', () => {
6
+ expect.extend({ toHaveValidData })
7
+ afterEach(() => {
8
+ vi.resetAllMocks()
9
+ })
10
+
11
+ it('should pass if the element dataset matches expected', () => {
12
+ const input = { dataset: { a: 1, b: 2 } }
13
+ const expected = { a: 1, b: 2 }
14
+ const result = toHaveValidData(input, expected)
15
+ expect(result.pass).toBe(true)
16
+ expect(result.message()).toBe(
17
+ `expected ${JSON.stringify(input.dataset)} to not deeply equal ${JSON.stringify(expected)}`
18
+ )
19
+ expect(input).toHaveValidData(expected)
20
+ })
21
+ it('should fail if the element dataset does not match expected', () => {
22
+ const input = { dataset: { a: 1, b: 2 } }
23
+ const expected = { a: 1, b: 3 }
24
+ const result = toHaveValidData(input, expected)
25
+ expect(result.pass).toBe(false)
26
+ expect(result.message()).toBe(
27
+ `expected ${JSON.stringify(input.dataset)} to deeply equal ${JSON.stringify(expected)}`
28
+ )
29
+ expect(input).not.toHaveValidData(expected)
30
+ })
31
+ })
32
+ })
@@ -0,0 +1,35 @@
1
+ import { describe, it, expect, vi, afterEach } from 'vitest'
2
+ import { toHaveBeenDispatchedWith } from '../../src/matchers/event'
3
+
4
+ describe('event', () => {
5
+ describe('toHaveBeenDispatchedWith', () => {
6
+ const detail = { foo: 'bar' }
7
+ const spy = vi.fn()
8
+
9
+ expect.extend({ toHaveBeenDispatchedWith })
10
+ afterEach(() => {
11
+ vi.resetAllMocks()
12
+ })
13
+
14
+ it('should pass if the event was dispatched with the correct data', () => {
15
+ spy({ detail })
16
+ const result = toHaveBeenDispatchedWith(spy, detail)
17
+
18
+ expect(result.pass).toBe(true)
19
+ expect(result.message()).toBe(
20
+ `expected ${JSON.stringify(detail)} to not deeply equal ${JSON.stringify(detail)}`
21
+ )
22
+ expect(spy).toHaveBeenDispatchedWith(detail)
23
+ })
24
+
25
+ it('should fail if the event was dispatched with the incorrect data', () => {
26
+ spy({ detail: 'baz' })
27
+ const result = toHaveBeenDispatchedWith(spy, detail)
28
+ expect(result.pass).toBe(false)
29
+ expect(result.message()).toBe(
30
+ `expected ${JSON.stringify('baz')} to deeply equal ${JSON.stringify(detail)}`
31
+ )
32
+ expect(spy).not.toHaveBeenDispatchedWith(detail)
33
+ })
34
+ })
35
+ })
@@ -0,0 +1,15 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ // skipcq: JS-C1003 - Importing all components for verification
3
+ import * as validators from '../../src/matchers/index'
4
+
5
+ describe('validators', () => {
6
+ it('should contain all exported validators', () => {
7
+ expect(Object.keys(validators)).toEqual([
8
+ 'toIncludeAll',
9
+ 'toUseHandlersFor',
10
+ 'toOnlyTrigger',
11
+ 'toHaveValidData',
12
+ 'toHaveBeenDispatchedWith'
13
+ ])
14
+ })
15
+ })
@@ -0,0 +1,24 @@
1
+ import { describe, it, expect, vi } from 'vitest'
2
+ import '../../src/mocks/animate'
3
+
4
+ describe('animate', () => {
5
+ it('should mock global.Element.prototype.animate', () => {
6
+ // Verify the mock is attached
7
+ expect(typeof global.Element.prototype.animate).toBe('function')
8
+
9
+ // Create an element and call animate
10
+ const el = document.createElement('div')
11
+ const animation = el.animate([{ opacity: 0 }, { opacity: 1 }], 1000)
12
+
13
+ // Check that animate was called
14
+ expect(global.Element.prototype.animate).toHaveBeenCalledTimes(1)
15
+
16
+ // animation should be the mock return object
17
+ expect(animation).toHaveProperty('play')
18
+ expect(animation.play).toBeInstanceOf(Function)
19
+
20
+ // Optional: you could further exercise the mock
21
+ animation.play()
22
+ expect(animation.play).toHaveBeenCalledTimes(1)
23
+ })
24
+ })
@@ -0,0 +1,136 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import {
3
+ getMockNode,
4
+ createNestedElement,
5
+ elementsWithSize,
6
+ mixedSizeElements
7
+ } from '../../src/mocks/element'
8
+
9
+ describe('element', () => {
10
+ describe('getMockNode', () => {
11
+ it('should return a mock node', () => {
12
+ const node = getMockNode(['click'])
13
+ expect(node).toEqual({
14
+ node: {
15
+ scrollTo: expect.any(Function),
16
+ querySelector: expect.any(Function),
17
+ querySelectorAll: expect.any(Function),
18
+ dispatchEvent: expect.any(Function),
19
+ addEventListener: expect.any(Function),
20
+ removeEventListener: expect.any(Function)
21
+ },
22
+ listeners: { click: 0 }
23
+ })
24
+ })
25
+ it('should get a mock node for querySelector', () => {
26
+ const { node } = getMockNode(['click'])
27
+
28
+ expect(typeof node.querySelector('div')).toEqual('object')
29
+ expect(Array.isArray(node.querySelectorAll('div'))).toBeTruthy()
30
+ })
31
+ })
32
+
33
+ describe('createNestedElement', () => {
34
+ it('should return a mock nested node', () => {
35
+ const item = {
36
+ name: 'div'
37
+ }
38
+ const node = createNestedElement(item)
39
+ expect(node.getAttribute('id')).toBeFalsy()
40
+ expect(node.getAttribute('data-path')).toBeFalsy()
41
+ expect(node.scrollIntoView).toEqual(expect.any(Function))
42
+ expect(node.children.length).toBe(0)
43
+ })
44
+
45
+ it('should return a mock nested node with id', () => {
46
+ const item = {
47
+ name: 'div',
48
+ id: 'foo'
49
+ }
50
+ const node = createNestedElement(item)
51
+ expect(node.getAttribute('id')).toBe('foo')
52
+ expect(node.getAttribute('data-path')).toBeFalsy()
53
+ expect(node.scrollIntoView).toEqual(expect.any(Function))
54
+ expect(node.children.length).toBe(0)
55
+ })
56
+
57
+ it('should return a mock nested node with data-path', () => {
58
+ const item = {
59
+ name: 'div',
60
+ dataPath: 'foo'
61
+ }
62
+ const node = createNestedElement(item)
63
+ expect(node.getAttribute('id')).toBeFalsy()
64
+ expect(node.getAttribute('data-path')).toBe('foo')
65
+ expect(node.scrollIntoView).toEqual(expect.any(Function))
66
+ expect(node.children.length).toBe(0)
67
+ })
68
+
69
+ it('should return a mock nested node with children', () => {
70
+ const item = {
71
+ name: 'div',
72
+ children: [
73
+ {
74
+ name: 'div'
75
+ }
76
+ ]
77
+ }
78
+ const node = createNestedElement(item)
79
+ expect(node.getAttribute('id')).toBeFalsy()
80
+ expect(node.getAttribute('data-path')).toBeFalsy()
81
+ expect(node.scrollIntoView).toEqual(expect.any(Function))
82
+ expect(node.children.length).toBe(1)
83
+ })
84
+ })
85
+
86
+ describe('elementsWithSize', () => {
87
+ it('should return an array of elements with offsetHeight property', () => {
88
+ const result = elementsWithSize(10, 20)
89
+ expect(result.length).toBe(10)
90
+ result.forEach((element) => {
91
+ expect(element.offsetHeight).toBe(20)
92
+ })
93
+ })
94
+ it('should return an array of elements with offsetWidth property', () => {
95
+ const result = elementsWithSize(10, 20, 'offsetWidth')
96
+ expect(result.length).toBe(10)
97
+ result.forEach((element) => {
98
+ expect(element.offsetWidth).toBe(20)
99
+ })
100
+ })
101
+ })
102
+
103
+ describe('mixedSizeElements', () => {
104
+ it('should create an array of mixed size elements', () => {
105
+ const result = mixedSizeElements([
106
+ { count: 10, size: 20 },
107
+ { count: 5, size: 10 }
108
+ ])
109
+ expect(result.length).toBe(15)
110
+ result.forEach((element, index) => {
111
+ if (index < 10) {
112
+ expect(element.offsetHeight).toBe(20)
113
+ } else {
114
+ expect(element.offsetHeight).toBe(10)
115
+ }
116
+ })
117
+ })
118
+ it('should create an array of mixed size elements with offsetWidth', () => {
119
+ const result = mixedSizeElements(
120
+ [
121
+ { count: 10, size: 20 },
122
+ { count: 5, size: 10 }
123
+ ],
124
+ 'offsetWidth'
125
+ )
126
+ expect(result.length).toBe(15)
127
+ result.forEach((element, index) => {
128
+ if (index < 10) {
129
+ expect(element.offsetWidth).toBe(20)
130
+ } else {
131
+ expect(element.offsetWidth).toBe(10)
132
+ }
133
+ })
134
+ })
135
+ })
136
+ })
@@ -0,0 +1,16 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ // skipcq: JS-C1003 - Importing all components for verification
3
+ import * as mocks from '../../src/mocks'
4
+
5
+ describe('mocks', () => {
6
+ it('should contain all exported mocks', () => {
7
+ expect(Object.keys(mocks)).toEqual([
8
+ 'matchMediaMock',
9
+ 'updateMedia',
10
+ 'elementsWithSize',
11
+ 'mixedSizeElements',
12
+ 'getMockNode',
13
+ 'createNestedElement'
14
+ ])
15
+ })
16
+ })