Skip to content

Commit 0bbc50a

Browse files
committed
Unit test case for service and script package
1 parent f4b9b5c commit 0bbc50a

2 files changed

Lines changed: 413 additions & 0 deletions

File tree

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/**
2+
* @vitest-environment happy-dom
3+
*/
4+
import { describe, it, expect, beforeEach } from 'vitest'
5+
import {
6+
waitForBody,
7+
assignRef,
8+
getRef,
9+
parseFragment,
10+
parseDocument
11+
} from '../src/utils.js'
12+
13+
describe('DOM mutation capture utilities', () => {
14+
beforeEach(() => {
15+
if (!document.body) {
16+
const body = document.createElement('body')
17+
document.documentElement.appendChild(body)
18+
}
19+
document.body.innerHTML = ''
20+
})
21+
22+
it('should wait for body to exist before capturing mutations', async () => {
23+
await expect(waitForBody()).resolves.toBeUndefined()
24+
})
25+
26+
it('should assign trackable refs to DOM elements for mutation identification', () => {
27+
const parent = document.createElement('div')
28+
const child1 = document.createElement('span')
29+
const child2 = document.createElement('p')
30+
parent.appendChild(child1)
31+
parent.appendChild(child2)
32+
33+
assignRef(parent)
34+
35+
const parentRef = getRef(parent)
36+
const child1Ref = getRef(child1)
37+
const child2Ref = getRef(child2)
38+
39+
// Each element should get unique ref
40+
expect(parentRef).toBeTruthy()
41+
expect(child1Ref).toBeTruthy()
42+
expect(child2Ref).toBeTruthy()
43+
expect(parentRef).not.toBe(child1Ref)
44+
expect(child1Ref).not.toBe(child2Ref)
45+
})
46+
47+
it('should maintain stable refs across multiple assignments', () => {
48+
const div = document.createElement('div')
49+
assignRef(div)
50+
const firstRef = getRef(div)
51+
52+
assignRef(div)
53+
const secondRef = getRef(div)
54+
55+
expect(firstRef).toBe(secondRef)
56+
})
57+
58+
it('should serialize DOM elements to transmittable VNode structure', () => {
59+
const button = document.createElement('button')
60+
button.id = 'submit'
61+
button.className = 'btn-primary'
62+
button.textContent = 'Submit'
63+
64+
const vnode = parseFragment(button)
65+
66+
// VNode should be serializable (has type and props)
67+
expect(vnode).toHaveProperty('type')
68+
expect(vnode).toHaveProperty('props')
69+
expect(JSON.stringify(vnode)).toBeTruthy()
70+
})
71+
72+
it('should serialize complete document hierarchy for initial capture', () => {
73+
const div = document.createElement('div')
74+
div.innerHTML = '<header><h1>App</h1></header><main><p>Content</p></main>'
75+
76+
const vnode = parseDocument(div)
77+
78+
// Document parsing wraps in html element
79+
expect(vnode).toHaveProperty('type')
80+
expect(vnode).toHaveProperty('props')
81+
expect(JSON.stringify(vnode)).toBeTruthy()
82+
})
83+
84+
it('should handle parsing errors without breaking mutation capture', () => {
85+
const fragmentResult = parseFragment(null as any)
86+
const documentResult = parseDocument(null as any)
87+
88+
// Should return error containers instead of throwing
89+
expect(typeof fragmentResult).toBe('object')
90+
expect(typeof documentResult).toBe('object')
91+
92+
if (typeof fragmentResult === 'object') {
93+
expect(fragmentResult.type).toBe('div')
94+
expect(fragmentResult.props.class).toBe('parseFragmentWrapper')
95+
}
96+
97+
if (typeof documentResult === 'object') {
98+
expect(documentResult.type).toBe('div')
99+
expect(documentResult.props.class).toBe('parseDocument')
100+
}
101+
})
102+
103+
it('should support complete mutation tracking workflow: assign ref → serialize → transmit', () => {
104+
// Simulate what happens in index.ts when MutationObserver detects changes
105+
const addedNode = document.createElement('article')
106+
addedNode.innerHTML = '<h2>New Section</h2><p>New content</p>'
107+
108+
// Step 1: Assign ref so we can track this node
109+
assignRef(addedNode)
110+
const nodeRef = getRef(addedNode)
111+
112+
// Step 2: Serialize for transmission to backend
113+
const serialized = parseFragment(addedNode)
114+
115+
// Step 3: Verify we can identify and serialize the mutation
116+
expect(nodeRef).toBeTruthy()
117+
expect(serialized).toHaveProperty('type')
118+
expect(serialized).toHaveProperty('props')
119+
120+
// The serialized VNode should be transmittable as JSON
121+
const json = JSON.stringify(serialized)
122+
expect(json).toBeTruthy()
123+
expect(() => JSON.parse(json)).not.toThrow()
124+
})
125+
126+
it('should support mutation removal tracking via refs', () => {
127+
const target = document.createElement('div')
128+
const child = document.createElement('span')
129+
target.appendChild(child)
130+
131+
assignRef(target)
132+
133+
// When mutation observer detects removals, we can get refs
134+
const targetRef = getRef(target)
135+
const childRef = getRef(child)
136+
137+
expect(targetRef).not.toBeNull()
138+
expect(childRef).not.toBeNull()
139+
})
140+
})

0 commit comments

Comments
 (0)