diff --git a/packages/document-api/package.json b/packages/document-api/package.json index 914a519977..1eb264f75e 100644 --- a/packages/document-api/package.json +++ b/packages/document-api/package.json @@ -16,6 +16,9 @@ "default": "./src/types/index.ts" } }, + "scripts": { + "test": "bun test" + }, "files": [ "src" ] diff --git a/packages/document-api/src/authorities/authorities.test.ts b/packages/document-api/src/authorities/authorities.test.ts index c4bad32bdd..182a8551db 100644 --- a/packages/document-api/src/authorities/authorities.test.ts +++ b/packages/document-api/src/authorities/authorities.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { DocumentApiValidationError } from '../errors.js'; import { executeAuthoritiesList, @@ -17,18 +17,18 @@ import { function makeAdapter(): AuthoritiesAdapter { return { - list: vi.fn().mockReturnValue({ items: [], total: 0 }), - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - configure: vi.fn().mockReturnValue({ success: true }), - rebuild: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), + list: mock().mockReturnValue({ items: [], total: 0 }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + configure: mock().mockReturnValue({ success: true }), + rebuild: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), entries: { - list: vi.fn().mockReturnValue({ items: [], total: 0 }), - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - update: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), + list: mock().mockReturnValue({ items: [], total: 0 }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + update: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), }, }; } diff --git a/packages/document-api/src/blocks/blocks.test.ts b/packages/document-api/src/blocks/blocks.test.ts index 905e91fc66..fe91f63cff 100644 --- a/packages/document-api/src/blocks/blocks.test.ts +++ b/packages/document-api/src/blocks/blocks.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it, vi } from 'vitest'; +import { describe, expect, it, mock } from 'bun:test'; import { executeBlocksDelete, type BlocksAdapter } from './blocks.js'; import type { BlocksDeleteInput, BlocksDeleteResult } from '../types/blocks.types.js'; import { DocumentApiValidationError } from '../errors.js'; @@ -9,7 +9,7 @@ function makeAdapter(result?: BlocksDeleteResult): BlocksAdapter { deleted: { kind: 'block', nodeType: 'paragraph', nodeId: 'p1' }, }; return { - delete: vi.fn(() => result ?? defaultResult), + delete: mock(() => result ?? defaultResult), }; } diff --git a/packages/document-api/src/bookmarks/bookmarks.test.ts b/packages/document-api/src/bookmarks/bookmarks.test.ts index 7fb9d417cb..90acb1d654 100644 --- a/packages/document-api/src/bookmarks/bookmarks.test.ts +++ b/packages/document-api/src/bookmarks/bookmarks.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { DocumentApiValidationError } from '../errors.js'; import { executeBookmarksList, @@ -11,11 +11,11 @@ import { function makeAdapter(): BookmarksAdapter { return { - list: vi.fn().mockReturnValue({ items: [], total: 0 }), - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - rename: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), + list: mock().mockReturnValue({ items: [], total: 0 }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + rename: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), }; } diff --git a/packages/document-api/src/captions/captions.test.ts b/packages/document-api/src/captions/captions.test.ts index 1c46a9e926..38973260be 100644 --- a/packages/document-api/src/captions/captions.test.ts +++ b/packages/document-api/src/captions/captions.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { DocumentApiValidationError } from '../errors.js'; import { executeCaptionsList, @@ -12,12 +12,12 @@ import { function makeAdapter(): CaptionsAdapter { return { - list: vi.fn().mockReturnValue({ items: [], total: 0 }), - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - update: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), - configure: vi.fn().mockReturnValue({ success: true }), + list: mock().mockReturnValue({ items: [], total: 0 }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + update: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), + configure: mock().mockReturnValue({ success: true }), }; } diff --git a/packages/document-api/src/citations/citations.test.ts b/packages/document-api/src/citations/citations.test.ts index 7c643efff2..b8fdd1be31 100644 --- a/packages/document-api/src/citations/citations.test.ts +++ b/packages/document-api/src/citations/citations.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { DocumentApiValidationError } from '../errors.js'; import { executeCitationsList, @@ -21,24 +21,24 @@ import { function makeAdapter(): CitationsAdapter { return { - list: vi.fn().mockReturnValue({ items: [], total: 0 }), - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - update: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), + list: mock().mockReturnValue({ items: [], total: 0 }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + update: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), sources: { - list: vi.fn().mockReturnValue({ items: [], total: 0 }), - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - update: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), + list: mock().mockReturnValue({ items: [], total: 0 }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + update: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), }, bibliography: { - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - rebuild: vi.fn().mockReturnValue({ success: true }), - configure: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + rebuild: mock().mockReturnValue({ success: true }), + configure: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), }, }; } diff --git a/packages/document-api/src/clear-content/clear-content.test.ts b/packages/document-api/src/clear-content/clear-content.test.ts index 6647c2e01b..64049bfb95 100644 --- a/packages/document-api/src/clear-content/clear-content.test.ts +++ b/packages/document-api/src/clear-content/clear-content.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it, mock } from 'bun:test'; import { executeClearContent } from './clear-content.js'; import type { ClearContentAdapter } from './clear-content.js'; import type { Receipt } from '../types/receipt.js'; @@ -8,7 +9,7 @@ const NOOP_RECEIPT: Receipt = { success: false, failure: { code: 'NO_OP', messag describe('executeClearContent', () => { it('delegates to adapter.clearContent with input and options', () => { const adapter: ClearContentAdapter = { - clearContent: vi.fn(() => SUCCESS_RECEIPT), + clearContent: mock(() => SUCCESS_RECEIPT), }; const result = executeClearContent(adapter, {}, { expectedRevision: 'r1' }); @@ -19,7 +20,7 @@ describe('executeClearContent', () => { it('returns adapter result when NO_OP', () => { const adapter: ClearContentAdapter = { - clearContent: vi.fn(() => NOOP_RECEIPT), + clearContent: mock(() => NOOP_RECEIPT), }; const result = executeClearContent(adapter, {}); diff --git a/packages/document-api/src/contract/blocks-delete-contract.test.ts b/packages/document-api/src/contract/blocks-delete-contract.test.ts index a4d078cd7b..9d92135e19 100644 --- a/packages/document-api/src/contract/blocks-delete-contract.test.ts +++ b/packages/document-api/src/contract/blocks-delete-contract.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { executeBlocksDelete, type BlocksAdapter } from '../blocks/blocks.js'; import type { BlocksDeleteResult } from '../types/blocks.types.js'; import { DocumentApiValidationError } from '../errors.js'; diff --git a/packages/document-api/src/contract/contract.test.ts b/packages/document-api/src/contract/contract.test.ts index 0a00a05d46..868bbe3621 100644 --- a/packages/document-api/src/contract/contract.test.ts +++ b/packages/document-api/src/contract/contract.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { COMMAND_CATALOG, OPERATION_DESCRIPTION_MAP, OPERATION_EXPECTED_RESULT_MAP } from './command-catalog.js'; import { OPERATION_DEFINITIONS, type ReferenceGroupKey } from './operation-definitions.js'; import { DOCUMENT_API_MEMBER_PATHS, OPERATION_MEMBER_PATH_MAP, memberPathForOperation } from './operation-map.js'; diff --git a/packages/document-api/src/contract/types.test.ts b/packages/document-api/src/contract/types.test.ts index fc34505742..4a306e8663 100644 --- a/packages/document-api/src/contract/types.test.ts +++ b/packages/document-api/src/contract/types.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it } from 'bun:test'; import { assertOperationId, isOperationId, isValidOperationIdFormat, OPERATION_IDS } from './types.js'; import type { DocumentApiMemberPath } from './operation-map.js'; diff --git a/packages/document-api/src/create/create.test.ts b/packages/document-api/src/create/create.test.ts index 3a1459aa7a..4186934bd6 100644 --- a/packages/document-api/src/create/create.test.ts +++ b/packages/document-api/src/create/create.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it, mock } from 'bun:test'; import { executeCreateParagraph, executeCreateSectionBreak, @@ -144,7 +145,7 @@ describe('executeCreateSectionBreak', () => { paragraph: () => ({ success: true }), heading: () => ({ success: true }), table: () => ({ success: true }), - sectionBreak: vi.fn(() => ({ + sectionBreak: mock(() => ({ success: true, section: { kind: 'section', sectionId: 'section-1' }, })), @@ -166,7 +167,7 @@ describe('executeCreateSectionBreak', () => { paragraph: () => ({ success: true }), heading: () => ({ success: true }), table: () => ({ success: true }), - sectionBreak: vi.fn(() => ({ success: true })), + sectionBreak: mock(() => ({ success: true })), } as any; expect(() => @@ -181,7 +182,7 @@ describe('executeCreateSectionBreak', () => { paragraph: () => ({ success: true }), heading: () => ({ success: true }), table: () => ({ success: true }), - sectionBreak: vi.fn(() => ({ success: true })), + sectionBreak: mock(() => ({ success: true })), } as any; expect(() => diff --git a/packages/document-api/src/cross-refs/cross-refs.test.ts b/packages/document-api/src/cross-refs/cross-refs.test.ts index d3f20c9344..263a267bb8 100644 --- a/packages/document-api/src/cross-refs/cross-refs.test.ts +++ b/packages/document-api/src/cross-refs/cross-refs.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { DocumentApiValidationError } from '../errors.js'; import { executeCrossRefsList, @@ -11,11 +11,11 @@ import { function makeAdapter(): CrossRefsAdapter { return { - list: vi.fn().mockReturnValue({ items: [], total: 0 }), - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - rebuild: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), + list: mock().mockReturnValue({ items: [], total: 0 }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + rebuild: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), }; } diff --git a/packages/document-api/src/fields/fields.test.ts b/packages/document-api/src/fields/fields.test.ts index dbd70b625b..2dbacc7438 100644 --- a/packages/document-api/src/fields/fields.test.ts +++ b/packages/document-api/src/fields/fields.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { DocumentApiValidationError } from '../errors.js'; import { executeFieldsList, @@ -11,11 +11,11 @@ import { function makeAdapter(): FieldsAdapter { return { - list: vi.fn().mockReturnValue({ items: [], total: 0 }), - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - rebuild: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), + list: mock().mockReturnValue({ items: [], total: 0 }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + rebuild: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), }; } diff --git a/packages/document-api/src/find/find.test.ts b/packages/document-api/src/find/find.test.ts index 2b9b13334e..62dba27893 100644 --- a/packages/document-api/src/find/find.test.ts +++ b/packages/document-api/src/find/find.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it, mock } from 'bun:test'; import { executeFind, normalizeFindQuery } from './find.js'; import type { Query, Selector } from '../types/index.js'; import type { SDFindInput, SDFindResult } from '../types/sd-envelope.js'; @@ -167,7 +168,7 @@ describe('executeFind', () => { offset: 0, items: [], }; - const adapter: FindAdapter = { find: vi.fn(() => sdResult) }; + const adapter: FindAdapter = { find: mock(() => sdResult) }; const input: SDFindInput = { select: { type: 'node', nodeType: 'paragraph' }, limit: 5, @@ -186,7 +187,7 @@ describe('executeFind', () => { offset: 0, items: [], }; - const adapter: FindAdapter = { find: vi.fn(() => sdResult) }; + const adapter: FindAdapter = { find: mock(() => sdResult) }; const input: SDFindInput = { select: { type: 'text', pattern: 'hello' }, limit: 10, diff --git a/packages/document-api/src/footnotes/footnotes.test.ts b/packages/document-api/src/footnotes/footnotes.test.ts index a49a61f758..925a7af915 100644 --- a/packages/document-api/src/footnotes/footnotes.test.ts +++ b/packages/document-api/src/footnotes/footnotes.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { DocumentApiValidationError } from '../errors.js'; import { executeFootnotesList, @@ -12,12 +12,12 @@ import { function makeAdapter(): FootnotesAdapter { return { - list: vi.fn().mockReturnValue({ items: [], total: 0 }), - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - update: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), - configure: vi.fn().mockReturnValue({ success: true }), + list: mock().mockReturnValue({ items: [], total: 0 }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + update: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), + configure: mock().mockReturnValue({ success: true }), }; } diff --git a/packages/document-api/src/format/format.test.ts b/packages/document-api/src/format/format.test.ts index d0297f1b1c..5c3b3b6f2c 100644 --- a/packages/document-api/src/format/format.test.ts +++ b/packages/document-api/src/format/format.test.ts @@ -1,5 +1,9 @@ -import { describe, expect, it, vi, assertType } from 'vitest'; +import { describe, expect, it, mock } from 'bun:test'; import type { FormatInlineAliasInput, StyleApplyInput } from './format.js'; + +/** Type-only assertion — validates at compile time, no-op at runtime. */ +function assertType(_value: T): void {} + import { executeStyleApply, executeInlineAlias } from './format.js'; import { DocumentApiValidationError } from '../errors.js'; import type { TextMutationReceipt } from '../types/index.js'; @@ -25,9 +29,9 @@ function makeReceipt(): TextMutationReceipt { }; } -function makeAdapter(): SelectionMutationAdapter & Record> { +function makeAdapter(): SelectionMutationAdapter & Record> { return { - execute: vi.fn(() => makeReceipt()), + execute: mock(() => makeReceipt()), }; } diff --git a/packages/document-api/src/format/inline-run-patch.test.ts b/packages/document-api/src/format/inline-run-patch.test.ts index 04e6a1dd21..f37869b836 100644 --- a/packages/document-api/src/format/inline-run-patch.test.ts +++ b/packages/document-api/src/format/inline-run-patch.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { INLINE_PROPERTY_BY_KEY, validateInlineRunPatch } from './inline-run-patch.js'; import { DocumentApiValidationError } from '../errors.js'; diff --git a/packages/document-api/src/get-html/get-html.test.ts b/packages/document-api/src/get-html/get-html.test.ts index c033b8c931..6542b5bf1f 100644 --- a/packages/document-api/src/get-html/get-html.test.ts +++ b/packages/document-api/src/get-html/get-html.test.ts @@ -1,10 +1,11 @@ +import { describe, expect, it, mock } from 'bun:test'; import { executeGetHtml } from './get-html.js'; import type { GetHtmlAdapter } from './get-html.js'; describe('executeGetHtml', () => { it('delegates to adapter.getHtml with the input', () => { const adapter: GetHtmlAdapter = { - getHtml: vi.fn(() => '

Hello world

'), + getHtml: mock(() => '

Hello world

'), }; const result = executeGetHtml(adapter, {}); @@ -15,7 +16,7 @@ describe('executeGetHtml', () => { it('passes unflattenLists option through to the adapter', () => { const adapter: GetHtmlAdapter = { - getHtml: vi.fn(() => '
  1. item
'), + getHtml: mock(() => '
  1. item
'), }; const result = executeGetHtml(adapter, { unflattenLists: false }); diff --git a/packages/document-api/src/get-markdown/get-markdown.test.ts b/packages/document-api/src/get-markdown/get-markdown.test.ts index 9b8c252f41..d0521a1c55 100644 --- a/packages/document-api/src/get-markdown/get-markdown.test.ts +++ b/packages/document-api/src/get-markdown/get-markdown.test.ts @@ -1,10 +1,11 @@ +import { describe, expect, it, mock } from 'bun:test'; import { executeGetMarkdown } from './get-markdown.js'; import type { GetMarkdownAdapter } from './get-markdown.js'; describe('executeGetMarkdown', () => { it('delegates to adapter.getMarkdown with the input', () => { const adapter: GetMarkdownAdapter = { - getMarkdown: vi.fn(() => '# Hello\n\nworld\n'), + getMarkdown: mock(() => '# Hello\n\nworld\n'), }; const result = executeGetMarkdown(adapter, {}); diff --git a/packages/document-api/src/get-node/get-node.test.ts b/packages/document-api/src/get-node/get-node.test.ts index d1bb087809..338a235b9a 100644 --- a/packages/document-api/src/get-node/get-node.test.ts +++ b/packages/document-api/src/get-node/get-node.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it, mock } from 'bun:test'; import type { NodeAddress, NodeInfo } from '../types/index.js'; import { executeGetNode, executeGetNodeById } from './get-node.js'; import type { GetNodeAdapter } from './get-node.js'; @@ -13,8 +14,8 @@ const PARAGRAPH_INFO: NodeInfo = { describe('executeGetNode', () => { it('delegates to adapter.getNode with the address', () => { const adapter: GetNodeAdapter = { - getNode: vi.fn(() => PARAGRAPH_INFO), - getNodeById: vi.fn(() => PARAGRAPH_INFO), + getNode: mock(() => PARAGRAPH_INFO), + getNodeById: mock(() => PARAGRAPH_INFO), }; const result = executeGetNode(adapter, PARAGRAPH_ADDRESS); @@ -27,8 +28,8 @@ describe('executeGetNode', () => { describe('executeGetNodeById', () => { it('delegates to adapter.getNodeById with the input', () => { const adapter: GetNodeAdapter = { - getNode: vi.fn(() => PARAGRAPH_INFO), - getNodeById: vi.fn(() => PARAGRAPH_INFO), + getNode: mock(() => PARAGRAPH_INFO), + getNodeById: mock(() => PARAGRAPH_INFO), }; const input = { nodeId: 'p1', nodeType: 'paragraph' as const }; diff --git a/packages/document-api/src/get-text/get-text.test.ts b/packages/document-api/src/get-text/get-text.test.ts index 911cd3a536..7df05207be 100644 --- a/packages/document-api/src/get-text/get-text.test.ts +++ b/packages/document-api/src/get-text/get-text.test.ts @@ -1,10 +1,11 @@ +import { describe, expect, it, mock } from 'bun:test'; import { executeGetText } from './get-text.js'; import type { GetTextAdapter } from './get-text.js'; describe('executeGetText', () => { it('delegates to adapter.getText with the input', () => { const adapter: GetTextAdapter = { - getText: vi.fn(() => 'Hello world'), + getText: mock(() => 'Hello world'), }; const result = executeGetText(adapter, {}); diff --git a/packages/document-api/src/history/history.test.ts b/packages/document-api/src/history/history.test.ts index eb796437f6..d26207f9ad 100644 --- a/packages/document-api/src/history/history.test.ts +++ b/packages/document-api/src/history/history.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it, vi } from 'vitest'; +import { describe, expect, it, mock } from 'bun:test'; import type { HistoryAdapter } from './history.js'; import { executeHistoryGet, executeHistoryUndo, executeHistoryRedo } from './history.js'; import type { HistoryState, HistoryActionResult } from './history.types.js'; @@ -27,9 +27,9 @@ function makeHistoryAdapter( }; return { - get: vi.fn(() => state), - undo: vi.fn(() => undoResult), - redo: vi.fn(() => redoResult), + get: mock(() => state), + undo: mock(() => undoResult), + redo: mock(() => redoResult), }; } diff --git a/packages/document-api/src/hyperlinks/hyperlinks.test.ts b/packages/document-api/src/hyperlinks/hyperlinks.test.ts index b43dd955b3..34b9b06567 100644 --- a/packages/document-api/src/hyperlinks/hyperlinks.test.ts +++ b/packages/document-api/src/hyperlinks/hyperlinks.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { executeHyperlinksList, executeHyperlinksGet, @@ -38,12 +38,12 @@ function makeAdapter(overrides: Partial = {}): HyperlinksAdap }; return { - list: vi.fn(() => defaultList), - get: vi.fn(() => defaultInfo), - wrap: vi.fn(() => defaultResult), - insert: vi.fn(() => defaultResult), - patch: vi.fn(() => defaultResult), - remove: vi.fn(() => defaultResult), + list: mock(() => defaultList), + get: mock(() => defaultInfo), + wrap: mock(() => defaultResult), + insert: mock(() => defaultResult), + patch: mock(() => defaultResult), + remove: mock(() => defaultResult), ...overrides, }; } diff --git a/packages/document-api/src/images/images.test.ts b/packages/document-api/src/images/images.test.ts index 6867cf61b5..1167a5bbfd 100644 --- a/packages/document-api/src/images/images.test.ts +++ b/packages/document-api/src/images/images.test.ts @@ -1,10 +1,10 @@ -import { describe, expect, it, vi } from 'vitest'; +import { describe, expect, it, mock } from 'bun:test'; import { DocumentApiValidationError } from '../errors.js'; import { executeImagesSetZOrder, type ImagesAdapter } from './images.js'; import { Z_ORDER_RELATIVE_HEIGHT_MAX, Z_ORDER_RELATIVE_HEIGHT_MIN } from './z-order.js'; function makeSetZOrderAdapter() { - const setZOrder = vi.fn(() => ({ + const setZOrder = mock(() => ({ success: true as const, image: { kind: 'inline' as const, diff --git a/packages/document-api/src/index.test.ts b/packages/document-api/src/index.test.ts index 2ae6560a36..f29cf2edbe 100644 --- a/packages/document-api/src/index.test.ts +++ b/packages/document-api/src/index.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it, mock } from 'bun:test'; import type { DocumentInfo, NodeAddress, SDNodeResult, SDFindResult } from './types/index.js'; import type { CommentsAdapter, @@ -21,25 +22,25 @@ import type { HistoryAdapter } from './history/history.js'; import type { TablesAdapter } from './index.js'; function makeFindAdapter(result: SDFindResult): FindAdapter { - return { find: vi.fn(() => result) }; + return { find: mock(() => result) }; } function makeGetAdapter(): GetAdapter { return { - get: vi.fn(() => ({ modelVersion: 'sdm/1' as const, body: [] })), + get: mock(() => ({ modelVersion: 'sdm/1' as const, body: [] })), }; } function makeGetNodeAdapter(result: SDNodeResult): GetNodeAdapter { return { - getNode: vi.fn(() => result), - getNodeById: vi.fn((_input) => result), + getNode: mock(() => result), + getNodeById: mock((_input) => result), }; } function makeGetTextAdapter(text = '') { return { - getText: vi.fn((_input) => text), + getText: mock((_input) => text), }; } @@ -68,7 +69,7 @@ function makeInfoAdapter(result?: Partial) { }; return { - info: vi.fn((_input) => ({ + info: mock((_input) => ({ ...defaultResult, ...result, counts: { @@ -86,21 +87,21 @@ function makeInfoAdapter(result?: Partial) { function makeCommentsAdapter(): CommentsAdapter { return { - add: vi.fn(() => ({ success: true as const })), - edit: vi.fn(() => ({ success: true as const })), - reply: vi.fn(() => ({ success: true as const })), - move: vi.fn(() => ({ success: true as const })), - resolve: vi.fn(() => ({ success: true as const })), - remove: vi.fn(() => ({ success: true as const })), - setInternal: vi.fn(() => ({ success: true as const })), - setActive: vi.fn(() => ({ success: true as const })), - goTo: vi.fn(() => ({ success: true as const })), - get: vi.fn(() => ({ + add: mock(() => ({ success: true as const })), + edit: mock(() => ({ success: true as const })), + reply: mock(() => ({ success: true as const })), + move: mock(() => ({ success: true as const })), + resolve: mock(() => ({ success: true as const })), + remove: mock(() => ({ success: true as const })), + setInternal: mock(() => ({ success: true as const })), + setActive: mock(() => ({ success: true as const })), + goTo: mock(() => ({ success: true as const })), + get: mock(() => ({ address: { kind: 'entity' as const, entityType: 'comment' as const, entityId: 'c1' }, commentId: 'c1', status: 'open' as const, })), - list: vi.fn(() => ({ evaluatedRevision: 'r1', total: 0, items: [], page: { limit: 0, offset: 0, returned: 0 } })), + list: mock(() => ({ evaluatedRevision: 'r1', total: 0, items: [], page: { limit: 0, offset: 0, returned: 0 } })), }; } @@ -124,15 +125,15 @@ function makeWriteAdapter(): WriteAdapter { }, }; return { - write: vi.fn(() => textReceipt), - insertStructured: vi.fn(() => sdReceipt), - replaceStructured: vi.fn(() => sdReceipt), + write: mock(() => textReceipt), + insertStructured: mock(() => sdReceipt), + replaceStructured: mock(() => sdReceipt), }; } function makeSelectionMutationAdapter(): SelectionMutationAdapter { return { - execute: vi.fn(() => ({ + execute: mock(() => ({ success: true as const, resolution: { target: { kind: 'text' as const, blockId: 'p1', range: { start: 0, end: 2 } }, @@ -145,37 +146,37 @@ function makeSelectionMutationAdapter(): SelectionMutationAdapter { function makeTrackChangesAdapter(): TrackChangesAdapter { return { - list: vi.fn((_input) => ({ + list: mock((_input) => ({ evaluatedRevision: 'r1', total: 0, items: [], page: { limit: 0, offset: 0, returned: 0 }, })), - get: vi.fn((input: { id: string }) => ({ + get: mock((input: { id: string }) => ({ address: { kind: 'entity' as const, entityType: 'trackedChange' as const, entityId: input.id }, id: input.id, type: 'insert' as const, })), - accept: vi.fn((_input) => ({ success: true as const })), - reject: vi.fn((_input) => ({ success: true as const })), - acceptAll: vi.fn((_input) => ({ success: true as const })), - rejectAll: vi.fn((_input) => ({ success: true as const })), + accept: mock((_input) => ({ success: true as const })), + reject: mock((_input) => ({ success: true as const })), + acceptAll: mock((_input) => ({ success: true as const })), + rejectAll: mock((_input) => ({ success: true as const })), }; } function makeCreateAdapter(): CreateAdapter { return { - paragraph: vi.fn(() => ({ + paragraph: mock(() => ({ success: true as const, paragraph: { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'new-p' }, insertionPoint: { kind: 'text' as const, blockId: 'new-p', range: { start: 0, end: 0 } }, })), - heading: vi.fn(() => ({ + heading: mock(() => ({ success: true as const, heading: { kind: 'block' as const, nodeType: 'heading' as const, nodeId: 'new-h' }, insertionPoint: { kind: 'text' as const, blockId: 'new-h', range: { start: 0, end: 0 } }, })), - table: vi.fn(() => ({ + table: mock(() => ({ success: true as const, table: { kind: 'block' as const, nodeType: 'table' as const, nodeId: 'new-t' }, })), @@ -184,73 +185,73 @@ function makeCreateAdapter(): CreateAdapter { function makeListsAdapter(): ListsAdapter { return { - list: vi.fn(() => ({ evaluatedRevision: 'r1', total: 0, items: [], page: { limit: 0, offset: 0, returned: 0 } })), - get: vi.fn(() => ({ + list: mock(() => ({ evaluatedRevision: 'r1', total: 0, items: [], page: { limit: 0, offset: 0, returned: 0 } })), + get: mock(() => ({ address: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, kind: 'ordered' as const, level: 0, text: 'List item', })), - insert: vi.fn(() => ({ + insert: mock(() => ({ success: true as const, item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-2' }, insertionPoint: { kind: 'text' as const, blockId: 'li-2', range: { start: 0, end: 0 } }, })), - indent: vi.fn(() => ({ + indent: mock(() => ({ success: true as const, item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, })), - outdent: vi.fn(() => ({ + outdent: mock(() => ({ success: true as const, item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, })), - create: vi.fn(() => ({ + create: mock(() => ({ success: true as const, listId: '99', item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, })), - attach: vi.fn(() => ({ + attach: mock(() => ({ success: true as const, item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, })), - detach: vi.fn(() => ({ + detach: mock(() => ({ success: true as const, paragraph: { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'p1' }, })), - join: vi.fn(() => ({ + join: mock(() => ({ success: true as const, listId: '1', })), - canJoin: vi.fn(() => ({ + canJoin: mock(() => ({ canJoin: true as const, adjacentListId: '2', })), - separate: vi.fn(() => ({ + separate: mock(() => ({ success: true as const, listId: '99', numId: 99, })), - setLevel: vi.fn(() => ({ + setLevel: mock(() => ({ success: true as const, item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, })), - setValue: vi.fn(() => ({ + setValue: mock(() => ({ success: true as const, item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, })), - continuePrevious: vi.fn(() => ({ + continuePrevious: mock(() => ({ success: true as const, item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, })), - canContinuePrevious: vi.fn(() => ({ + canContinuePrevious: mock(() => ({ canContinue: true as const, previousListId: '1', })), - setLevelRestart: vi.fn(() => ({ + setLevelRestart: mock(() => ({ success: true as const, item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, })), - convertToText: vi.fn(() => ({ + convertToText: mock(() => ({ success: true as const, paragraph: { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'p1' }, })), @@ -263,7 +264,7 @@ const TABLE_MUTATION_RESULT = { }; function makeTablesAdapter(): TablesAdapter { - const mutation = vi.fn(() => ({ ...TABLE_MUTATION_RESULT })); + const mutation = mock(() => ({ ...TABLE_MUTATION_RESULT })); return { convertFromText: mutation, delete: mutation, @@ -301,13 +302,13 @@ function makeTablesAdapter(): TablesAdapter { setCellPadding: mutation, setCellSpacing: mutation, clearCellSpacing: mutation, - get: vi.fn(() => ({ + get: mock(() => ({ nodeId: 't1', address: { kind: 'block' as const, nodeType: 'table' as const, nodeId: 't1' }, rows: 3, columns: 3, })), - getCells: vi.fn(() => ({ + getCells: mock(() => ({ nodeId: 't1', address: { kind: 'block' as const, nodeType: 'table' as const, nodeId: 't1' }, cells: [ @@ -321,7 +322,7 @@ function makeTablesAdapter(): TablesAdapter { }, ], })), - getProperties: vi.fn(() => ({ + getProperties: mock(() => ({ nodeId: 't1', address: { kind: 'block' as const, nodeType: 'table' as const, nodeId: 't1' }, styleId: 'TableGrid', @@ -332,15 +333,15 @@ function makeTablesAdapter(): TablesAdapter { function makeHistoryAdapter(): HistoryAdapter { return { - get: vi.fn(() => ({ + get: mock(() => ({ undoDepth: 0, redoDepth: 0, canUndo: false, canRedo: false, historyUnsafeOperations: [], })), - undo: vi.fn(() => ({ noop: true, revision: { before: '0', after: '0' } })), - redo: vi.fn(() => ({ noop: true, revision: { before: '0', after: '0' } })), + undo: mock(() => ({ noop: true, revision: { before: '0', after: '0' } })), + redo: mock(() => ({ noop: true, revision: { before: '0', after: '0' } })), }; } @@ -363,7 +364,7 @@ function makeCapabilitiesAdapter(overrides?: Partial): }, }; return { - get: vi.fn(() => ({ ...defaultCapabilities, ...overrides })), + get: mock(() => ({ ...defaultCapabilities, ...overrides })), }; } diff --git a/packages/document-api/src/index/index.test.ts b/packages/document-api/src/index/index.test.ts index 39d353f3df..83b3f18968 100644 --- a/packages/document-api/src/index/index.test.ts +++ b/packages/document-api/src/index/index.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { DocumentApiValidationError } from '../errors.js'; import { executeIndexList, @@ -17,18 +17,18 @@ import { function makeAdapter(): IndexAdapter { return { - list: vi.fn().mockReturnValue({ items: [], total: 0 }), - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - configure: vi.fn().mockReturnValue({ success: true }), - rebuild: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), + list: mock().mockReturnValue({ items: [], total: 0 }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + configure: mock().mockReturnValue({ success: true }), + rebuild: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), entries: { - list: vi.fn().mockReturnValue({ items: [], total: 0 }), - get: vi.fn().mockReturnValue({}), - insert: vi.fn().mockReturnValue({ success: true }), - update: vi.fn().mockReturnValue({ success: true }), - remove: vi.fn().mockReturnValue({ success: true }), + list: mock().mockReturnValue({ items: [], total: 0 }), + get: mock().mockReturnValue({}), + insert: mock().mockReturnValue({ success: true }), + update: mock().mockReturnValue({ success: true }), + remove: mock().mockReturnValue({ success: true }), }, }; } diff --git a/packages/document-api/src/info/info.test.ts b/packages/document-api/src/info/info.test.ts index 528862e9c1..05e293f099 100644 --- a/packages/document-api/src/info/info.test.ts +++ b/packages/document-api/src/info/info.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it, mock } from 'bun:test'; import type { DocumentInfo } from '../types/index.js'; import { executeInfo } from './info.js'; import type { InfoAdapter } from './info.js'; @@ -23,7 +24,7 @@ const DEFAULT_INFO: DocumentInfo = { describe('executeInfo', () => { it('delegates to adapter.info with the input', () => { const adapter: InfoAdapter = { - info: vi.fn(() => DEFAULT_INFO), + info: mock(() => DEFAULT_INFO), }; const result = executeInfo(adapter, {}); diff --git a/packages/document-api/src/inline-semantics/directives.test.ts b/packages/document-api/src/inline-semantics/directives.test.ts index 642d57cf08..dbfd5bfed1 100644 --- a/packages/document-api/src/inline-semantics/directives.test.ts +++ b/packages/document-api/src/inline-semantics/directives.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { applyDirectiveTransition, wouldDirectiveChange, diff --git a/packages/document-api/src/inline-semantics/property-ids.test.ts b/packages/document-api/src/inline-semantics/property-ids.test.ts index 82a8f7825a..d721659e0f 100644 --- a/packages/document-api/src/inline-semantics/property-ids.test.ts +++ b/packages/document-api/src/inline-semantics/property-ids.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { CORE_PROPERTY_IDS, CORE_PROPERTY_ID_SET, diff --git a/packages/document-api/src/inline-semantics/token-parsers.test.ts b/packages/document-api/src/inline-semantics/token-parsers.test.ts index 7d8bc9bc14..63d7c7302b 100644 --- a/packages/document-api/src/inline-semantics/token-parsers.test.ts +++ b/packages/document-api/src/inline-semantics/token-parsers.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { parseStOnOff, parseStUnderline, diff --git a/packages/document-api/src/invoke/invoke.test.ts b/packages/document-api/src/invoke/invoke.test.ts index 32e13640bb..5fb7718f46 100644 --- a/packages/document-api/src/invoke/invoke.test.ts +++ b/packages/document-api/src/invoke/invoke.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { OPERATION_IDS, type OperationId } from '../contract/types.js'; import { createDocumentApi, type DocumentApiAdapters } from '../index.js'; import { buildDispatchTable } from './invoke.js'; @@ -15,15 +15,15 @@ import type { CapabilitiesAdapter, DocumentApiCapabilities } from '../capabiliti function makeAdapters() { const findAdapter: FindAdapter = { - find: vi.fn(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 50, offset: 0, returned: 0 } })), + find: mock(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 50, offset: 0, returned: 0 } })), }; const getNodeAdapter: GetNodeAdapter = { - getNode: vi.fn(() => ({ kind: 'block' as const, nodeType: 'paragraph' as const, properties: {} })), - getNodeById: vi.fn(() => ({ kind: 'block' as const, nodeType: 'paragraph' as const, properties: {} })), + getNode: mock(() => ({ kind: 'block' as const, nodeType: 'paragraph' as const, properties: {} })), + getNodeById: mock(() => ({ kind: 'block' as const, nodeType: 'paragraph' as const, properties: {} })), }; - const getTextAdapter = { getText: vi.fn(() => 'hello') }; + const getTextAdapter = { getText: mock(() => 'hello') }; const infoAdapter = { - info: vi.fn(() => ({ + info: mock(() => ({ counts: { words: 1, characters: 5, @@ -42,7 +42,7 @@ function makeAdapters() { })), }; const capabilitiesAdapter: CapabilitiesAdapter = { - get: vi.fn( + get: mock( (): DocumentApiCapabilities => ({ global: { trackChanges: { enabled: false }, @@ -62,24 +62,24 @@ function makeAdapters() { ), }; const commentsAdapter: CommentsAdapter = { - add: vi.fn(() => ({ success: true as const })), - edit: vi.fn(() => ({ success: true as const })), - reply: vi.fn(() => ({ success: true as const })), - move: vi.fn(() => ({ success: true as const })), - resolve: vi.fn(() => ({ success: true as const })), - remove: vi.fn(() => ({ success: true as const })), - setInternal: vi.fn(() => ({ success: true as const })), - setActive: vi.fn(() => ({ success: true as const })), - goTo: vi.fn(() => ({ success: true as const })), - get: vi.fn(() => ({ + add: mock(() => ({ success: true as const })), + edit: mock(() => ({ success: true as const })), + reply: mock(() => ({ success: true as const })), + move: mock(() => ({ success: true as const })), + resolve: mock(() => ({ success: true as const })), + remove: mock(() => ({ success: true as const })), + setInternal: mock(() => ({ success: true as const })), + setActive: mock(() => ({ success: true as const })), + goTo: mock(() => ({ success: true as const })), + get: mock(() => ({ address: { kind: 'entity' as const, entityType: 'comment' as const, entityId: 'c1' }, commentId: 'c1', status: 'open' as const, })), - list: vi.fn(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 50, offset: 0, returned: 0 } })), + list: mock(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 50, offset: 0, returned: 0 } })), }; const writeAdapter: WriteAdapter = { - write: vi.fn(() => ({ + write: mock(() => ({ success: true as const, resolution: { target: { kind: 'text' as const, blockId: 'p1', range: { start: 0, end: 0 } }, @@ -87,7 +87,7 @@ function makeAdapters() { text: '', }, })), - insertStructured: vi.fn(() => ({ + insertStructured: mock(() => ({ success: true as const, resolution: { target: { kind: 'text' as const, blockId: 'p1', range: { start: 0, end: 0 } }, @@ -111,10 +111,10 @@ function makeAdapters() { }, }); const selectionMutationAdapter: SelectionMutationAdapter = { - execute: vi.fn(selectionMutationReceipt), + execute: mock(selectionMutationReceipt), }; const stylesAdapter: StylesAdapter = { - apply: vi.fn(() => ({ + apply: mock(() => ({ success: true as const, changed: true, resolution: { @@ -129,24 +129,24 @@ function makeAdapters() { })), }; const trackChangesAdapter: TrackChangesAdapter = { - list: vi.fn(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 50, offset: 0, returned: 0 } })), - get: vi.fn((input: { id: string }) => ({ + list: mock(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 50, offset: 0, returned: 0 } })), + get: mock((input: { id: string }) => ({ address: { kind: 'entity' as const, entityType: 'trackedChange' as const, entityId: input.id }, id: input.id, type: 'insert' as const, })), - accept: vi.fn(() => ({ success: true as const })), - reject: vi.fn(() => ({ success: true as const })), - acceptAll: vi.fn(() => ({ success: true as const })), - rejectAll: vi.fn(() => ({ success: true as const })), + accept: mock(() => ({ success: true as const })), + reject: mock(() => ({ success: true as const })), + acceptAll: mock(() => ({ success: true as const })), + rejectAll: mock(() => ({ success: true as const })), }; const createAdapter: CreateAdapter = { - paragraph: vi.fn(() => ({ + paragraph: mock(() => ({ success: true as const, paragraph: { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'new-p' }, insertionPoint: { kind: 'text' as const, blockId: 'new-p', range: { start: 0, end: 0 } }, })), - heading: vi.fn(() => ({ + heading: mock(() => ({ success: true as const, heading: { kind: 'block' as const, nodeType: 'heading' as const, nodeId: 'new-h' }, insertionPoint: { kind: 'text' as const, blockId: 'new-h', range: { start: 0, end: 0 } }, @@ -157,62 +157,62 @@ function makeAdapters() { item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, }); const listsAdapter: ListsAdapter = { - list: vi.fn(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 50, offset: 0, returned: 0 } })), - get: vi.fn(() => ({ + list: mock(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 50, offset: 0, returned: 0 } })), + get: mock(() => ({ address: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, listId: 'list-1', })), - insert: vi.fn(() => ({ + insert: mock(() => ({ success: true as const, item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-2' }, insertionPoint: { kind: 'text' as const, blockId: 'li-2', range: { start: 0, end: 0 } }, })), - indent: vi.fn(listsMutateResult), - outdent: vi.fn(listsMutateResult), - create: vi.fn(() => ({ + indent: mock(listsMutateResult), + outdent: mock(listsMutateResult), + create: mock(() => ({ success: true as const, listId: 'list-new', item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-new' }, })), - attach: vi.fn(listsMutateResult), - detach: vi.fn(() => ({ + attach: mock(listsMutateResult), + detach: mock(() => ({ success: true as const, paragraph: { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'p3' }, })), - join: vi.fn(() => ({ success: true as const, listId: 'list-1' })), - canJoin: vi.fn(() => ({ canJoin: true })), - separate: vi.fn(() => ({ success: true as const, listId: 'list-new', numId: 2 })), - setLevel: vi.fn(listsMutateResult), - setValue: vi.fn(listsMutateResult), - continuePrevious: vi.fn(listsMutateResult), - canContinuePrevious: vi.fn(() => ({ canContinue: true })), - setLevelRestart: vi.fn(listsMutateResult), - convertToText: vi.fn(() => ({ + join: mock(() => ({ success: true as const, listId: 'list-1' })), + canJoin: mock(() => ({ canJoin: true })), + separate: mock(() => ({ success: true as const, listId: 'list-new', numId: 2 })), + setLevel: mock(listsMutateResult), + setValue: mock(listsMutateResult), + continuePrevious: mock(listsMutateResult), + canContinuePrevious: mock(() => ({ canContinue: true })), + setLevelRestart: mock(listsMutateResult), + convertToText: mock(() => ({ success: true as const, paragraph: { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'p3' }, })), - applyTemplate: vi.fn(listsMutateResult), - applyPreset: vi.fn(listsMutateResult), - captureTemplate: vi.fn(() => ({ + applyTemplate: mock(listsMutateResult), + applyPreset: mock(listsMutateResult), + captureTemplate: mock(() => ({ success: true as const, template: { version: 1, levels: [] }, })), - setLevelNumbering: vi.fn(listsMutateResult), - setLevelBullet: vi.fn(listsMutateResult), - setLevelPictureBullet: vi.fn(listsMutateResult), - setLevelAlignment: vi.fn(listsMutateResult), - setLevelIndents: vi.fn(listsMutateResult), - setLevelTrailingCharacter: vi.fn(listsMutateResult), - setLevelMarkerFont: vi.fn(listsMutateResult), - clearLevelOverrides: vi.fn(listsMutateResult), + setLevelNumbering: mock(listsMutateResult), + setLevelBullet: mock(listsMutateResult), + setLevelPictureBullet: mock(listsMutateResult), + setLevelAlignment: mock(listsMutateResult), + setLevelIndents: mock(listsMutateResult), + setLevelTrailingCharacter: mock(listsMutateResult), + setLevelMarkerFont: mock(listsMutateResult), + clearLevelOverrides: mock(listsMutateResult), }; const queryAdapter = { - match: vi.fn(() => ({ evaluatedRevision: 'r1', total: 0, items: [], page: { limit: 0, offset: 0, returned: 0 } })), + match: mock(() => ({ evaluatedRevision: 'r1', total: 0, items: [], page: { limit: 0, offset: 0, returned: 0 } })), }; const mutationsAdapter = { - preview: vi.fn(() => ({ evaluatedRevision: 'r1', steps: [], valid: true })), - apply: vi.fn(() => ({ + preview: mock(() => ({ evaluatedRevision: 'r1', steps: [], valid: true })), + apply: mock(() => ({ success: true as const, revision: { before: 'r1', after: 'r2' }, steps: [], @@ -222,8 +222,8 @@ function makeAdapters() { }; const headerFootersAdapter = { - list: vi.fn(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 250, offset: 0, returned: 0 } })), - get: vi.fn(() => ({ + list: mock(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 250, offset: 0, returned: 0 } })), + get: mock(() => ({ section: { kind: 'section' as const, sectionId: 's0' }, sectionIndex: 0, kind: 'header' as const, @@ -231,19 +231,19 @@ function makeAdapters() { refId: null, isExplicit: false, })), - resolve: vi.fn(() => ({ status: 'none' as const })), + resolve: mock(() => ({ status: 'none' as const })), refs: { - set: vi.fn(() => ({ success: true as const, section: { kind: 'section' as const, sectionId: 's0' } })), - clear: vi.fn(() => ({ success: true as const, section: { kind: 'section' as const, sectionId: 's0' } })), - setLinkedToPrevious: vi.fn(() => ({ + set: mock(() => ({ success: true as const, section: { kind: 'section' as const, sectionId: 's0' } })), + clear: mock(() => ({ success: true as const, section: { kind: 'section' as const, sectionId: 's0' } })), + setLinkedToPrevious: mock(() => ({ success: true as const, section: { kind: 'section' as const, sectionId: 's0' }, })), }, parts: { - list: vi.fn(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 250, offset: 0, returned: 0 } })), - create: vi.fn(() => ({ success: true as const, refId: 'rId99', partPath: 'word/header99.xml' })), - delete: vi.fn(() => ({ success: true as const, refId: 'rId99', partPath: 'word/header99.xml' })), + list: mock(() => ({ evaluatedRevision: '', total: 0, items: [], page: { limit: 250, offset: 0, returned: 0 } })), + create: mock(() => ({ success: true as const, refId: 'rId99', partPath: 'word/header99.xml' })), + delete: mock(() => ({ success: true as const, refId: 'rId99', partPath: 'word/header99.xml' })), }, }; diff --git a/packages/document-api/src/markdown-to-fragment/markdown-to-fragment.test.ts b/packages/document-api/src/markdown-to-fragment/markdown-to-fragment.test.ts index 0bab033098..1c05d86321 100644 --- a/packages/document-api/src/markdown-to-fragment/markdown-to-fragment.test.ts +++ b/packages/document-api/src/markdown-to-fragment/markdown-to-fragment.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { executeMarkdownToFragment } from './markdown-to-fragment.js'; import type { MarkdownToFragmentAdapter, MarkdownToFragmentInput } from './markdown-to-fragment.js'; import type { SDMarkdownToFragmentResult } from '../types/sd-contract.js'; @@ -11,7 +11,7 @@ describe('executeMarkdownToFragment', () => { diagnostics: [], }; const adapter: MarkdownToFragmentAdapter = { - markdownToFragment: vi.fn(() => result), + markdownToFragment: mock(() => result), }; const input: MarkdownToFragmentInput = { markdown: '# Hello' }; @@ -28,7 +28,7 @@ describe('executeMarkdownToFragment', () => { diagnostics: [{ code: 'MD_BLOCKQUOTE', severity: 'warning', message: 'Blockquotes have no direct equivalent.' }], }; const adapter: MarkdownToFragmentAdapter = { - markdownToFragment: vi.fn(() => result), + markdownToFragment: mock(() => result), }; const input: MarkdownToFragmentInput = { markdown: '> blockquote' }; diff --git a/packages/document-api/src/overview-examples.test.ts b/packages/document-api/src/overview-examples.test.ts index 8d2a93e823..786eb66827 100644 --- a/packages/document-api/src/overview-examples.test.ts +++ b/packages/document-api/src/overview-examples.test.ts @@ -6,7 +6,7 @@ * If any of these tests break, the corresponding documentation example is wrong * and must be updated to match. */ -import { describe, expect, it, vi } from 'vitest'; +import { describe, expect, it, mock } from 'bun:test'; import { createDocumentApi } from './index.js'; import type { DocumentApiCapabilities } from './capabilities/capabilities.js'; import type { SelectionTarget } from './types/index.js'; @@ -35,7 +35,7 @@ function makeTextMutationReceipt() { function makeFindAdapter() { return { - find: vi.fn(() => ({ + find: mock(() => ({ evaluatedRevision: '', total: 1, items: [ @@ -79,18 +79,18 @@ function makeFindAdapter() { function makeGetNodeAdapter() { return { - getNode: vi.fn(() => ({ nodeType: 'paragraph', kind: 'block', properties: {} })), - getNodeById: vi.fn(() => ({ nodeType: 'paragraph', kind: 'block', properties: {} })), + getNode: mock(() => ({ nodeType: 'paragraph', kind: 'block', properties: {} })), + getNodeById: mock(() => ({ nodeType: 'paragraph', kind: 'block', properties: {} })), }; } function makeGetTextAdapter() { - return { getText: vi.fn(() => 'hello') }; + return { getText: mock(() => 'hello') }; } function makeInfoAdapter() { return { - info: vi.fn(() => ({ + info: mock(() => ({ counts: { words: 0, characters: 0, @@ -125,15 +125,15 @@ function makeSDMutationReceipt() { function makeWriteAdapter() { return { - write: vi.fn(() => makeTextMutationReceipt()), - insertStructured: vi.fn(() => makeSDMutationReceipt()), - replaceStructured: vi.fn(() => makeSDMutationReceipt()), + write: mock(() => makeTextMutationReceipt()), + insertStructured: mock(() => makeSDMutationReceipt()), + replaceStructured: mock(() => makeSDMutationReceipt()), }; } function makeSelectionMutationAdapter() { return { - execute: vi.fn(() => makeTextMutationReceipt()), + execute: mock(() => makeTextMutationReceipt()), }; } @@ -145,46 +145,46 @@ function makeParagraphsAdapter() { }); return { - setStyle: vi.fn(ok), - clearStyle: vi.fn(ok), - resetDirectFormatting: vi.fn(ok), - setAlignment: vi.fn(ok), - clearAlignment: vi.fn(ok), - setIndentation: vi.fn(ok), - clearIndentation: vi.fn(ok), - setSpacing: vi.fn(ok), - clearSpacing: vi.fn(ok), - setKeepOptions: vi.fn(ok), - setOutlineLevel: vi.fn(ok), - setFlowOptions: vi.fn(ok), - setTabStop: vi.fn(ok), - clearTabStop: vi.fn(ok), - clearAllTabStops: vi.fn(ok), - setBorder: vi.fn(ok), - clearBorder: vi.fn(ok), - setShading: vi.fn(ok), - clearShading: vi.fn(ok), + setStyle: mock(ok), + clearStyle: mock(ok), + resetDirectFormatting: mock(ok), + setAlignment: mock(ok), + clearAlignment: mock(ok), + setIndentation: mock(ok), + clearIndentation: mock(ok), + setSpacing: mock(ok), + clearSpacing: mock(ok), + setKeepOptions: mock(ok), + setOutlineLevel: mock(ok), + setFlowOptions: mock(ok), + setTabStop: mock(ok), + clearTabStop: mock(ok), + clearAllTabStops: mock(ok), + setBorder: mock(ok), + clearBorder: mock(ok), + setShading: mock(ok), + clearShading: mock(ok), }; } function makeCommentsAdapter() { return { - add: vi.fn(() => ({ success: true as const })), - edit: vi.fn(() => ({ success: true as const })), - reply: vi.fn(() => ({ success: true as const })), - move: vi.fn(() => ({ success: true as const })), - resolve: vi.fn(() => ({ success: true as const })), - remove: vi.fn(() => ({ success: true as const })), - setInternal: vi.fn(() => ({ success: true as const })), - setActive: vi.fn(() => ({ success: true as const })), - goTo: vi.fn(() => ({ success: true as const })), - get: vi.fn(() => ({ + add: mock(() => ({ success: true as const })), + edit: mock(() => ({ success: true as const })), + reply: mock(() => ({ success: true as const })), + move: mock(() => ({ success: true as const })), + resolve: mock(() => ({ success: true as const })), + remove: mock(() => ({ success: true as const })), + setInternal: mock(() => ({ success: true as const })), + setActive: mock(() => ({ success: true as const })), + goTo: mock(() => ({ success: true as const })), + get: mock(() => ({ address: { kind: 'entity' as const, entityType: 'comment' as const, entityId: 'c1' }, commentId: 'c1', status: 'open' as const, text: 'Review this section.', })), - list: vi.fn(() => ({ + list: mock(() => ({ evaluatedRevision: 'r1', total: 1, items: [ @@ -204,27 +204,27 @@ function makeCommentsAdapter() { function makeTrackChangesAdapter() { return { - list: vi.fn(() => ({ evaluatedRevision: 'r1', total: 0, items: [], page: { limit: 0, offset: 0, returned: 0 } })), - get: vi.fn((input: { id: string }) => ({ + list: mock(() => ({ evaluatedRevision: 'r1', total: 0, items: [], page: { limit: 0, offset: 0, returned: 0 } })), + get: mock((input: { id: string }) => ({ address: { kind: 'entity' as const, entityType: 'trackedChange' as const, entityId: input.id }, id: input.id, type: 'insert' as const, })), - accept: vi.fn(() => ({ success: true as const })), - reject: vi.fn(() => ({ success: true as const })), - acceptAll: vi.fn(() => ({ success: true as const })), - rejectAll: vi.fn(() => ({ success: true as const })), + accept: mock(() => ({ success: true as const })), + reject: mock(() => ({ success: true as const })), + acceptAll: mock(() => ({ success: true as const })), + rejectAll: mock(() => ({ success: true as const })), }; } function makeCreateAdapter() { return { - paragraph: vi.fn(() => ({ + paragraph: mock(() => ({ success: true as const, paragraph: { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'new-p' }, insertionPoint: { kind: 'text' as const, blockId: 'new-p', range: { start: 0, end: 0 } }, })), - heading: vi.fn(() => ({ + heading: mock(() => ({ success: true as const, heading: { kind: 'block' as const, nodeType: 'heading' as const, nodeId: 'new-h' }, insertionPoint: { kind: 'text' as const, blockId: 'new-h', range: { start: 0, end: 0 } }, @@ -239,7 +239,7 @@ function makeListsAdapter() { }); return { - list: vi.fn(() => ({ + list: mock(() => ({ evaluatedRevision: 'r1', total: 1, items: [ @@ -254,60 +254,60 @@ function makeListsAdapter() { ], page: { limit: 1, offset: 0, returned: 1 }, })), - get: vi.fn(() => ({ + get: mock(() => ({ address: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-1' }, listId: 'list-1', kind: 'ordered' as const, level: 0, text: 'List item', })), - insert: vi.fn(() => ({ + insert: mock(() => ({ success: true as const, item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-2' }, insertionPoint: { kind: 'text' as const, blockId: 'li-2', range: { start: 0, end: 0 } }, })), - indent: vi.fn(mutateResult), - outdent: vi.fn(mutateResult), - create: vi.fn(() => ({ + indent: mock(mutateResult), + outdent: mock(mutateResult), + create: mock(() => ({ success: true as const, listId: 'list-new', item: { kind: 'block' as const, nodeType: 'listItem' as const, nodeId: 'li-new' }, })), - attach: vi.fn(mutateResult), - detach: vi.fn(() => ({ + attach: mock(mutateResult), + detach: mock(() => ({ success: true as const, paragraph: { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'p1' }, })), - join: vi.fn(() => ({ success: true as const, listId: 'list-1' })), - canJoin: vi.fn(() => ({ canJoin: true })), - separate: vi.fn(() => ({ success: true as const, listId: 'list-new', numId: 2 })), - setLevel: vi.fn(mutateResult), - setValue: vi.fn(mutateResult), - continuePrevious: vi.fn(mutateResult), - canContinuePrevious: vi.fn(() => ({ canContinue: true })), - setLevelRestart: vi.fn(mutateResult), - convertToText: vi.fn(() => ({ + join: mock(() => ({ success: true as const, listId: 'list-1' })), + canJoin: mock(() => ({ canJoin: true })), + separate: mock(() => ({ success: true as const, listId: 'list-new', numId: 2 })), + setLevel: mock(mutateResult), + setValue: mock(mutateResult), + continuePrevious: mock(mutateResult), + canContinuePrevious: mock(() => ({ canContinue: true })), + setLevelRestart: mock(mutateResult), + convertToText: mock(() => ({ success: true as const, paragraph: { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'p1' }, })), - applyTemplate: vi.fn(mutateResult), - applyPreset: vi.fn(mutateResult), - captureTemplate: vi.fn(() => ({ + applyTemplate: mock(mutateResult), + applyPreset: mock(mutateResult), + captureTemplate: mock(() => ({ success: true as const, template: { version: 1, levels: [] }, })), - setLevelNumbering: vi.fn(mutateResult), - setLevelBullet: vi.fn(mutateResult), - setLevelPictureBullet: vi.fn(mutateResult), - setLevelAlignment: vi.fn(mutateResult), - setLevelIndents: vi.fn(mutateResult), - setLevelTrailingCharacter: vi.fn(mutateResult), - setLevelMarkerFont: vi.fn(mutateResult), - clearLevelOverrides: vi.fn(mutateResult), + setLevelNumbering: mock(mutateResult), + setLevelBullet: mock(mutateResult), + setLevelPictureBullet: mock(mutateResult), + setLevelAlignment: mock(mutateResult), + setLevelIndents: mock(mutateResult), + setLevelTrailingCharacter: mock(mutateResult), + setLevelMarkerFont: mock(mutateResult), + clearLevelOverrides: mock(mutateResult), }; } -function makeCapabilitiesAdapter(): { get: ReturnType } { +function makeCapabilitiesAdapter(): { get: ReturnType } { const caps: DocumentApiCapabilities = { global: { trackChanges: { enabled: true }, @@ -358,7 +358,7 @@ function makeCapabilitiesAdapter(): { get: ReturnType } { regex: { maxPatternLength: 1024, maxExecutionMs: 100 }, }, }; - return { get: vi.fn(() => caps) }; + return { get: mock(() => caps) }; } function makeApi() { @@ -376,7 +376,7 @@ function makeApi() { create: makeCreateAdapter(), lists: makeListsAdapter(), query: { - match: vi.fn(() => ({ + match: mock(() => ({ evaluatedRevision: 'r1', total: 1, items: [ @@ -424,8 +424,8 @@ function makeApi() { })), }, mutations: { - preview: vi.fn(() => ({ evaluatedRevision: 'r1', steps: [], valid: true })), - apply: vi.fn(() => ({ + preview: mock(() => ({ evaluatedRevision: 'r1', steps: [], valid: true })), + apply: mock(() => ({ success: true as const, revision: { before: 'r1', after: 'r2' }, steps: [], diff --git a/packages/document-api/src/ranges/resolve.test.ts b/packages/document-api/src/ranges/resolve.test.ts index 9e4bb31973..ab426389c9 100644 --- a/packages/document-api/src/ranges/resolve.test.ts +++ b/packages/document-api/src/ranges/resolve.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { executeResolveRange } from './resolve.js'; import type { RangeResolverAdapter, ResolveRangeInput, ResolveRangeOutput } from './ranges.types.js'; import type { SelectionTarget } from '../types/address.js'; @@ -21,7 +21,7 @@ const STUB_OUTPUT: ResolveRangeOutput = { }; function createStubAdapter(output: ResolveRangeOutput = STUB_OUTPUT): RangeResolverAdapter { - return { resolve: vi.fn(() => output) }; + return { resolve: mock(() => output) }; } // --------------------------------------------------------------------------- diff --git a/packages/document-api/src/sections/sections.test.ts b/packages/document-api/src/sections/sections.test.ts index 4172713db6..a912c6b281 100644 --- a/packages/document-api/src/sections/sections.test.ts +++ b/packages/document-api/src/sections/sections.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it, mock } from 'bun:test'; import { executeSectionsList, executeSectionsGet, @@ -48,7 +49,7 @@ function makeAdapter(overrides: Partial = {}): SectionsAdapter describe('sections API validation', () => { it('normalizes list defaults to limit=250 and offset=0', () => { - const list = vi.fn(makeAdapter().list); + const list = mock(makeAdapter().list); const adapter = makeAdapter({ list }); executeSectionsList(adapter); @@ -90,7 +91,7 @@ describe('sections API validation', () => { }); it('accepts targetless odd/even settings mutation input', () => { - const setOddEvenHeadersFooters = vi.fn(makeAdapter().setOddEvenHeadersFooters); + const setOddEvenHeadersFooters = mock(makeAdapter().setOddEvenHeadersFooters); const adapter = makeAdapter({ setOddEvenHeadersFooters }); executeSectionsSetOddEvenHeadersFooters(adapter, { enabled: true }, { dryRun: true }); diff --git a/packages/document-api/src/styles/registry.test.ts b/packages/document-api/src/styles/registry.test.ts index 351f247d60..02c1891f8c 100644 --- a/packages/document-api/src/styles/registry.test.ts +++ b/packages/document-api/src/styles/registry.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { PROPERTY_REGISTRY, EXCLUDED_KEYS } from './registry.js'; // --------------------------------------------------------------------------- diff --git a/packages/document-api/src/styles/styles.test.ts b/packages/document-api/src/styles/styles.test.ts index d60cf64312..a3c48fbfde 100644 --- a/packages/document-api/src/styles/styles.test.ts +++ b/packages/document-api/src/styles/styles.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { executeStylesApply, type StylesAdapter, @@ -14,7 +14,7 @@ import { DocumentApiValidationError } from '../errors.js'; function makeAdapter(receipt?: Partial): StylesAdapter { return { - apply: vi.fn( + apply: mock( (): StylesApplyReceipt => ({ success: true, changed: true, diff --git a/packages/document-api/src/styles/validation.test.ts b/packages/document-api/src/styles/validation.test.ts index 3410445e2d..6ddfe01f9b 100644 --- a/packages/document-api/src/styles/validation.test.ts +++ b/packages/document-api/src/styles/validation.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect, mock } from 'bun:test'; import { executeStylesApply, PROPERTY_REGISTRY, @@ -15,7 +15,7 @@ import { DocumentApiValidationError } from '../errors.js'; function makeAdapter(): StylesAdapter { return { - apply: vi.fn( + apply: mock( (): StylesApplyReceipt => ({ success: true, changed: true, diff --git a/packages/document-api/src/tables/tables.test.ts b/packages/document-api/src/tables/tables.test.ts index 793e5a47c0..e335295c8b 100644 --- a/packages/document-api/src/tables/tables.test.ts +++ b/packages/document-api/src/tables/tables.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it, vi } from 'vitest'; +import { describe, expect, it, mock } from 'bun:test'; import { executeTablesApplyStyle, executeTablesSetBorders, @@ -7,7 +7,7 @@ import { } from './tables.js'; import { DocumentApiValidationError } from '../errors.js'; -const MOCK_ADAPTER = vi.fn(() => ({ success: true })); +const MOCK_ADAPTER = mock(() => ({ success: true })); const nodeId = 'table-1'; describe('normalizeTablesSplitInput', () => { diff --git a/packages/document-api/src/validation-primitives.test.ts b/packages/document-api/src/validation-primitives.test.ts index a5879c90ee..1b44f97895 100644 --- a/packages/document-api/src/validation-primitives.test.ts +++ b/packages/document-api/src/validation-primitives.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { isRecord, isInteger, isTextAddress, assertNoUnknownFields } from './validation-primitives.js'; import { DocumentApiValidationError } from './errors.js'; diff --git a/packages/document-api/src/validation/fragment-validator.test.ts b/packages/document-api/src/validation/fragment-validator.test.ts index dbc02d286b..4acd4f8584 100644 --- a/packages/document-api/src/validation/fragment-validator.test.ts +++ b/packages/document-api/src/validation/fragment-validator.test.ts @@ -4,7 +4,7 @@ * Each test corresponds to a numbered validation rule from the spec. * Tests cover both SDM/1 shapes (kind-discriminated) and legacy backward compat. */ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { validateSDFragment, validateDocumentFragment } from './fragment-validator.js'; import { DocumentApiValidationError } from '../errors.js'; diff --git a/packages/document-api/src/write/write.test.ts b/packages/document-api/src/write/write.test.ts index 3035fc948b..970c005849 100644 --- a/packages/document-api/src/write/write.test.ts +++ b/packages/document-api/src/write/write.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it } from 'bun:test'; import { normalizeMutationOptions } from './write.js'; describe('normalizeMutationOptions', () => { diff --git a/packages/layout-engine/geometry-utils/package.json b/packages/layout-engine/geometry-utils/package.json index fbb768d626..405a787ba0 100644 --- a/packages/layout-engine/geometry-utils/package.json +++ b/packages/layout-engine/geometry-utils/package.json @@ -10,7 +10,7 @@ }, "scripts": { "build": "tsc --project tsconfig.json --noEmit", - "test": "vitest run" + "test": "bun test" }, "devDependencies": { "typescript": "catalog:", diff --git a/packages/layout-engine/geometry-utils/src/index.test.ts b/packages/layout-engine/geometry-utils/src/index.test.ts index 6e89685be0..5faebbb0a6 100644 --- a/packages/layout-engine/geometry-utils/src/index.test.ts +++ b/packages/layout-engine/geometry-utils/src/index.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { applyMatrix, calculateRotatedBounds, diff --git a/packages/layout-engine/layout-engine/package.json b/packages/layout-engine/layout-engine/package.json index d21efc8256..241ef6a60d 100644 --- a/packages/layout-engine/layout-engine/package.json +++ b/packages/layout-engine/layout-engine/package.json @@ -10,7 +10,7 @@ }, "scripts": { "build": "tsc --project tsconfig.json --noEmit", - "test": "vitest run" + "test": "bun test" }, "dependencies": { "@superdoc/common": "workspace:*", diff --git a/packages/layout-engine/layout-engine/src/anchors.test.ts b/packages/layout-engine/layout-engine/src/anchors.test.ts index 7e66393033..0bcaef624d 100644 --- a/packages/layout-engine/layout-engine/src/anchors.test.ts +++ b/packages/layout-engine/layout-engine/src/anchors.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { isPageRelativeAnchor, collectPreRegisteredAnchors, collectAnchoredDrawings } from './anchors.js'; import type { FlowBlock, ImageBlock, DrawingBlock, Measure, ImageMeasure, DrawingMeasure } from '@superdoc/contracts'; diff --git a/packages/layout-engine/layout-engine/src/column-balancing.test.ts b/packages/layout-engine/layout-engine/src/column-balancing.test.ts index 46d835aa32..7aa7431135 100644 --- a/packages/layout-engine/layout-engine/src/column-balancing.test.ts +++ b/packages/layout-engine/layout-engine/src/column-balancing.test.ts @@ -4,7 +4,7 @@ * Tests for Word-compatible column balancing algorithm. */ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { calculateBalancedColumnHeight, shouldBalanceColumns, diff --git a/packages/layout-engine/layout-engine/src/floating-objects.test.ts b/packages/layout-engine/layout-engine/src/floating-objects.test.ts index 922534c4ad..266a4fec00 100644 --- a/packages/layout-engine/layout-engine/src/floating-objects.test.ts +++ b/packages/layout-engine/layout-engine/src/floating-objects.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { createFloatingObjectManager } from './floating-objects.js'; import type { ImageBlock, ImageMeasure } from '@superdoc/contracts'; diff --git a/packages/layout-engine/layout-engine/src/index.test.ts b/packages/layout-engine/layout-engine/src/index.test.ts index bec84922bf..ce43453a21 100644 --- a/packages/layout-engine/layout-engine/src/index.test.ts +++ b/packages/layout-engine/layout-engine/src/index.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import type { FlowBlock, Measure, diff --git a/packages/layout-engine/layout-engine/src/layout-drawing.test.ts b/packages/layout-engine/layout-engine/src/layout-drawing.test.ts index e50fad9179..c7c252b6ac 100644 --- a/packages/layout-engine/layout-engine/src/layout-drawing.test.ts +++ b/packages/layout-engine/layout-engine/src/layout-drawing.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { layoutDrawingBlock } from './layout-drawing.js'; import type { DrawingBlock, DrawingMeasure, DrawingFragment, DrawingGeometry } from '@superdoc/contracts'; import type { DrawingLayoutContext } from './layout-drawing.js'; diff --git a/packages/layout-engine/layout-engine/src/layout-paragraph.test.ts b/packages/layout-engine/layout-engine/src/layout-paragraph.test.ts index cf7473edd6..ade89230e7 100644 --- a/packages/layout-engine/layout-engine/src/layout-paragraph.test.ts +++ b/packages/layout-engine/layout-engine/src/layout-paragraph.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it, vi } from 'vitest'; +import { describe, expect, it, mock } from 'bun:test'; import type { ParagraphBlock, ParagraphMeasure, Line } from '@superdoc/contracts'; import { layoutParagraphBlock, type ParagraphLayoutContext } from './layout-paragraph.js'; import type { PageState } from './paginator.js'; @@ -66,22 +66,22 @@ const makePageState = (): PageState => ({ * Helper to create a minimal floating object manager for testing. */ const makeFloatManager = (): FloatingObjectManager => ({ - registerDrawing: vi.fn(), - registerTable: vi.fn(), - getExclusionsForLine: vi.fn(() => []), - computeAvailableWidth: vi.fn((lineY, lineHeight, columnWidth) => ({ + registerDrawing: mock(), + registerTable: mock(), + getExclusionsForLine: mock(() => []), + computeAvailableWidth: mock((lineY, lineHeight, columnWidth) => ({ width: columnWidth, offsetX: 0, })), - getAllFloatsForPage: vi.fn(() => []), - clear: vi.fn(), - setLayoutContext: vi.fn(), + getAllFloatsForPage: mock(() => []), + clear: mock(), + setLayoutContext: mock(), }); describe('layoutParagraphBlock - remeasurement with list markers', () => { describe('standard hanging indent mode', () => { it('remeasures with firstLineIndent=0 when firstLineIndentMode is not set', () => { - const remeasureParagraph = vi.fn((block, maxWidth, firstLineIndent) => { + const remeasureParagraph = mock((block, maxWidth, firstLineIndent) => { // Verify that firstLineIndent is 0 for standard hanging indent expect(firstLineIndent).toBe(0); return makeMeasure([{ width: 100, lineHeight: 20, maxWidth: 150 }]); @@ -110,9 +110,9 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { block, measure, columnWidth: 150, // Narrower than measurement width - ensurePage: vi.fn(() => makePageState()), - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + ensurePage: mock(() => makePageState()), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), remeasureParagraph, }; @@ -123,7 +123,7 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { }); it('remeasures with firstLineIndent=0 when marker is missing in measure', () => { - const remeasureParagraph = vi.fn((block, maxWidth, firstLineIndent) => { + const remeasureParagraph = mock((block, maxWidth, firstLineIndent) => { expect(firstLineIndent).toBe(0); return makeMeasure([{ width: 100, lineHeight: 20, maxWidth: 150 }]); }); @@ -151,9 +151,9 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { block, measure, columnWidth: 150, - ensurePage: vi.fn(() => makePageState()), - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + ensurePage: mock(() => makePageState()), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), remeasureParagraph, }; @@ -166,7 +166,7 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { describe('firstLineIndentMode', () => { it('remeasures with correct firstLineIndent when marker is inline', () => { - const remeasureParagraph = vi.fn((block, maxWidth, firstLineIndent) => { + const remeasureParagraph = mock((block, maxWidth, firstLineIndent) => { // Verify that firstLineIndent is markerWidth + gutterWidth expect(firstLineIndent).toBe(24); // 18 + 6 return makeMeasure([{ width: 100, lineHeight: 20, maxWidth: 150 }]); @@ -192,9 +192,9 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { block, measure, columnWidth: 150, - ensurePage: vi.fn(() => makePageState()), - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + ensurePage: mock(() => makePageState()), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), remeasureParagraph, }; @@ -205,7 +205,7 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { }); it('uses markerWidth=0 fallback when markerWidth is missing', () => { - const remeasureParagraph = vi.fn((block, maxWidth, firstLineIndent) => { + const remeasureParagraph = mock((block, maxWidth, firstLineIndent) => { // markerWidth defaults to 0 when the measure marker is present expect(firstLineIndent).toBe(6); return makeMeasure([{ width: 100, lineHeight: 20, maxWidth: 150 }]); @@ -234,9 +234,9 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { block, measure, columnWidth: 150, - ensurePage: vi.fn(() => makePageState()), - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + ensurePage: mock(() => makePageState()), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), remeasureParagraph, }; @@ -247,7 +247,7 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { }); it('uses fallback to 0 when both markerWidth and markerBoxWidthPx are missing', () => { - const remeasureParagraph = vi.fn((block, maxWidth, firstLineIndent) => { + const remeasureParagraph = mock((block, maxWidth, firstLineIndent) => { // Should use 0 + gutterWidth (6) expect(firstLineIndent).toBe(6); return makeMeasure([{ width: 100, lineHeight: 20, maxWidth: 150 }]); @@ -276,9 +276,9 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { block, measure, columnWidth: 150, - ensurePage: vi.fn(() => makePageState()), - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + ensurePage: mock(() => makePageState()), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), remeasureParagraph, }; @@ -291,7 +291,7 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { describe('input validation', () => { it('handles NaN marker width gracefully', () => { - const remeasureParagraph = vi.fn((block, maxWidth, firstLineIndent) => { + const remeasureParagraph = mock((block, maxWidth, firstLineIndent) => { // NaN should be treated as 0 expect(firstLineIndent).toBe(6); // 0 + 6 return makeMeasure([{ width: 100, lineHeight: 20, maxWidth: 150 }]); @@ -320,9 +320,9 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { block, measure, columnWidth: 150, - ensurePage: vi.fn(() => makePageState()), - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + ensurePage: mock(() => makePageState()), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), remeasureParagraph, }; @@ -333,7 +333,7 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { }); it('handles Infinity marker width gracefully', () => { - const remeasureParagraph = vi.fn((block, maxWidth, firstLineIndent) => { + const remeasureParagraph = mock((block, maxWidth, firstLineIndent) => { // Infinity should be treated as 0 expect(firstLineIndent).toBe(6); // 0 + 6 return makeMeasure([{ width: 100, lineHeight: 20, maxWidth: 150 }]); @@ -362,9 +362,9 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { block, measure, columnWidth: 150, - ensurePage: vi.fn(() => makePageState()), - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + ensurePage: mock(() => makePageState()), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), remeasureParagraph, }; @@ -375,7 +375,7 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { }); it('handles negative marker width gracefully', () => { - const remeasureParagraph = vi.fn((block, maxWidth, firstLineIndent) => { + const remeasureParagraph = mock((block, maxWidth, firstLineIndent) => { // Negative values should be treated as 0 expect(firstLineIndent).toBe(6); // 0 + 6 return makeMeasure([{ width: 100, lineHeight: 20, maxWidth: 150 }]); @@ -404,9 +404,9 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { block, measure, columnWidth: 150, - ensurePage: vi.fn(() => makePageState()), - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + ensurePage: mock(() => makePageState()), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), remeasureParagraph, }; @@ -417,7 +417,7 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { }); it('handles NaN gutter width gracefully', () => { - const remeasureParagraph = vi.fn((block, maxWidth, firstLineIndent) => { + const remeasureParagraph = mock((block, maxWidth, firstLineIndent) => { // NaN gutter should be treated as 0 expect(firstLineIndent).toBe(18); // 18 + 0 return makeMeasure([{ width: 100, lineHeight: 20, maxWidth: 150 }]); @@ -446,9 +446,9 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { block, measure, columnWidth: 150, - ensurePage: vi.fn(() => makePageState()), - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + ensurePage: mock(() => makePageState()), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), remeasureParagraph, }; @@ -459,7 +459,7 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { }); it('handles negative gutter width gracefully', () => { - const remeasureParagraph = vi.fn((block, maxWidth, firstLineIndent) => { + const remeasureParagraph = mock((block, maxWidth, firstLineIndent) => { // Negative gutter should be treated as 0 expect(firstLineIndent).toBe(18); // 18 + 0 return makeMeasure([{ width: 100, lineHeight: 20, maxWidth: 150 }]); @@ -488,9 +488,9 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { block, measure, columnWidth: 150, - ensurePage: vi.fn(() => makePageState()), - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + ensurePage: mock(() => makePageState()), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), remeasureParagraph, }; @@ -503,7 +503,7 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { describe('float remeasurement', () => { it('remeasures with correct firstLineIndent when narrower width is found due to floats', () => { - const remeasureParagraph = vi.fn((block, maxWidth, firstLineIndent) => { + const remeasureParagraph = mock((block, maxWidth, firstLineIndent) => { if (maxWidth === 120) { // This is the float remeasurement - should include marker indent expect(firstLineIndent).toBe(24); // 18 + 6 @@ -513,7 +513,7 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { const floatManager = makeFloatManager(); // Mock float manager to return narrower width - floatManager.computeAvailableWidth = vi.fn(() => ({ + floatManager.computeAvailableWidth = mock(() => ({ width: 120, // Narrower than column width offsetX: 10, })); @@ -538,9 +538,9 @@ describe('layoutParagraphBlock - remeasurement with list markers', () => { block, measure, columnWidth: 150, - ensurePage: vi.fn(() => makePageState()), - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + ensurePage: mock(() => makePageState()), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager, remeasureParagraph, }; @@ -561,7 +561,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = 20; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -584,8 +584,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -607,7 +607,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = 15; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -630,8 +630,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -654,7 +654,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = 0; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -677,8 +677,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -702,7 +702,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { (pageState.trailingSpacing as any) = null; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -725,8 +725,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -744,7 +744,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = 0; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -767,8 +767,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -787,7 +787,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = 20; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -810,8 +810,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -833,7 +833,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = 20; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -856,8 +856,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -875,7 +875,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = 20; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -898,8 +898,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -919,7 +919,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = 20; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -942,8 +942,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -960,7 +960,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = 20; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -983,8 +983,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -1004,7 +1004,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = NaN; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -1027,8 +1027,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -1046,7 +1046,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = Infinity; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -1069,8 +1069,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -1088,7 +1088,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = -10; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -1111,8 +1111,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -1132,7 +1132,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = 20; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -1152,8 +1152,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -1172,7 +1172,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { pageState.trailingSpacing = 20; pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); const block: ParagraphBlock = { kind: 'paragraph', @@ -1192,8 +1192,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -1209,7 +1209,7 @@ describe('layoutParagraphBlock - contextualSpacing', () => { const pageState = makePageState(); pageState.cursorY = 100; - const ensurePage = vi.fn(() => pageState); + const ensurePage = mock(() => pageState); // A positioned-frame paragraph with contextualSpacing=true const frameBlock: ParagraphBlock = { @@ -1230,8 +1230,8 @@ describe('layoutParagraphBlock - contextualSpacing', () => { measure, columnWidth: 150, ensurePage, - advanceColumn: vi.fn((state) => state), - columnX: vi.fn(() => 50), + advanceColumn: mock((state) => state), + columnX: mock(() => 50), floatManager: makeFloatManager(), }); @@ -1267,7 +1267,7 @@ describe('layoutParagraphBlock - keepLines', () => { pageState.page.fragments.push({ blockId: 'existing', kind: 'para' } as never); let currentState = pageState; - const advanceColumn = vi.fn((state: PageState) => { + const advanceColumn = mock((state: PageState) => { currentState = { ...state, cursorY: 50, // Reset to top of new page @@ -1281,9 +1281,9 @@ describe('layoutParagraphBlock - keepLines', () => { block, measure, columnWidth: 200, - ensurePage: vi.fn(() => currentState), + ensurePage: mock(() => currentState), advanceColumn, - columnX: vi.fn(() => 50), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -1315,15 +1315,15 @@ describe('layoutParagraphBlock - keepLines', () => { // cursorY=50, contentBottom=750, available = 700px - enough for 150px pageState.page.fragments.push({ blockId: 'existing', kind: 'para' } as never); - const advanceColumn = vi.fn((state: PageState) => state); + const advanceColumn = mock((state: PageState) => state); const ctx: ParagraphLayoutContext = { block, measure, columnWidth: 200, - ensurePage: vi.fn(() => pageState), + ensurePage: mock(() => pageState), advanceColumn, - columnX: vi.fn(() => 50), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -1357,7 +1357,7 @@ describe('layoutParagraphBlock - keepLines', () => { pageState.page.fragments.push({ blockId: 'existing', kind: 'para' } as never); let currentState = pageState; - const advanceColumn = vi.fn((state: PageState) => { + const advanceColumn = mock((state: PageState) => { currentState = { ...state, page: { number: state.page.number + 1, fragments: [] }, @@ -1371,9 +1371,9 @@ describe('layoutParagraphBlock - keepLines', () => { block, measure, columnWidth: 200, - ensurePage: vi.fn(() => currentState), + ensurePage: mock(() => currentState), advanceColumn, - columnX: vi.fn(() => 50), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; @@ -1417,7 +1417,7 @@ describe('layoutParagraphBlock - keepLines', () => { pageState.cursorY = 100; // 650px remaining on current page pageState.page.fragments.push({ blockId: 'existing', kind: 'para' } as never); - const advanceColumn = vi.fn((state: PageState) => ({ + const advanceColumn = mock((state: PageState) => ({ ...state, cursorY: 50, trailingSpacing: 0, @@ -1428,9 +1428,9 @@ describe('layoutParagraphBlock - keepLines', () => { block, measure, columnWidth: 200, - ensurePage: vi.fn(() => pageState), + ensurePage: mock(() => pageState), advanceColumn, - columnX: vi.fn(() => 50), + columnX: mock(() => 50), floatManager: makeFloatManager(), }; diff --git a/packages/layout-engine/layout-engine/src/layout-table.test.ts b/packages/layout-engine/layout-engine/src/layout-table.test.ts index 85c03c4fdf..d37112201d 100644 --- a/packages/layout-engine/layout-engine/src/layout-table.test.ts +++ b/packages/layout-engine/layout-engine/src/layout-table.test.ts @@ -3,7 +3,7 @@ */ import type { BlockId, TableAttrs, TableBlock, TableFragment, TableMeasure } from '@superdoc/contracts'; -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { layoutTableBlock } from './layout-table.js'; /** diff --git a/packages/layout-engine/layout-engine/src/layout-utils.test.ts b/packages/layout-engine/layout-engine/src/layout-utils.test.ts index 69b562419e..926ed7b129 100644 --- a/packages/layout-engine/layout-engine/src/layout-utils.test.ts +++ b/packages/layout-engine/layout-engine/src/layout-utils.test.ts @@ -3,7 +3,7 @@ * Tests empty paragraph detection and spacing suppression utilities. */ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import type { ParagraphBlock, TextRun, ImageRun } from '@superdoc/contracts'; import { isEmptyTextParagraph, shouldSuppressSpacingForEmpty, shouldSuppressOwnSpacing } from './layout-utils.js'; diff --git a/packages/layout-engine/layout-engine/src/pageNumbering.test.ts b/packages/layout-engine/layout-engine/src/pageNumbering.test.ts index 9b79a483d8..d550dab76f 100644 --- a/packages/layout-engine/layout-engine/src/pageNumbering.test.ts +++ b/packages/layout-engine/layout-engine/src/pageNumbering.test.ts @@ -5,7 +5,7 @@ * page number formatting and section-aware display numbering. */ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { formatPageNumber, computeDisplayPageNumber } from './pageNumbering'; import type { Page, SectionMetadata } from '@superdoc/contracts'; diff --git a/packages/layout-engine/layout-engine/src/perf/reflow-baseline.test.ts b/packages/layout-engine/layout-engine/src/perf/reflow-baseline.test.ts index 71409c351f..49ea8aca3d 100644 --- a/packages/layout-engine/layout-engine/src/perf/reflow-baseline.test.ts +++ b/packages/layout-engine/layout-engine/src/perf/reflow-baseline.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import fs from 'node:fs'; import path from 'node:path'; import { layoutDocument } from '../index.js'; diff --git a/packages/layout-engine/layout-engine/src/resolvePageNumberTokens.test.ts b/packages/layout-engine/layout-engine/src/resolvePageNumberTokens.test.ts index c4ef597e0e..f2ada1c9d6 100644 --- a/packages/layout-engine/layout-engine/src/resolvePageNumberTokens.test.ts +++ b/packages/layout-engine/layout-engine/src/resolvePageNumberTokens.test.ts @@ -5,7 +5,7 @@ * section-aware numbering context support. */ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { resolvePageNumberTokens } from './resolvePageTokens'; import type { Layout, FlowBlock, ParagraphBlock, Measure, TextRun } from '@superdoc/contracts'; import type { NumberingContext } from './resolvePageTokens'; diff --git a/packages/layout-engine/layout-engine/src/resolvePageRefs.test.ts b/packages/layout-engine/layout-engine/src/resolvePageRefs.test.ts index d3ae538edf..6a5af7abca 100644 --- a/packages/layout-engine/layout-engine/src/resolvePageRefs.test.ts +++ b/packages/layout-engine/layout-engine/src/resolvePageRefs.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { buildAnchorMap, resolvePageRefTokens, getTocBlocksForRemeasurement } from './resolvePageRefs.js'; import type { Layout, FlowBlock } from '@superdoc/contracts'; diff --git a/packages/layout-engine/layout-engine/src/resolvePageTokens.test.ts b/packages/layout-engine/layout-engine/src/resolvePageTokens.test.ts index 64fe049b79..8857cf8cf4 100644 --- a/packages/layout-engine/layout-engine/src/resolvePageTokens.test.ts +++ b/packages/layout-engine/layout-engine/src/resolvePageTokens.test.ts @@ -4,7 +4,7 @@ * Tests the resolution of page number and total page count tokens in paragraph blocks. */ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { resolveTokensInBlock } from './resolvePageTokens'; import type { ParagraphBlock, TextRun } from '@superdoc/contracts'; diff --git a/packages/layout-engine/layout-engine/src/section-breaks.test.ts b/packages/layout-engine/layout-engine/src/section-breaks.test.ts index 853e145645..209c601ecf 100644 --- a/packages/layout-engine/layout-engine/src/section-breaks.test.ts +++ b/packages/layout-engine/layout-engine/src/section-breaks.test.ts @@ -1,5 +1,5 @@ import type { SectionBreakBlock } from '@superdoc/contracts'; -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { scheduleSectionBreak, applyPendingToActive, type SectionState } from './section-breaks'; diff --git a/packages/layout-engine/layout-engine/src/section-props.test.ts b/packages/layout-engine/layout-engine/src/section-props.test.ts index 61d486149e..49dbfd4f30 100644 --- a/packages/layout-engine/layout-engine/src/section-props.test.ts +++ b/packages/layout-engine/layout-engine/src/section-props.test.ts @@ -1,5 +1,5 @@ import type { FlowBlock } from '@superdoc/contracts'; -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { computeNextSectionPropsAtBreak } from './section-props'; diff --git a/packages/layout-engine/style-engine/package.json b/packages/layout-engine/style-engine/package.json index 0ec8a00212..6cadb2d942 100644 --- a/packages/layout-engine/style-engine/package.json +++ b/packages/layout-engine/style-engine/package.json @@ -17,7 +17,7 @@ }, "scripts": { "build": "tsc --project tsconfig.json --noEmit", - "test": "vitest run" + "test": "bun test" }, "dependencies": { "@superdoc/contracts": "workspace:*", diff --git a/packages/layout-engine/style-engine/src/cascade.test.ts b/packages/layout-engine/style-engine/src/cascade.test.ts index da710b03ea..c8f5021f73 100644 --- a/packages/layout-engine/style-engine/src/cascade.test.ts +++ b/packages/layout-engine/style-engine/src/cascade.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { combineProperties, combineRunProperties, combineIndentProperties } from './cascade.js'; describe('cascade - combineProperties', () => { diff --git a/packages/layout-engine/style-engine/src/index.test.ts b/packages/layout-engine/style-engine/src/index.test.ts index f21034729c..1188a62646 100644 --- a/packages/layout-engine/style-engine/src/index.test.ts +++ b/packages/layout-engine/style-engine/src/index.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it, beforeEach } from 'vitest'; +import { describe, expect, it, beforeEach } from 'bun:test'; import { resolveSdtMetadata, clearSdtMetadataCache } from './index.js'; describe('resolveSdtMetadata', () => { diff --git a/packages/layout-engine/style-engine/src/ooxml/index.test.ts b/packages/layout-engine/style-engine/src/ooxml/index.test.ts index d6d1804558..7cd3505210 100644 --- a/packages/layout-engine/style-engine/src/ooxml/index.test.ts +++ b/packages/layout-engine/style-engine/src/ooxml/index.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { DEFAULT_TBL_LOOK, resolveStyleChain, diff --git a/packages/layout-engine/style-engine/src/ooxml/table-style-selection.test.ts b/packages/layout-engine/style-engine/src/ooxml/table-style-selection.test.ts index e625bf2baa..a33427a189 100644 --- a/packages/layout-engine/style-engine/src/ooxml/table-style-selection.test.ts +++ b/packages/layout-engine/style-engine/src/ooxml/table-style-selection.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { TABLE_STYLE_ID_TABLE_GRID, TABLE_STYLE_ID_TABLE_NORMAL, diff --git a/packages/super-editor/vite.config.js b/packages/super-editor/vite.config.js index 44025a9d2a..9953714b99 100644 --- a/packages/super-editor/vite.config.js +++ b/packages/super-editor/vite.config.js @@ -42,6 +42,33 @@ export default defineConfig(({ mode }) => { globals: true, // Use happy-dom for faster tests (set VITEST_DOM=jsdom to use jsdom) environment: process.env.VITEST_DOM || 'happy-dom', + // Override environment to 'node' for directories that don't need DOM. + // This avoids the cost of setting up happy-dom for pure logic tests. + // Override to 'node' for directories that don't need DOM, with + // explicit happy-dom exceptions for files that do (first match wins). + environmentMatchGlobs: [ + // super-converter: all pure logic except tiff-converter (uses document.createElement) + ['src/core/super-converter/**/tiff-converter.test.*', 'happy-dom'], + ['src/core/super-converter/**', 'node'], + // commands: mostly pure, except deleteSelection (document.getSelection) + // and insertContent integration tests (Editor with DOM view) + ['src/core/commands/deleteSelection.test.*', 'happy-dom'], + ['src/core/commands/insertContent.test.*', 'happy-dom'], + ['src/core/commands/**', 'node'], + // helpers: several need DOM (HTML parsing, sanitizer, content processor) + ['src/core/helpers/updateDOMAttributes.test.*', 'happy-dom'], + ['src/core/helpers/catchAllSchema.test.*', 'happy-dom'], + ['src/core/helpers/contentProcessor.test.*', 'happy-dom'], + ['src/core/helpers/createNodeFromContent.test.*', 'happy-dom'], + ['src/core/helpers/getHTMLFromFragment.test.*', 'happy-dom'], + ['src/core/helpers/htmlSanitizer.test.*', 'happy-dom'], + ['src/core/helpers/**', 'node'], + ['src/core/parts/**', 'node'], + // document-api-adapters: insert-structured-wrapper needs DOM for HTML insert + ['src/document-api-adapters/**/insert-structured-wrapper.test.*', 'happy-dom'], + ['src/document-api-adapters/**', 'node'], + ['src/utils/**', 'node'], + ], retry: 2, testTimeout: 20000, hookTimeout: 10000, diff --git a/packages/word-layout/package.json b/packages/word-layout/package.json index e7b46ba4da..00ba5347c7 100644 --- a/packages/word-layout/package.json +++ b/packages/word-layout/package.json @@ -15,7 +15,7 @@ }, "scripts": { "build": "tsc --project tsconfig.json", - "test": "vitest run" + "test": "bun test" }, "devDependencies": { "vitest": "catalog:" diff --git a/packages/word-layout/tests/numbering-manager.test.ts b/packages/word-layout/tests/numbering-manager.test.ts index 606a196670..c913454d99 100644 --- a/packages/word-layout/tests/numbering-manager.test.ts +++ b/packages/word-layout/tests/numbering-manager.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { createNumberingManager } from '../src/numbering-manager.js'; diff --git a/packages/word-layout/tests/unit-conversions.test.ts b/packages/word-layout/tests/unit-conversions.test.ts index e23927cb26..d85368c36e 100644 --- a/packages/word-layout/tests/unit-conversions.test.ts +++ b/packages/word-layout/tests/unit-conversions.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { TWIPS_PER_PIXEL, diff --git a/packages/word-layout/tests/word-layout.test.ts b/packages/word-layout/tests/word-layout.test.ts index 93e994f0b4..cfad577864 100644 --- a/packages/word-layout/tests/word-layout.test.ts +++ b/packages/word-layout/tests/word-layout.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { computeWordParagraphLayout, DEFAULT_LIST_HANGING_PX, LIST_MARKER_GAP } from '../src/index.js'; import type { WordParagraphLayoutInput } from '../src/types.js'; diff --git a/scripts/test.mjs b/scripts/test.mjs index 0d1592e675..68e5e617fc 100644 --- a/scripts/test.mjs +++ b/scripts/test.mjs @@ -16,9 +16,20 @@ function run(command, commandArgs) { } const vitestExitCode = run(pnpmCommand, ['exec', 'vitest', 'run', ...args]); + +// Always run bun test for migrated packages +const bunTestExitCode = run(pnpmCommand, ['-r', '--parallel', '--filter', '@superdoc/document-api', + '--filter', '@superdoc/layout-engine', '--filter', '@superdoc/style-engine', + '--filter', '@superdoc/geometry-utils', '--filter', '@superdoc/word-layout', + '--filter', '@superdoc/common', '--filter', '@font-utils', + '--filter', '@locale-utils', '--filter', '@url-validation', 'test']); + if (vitestExitCode !== 0) { process.exit(vitestExitCode); } +if (bunTestExitCode !== 0) { + process.exit(bunTestExitCode); +} if (args.length === 0) { const sdkScriptsExitCode = run(pnpmCommand, ['--prefix', 'packages/sdk', 'run', 'test:scripts']); diff --git a/shared/common/Telemetry.test.ts b/shared/common/Telemetry.test.ts index 11efb4d897..54aa78f0c0 100644 --- a/shared/common/Telemetry.test.ts +++ b/shared/common/Telemetry.test.ts @@ -1,8 +1,8 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach, spyOn } from 'bun:test'; import { Telemetry, TelemetryConfig, TelemetryPayload } from './Telemetry'; describe('Telemetry', () => { - let fetchSpy: ReturnType; + let fetchSpy: ReturnType; const testConfig: TelemetryConfig = { enabled: true, endpoint: 'https://test.example.com/collect', @@ -10,7 +10,7 @@ describe('Telemetry', () => { }; beforeEach(() => { - fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response()); + fetchSpy = spyOn(globalThis, 'fetch').mockResolvedValue(new Response()); }); afterEach(() => { diff --git a/shared/common/helpers/compare-superdoc-versions.test.ts b/shared/common/helpers/compare-superdoc-versions.test.ts index 68666658a8..3634b45a38 100644 --- a/shared/common/helpers/compare-superdoc-versions.test.ts +++ b/shared/common/helpers/compare-superdoc-versions.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { compareVersions } from './compare-superdoc-versions'; describe('compareVersions', () => { diff --git a/shared/common/helpers/get-file-object.test.ts b/shared/common/helpers/get-file-object.test.ts index 29df57ef35..7f2144002c 100644 --- a/shared/common/helpers/get-file-object.test.ts +++ b/shared/common/helpers/get-file-object.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest'; +import { describe, expect, it, mock, beforeEach, afterEach, beforeAll, afterAll } from 'bun:test'; import { getFileObject } from './get-file-object'; // Type-safe interface for globalThis augmentation in tests @@ -53,16 +53,15 @@ describe('getFileObject', () => { beforeEach(() => { mockBlob = new Blob(['hello world'], { type: 'text/plain' }); - (globalThis as unknown as GlobalThisWithOptionalAPIs).fetch = vi.fn().mockResolvedValue({ + (globalThis as unknown as GlobalThisWithOptionalAPIs).fetch = mock().mockResolvedValue({ ok: true, status: 200, statusText: 'OK', - blob: vi.fn().mockResolvedValue(mockBlob), + blob: mock().mockResolvedValue(mockBlob), }) as unknown as typeof globalThis.fetch; }); afterEach(() => { - vi.restoreAllMocks(); (globalThis as unknown as GlobalThisWithOptionalAPIs).fetch = originalFetch; }); @@ -72,7 +71,7 @@ describe('getFileObject', () => { expect(globalThis.fetch).toHaveBeenCalledWith('https://example.com/file.txt'); expect(result).toBeInstanceOf(File); expect(result.name).toBe('file.txt'); - expect(result.type).toBe('text/plain'); + expect(result.type).toStartWith('text/plain'); await expect(result.text()).resolves.toBe('hello world'); }); @@ -88,7 +87,7 @@ describe('getFileObject', () => { expect(result).toBeInstanceOf(File); expect(result.name).toBe('test.txt'); - expect(result.type).toBe('text/plain'); + expect(result.type).toStartWith('text/plain'); await expect(result.text()).resolves.toBe(payload); }); @@ -123,6 +122,6 @@ describe('getFileObject', () => { expect(result).toBeInstanceOf(File); expect(result.name).toBe('test.txt'); - expect(result.type).toBe('text/plain'); + expect(result.type).toStartWith('text/plain'); }); }); diff --git a/shared/common/helpers/v-click-outside.test.ts b/shared/common/helpers/v-click-outside.test.ts index 25bb6f59a4..135e9b28a2 100644 --- a/shared/common/helpers/v-click-outside.test.ts +++ b/shared/common/helpers/v-click-outside.test.ts @@ -1,5 +1,5 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import type { Mock } from 'vitest'; +import { describe, expect, it, mock, beforeEach, afterEach } from 'bun:test'; + import type { DirectiveBinding } from 'vue'; import vClickOutside from './v-click-outside'; @@ -21,8 +21,8 @@ describe('v-click-outside directive', () => { beforeEach(() => { originalDocument = globalThis.document; - addEventListenerMock = vi.fn(); - removeEventListenerMock = vi.fn(); + addEventListenerMock = mock(); + removeEventListenerMock = mock(); (globalThis as unknown as { document: MockDocument }).document = { addEventListener: addEventListenerMock, @@ -31,7 +31,6 @@ describe('v-click-outside directive', () => { }); afterEach(() => { - vi.restoreAllMocks(); if (originalDocument === undefined) { delete (globalThis as unknown as { document?: MockDocument }).document; } else { @@ -40,9 +39,9 @@ describe('v-click-outside directive', () => { }); it('invokes binding when clicks originate outside the element and unregisters on unmount', () => { - const containsMock = vi.fn().mockReturnValue(false); + const containsMock = mock().mockReturnValue(false); const binding: DirectiveBinding = { - value: vi.fn(), + value: mock(), oldValue: undefined, arg: undefined, modifiers: {}, diff --git a/shared/common/list-marker-utils.test.ts b/shared/common/list-marker-utils.test.ts index cccc57b481..7ad65feaf7 100644 --- a/shared/common/list-marker-utils.test.ts +++ b/shared/common/list-marker-utils.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { resolveListMarkerGeometry, resolveListTextStartPx, diff --git a/shared/common/list-numbering/index.test.ts b/shared/common/list-numbering/index.test.ts index 3076ebcd50..6beba11c48 100644 --- a/shared/common/list-numbering/index.test.ts +++ b/shared/common/list-numbering/index.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { generateOrderedListIndex, intToJapaneseCounting, normalizeLvlTextChar } from './index'; describe('generateOrderedListIndex', () => { diff --git a/shared/common/list-rendering.test.ts b/shared/common/list-rendering.test.ts index 6ccdfcc5b8..592167a326 100644 --- a/shared/common/list-rendering.test.ts +++ b/shared/common/list-rendering.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { getListOrdinalFromPath, getListRendering } from './list-rendering'; describe('list-rendering helpers', () => { diff --git a/shared/common/package.json b/shared/common/package.json index e5284252a1..86be270832 100644 --- a/shared/common/package.json +++ b/shared/common/package.json @@ -35,7 +35,7 @@ ], "scripts": { "build": "tsc --project tsconfig.json --emitDeclarationOnly", - "test": "vitest run", + "test": "bun test", "test:watch": "vitest", "typecheck": "tsc --noEmit" }, diff --git a/shared/font-utils/index.test.js b/shared/font-utils/index.test.js index efea821b12..1810da76bd 100644 --- a/shared/font-utils/index.test.js +++ b/shared/font-utils/index.test.js @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { FONT_FAMILY_FALLBACKS, DEFAULT_GENERIC_FALLBACK, mapWordFamilyFallback, toCssFontFamily } from './index.js'; describe('FONT_FAMILY_FALLBACKS', () => { diff --git a/shared/font-utils/package.json b/shared/font-utils/package.json index dd946d506f..bf72e387be 100644 --- a/shared/font-utils/package.json +++ b/shared/font-utils/package.json @@ -7,5 +7,8 @@ "main": "./index.js", "exports": { ".": "./index.js" + }, + "scripts": { + "test": "bun test" } } diff --git a/shared/locale-utils/index.test.js b/shared/locale-utils/index.test.js index 946a00f740..c8aff476a6 100644 --- a/shared/locale-utils/index.test.js +++ b/shared/locale-utils/index.test.js @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'bun:test'; import { defaultDecimalSeparatorFor, isCommaLocale } from './index.js'; describe('locale-utils', () => { diff --git a/shared/locale-utils/package.json b/shared/locale-utils/package.json index 01e57d36b7..06609bd850 100644 --- a/shared/locale-utils/package.json +++ b/shared/locale-utils/package.json @@ -6,5 +6,8 @@ "main": "./index.js", "exports": { ".": "./index.js" + }, + "scripts": { + "test": "bun test" } } diff --git a/shared/url-validation/index.test.js b/shared/url-validation/index.test.js index 1722194dd9..cf8cbc91e8 100644 --- a/shared/url-validation/index.test.js +++ b/shared/url-validation/index.test.js @@ -1,4 +1,4 @@ -import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest'; +import { describe, expect, it, beforeEach, afterEach, spyOn } from 'bun:test'; import { sanitizeHref, encodeTooltip, UrlValidationConstants, buildAllowedProtocols } from './index.js'; describe('url-validation', () => { @@ -203,7 +203,7 @@ describe('url-validation', () => { let originalEnv; beforeEach(() => { - warnSpy = vi.spyOn(console, 'warn').mockImplementation(); + warnSpy = spyOn(console, 'warn').mockImplementation(); originalEnv = process.env.NODE_ENV; process.env.NODE_ENV = 'development'; }); diff --git a/shared/url-validation/package.json b/shared/url-validation/package.json index 08a7b1538b..d7e90e09e0 100644 --- a/shared/url-validation/package.json +++ b/shared/url-validation/package.json @@ -10,5 +10,8 @@ "types": "./index.d.ts", "default": "./index.js" } + }, + "scripts": { + "test": "bun test" } } diff --git a/vitest.config.mjs b/vitest.config.mjs index 27dd4dd6d6..e36e6b0ca3 100644 --- a/vitest.config.mjs +++ b/vitest.config.mjs @@ -10,26 +10,20 @@ export default defineConfig({ minWorkers, maxWorkers, // Use package directories; Vitest will pick up each package's vite.config.js + // Packages migrated to bun test: document-api, layout-engine/{layout-engine,style-engine,geometry-utils}, + // word-layout, shared/{common,font-utils,locale-utils,url-validation} + // Run them via: pnpm -r --filter '!@superdoc/super-editor' test projects: [ './packages/super-editor', - './packages/document-api', './packages/superdoc', './packages/ai', './packages/collaboration-yjs', './packages/layout-engine/contracts', - './packages/layout-engine/geometry-utils', './packages/layout-engine/layout-bridge', - './packages/layout-engine/layout-engine', './packages/layout-engine/measuring/dom', './packages/layout-engine/painters/dom', './packages/layout-engine/pm-adapter', - './packages/layout-engine/style-engine', './packages/layout-engine/tests', - './packages/word-layout', - './shared/common', - './shared/font-utils', - './shared/locale-utils', - './shared/url-validation', ], coverage: { exclude: [