mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 06:20:11 +00:00
*PR Created by the Glary-Bot Agent* --- ## Summary - Replace all `as unknown as Type` assertions in 59 unit test files with type-safe `@total-typescript/shoehorn` functions - Use `fromPartial<Type>()` for partial mock objects where deep-partial type-checks (21 files) - Use `fromAny<Type>()` for fundamentally incompatible types: null, undefined, primitives, variables, class expressions, and mocks with test-specific extra properties that `PartialDeepObject` rejects (remaining files) - All explicit type parameters preserved so TypeScript return types are correct - Browser test `.spec.ts` files excluded (shoehorn unavailable in `page.evaluate` browser context) ## Verification - `pnpm typecheck` ✅ - `pnpm lint` ✅ - `pnpm format` ✅ - Pre-commit hooks passed (format + oxlint + eslint + typecheck) - Migrated test files verified passing (ran representative subset) - No test behavior changes — only type assertion syntax changed - No UI changes — screenshots not applicable ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-10761-test-migrate-as-unknown-as-to-total-typescript-shoehorn-3336d73d365081f6b8adc44db5dcc380) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> Co-authored-by: Amp <amp@ampcode.com>
134 lines
3.8 KiB
TypeScript
134 lines
3.8 KiB
TypeScript
import { fromAny } from '@total-typescript/shoehorn'
|
|
import { ref } from 'vue'
|
|
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import { useWaveAudioPlayer } from './useWaveAudioPlayer'
|
|
|
|
vi.mock('@vueuse/core', async (importOriginal) => {
|
|
const actual = await importOriginal<Record<string, unknown>>()
|
|
return {
|
|
...actual,
|
|
useMediaControls: () => ({
|
|
playing: ref(false),
|
|
currentTime: ref(0),
|
|
duration: ref(0)
|
|
})
|
|
}
|
|
})
|
|
|
|
const mockFetchApi = vi.fn()
|
|
const originalAudioContext = globalThis.AudioContext
|
|
|
|
afterEach(() => {
|
|
globalThis.AudioContext = originalAudioContext
|
|
mockFetchApi.mockReset()
|
|
})
|
|
|
|
vi.mock('@/scripts/api', () => ({
|
|
api: {
|
|
apiURL: (route: string) => '/api' + route,
|
|
fetchApi: (...args: unknown[]) => mockFetchApi(...args)
|
|
}
|
|
}))
|
|
|
|
describe('useWaveAudioPlayer', () => {
|
|
it('initializes with default bar count', () => {
|
|
const src = ref('')
|
|
const { bars } = useWaveAudioPlayer({ src })
|
|
expect(bars.value).toHaveLength(40)
|
|
})
|
|
|
|
it('initializes with custom bar count', () => {
|
|
const src = ref('')
|
|
const { bars } = useWaveAudioPlayer({ src, barCount: 20 })
|
|
expect(bars.value).toHaveLength(20)
|
|
})
|
|
|
|
it('returns playedBarIndex as -1 when duration is 0', () => {
|
|
const src = ref('')
|
|
const { playedBarIndex } = useWaveAudioPlayer({ src })
|
|
expect(playedBarIndex.value).toBe(-1)
|
|
})
|
|
|
|
it('generates bars with heights between 10 and 70', () => {
|
|
const src = ref('')
|
|
const { bars } = useWaveAudioPlayer({ src })
|
|
for (const bar of bars.value) {
|
|
expect(bar.height).toBeGreaterThanOrEqual(10)
|
|
expect(bar.height).toBeLessThanOrEqual(70)
|
|
}
|
|
})
|
|
|
|
it('starts in paused state', () => {
|
|
const src = ref('')
|
|
const { isPlaying } = useWaveAudioPlayer({ src })
|
|
expect(isPlaying.value).toBe(false)
|
|
})
|
|
|
|
it('shows 0:00 for formatted times initially', () => {
|
|
const src = ref('')
|
|
const { formattedCurrentTime, formattedDuration } = useWaveAudioPlayer({
|
|
src
|
|
})
|
|
expect(formattedCurrentTime.value).toBe('0:00')
|
|
expect(formattedDuration.value).toBe('0:00')
|
|
})
|
|
|
|
it('fetches and decodes audio when src changes', async () => {
|
|
const mockAudioBuffer = {
|
|
getChannelData: vi.fn(() => new Float32Array(80))
|
|
}
|
|
|
|
const mockDecodeAudioData = vi.fn(() => Promise.resolve(mockAudioBuffer))
|
|
const mockClose = vi.fn().mockResolvedValue(undefined)
|
|
globalThis.AudioContext = fromAny<typeof AudioContext, unknown>(
|
|
class {
|
|
decodeAudioData = mockDecodeAudioData
|
|
close = mockClose
|
|
}
|
|
)
|
|
|
|
mockFetchApi.mockResolvedValue({
|
|
ok: true,
|
|
arrayBuffer: () => Promise.resolve(new ArrayBuffer(8)),
|
|
headers: { get: () => 'audio/wav' }
|
|
})
|
|
|
|
const src = ref('/api/view?filename=audio.wav&type=output')
|
|
const { bars, loading } = useWaveAudioPlayer({ src, barCount: 10 })
|
|
|
|
await vi.waitFor(() => {
|
|
expect(loading.value).toBe(false)
|
|
})
|
|
|
|
expect(mockFetchApi).toHaveBeenCalledWith(
|
|
'/view?filename=audio.wav&type=output'
|
|
)
|
|
expect(mockDecodeAudioData).toHaveBeenCalled()
|
|
expect(bars.value).toHaveLength(10)
|
|
})
|
|
|
|
it('clears blobUrl and shows placeholder bars when fetch fails', async () => {
|
|
mockFetchApi.mockRejectedValue(new Error('Network error'))
|
|
|
|
const src = ref('/api/view?filename=audio.wav&type=output')
|
|
const { bars, loading, audioSrc } = useWaveAudioPlayer({
|
|
src,
|
|
barCount: 10
|
|
})
|
|
|
|
await vi.waitFor(() => {
|
|
expect(loading.value).toBe(false)
|
|
})
|
|
|
|
expect(bars.value).toHaveLength(10)
|
|
expect(audioSrc.value).toBe('/api/view?filename=audio.wav&type=output')
|
|
})
|
|
|
|
it('does not call decodeAudioSource when src is empty', () => {
|
|
const src = ref('')
|
|
useWaveAudioPlayer({ src })
|
|
expect(mockFetchApi).not.toHaveBeenCalled()
|
|
})
|
|
})
|