mirror of
https://github.com/langgenius/dify.git
synced 2026-02-09 23:20:12 -05:00
refactor(web): migrate to Vitest and esm (#29974)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
This commit is contained in:
@@ -66,7 +66,7 @@ describe('app-redirection', () => {
|
||||
*/
|
||||
test('calls redirection function with correct path for non-editor', () => {
|
||||
const app = { id: 'app-123', mode: AppModeEnum.CHAT }
|
||||
const mockRedirect = jest.fn()
|
||||
const mockRedirect = vi.fn()
|
||||
|
||||
getRedirection(false, app, mockRedirect)
|
||||
|
||||
@@ -76,7 +76,7 @@ describe('app-redirection', () => {
|
||||
|
||||
test('calls redirection function with workflow path for editor', () => {
|
||||
const app = { id: 'app-123', mode: AppModeEnum.WORKFLOW }
|
||||
const mockRedirect = jest.fn()
|
||||
const mockRedirect = vi.fn()
|
||||
|
||||
getRedirection(true, app, mockRedirect)
|
||||
|
||||
@@ -86,7 +86,7 @@ describe('app-redirection', () => {
|
||||
|
||||
test('calls redirection function with configuration path for chat mode editor', () => {
|
||||
const app = { id: 'app-123', mode: AppModeEnum.CHAT }
|
||||
const mockRedirect = jest.fn()
|
||||
const mockRedirect = vi.fn()
|
||||
|
||||
getRedirection(true, app, mockRedirect)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { writeTextToClipboard } from './clipboard'
|
||||
describe('Clipboard Utilities', () => {
|
||||
describe('writeTextToClipboard', () => {
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks()
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -21,7 +21,7 @@ describe('Clipboard Utilities', () => {
|
||||
* When navigator.clipboard is available, should use the modern API
|
||||
*/
|
||||
it('should use navigator.clipboard.writeText when available', async () => {
|
||||
const mockWriteText = jest.fn().mockResolvedValue(undefined)
|
||||
const mockWriteText = vi.fn().mockResolvedValue(undefined)
|
||||
Object.defineProperty(navigator, 'clipboard', {
|
||||
value: { writeText: mockWriteText },
|
||||
writable: true,
|
||||
@@ -44,11 +44,11 @@ describe('Clipboard Utilities', () => {
|
||||
configurable: true,
|
||||
})
|
||||
|
||||
const mockExecCommand = jest.fn().mockReturnValue(true)
|
||||
const mockExecCommand = vi.fn().mockReturnValue(true)
|
||||
document.execCommand = mockExecCommand
|
||||
|
||||
const appendChildSpy = jest.spyOn(document.body, 'appendChild')
|
||||
const removeChildSpy = jest.spyOn(document.body, 'removeChild')
|
||||
const appendChildSpy = vi.spyOn(document.body, 'appendChild')
|
||||
const removeChildSpy = vi.spyOn(document.body, 'removeChild')
|
||||
|
||||
await writeTextToClipboard('fallback text')
|
||||
|
||||
@@ -68,7 +68,7 @@ describe('Clipboard Utilities', () => {
|
||||
configurable: true,
|
||||
})
|
||||
|
||||
const mockExecCommand = jest.fn().mockReturnValue(false)
|
||||
const mockExecCommand = vi.fn().mockReturnValue(false)
|
||||
document.execCommand = mockExecCommand
|
||||
|
||||
await expect(writeTextToClipboard('fail text')).rejects.toThrow()
|
||||
@@ -85,7 +85,7 @@ describe('Clipboard Utilities', () => {
|
||||
configurable: true,
|
||||
})
|
||||
|
||||
const mockExecCommand = jest.fn().mockImplementation(() => {
|
||||
const mockExecCommand = vi.fn().mockImplementation(() => {
|
||||
throw new Error('execCommand error')
|
||||
})
|
||||
document.execCommand = mockExecCommand
|
||||
@@ -104,8 +104,8 @@ describe('Clipboard Utilities', () => {
|
||||
configurable: true,
|
||||
})
|
||||
|
||||
document.execCommand = jest.fn().mockReturnValue(true)
|
||||
const removeChildSpy = jest.spyOn(document.body, 'removeChild')
|
||||
document.execCommand = vi.fn().mockReturnValue(true)
|
||||
const removeChildSpy = vi.spyOn(document.body, 'removeChild')
|
||||
|
||||
await writeTextToClipboard('cleanup test')
|
||||
|
||||
@@ -117,7 +117,7 @@ describe('Clipboard Utilities', () => {
|
||||
* Should handle edge case of empty clipboard content
|
||||
*/
|
||||
it('should handle empty string', async () => {
|
||||
const mockWriteText = jest.fn().mockResolvedValue(undefined)
|
||||
const mockWriteText = vi.fn().mockResolvedValue(undefined)
|
||||
Object.defineProperty(navigator, 'clipboard', {
|
||||
value: { writeText: mockWriteText },
|
||||
writable: true,
|
||||
@@ -133,7 +133,7 @@ describe('Clipboard Utilities', () => {
|
||||
* Should preserve newlines, tabs, quotes, unicode, and emojis
|
||||
*/
|
||||
it('should handle special characters', async () => {
|
||||
const mockWriteText = jest.fn().mockResolvedValue(undefined)
|
||||
const mockWriteText = vi.fn().mockResolvedValue(undefined)
|
||||
Object.defineProperty(navigator, 'clipboard', {
|
||||
value: { writeText: mockWriteText },
|
||||
writable: true,
|
||||
|
||||
@@ -61,7 +61,7 @@ describe('Context Utilities', () => {
|
||||
})
|
||||
|
||||
// Suppress console.error for this test
|
||||
const consoleError = jest.spyOn(console, 'error').mockImplementation(() => { /* suppress error */ })
|
||||
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => { /* suppress error */ })
|
||||
|
||||
expect(() => {
|
||||
renderHook(() => useTestContext())
|
||||
@@ -206,7 +206,7 @@ describe('Context Utilities', () => {
|
||||
name: 'SelectorTest',
|
||||
})
|
||||
|
||||
const consoleError = jest.spyOn(console, 'error').mockImplementation(() => { /* suppress error */ })
|
||||
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => { /* suppress error */ })
|
||||
|
||||
expect(() => {
|
||||
renderHook(() => useTestContext())
|
||||
@@ -241,7 +241,7 @@ describe('Context Utilities', () => {
|
||||
type TestContextValue = { value: string }
|
||||
const [, useTestContext] = createCtx<TestContextValue>()
|
||||
|
||||
const consoleError = jest.spyOn(console, 'error').mockImplementation(() => { /* suppress error */ })
|
||||
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => { /* suppress error */ })
|
||||
|
||||
expect(() => {
|
||||
renderHook(() => useTestContext())
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import type { Mock } from 'vitest'
|
||||
import { searchEmoji } from './emoji'
|
||||
import { SearchIndex } from 'emoji-mart'
|
||||
|
||||
jest.mock('emoji-mart', () => ({
|
||||
vi.mock('emoji-mart', () => ({
|
||||
SearchIndex: {
|
||||
search: jest.fn(),
|
||||
search: vi.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
describe('Emoji Utilities', () => {
|
||||
describe('searchEmoji', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('should return emoji natives for search results', async () => {
|
||||
@@ -19,28 +20,28 @@ describe('Emoji Utilities', () => {
|
||||
{ skins: [{ native: '😃' }] },
|
||||
{ skins: [{ native: '😄' }] },
|
||||
]
|
||||
;(SearchIndex.search as jest.Mock).mockResolvedValue(mockEmojis)
|
||||
;(SearchIndex.search as Mock).mockResolvedValue(mockEmojis)
|
||||
|
||||
const result = await searchEmoji('smile')
|
||||
expect(result).toEqual(['😀', '😃', '😄'])
|
||||
})
|
||||
|
||||
it('should return empty array when no results', async () => {
|
||||
;(SearchIndex.search as jest.Mock).mockResolvedValue([])
|
||||
;(SearchIndex.search as Mock).mockResolvedValue([])
|
||||
|
||||
const result = await searchEmoji('nonexistent')
|
||||
expect(result).toEqual([])
|
||||
})
|
||||
|
||||
it('should return empty array when search returns null', async () => {
|
||||
;(SearchIndex.search as jest.Mock).mockResolvedValue(null)
|
||||
;(SearchIndex.search as Mock).mockResolvedValue(null)
|
||||
|
||||
const result = await searchEmoji('test')
|
||||
expect(result).toEqual([])
|
||||
})
|
||||
|
||||
it('should handle search with empty string', async () => {
|
||||
;(SearchIndex.search as jest.Mock).mockResolvedValue([])
|
||||
;(SearchIndex.search as Mock).mockResolvedValue([])
|
||||
|
||||
const result = await searchEmoji('')
|
||||
expect(result).toEqual([])
|
||||
@@ -57,7 +58,7 @@ describe('Emoji Utilities', () => {
|
||||
],
|
||||
},
|
||||
]
|
||||
;(SearchIndex.search as jest.Mock).mockResolvedValue(mockEmojis)
|
||||
;(SearchIndex.search as Mock).mockResolvedValue(mockEmojis)
|
||||
|
||||
const result = await searchEmoji('thumbs')
|
||||
expect(result).toEqual(['👍'])
|
||||
@@ -68,7 +69,7 @@ describe('Emoji Utilities', () => {
|
||||
{ skins: [{ native: '❤️' }] },
|
||||
{ skins: [{ native: '💙' }] },
|
||||
]
|
||||
;(SearchIndex.search as jest.Mock).mockResolvedValue(mockEmojis)
|
||||
;(SearchIndex.search as Mock).mockResolvedValue(mockEmojis)
|
||||
|
||||
const result = await searchEmoji('heart love')
|
||||
expect(result).toEqual(['❤️', '💙'])
|
||||
|
||||
@@ -68,8 +68,8 @@ describe('downloadFile', () => {
|
||||
const mockUrl = 'blob:mockUrl'
|
||||
|
||||
// Mock URL.createObjectURL
|
||||
const createObjectURLMock = jest.fn().mockReturnValue(mockUrl)
|
||||
const revokeObjectURLMock = jest.fn()
|
||||
const createObjectURLMock = vi.fn().mockReturnValue(mockUrl)
|
||||
const revokeObjectURLMock = vi.fn()
|
||||
Object.defineProperty(window.URL, 'createObjectURL', { value: createObjectURLMock })
|
||||
Object.defineProperty(window.URL, 'revokeObjectURL', { value: revokeObjectURLMock })
|
||||
|
||||
@@ -77,11 +77,11 @@ describe('downloadFile', () => {
|
||||
const mockLink = {
|
||||
href: '',
|
||||
download: '',
|
||||
click: jest.fn(),
|
||||
remove: jest.fn(),
|
||||
click: vi.fn(),
|
||||
remove: vi.fn(),
|
||||
}
|
||||
const createElementMock = jest.spyOn(document, 'createElement').mockReturnValue(mockLink as any)
|
||||
const appendChildMock = jest.spyOn(document.body, 'appendChild').mockImplementation((node: Node) => {
|
||||
const createElementMock = vi.spyOn(document, 'createElement').mockReturnValue(mockLink as any)
|
||||
const appendChildMock = vi.spyOn(document.body, 'appendChild').mockImplementation((node: Node) => {
|
||||
return node
|
||||
})
|
||||
|
||||
@@ -99,7 +99,7 @@ describe('downloadFile', () => {
|
||||
expect(revokeObjectURLMock).toHaveBeenCalledWith(mockUrl)
|
||||
|
||||
// Clean up mocks
|
||||
jest.restoreAllMocks()
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { Mock } from 'vitest'
|
||||
import {
|
||||
asyncRunSafe,
|
||||
canFindTool,
|
||||
@@ -50,13 +51,13 @@ describe('getTextWidthWithCanvas', () => {
|
||||
originalCreateElement = document.createElement
|
||||
|
||||
// Mock canvas and context
|
||||
const measureTextMock = jest.fn().mockReturnValue({ width: 100 })
|
||||
const getContextMock = jest.fn().mockReturnValue({
|
||||
const measureTextMock = vi.fn().mockReturnValue({ width: 100 })
|
||||
const getContextMock = vi.fn().mockReturnValue({
|
||||
measureText: measureTextMock,
|
||||
font: '',
|
||||
})
|
||||
|
||||
document.createElement = jest.fn().mockReturnValue({
|
||||
document.createElement = vi.fn().mockReturnValue({
|
||||
getContext: getContextMock,
|
||||
})
|
||||
})
|
||||
@@ -73,7 +74,7 @@ describe('getTextWidthWithCanvas', () => {
|
||||
|
||||
it('should return 0 if context is not available', () => {
|
||||
// Override mock for this test
|
||||
document.createElement = jest.fn().mockReturnValue({
|
||||
document.createElement = vi.fn().mockReturnValue({
|
||||
getContext: () => null,
|
||||
})
|
||||
|
||||
@@ -243,6 +244,7 @@ describe('removeSpecificQueryParam', () => {
|
||||
// Mock window.location using defineProperty to handle URL properly
|
||||
delete (window as any).location
|
||||
Object.defineProperty(window, 'location', {
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: {
|
||||
...originalLocation,
|
||||
@@ -252,11 +254,12 @@ describe('removeSpecificQueryParam', () => {
|
||||
},
|
||||
})
|
||||
|
||||
window.history.replaceState = jest.fn()
|
||||
window.history.replaceState = vi.fn()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
Object.defineProperty(window, 'location', {
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: originalLocation,
|
||||
})
|
||||
@@ -266,7 +269,7 @@ describe('removeSpecificQueryParam', () => {
|
||||
it('should remove a single query parameter', () => {
|
||||
removeSpecificQueryParam('param2')
|
||||
expect(window.history.replaceState).toHaveBeenCalledTimes(1)
|
||||
const replaceStateCall = (window.history.replaceState as jest.Mock).mock.calls[0]
|
||||
const replaceStateCall = (window.history.replaceState as Mock).mock.calls[0]
|
||||
expect(replaceStateCall[0]).toBe(null)
|
||||
expect(replaceStateCall[1]).toBe('')
|
||||
expect(replaceStateCall[2]).toMatch(/param1=value1/)
|
||||
@@ -277,7 +280,7 @@ describe('removeSpecificQueryParam', () => {
|
||||
it('should remove multiple query parameters', () => {
|
||||
removeSpecificQueryParam(['param1', 'param3'])
|
||||
expect(window.history.replaceState).toHaveBeenCalledTimes(1)
|
||||
const replaceStateCall = (window.history.replaceState as jest.Mock).mock.calls[0]
|
||||
const replaceStateCall = (window.history.replaceState as Mock).mock.calls[0]
|
||||
expect(replaceStateCall[2]).toMatch(/param2=value2/)
|
||||
expect(replaceStateCall[2]).not.toMatch(/param1=value1/)
|
||||
expect(replaceStateCall[2]).not.toMatch(/param3=value3/)
|
||||
@@ -287,7 +290,7 @@ describe('removeSpecificQueryParam', () => {
|
||||
removeSpecificQueryParam('nonexistent')
|
||||
|
||||
expect(window.history.replaceState).toHaveBeenCalledTimes(1)
|
||||
const replaceStateCall = (window.history.replaceState as jest.Mock).mock.calls[0]
|
||||
const replaceStateCall = (window.history.replaceState as Mock).mock.calls[0]
|
||||
expect(replaceStateCall[2]).toMatch(/param1=value1/)
|
||||
expect(replaceStateCall[2]).toMatch(/param2=value2/)
|
||||
expect(replaceStateCall[2]).toMatch(/param3=value3/)
|
||||
@@ -344,38 +347,38 @@ describe('asyncRunSafe extended', () => {
|
||||
|
||||
describe('getTextWidthWithCanvas', () => {
|
||||
it('should return 0 when canvas context is not available', () => {
|
||||
const mockGetContext = jest.fn().mockReturnValue(null)
|
||||
jest.spyOn(document, 'createElement').mockReturnValue({
|
||||
const mockGetContext = vi.fn().mockReturnValue(null)
|
||||
vi.spyOn(document, 'createElement').mockReturnValue({
|
||||
getContext: mockGetContext,
|
||||
} as any)
|
||||
|
||||
const width = getTextWidthWithCanvas('test')
|
||||
expect(width).toBe(0)
|
||||
|
||||
jest.restoreAllMocks()
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
it('should measure text width with custom font', () => {
|
||||
const mockMeasureText = jest.fn().mockReturnValue({ width: 123.456 })
|
||||
const mockMeasureText = vi.fn().mockReturnValue({ width: 123.456 })
|
||||
const mockContext = {
|
||||
font: '',
|
||||
measureText: mockMeasureText,
|
||||
}
|
||||
jest.spyOn(document, 'createElement').mockReturnValue({
|
||||
getContext: jest.fn().mockReturnValue(mockContext),
|
||||
vi.spyOn(document, 'createElement').mockReturnValue({
|
||||
getContext: vi.fn().mockReturnValue(mockContext),
|
||||
} as any)
|
||||
|
||||
const width = getTextWidthWithCanvas('test', '16px Arial')
|
||||
expect(mockContext.font).toBe('16px Arial')
|
||||
expect(width).toBe(123.46)
|
||||
|
||||
jest.restoreAllMocks()
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
it('should handle empty string', () => {
|
||||
const mockMeasureText = jest.fn().mockReturnValue({ width: 0 })
|
||||
jest.spyOn(document, 'createElement').mockReturnValue({
|
||||
getContext: jest.fn().mockReturnValue({
|
||||
const mockMeasureText = vi.fn().mockReturnValue({ width: 0 })
|
||||
vi.spyOn(document, 'createElement').mockReturnValue({
|
||||
getContext: vi.fn().mockReturnValue({
|
||||
font: '',
|
||||
measureText: mockMeasureText,
|
||||
}),
|
||||
@@ -384,7 +387,7 @@ describe('getTextWidthWithCanvas', () => {
|
||||
const width = getTextWidthWithCanvas('')
|
||||
expect(width).toBe(0)
|
||||
|
||||
jest.restoreAllMocks()
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -451,19 +454,20 @@ describe('fetchWithRetry extended', () => {
|
||||
expect(result).toBe('success')
|
||||
})
|
||||
|
||||
it('should retry specified number of times', async () => {
|
||||
let _attempts = 0
|
||||
it('should return error when promise rejects', async () => {
|
||||
let attempts = 0
|
||||
const failingPromise = () => {
|
||||
_attempts++
|
||||
attempts++
|
||||
return Promise.reject(new Error('fail'))
|
||||
}
|
||||
|
||||
await fetchWithRetry(failingPromise(), 3)
|
||||
// Initial attempt + 3 retries = 4 total attempts
|
||||
// But the function structure means it will try once, then retry 3 times
|
||||
const [error] = await fetchWithRetry(failingPromise(), 3)
|
||||
expect(error).toBeInstanceOf(Error)
|
||||
expect(error?.message).toBe('fail')
|
||||
expect(attempts).toBe(1)
|
||||
})
|
||||
|
||||
it('should succeed after retries', async () => {
|
||||
it('should surface rejection from a settled promise', async () => {
|
||||
let attempts = 0
|
||||
const eventuallySucceed = new Promise((resolve, reject) => {
|
||||
attempts++
|
||||
@@ -473,8 +477,10 @@ describe('fetchWithRetry extended', () => {
|
||||
resolve('success')
|
||||
})
|
||||
|
||||
await fetchWithRetry(eventuallySucceed, 3)
|
||||
// Note: This test may need adjustment based on actual retry logic
|
||||
const [error] = await fetchWithRetry(eventuallySucceed, 3)
|
||||
expect(error).toBeInstanceOf(Error)
|
||||
expect(error?.message).toBe('not yet')
|
||||
expect(attempts).toBe(1)
|
||||
})
|
||||
|
||||
/*
|
||||
@@ -565,7 +571,7 @@ describe('removeSpecificQueryParam extended', () => {
|
||||
})
|
||||
|
||||
it('should remove single query parameter', () => {
|
||||
const mockReplaceState = jest.fn()
|
||||
const mockReplaceState = vi.fn()
|
||||
window.history.replaceState = mockReplaceState
|
||||
|
||||
removeSpecificQueryParam('param1')
|
||||
@@ -576,7 +582,7 @@ describe('removeSpecificQueryParam extended', () => {
|
||||
})
|
||||
|
||||
it('should remove multiple query parameters', () => {
|
||||
const mockReplaceState = jest.fn()
|
||||
const mockReplaceState = vi.fn()
|
||||
window.history.replaceState = mockReplaceState
|
||||
|
||||
removeSpecificQueryParam(['param1', 'param2'])
|
||||
@@ -588,7 +594,7 @@ describe('removeSpecificQueryParam extended', () => {
|
||||
})
|
||||
|
||||
it('should preserve other parameters', () => {
|
||||
const mockReplaceState = jest.fn()
|
||||
const mockReplaceState = vi.fn()
|
||||
window.history.replaceState = mockReplaceState
|
||||
|
||||
removeSpecificQueryParam('param1')
|
||||
|
||||
@@ -68,7 +68,7 @@ describe('navigation', () => {
|
||||
* Tests that the returned function properly navigates with preserved params
|
||||
*/
|
||||
test('returns function that calls router.push with correct path', () => {
|
||||
const mockRouter = { push: jest.fn() }
|
||||
const mockRouter = { push: vi.fn() }
|
||||
const backNav = createBackNavigation(mockRouter, '/datasets/123/documents')
|
||||
|
||||
backNav()
|
||||
@@ -77,7 +77,7 @@ describe('navigation', () => {
|
||||
})
|
||||
|
||||
test('returns function that navigates without params when preserveParams is false', () => {
|
||||
const mockRouter = { push: jest.fn() }
|
||||
const mockRouter = { push: vi.fn() }
|
||||
const backNav = createBackNavigation(mockRouter, '/datasets/123/documents', false)
|
||||
|
||||
backNav()
|
||||
@@ -86,7 +86,7 @@ describe('navigation', () => {
|
||||
})
|
||||
|
||||
test('can be called multiple times', () => {
|
||||
const mockRouter = { push: jest.fn() }
|
||||
const mockRouter = { push: vi.fn() }
|
||||
const backNav = createBackNavigation(mockRouter, '/datasets/123/documents')
|
||||
|
||||
backNav()
|
||||
@@ -257,7 +257,7 @@ describe('navigation', () => {
|
||||
*/
|
||||
describe('backToDocuments', () => {
|
||||
test('creates navigation function with preserved params', () => {
|
||||
const mockRouter = { push: jest.fn() }
|
||||
const mockRouter = { push: vi.fn() }
|
||||
const backNav = datasetNavigation.backToDocuments(mockRouter, 'dataset-123')
|
||||
|
||||
backNav()
|
||||
@@ -271,7 +271,7 @@ describe('navigation', () => {
|
||||
*/
|
||||
describe('toDocumentDetail', () => {
|
||||
test('creates navigation function to document detail', () => {
|
||||
const mockRouter = { push: jest.fn() }
|
||||
const mockRouter = { push: vi.fn() }
|
||||
const navFunc = datasetNavigation.toDocumentDetail(mockRouter, 'dataset-123', 'doc-456')
|
||||
|
||||
navFunc()
|
||||
@@ -285,7 +285,7 @@ describe('navigation', () => {
|
||||
*/
|
||||
describe('toDocumentSettings', () => {
|
||||
test('creates navigation function to document settings', () => {
|
||||
const mockRouter = { push: jest.fn() }
|
||||
const mockRouter = { push: vi.fn() }
|
||||
const navFunc = datasetNavigation.toDocumentSettings(mockRouter, 'dataset-123', 'doc-456')
|
||||
|
||||
navFunc()
|
||||
|
||||
@@ -2,7 +2,7 @@ import { isSupportMCP } from './plugin-version-feature'
|
||||
|
||||
describe('plugin-version-feature', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
describe('isSupportMCP', () => {
|
||||
|
||||
@@ -132,11 +132,11 @@ describe('Zod Features', () => {
|
||||
expect(stringArraySchema.parse(['a', 'b', 'c'])).toEqual(['a', 'b', 'c'])
|
||||
})
|
||||
|
||||
it('should support promise', () => {
|
||||
it('should support promise', async () => {
|
||||
const promiseSchema = z.promise(z.string())
|
||||
const validPromise = Promise.resolve('success')
|
||||
|
||||
expect(promiseSchema.parse(validPromise)).resolves.toBe('success')
|
||||
await expect(promiseSchema.parse(validPromise)).resolves.toBe('success')
|
||||
})
|
||||
|
||||
it('should support unions', () => {
|
||||
|
||||
Reference in New Issue
Block a user