mirror of
https://github.com/langgenius/dify.git
synced 2026-04-15 01:38:19 +08:00
110 lines
3.5 KiB
TypeScript
110 lines
3.5 KiB
TypeScript
import { render } from '@testing-library/react'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
const mockSetTune = vi.fn()
|
|
const mockLoad = vi.fn()
|
|
const mockInit = vi.fn().mockResolvedValue(undefined)
|
|
const mockRenderAbc = vi.fn().mockReturnValue([{}])
|
|
|
|
vi.mock('abcjs', () => ({
|
|
__esModule: true,
|
|
default: {
|
|
renderAbc: (...args: unknown[]) => mockRenderAbc(...args),
|
|
synth: {
|
|
SynthController: class {
|
|
load(...args: unknown[]) {
|
|
mockLoad(...args)
|
|
}
|
|
|
|
setTune(...args: unknown[]) {
|
|
mockSetTune(...args)
|
|
}
|
|
},
|
|
CreateSynth: class {
|
|
init(...args: unknown[]) {
|
|
return mockInit(...args)
|
|
}
|
|
},
|
|
},
|
|
},
|
|
}))
|
|
|
|
const loadMarkdownMusic = async () => (await import('../music')).default
|
|
|
|
describe('MarkdownMusic', () => {
|
|
beforeEach(() => {
|
|
vi.resetModules()
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
// Base rendering behavior for the component shell.
|
|
describe('Rendering', () => {
|
|
it('should render wrapper and two internal container nodes', async () => {
|
|
const MarkdownMusic = await loadMarkdownMusic()
|
|
const { container } = render(<MarkdownMusic><span>child</span></MarkdownMusic>)
|
|
|
|
const topLevel = container.firstElementChild as HTMLElement | null
|
|
expect(topLevel).toBeTruthy()
|
|
expect(topLevel?.children.length).toBe(2)
|
|
expect(topLevel?.style.minWidth).toBe('100%')
|
|
expect(topLevel?.style.overflow).toBe('auto')
|
|
})
|
|
})
|
|
|
|
// String input should trigger abcjs rendering and synth initialization.
|
|
describe('String Input', () => {
|
|
it('should render music notation and initialize synth when children is a string', async () => {
|
|
const MarkdownMusic = await loadMarkdownMusic()
|
|
render(<MarkdownMusic>{'X:1\nT:Test\nK:C\nC D E F|'}</MarkdownMusic>)
|
|
|
|
expect(mockRenderAbc).toHaveBeenCalledTimes(1)
|
|
expect(mockLoad).toHaveBeenCalledTimes(1)
|
|
expect(mockInit).toHaveBeenCalledTimes(1)
|
|
await Promise.resolve()
|
|
expect(mockSetTune).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('should not render fallback when children is not a string', async () => {
|
|
const MarkdownMusic = await loadMarkdownMusic()
|
|
render(<MarkdownMusic><span>not a string</span></MarkdownMusic>)
|
|
expect(mockRenderAbc).not.toHaveBeenCalled()
|
|
expect(mockLoad).not.toHaveBeenCalled()
|
|
expect(mockInit).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should call abcjs renderer with expected options for string input', async () => {
|
|
const MarkdownMusic = await loadMarkdownMusic()
|
|
render(<MarkdownMusic>{'X:1\nT:Opts\nK:C\nC D E F|'}</MarkdownMusic>)
|
|
|
|
expect(mockRenderAbc).toHaveBeenCalledWith(
|
|
expect.any(HTMLDivElement),
|
|
'X:1\nT:Opts\nK:C\nC D E F|',
|
|
expect.objectContaining({
|
|
add_classes: true,
|
|
responsive: 'resize',
|
|
}),
|
|
)
|
|
})
|
|
|
|
it('should skip initialization when refs are unavailable', async () => {
|
|
vi.doMock('react', async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import('react')>()
|
|
return {
|
|
...actual,
|
|
useEffect: (effect: () => void) => {
|
|
effect()
|
|
},
|
|
}
|
|
})
|
|
const MarkdownMusic = await loadMarkdownMusic()
|
|
render(<MarkdownMusic>{'X:1\nT:NoRef\nK:C\nC D E F|'}</MarkdownMusic>)
|
|
|
|
expect(mockRenderAbc).not.toHaveBeenCalled()
|
|
expect(mockLoad).not.toHaveBeenCalled()
|
|
expect(mockInit).not.toHaveBeenCalled()
|
|
|
|
vi.doUnmock('react')
|
|
})
|
|
})
|
|
})
|