chore: establish YCode replication baseline and TODO
This commit is contained in:
commit
6dc59f89ba
1118 files changed
+196002
No files matched your search
@@ -0,0 +1,156 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { createElement } from 'react'
|
||||
import { renderToStaticMarkup } from 'react-dom/server'
|
||||
import { MermaidSvgCache } from '../src/renderer/src/workbuddy/mermaid/cache'
|
||||
import { MermaidBlock } from '../src/renderer/src/workbuddy/mermaid/MermaidBlock'
|
||||
import {
|
||||
createMermaidRenderer,
|
||||
type MermaidApi,
|
||||
type MermaidConfiguration
|
||||
} from '../src/renderer/src/workbuddy/mermaid/renderer'
|
||||
import {
|
||||
isWidthDependentDiagram,
|
||||
normalizeMermaidCode
|
||||
} from '../src/renderer/src/workbuddy/mermaid/sanitize'
|
||||
import { remapSvgIdReferences } from '../src/renderer/src/workbuddy/mermaid/svg'
|
||||
import {
|
||||
MERMAID_ACTIVATION_ROOT_MARGIN,
|
||||
MERMAID_VISIBLE_ROOT_MARGIN
|
||||
} from '../src/renderer/src/workbuddy/mermaid/visibility'
|
||||
import {
|
||||
MERMAID_WIDTH_DEBOUNCE_MS,
|
||||
shouldPublishMermaidWidth
|
||||
} from '../src/renderer/src/workbuddy/mermaid/width'
|
||||
|
||||
const flowchart = normalizeMermaidCode('flowchart LR\nA["draft (one)"] --> B[\'two\']')
|
||||
assert.equal(flowchart, 'flowchart LR\nA[draft one] --> B[two]')
|
||||
|
||||
const graph = normalizeMermaidCode('graph TD\nA["one"] --> B[\'two\']\nclick A "open \"details\""')
|
||||
assert.match(graph, /A\[one\] --> B\[two\]/)
|
||||
assert.ok(graph.includes("click A \"open 'details'\""))
|
||||
|
||||
const xychart = normalizeMermaidCode('xychart-beta\nx-axis "Quarter (Q1)" ["One", "Two"]')
|
||||
assert.match(xychart, /x-axis ".*Quarter.*Q1.*" \[/)
|
||||
assert.match(xychart, /_#40#_.*_#41#_/)
|
||||
assert.equal(isWidthDependentDiagram('---\ntitle: Plan\n---\n%% note\ngantt\ndateFormat YYYY-MM-DD'), true)
|
||||
assert.equal(isWidthDependentDiagram('flowchart LR\nA-->B'), false)
|
||||
assert.equal(MERMAID_VISIBLE_ROOT_MARGIN, '320px')
|
||||
assert.equal(MERMAID_ACTIVATION_ROOT_MARGIN, '320px 0px')
|
||||
assert.equal(MERMAID_WIDTH_DEBOUNCE_MS, 360)
|
||||
assert.equal(shouldPublishMermaidWidth(0, 1), true)
|
||||
assert.equal(shouldPublishMermaidWidth(500, 515), false)
|
||||
assert.equal(shouldPublishMermaidWidth(500, 516), true)
|
||||
|
||||
const ids = new Map([
|
||||
['a', 'cr-mermaid-1-a'],
|
||||
['long-id', 'cr-mermaid-1-long-id']
|
||||
])
|
||||
assert.equal(
|
||||
remapSvgIdReferences('fill="url(#a)" href="#long-id" url(#a-next)', ids),
|
||||
'fill="url(#cr-mermaid-1-a)" href="#cr-mermaid-1-long-id" url(#a-next)'
|
||||
)
|
||||
assert.equal(
|
||||
remapSvgIdReferences('url(#a.b) url(#axb)', new Map([['a.b', 'safe-a-b']])),
|
||||
'url(#safe-a-b) url(#axb)'
|
||||
)
|
||||
|
||||
const lru = new MermaidSvgCache(1024, 2)
|
||||
lru.set('one', '<svg>one</svg>')
|
||||
lru.set('two', '<svg>two</svg>')
|
||||
assert.equal(lru.get('one'), '<svg>one</svg>')
|
||||
lru.set('three', '<svg>three</svg>')
|
||||
assert.equal(lru.get('two'), undefined)
|
||||
assert.equal(lru.size, 2)
|
||||
assert.ok(lru.byteSize <= 1024)
|
||||
|
||||
const entryBounded = new MermaidSvgCache()
|
||||
for (let index = 0; index < 65; index++) entryBounded.set(`diagram-${index}`, '<svg/>')
|
||||
assert.equal(entryBounded.size, 64)
|
||||
assert.equal(entryBounded.get('diagram-0'), undefined)
|
||||
|
||||
const oversized = new MermaidSvgCache(8, 4)
|
||||
oversized.set('too-large-key', '<svg/>')
|
||||
assert.equal(oversized.size, 0)
|
||||
|
||||
let activeRenders = 0
|
||||
let maxActiveRenders = 0
|
||||
const renderedCodes: string[] = []
|
||||
const configurations: MermaidConfiguration[] = []
|
||||
const fakeMermaid: MermaidApi = {
|
||||
initialize(configuration) { configurations.push(configuration) },
|
||||
async render(_id, code) {
|
||||
activeRenders++
|
||||
maxActiveRenders = Math.max(maxActiveRenders, activeRenders)
|
||||
renderedCodes.push(code)
|
||||
await new Promise((resolve) => setTimeout(resolve, 10))
|
||||
activeRenders--
|
||||
return { svg: `<svg>${code}</svg>` }
|
||||
}
|
||||
}
|
||||
|
||||
const render = createMermaidRenderer()
|
||||
const firstController = new AbortController()
|
||||
const secondController = new AbortController()
|
||||
const firstRender = render({
|
||||
mermaid: fakeMermaid,
|
||||
code: 'gantt\ntitle first',
|
||||
dark: true,
|
||||
width: 540,
|
||||
signal: firstController.signal
|
||||
})
|
||||
const secondRender = render({
|
||||
mermaid: fakeMermaid,
|
||||
code: 'flowchart LR\nA-->B',
|
||||
dark: false,
|
||||
width: 540,
|
||||
signal: secondController.signal
|
||||
})
|
||||
secondController.abort()
|
||||
assert.equal(await firstRender, '<svg>gantt\ntitle first</svg>')
|
||||
assert.equal(await secondRender, undefined)
|
||||
assert.deepEqual(renderedCodes, ['gantt\ntitle first'])
|
||||
assert.equal(maxActiveRenders, 1)
|
||||
assert.equal(configurations[0].gantt.useWidth, 540)
|
||||
|
||||
const cacheHitController = new AbortController()
|
||||
assert.equal(await render({
|
||||
mermaid: fakeMermaid,
|
||||
code: 'gantt\ntitle first',
|
||||
dark: true,
|
||||
width: 540,
|
||||
signal: cacheHitController.signal
|
||||
}), '<svg>gantt\ntitle first</svg>')
|
||||
assert.equal(renderedCodes.length, 1)
|
||||
|
||||
let releaseSlowRender: ((value: string) => void) | undefined
|
||||
let slowStarted: (() => void) | undefined
|
||||
const slowApi: MermaidApi = {
|
||||
initialize() {},
|
||||
render() {
|
||||
slowStarted?.()
|
||||
return new Promise<string>((resolve) => { releaseSlowRender = resolve })
|
||||
}
|
||||
}
|
||||
const staleController = new AbortController()
|
||||
const staleRenderer = createMermaidRenderer()
|
||||
const staleResult = staleRenderer({
|
||||
mermaid: slowApi,
|
||||
code: 'flowchart LR\nA-->B',
|
||||
dark: false,
|
||||
width: 800,
|
||||
signal: staleController.signal
|
||||
})
|
||||
await new Promise<void>((resolve) => { slowStarted = resolve })
|
||||
staleController.abort()
|
||||
releaseSlowRender?.('<svg>stale</svg>')
|
||||
assert.equal(await staleResult, undefined)
|
||||
|
||||
const blockMarkup = renderToStaticMarkup(createElement(MermaidBlock, {
|
||||
code: 'flowchart LR\nA-->B',
|
||||
isRendering: false
|
||||
}))
|
||||
assert.match(blockMarkup, /cr-mermaid-block__tab--active/)
|
||||
assert.match(blockMarkup, />图表</)
|
||||
assert.match(blockMarkup, /data-mermaid-render-state="pending"/)
|
||||
|
||||
console.log('Mermaid cache, sanitizer, queue, and abort regression checks passed')
|
||||
Reference in new issue
Block a user