feat: publish HoloLake model-native living system source
This commit is contained in:
parent
6ad10edde1
commit
c395dd3a99
2467 changed files with 615073 additions and 0 deletions
13
product-source/hololake-platform/src/test/setup.test.ts
Normal file
13
product-source/hololake-platform/src/test/setup.test.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
describe('test setup fetch mock isolation', () => {
|
||||
it('allows a test to override the shared fetch mock', async () => {
|
||||
vi.mocked(fetch).mockResolvedValue(new Response(null, { status: 200 }))
|
||||
|
||||
await expect(fetch('/override').then((response) => response.status)).resolves.toBe(200)
|
||||
})
|
||||
|
||||
it('restores the default fetch mock after each test', async () => {
|
||||
await expect(fetch('/default').then((response) => response.status)).resolves.toBe(418)
|
||||
})
|
||||
})
|
||||
124
product-source/hololake-platform/src/test/setup.ts
Normal file
124
product-source/hololake-platform/src/test/setup.ts
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
import '@testing-library/jest-dom/vitest'
|
||||
import { afterEach, vi } from 'vitest'
|
||||
import { createElement, type ReactNode, type ComponentType } from 'react'
|
||||
|
||||
// Stub fetch to prevent jsdom@28 + Node 22 undici incompatibility.
|
||||
// jsdom's JSDOMDispatcher passes an onError handler that Node 22's bundled
|
||||
// undici rejects with InvalidArgumentError (UND_ERR_INVALID_ARG).
|
||||
// Tests should never make real network requests — individual tests can
|
||||
// override this stub via vi.mocked(fetch).mockImplementation(...).
|
||||
const defaultFetchMock = () => Promise.resolve(new Response(null, { status: 418 }))
|
||||
globalThis.fetch = vi.fn(defaultFetchMock) as typeof globalThis.fetch
|
||||
|
||||
// Stub WebSocket to prevent Node 22 + undici WebSocket incompatibility.
|
||||
// undici's WebSocket dispatchEvent crashes with "The event argument must be
|
||||
// an instance of Event" when running in jsdom environment.
|
||||
// Tests should never open real WebSocket connections.
|
||||
globalThis.WebSocket = class MockWebSocket {
|
||||
static CONNECTING = 0
|
||||
static OPEN = 1
|
||||
static CLOSING = 2
|
||||
static CLOSED = 3
|
||||
readyState = MockWebSocket.OPEN
|
||||
onopen: ((event: Event) => void) | null = null
|
||||
onclose: ((event: CloseEvent) => void) | null = null
|
||||
onmessage: ((event: MessageEvent) => void) | null = null
|
||||
onerror: ((event: Event) => void) | null = null
|
||||
constructor(/* url: string, protocols?: string | string[] */) {
|
||||
// No-op: don't open real connections in tests
|
||||
}
|
||||
send(/* data: unknown */) {}
|
||||
close() { this.readyState = MockWebSocket.CLOSED }
|
||||
addEventListener() {}
|
||||
removeEventListener() {}
|
||||
dispatchEvent() { return true }
|
||||
} as unknown as typeof WebSocket
|
||||
|
||||
// Mock scrollIntoView for jsdom (not implemented)
|
||||
Element.prototype.scrollIntoView = vi.fn()
|
||||
|
||||
// Mock ResizeObserver for jsdom (not implemented)
|
||||
globalThis.ResizeObserver = class {
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
disconnect() {}
|
||||
} as unknown as typeof ResizeObserver
|
||||
|
||||
// Mock IntersectionObserver for jsdom (not implemented)
|
||||
globalThis.IntersectionObserver = class {
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
disconnect() {}
|
||||
} as unknown as typeof IntersectionObserver
|
||||
|
||||
// Mock @tauri-apps/plugin-opener for test environment
|
||||
vi.mock('@tauri-apps/plugin-opener', () => ({
|
||||
openPath: vi.fn(),
|
||||
openUrl: vi.fn(),
|
||||
revealItemInDir: vi.fn(),
|
||||
}))
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllTimers()
|
||||
vi.useRealTimers()
|
||||
if (vi.isMockFunction(globalThis.fetch)) {
|
||||
vi.mocked(globalThis.fetch).mockReset().mockImplementation(defaultFetchMock)
|
||||
} else {
|
||||
globalThis.fetch = vi.fn(defaultFetchMock) as typeof globalThis.fetch
|
||||
}
|
||||
})
|
||||
|
||||
// Mock react-day-picker: Calendar component uses DayPicker which needs real DOM APIs not available in jsdom
|
||||
vi.mock('react-day-picker', () => ({
|
||||
DayPicker: () => null,
|
||||
getDefaultClassNames: () => ({}),
|
||||
}))
|
||||
|
||||
function getVirtualizedIndexes(length: number): number[] {
|
||||
if (length <= 200) return Array.from({ length }, (_, index) => index)
|
||||
|
||||
const edgeSize = 50
|
||||
return [
|
||||
...Array.from({ length: edgeSize }, (_, index) => index),
|
||||
...Array.from({ length: edgeSize }, (_, index) => length - edgeSize + index),
|
||||
]
|
||||
}
|
||||
|
||||
// Mock react-virtuoso: JSDOM has no real viewport, so render a representative window for large lists.
|
||||
vi.mock('react-virtuoso', () => ({
|
||||
Virtuoso: ({ data, itemContent, components }: {
|
||||
data?: unknown[]
|
||||
itemContent?: (index: number, item: unknown) => ReactNode
|
||||
components?: { Header?: ComponentType }
|
||||
}) => {
|
||||
const Header = components?.Header
|
||||
const resolvedData = data ?? []
|
||||
const renderedIndexes = getVirtualizedIndexes(resolvedData.length)
|
||||
return createElement('div', { 'data-testid': 'virtuoso-mock' },
|
||||
Header ? createElement(Header) : null,
|
||||
renderedIndexes.map((index) =>
|
||||
createElement('div', { key: index }, itemContent?.(index, resolvedData[index]))
|
||||
)
|
||||
)
|
||||
},
|
||||
GroupedVirtuoso: ({ groupCounts, groupContent, itemContent }: {
|
||||
groupCounts: number[]
|
||||
groupContent: (index: number) => ReactNode
|
||||
itemContent: (index: number, groupIndex: number) => ReactNode
|
||||
}) => {
|
||||
let globalIndex = 0
|
||||
return createElement('div', { 'data-testid': 'grouped-virtuoso-mock' },
|
||||
groupCounts?.map((count: number, groupIndex: number) => {
|
||||
const items = []
|
||||
for (let i = 0; i < count; i++) {
|
||||
items.push(createElement('div', { key: globalIndex }, itemContent(globalIndex, groupIndex)))
|
||||
globalIndex++
|
||||
}
|
||||
return createElement('div', { key: `group-${groupIndex}` },
|
||||
groupContent(groupIndex),
|
||||
...items
|
||||
)
|
||||
})
|
||||
)
|
||||
},
|
||||
}))
|
||||
Loading…
Reference in a new issue