e0a5f57793
Vendor the rebranded BoosAPI Desktop client (Tauri + Vue) into metapi as a monorepo subdirectory under desktop/. Source only — node_modules, dist, Cargo target and the upstream .git history are excluded. desktop/ keeps its own independent Cargo workspace (desktop/src-tauri with crates/*); it is not part of the backend boosapi crate, so a `cargo check` at the metapi root still compiles only the backend. Build the desktop app from desktop/src-tauri per desktop/README.md. Note: app icons are still placeholder assets pending the final BoosAPI logo. The updater signing keys live outside the repo and are not included.
130 lines
3.5 KiB
TypeScript
130 lines
3.5 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { parseFenceToken } from '../src'
|
|
|
|
function parseStreamingDiff(content: string, closed = false) {
|
|
return parseFenceToken({
|
|
type: 'fence',
|
|
info: 'diff json:package.json',
|
|
content,
|
|
map: [0, 1],
|
|
meta: { closed },
|
|
} as any)
|
|
}
|
|
|
|
describe('parseFenceToken - streaming unified diff stability', () => {
|
|
it('splits standard unified diff lines without requiring a space after the marker', () => {
|
|
const node = parseFenceToken({
|
|
type: 'fence',
|
|
info: 'diff typescript',
|
|
content: [
|
|
'diff --git a/src/render.ts b/src/render.ts',
|
|
'index 0000000..1111111 100644',
|
|
'--- a/src/render.ts',
|
|
'+++ b/src/render.ts',
|
|
'@@ -1,7 +1,12 @@',
|
|
'-export function render(input) {',
|
|
'- return input',
|
|
'+export function render(input: string) {',
|
|
'+ if (!input.trim())',
|
|
'+ return \'empty\'',
|
|
'+',
|
|
'+ const normalized = input.replace(/\\r\\n/g, \'\\n\')',
|
|
'+ return normalized',
|
|
' }',
|
|
].join('\n'),
|
|
map: [0, 1],
|
|
meta: { closed: true },
|
|
} as any)
|
|
|
|
expect(node.language).toBe('typescript')
|
|
expect(node.originalCode).toBe([
|
|
'export function render(input) {',
|
|
' return input',
|
|
'}',
|
|
].join('\n'))
|
|
expect(node.updatedCode).toBe([
|
|
'export function render(input: string) {',
|
|
' if (!input.trim())',
|
|
' return \'empty\'',
|
|
'',
|
|
' const normalized = input.replace(/\\r\\n/g, \'\\n\')',
|
|
' return normalized',
|
|
'}',
|
|
].join('\n'))
|
|
})
|
|
|
|
it('withholds an unfinished replacement hunk until the added side is available', () => {
|
|
const node = parseStreamingDiff([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
'- "version": "0.0.49",',
|
|
].join('\n'))
|
|
|
|
expect(node.originalCode).toBe([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
].join('\n'))
|
|
expect(node.updatedCode).toBe([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
].join('\n'))
|
|
})
|
|
|
|
it('flushes a finished replacement hunk once the added line becomes stable', () => {
|
|
const node = parseStreamingDiff([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
'- "version": "0.0.49",',
|
|
'+ "version": "0.0.54-beta.1",',
|
|
'',
|
|
].join('\n'))
|
|
|
|
expect(node.originalCode).toBe([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
' "version": "0.0.49",',
|
|
].join('\n'))
|
|
expect(node.updatedCode).toBe([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
' "version": "0.0.54-beta.1",',
|
|
].join('\n'))
|
|
})
|
|
|
|
it('withholds a trailing incomplete added line instead of leaking a mismatched preview', () => {
|
|
const node = parseStreamingDiff([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
'- "version": "0.0.49",',
|
|
'+ "version": "0.0.54-b',
|
|
].join('\n'))
|
|
|
|
expect(node.originalCode).toBe([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
].join('\n'))
|
|
expect(node.updatedCode).toBe([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
].join('\n'))
|
|
})
|
|
|
|
it('flushes the trailing hunk once the fence is closed', () => {
|
|
const node = parseStreamingDiff([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
'- "version": "0.0.49",',
|
|
].join('\n'), true)
|
|
|
|
expect(node.originalCode).toBe([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
' "version": "0.0.49",',
|
|
].join('\n'))
|
|
expect(node.updatedCode).toBe([
|
|
'{',
|
|
' "name": "markstream-vue",',
|
|
].join('\n'))
|
|
})
|
|
})
|