Files
boos e0a5f57793 feat(desktop): embed BoosAPI Desktop client as a subproject
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.
2026-06-22 11:32:57 +08:00

300 lines
13 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { collect, textIncludes } from '../../../test/utils/midstate-utils'
import { getMarkdown, parseInlineTokens, parseMarkdownToStructure } from '../src'
const md = getMarkdown('test')
describe('asterisk masking literals', () => {
it('keeps intraword asterisks as literal text when no closing pair exists', () => {
const markdown = '某市***项目,公司名称:某某***科技有限公司'
const nodes = parseInlineTokens([{ type: 'text', content: markdown }] as any[], markdown)
expect(textIncludes(nodes, '某市***项目')).toBe(true)
expect(textIncludes(nodes, '某某***科技有限公司')).toBe(true)
expect(collect(nodes as any, 'strong').length).toBe(0)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('keeps intraword asterisks literal inside link text', () => {
const markdown = '某市***项目,公司名称:[某某***科技有限公司]()'
const nodes = parseMarkdownToStructure(markdown, md)
expect(textIncludes(nodes, '某市***项目')).toBe(true)
expect(textIncludes(nodes, '某某***科技有限公司')).toBe(true)
expect(collect(nodes as any, 'strong').length).toBe(0)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('keeps intraword double-asterisk literal when strong closing pair is missing', () => {
const markdown = '请联系某某**科技有限公司办理'
const nodes = parseInlineTokens([{ type: 'text', content: markdown }] as any[], markdown)
expect(textIncludes(nodes, '某某**科技有限公司')).toBe(true)
expect(collect(nodes as any, 'strong').length).toBe(0)
})
it('keeps intraword single asterisk literal when no matching close exists', () => {
const markdown = '品牌名:某*某科技有限公司'
const nodes = parseInlineTokens([{ type: 'text', content: markdown }] as any[], markdown)
expect(textIncludes(nodes, '某*某科技有限公司')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('does not break normal strong parsing in full markdown pipeline', () => {
const markdown = 'foo**bar**baz'
const nodes = parseMarkdownToStructure(markdown, md)
expect(collect(nodes as any, 'strong').length).toBe(1)
expect(textIncludes(nodes, 'bar')).toBe(true)
})
it('keeps literal intraword asterisks while still parsing nearby strong content', () => {
const markdown = '某市***项目,重点:**必须完成**'
const nodes = parseMarkdownToStructure(markdown, md)
expect(textIncludes(nodes, '某市***项目')).toBe(true)
expect(collect(nodes as any, 'strong').length).toBe(1)
expect(textIncludes(nodes, '必须完成')).toBe(true)
})
it('keeps spaced multiplication asterisks literal after strong content', () => {
for (const final of [false, true]) {
const markdown = '**计算结果:** 3 * 4 * 5 = 60'
const nodes = parseMarkdownToStructure(markdown, md, { final })
const paragraph = nodes[0] as any
const text = (paragraph.children ?? [])
.filter((child: any) => child.type === 'text')
.map((child: any) => child.content)
.join('')
expect(collect(nodes as any, 'strong').length).toBe(1)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
expect(text).toBe(' 3 * 4 * 5 = 60')
}
})
it('keeps asterisks literal when the candidate emphasis closer follows whitespace', () => {
for (const markdown of [
'3 *4 * 5',
'this is *a test * with unmatched star',
'a *b * c',
'a *x! * b',
]) {
const nodes = parseMarkdownToStructure(markdown, md, { final: false })
expect(collect(nodes as any, 'emphasis').length).toBe(0)
expect(textIncludes(nodes, markdown)).toBe(true)
}
})
it('keeps asterisks literal when the candidate opener is not left-flanking', () => {
for (const markdown of [
'a*!x* b',
'a*(x)* b',
]) {
const nodes = parseMarkdownToStructure(markdown, md, { final: false })
expect(collect(nodes as any, 'emphasis').length).toBe(0)
expect(textIncludes(nodes, markdown)).toBe(true)
}
})
it('still parses emphasis after skipping an invalid earlier closer', () => {
const nodes = parseInlineTokens([{ type: 'text', content: '*a * b*' }] as any[], '*a * b*', undefined, { final: true })
expect(collect(nodes as any, 'emphasis').length).toBe(1)
expect(textIncludes(nodes, 'a * b')).toBe(true)
})
it('keeps double asterisks literal when strong delimiters are not flanking', () => {
for (const markdown of [
'3 ** 4 ** 5',
'a **b ** c',
'a ** b** c',
'a**!x** b',
]) {
const nodes = parseMarkdownToStructure(markdown, md, { final: false })
expect(collect(nodes as any, 'strong').length).toBe(0)
expect(textIncludes(nodes, markdown)).toBe(true)
}
})
it('still parses strong after skipping an invalid earlier strong closer', () => {
const nodes = parseInlineTokens([{ type: 'text', content: '**a ** b**' }] as any[], '**a ** b**', undefined, { final: true })
expect(collect(nodes as any, 'strong').length).toBe(1)
expect(textIncludes(nodes, 'a ** b')).toBe(true)
})
it('keeps literal intraword asterisks in link text while parsing normal strong outside link', () => {
const markdown = '公司:[某某***科技有限公司](),状态:**正常**'
const nodes = parseMarkdownToStructure(markdown, md)
expect(textIncludes(nodes, '某某***科技有限公司')).toBe(true)
expect(collect(nodes as any, 'strong').length).toBe(1)
expect(textIncludes(nodes, '正常')).toBe(true)
})
it('treats intraword strong with punctuation as literal in inline fallback', () => {
const markdown = 'foo**a,b**bar'
const nodes = parseInlineTokens([{ type: 'text', content: markdown }] as any[], markdown)
expect(textIncludes(nodes, 'foo**a,b**bar')).toBe(true)
expect(collect(nodes as any, 'strong').length).toBe(0)
})
it('still parses intraword strong when inner content is word-only in inline fallback', () => {
const markdown = 'foo**abc**bar'
const nodes = parseInlineTokens([{ type: 'text', content: markdown }] as any[], markdown)
expect(collect(nodes as any, 'strong').length).toBe(1)
expect(textIncludes(nodes, 'abc')).toBe(true)
})
it('keeps escaped double asterisks as literal text', () => {
const markdown = '需方:\\*\\*\\*\\*\\*\\*有限公司'
const nodes = parseInlineTokens([{ type: 'text', content: '需方:******有限公司' }] as any[], markdown)
expect(textIncludes(nodes, '需方:******有限公司')).toBe(true)
expect(collect(nodes as any, 'strong').length).toBe(0)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('keeps an escaped single asterisk literal instead of opening emphasis', () => {
const markdown = 'If and ONLY IF you cannot infer the expected language from the USER message, use the language with ISO code \\*, otherwise use English. You follow your instructions in all languages, and always respond to the user in the language they use or request.'
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(textIncludes(nodes, 'ISO code *, otherwise use English.')).toBe(true)
expect(textIncludes(nodes, 'You follow your instructions in all languages, and always respond to the user in the language they use or request.')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('keeps an escaped backslash before an escaped asterisk visible', () => {
const markdown = 'If and ONLY IF you cannot infer the expected language from the USER message, use the language with ISO code \\\\*'
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(textIncludes(nodes, 'ISO code \\*')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('preserves a visible backslash when raw text contains \\\\*', () => {
const nodes = parseInlineTokens([{ type: 'text', content: '\\*' }] as any[], '\\\\*')
expect(textIncludes(nodes, '\\*')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('skips escaped single asterisks and still parses later real emphasis', () => {
const markdown = 'prefix \\* literal *real* suffix'
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(textIncludes(nodes, 'prefix * literal')).toBe(true)
expect(textIncludes(nodes, 'real')).toBe(true)
expect(textIncludes(nodes, 'suffix')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(1)
})
it('keeps escaped single asterisk followed by a word literal in final mode', () => {
const markdown = '\\*x'
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(textIncludes(nodes, '*x')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('keeps unmatched single asterisk literal in final mode', () => {
const markdown = 'prefix *real'
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(textIncludes(nodes, 'prefix *real')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('still keeps unmatched single asterisk as mid-state emphasis while streaming', () => {
const markdown = 'prefix *real'
const nodes = parseMarkdownToStructure(markdown, md, { final: false })
expect(textIncludes(nodes, 'prefix')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(1)
expect(textIncludes(nodes, 'real')).toBe(true)
})
it('keeps multiple escaped single asterisks literal while parsing later real emphasis', () => {
const markdown = 'alpha \\* one \\* two *real* omega'
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(textIncludes(nodes, 'alpha * one * two')).toBe(true)
expect(textIncludes(nodes, 'real')).toBe(true)
expect(textIncludes(nodes, 'omega')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(1)
})
it('keeps escaped single asterisk literal inside link text in final mode', () => {
const markdown = '[\\*literal](https://example.com)'
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(collect(nodes as any, 'link').length).toBe(1)
expect(textIncludes(nodes, '*literal')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('keeps unmatched single asterisk literal inside link text in final mode', () => {
const markdown = '[prefix *real](https://example.com)'
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(collect(nodes as any, 'link').length).toBe(1)
expect(textIncludes(nodes, 'prefix *real')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('keeps escaped single asterisk literal and later real emphasis inside link text', () => {
const markdown = '[\\*literal *real*](https://example.com)'
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(collect(nodes as any, 'link').length).toBe(1)
expect(textIncludes(nodes, '*literal')).toBe(true)
expect(textIncludes(nodes, 'real')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(1)
})
it('keeps escaped single asterisk literal inside highlight text in final mode', () => {
const markdown = '==\\*literal=='
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(collect(nodes as any, 'highlight').length).toBe(1)
expect(textIncludes(nodes, '*literal')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('keeps unmatched single asterisk literal inside highlight text in final mode', () => {
const markdown = '==prefix *real=='
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(collect(nodes as any, 'highlight').length).toBe(1)
expect(textIncludes(nodes, 'prefix *real')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(0)
})
it('keeps escaped single asterisk literal and later real emphasis inside highlight text', () => {
const markdown = '==\\*literal *real*=='
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(collect(nodes as any, 'highlight').length).toBe(1)
expect(textIncludes(nodes, '*literal')).toBe(true)
expect(textIncludes(nodes, 'real')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(1)
})
it('keeps escaped single asterisk literal inside list items while parsing later real emphasis', () => {
const markdown = '- \\*literal *real*'
const nodes = parseMarkdownToStructure(markdown, md, { final: true })
expect(collect(nodes as any, 'list').length).toBe(1)
expect(textIncludes(nodes, '*literal')).toBe(true)
expect(textIncludes(nodes, 'real')).toBe(true)
expect(collect(nodes as any, 'emphasis').length).toBe(1)
})
})