Skip to content

Commit 5d75ed1

Browse files
Copilotmattcosta7
andcommitted
Fix all lazy-define performance and correctness issues with tests
Co-authored-by: mattcosta7 <8616962+mattcosta7@users.noreply.github.com>
1 parent bead172 commit 5d75ed1

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

test/lazy-define.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,109 @@ describe('lazyDefine', () => {
115115
await animationFrame()
116116
expect(onDefine).to.be.callCount(1)
117117
})
118+
119+
it('waits for element to be added to DOM before observing', async () => {
120+
const onDefine = spy()
121+
lazyDefine('late-visible-element', onDefine)
122+
123+
await animationFrame()
124+
expect(onDefine).to.be.callCount(0)
125+
126+
// Add the element later
127+
await fixture(html`<late-visible-element data-load-on="visible"></late-visible-element>`)
128+
129+
await animationFrame()
130+
expect(onDefine).to.be.callCount(1)
131+
})
132+
})
133+
134+
describe('race condition prevention', () => {
135+
it('does not fire callbacks multiple times from concurrent scans', async () => {
136+
const onDefine = spy()
137+
lazyDefine('race-test-element', onDefine)
138+
139+
// Create multiple elements to trigger multiple scans
140+
const el1 = await fixture(html`<race-test-element></race-test-element>`)
141+
const el2 = await fixture(html`<race-test-element></race-test-element>`)
142+
143+
await animationFrame()
144+
await animationFrame()
145+
146+
// Should only be called once despite multiple elements triggering scans
147+
expect(onDefine).to.be.callCount(1)
148+
})
149+
})
150+
151+
describe('late registration', () => {
152+
it('executes callback immediately for already-triggered tags', async () => {
153+
const onDefine1 = spy()
154+
const onDefine2 = spy()
155+
156+
// Register and trigger first callback
157+
lazyDefine('late-reg-element', onDefine1)
158+
await fixture(html`<late-reg-element></late-reg-element>`)
159+
await animationFrame()
160+
expect(onDefine1).to.be.callCount(1)
161+
162+
// Register second callback after element is already triggered
163+
lazyDefine('late-reg-element', onDefine2)
164+
await animationFrame()
165+
166+
// Second callback should be executed immediately
167+
expect(onDefine2).to.be.callCount(1)
168+
})
169+
})
170+
171+
describe('error handling', () => {
172+
it('handles callback errors without breaking other callbacks', async () => {
173+
const onDefine1 = spy(() => {
174+
throw new Error('Test error')
175+
})
176+
const onDefine2 = spy()
177+
178+
// Suppress global error reporting for this test
179+
const originalReportError = globalThis.reportError
180+
const errors: unknown[] = []
181+
globalThis.reportError = (err: unknown) => errors.push(err)
182+
183+
try {
184+
lazyDefine('error-test-element', onDefine1)
185+
lazyDefine('error-test-element', onDefine2)
186+
187+
await fixture(html`<error-test-element></error-test-element>`)
188+
await animationFrame()
189+
190+
// Both callbacks should be called despite first one throwing
191+
expect(onDefine1).to.be.callCount(1)
192+
expect(onDefine2).to.be.callCount(1)
193+
194+
// Error should have been reported
195+
expect(errors.length).to.be.greaterThan(0)
196+
} finally {
197+
globalThis.reportError = originalReportError
198+
}
199+
})
200+
})
201+
202+
describe('redundant observe calls', () => {
203+
it('does not observe the same target multiple times', async () => {
204+
const onDefine = spy()
205+
const el = await fixture(html`<div></div>`)
206+
const shadowRoot = el.attachShadow({mode: 'open'})
207+
208+
// Observe the same shadow root multiple times
209+
observe(shadowRoot)
210+
observe(shadowRoot)
211+
observe(shadowRoot)
212+
213+
lazyDefine('redundant-test-element', onDefine)
214+
// eslint-disable-next-line github/unescaped-html-literal
215+
shadowRoot.innerHTML = '<redundant-test-element></redundant-test-element>'
216+
217+
await animationFrame()
218+
219+
// Should still only be called once
220+
expect(onDefine).to.be.callCount(1)
221+
})
118222
})
119223
})

0 commit comments

Comments
 (0)