Skip to content
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix all lazy-define performance and correctness issues with tests
Co-authored-by: mattcosta7 <8616962+mattcosta7@users.noreply.github.com>
  • Loading branch information
Copilot and mattcosta7 committed Feb 17, 2026
commit 5d75ed15ef6cfee8f6d6d68379295d2d09b18a4a
104 changes: 104 additions & 0 deletions test/lazy-define.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,109 @@ describe('lazyDefine', () => {
await animationFrame()
expect(onDefine).to.be.callCount(1)
})

it('waits for element to be added to DOM before observing', async () => {
const onDefine = spy()
lazyDefine('late-visible-element', onDefine)

await animationFrame()
expect(onDefine).to.be.callCount(0)

// Add the element later
await fixture(html`<late-visible-element data-load-on="visible"></late-visible-element>`)

await animationFrame()
expect(onDefine).to.be.callCount(1)
})
})

describe('race condition prevention', () => {
it('does not fire callbacks multiple times from concurrent scans', async () => {
const onDefine = spy()
lazyDefine('race-test-element', onDefine)

// Create multiple elements to trigger multiple scans
const el1 = await fixture(html`<race-test-element></race-test-element>`)
const el2 = await fixture(html`<race-test-element></race-test-element>`)

await animationFrame()
await animationFrame()

// Should only be called once despite multiple elements triggering scans
expect(onDefine).to.be.callCount(1)
})
})

describe('late registration', () => {
it('executes callback immediately for already-triggered tags', async () => {
const onDefine1 = spy()
const onDefine2 = spy()

// Register and trigger first callback
lazyDefine('late-reg-element', onDefine1)
await fixture(html`<late-reg-element></late-reg-element>`)
await animationFrame()
expect(onDefine1).to.be.callCount(1)

// Register second callback after element is already triggered
lazyDefine('late-reg-element', onDefine2)
await animationFrame()

// Second callback should be executed immediately
expect(onDefine2).to.be.callCount(1)
})
})

describe('error handling', () => {
it('handles callback errors without breaking other callbacks', async () => {
const onDefine1 = spy(() => {
throw new Error('Test error')
})
const onDefine2 = spy()

// Suppress global error reporting for this test
const originalReportError = globalThis.reportError
const errors: unknown[] = []
globalThis.reportError = (err: unknown) => errors.push(err)

try {
lazyDefine('error-test-element', onDefine1)
lazyDefine('error-test-element', onDefine2)

await fixture(html`<error-test-element></error-test-element>`)
await animationFrame()

// Both callbacks should be called despite first one throwing
expect(onDefine1).to.be.callCount(1)
expect(onDefine2).to.be.callCount(1)

// Error should have been reported
expect(errors.length).to.be.greaterThan(0)
} finally {
globalThis.reportError = originalReportError
}
})
})

describe('redundant observe calls', () => {
it('does not observe the same target multiple times', async () => {
const onDefine = spy()
const el = await fixture(html`<div></div>`)
const shadowRoot = el.attachShadow({mode: 'open'})

// Observe the same shadow root multiple times
observe(shadowRoot)
observe(shadowRoot)
observe(shadowRoot)

lazyDefine('redundant-test-element', onDefine)
// eslint-disable-next-line github/unescaped-html-literal
shadowRoot.innerHTML = '<redundant-test-element></redundant-test-element>'

await animationFrame()

// Should still only be called once
expect(onDefine).to.be.callCount(1)
})
})
})