diff --git a/tests/client/components/browser.spec.ts b/tests/client/components/browser.spec.ts index c4605df..49ada55 100644 --- a/tests/client/components/browser.spec.ts +++ b/tests/client/components/browser.spec.ts @@ -1,8 +1,3 @@ -// ContextBrowser (src/client/components/browser.tsx) rendered with real -// React in jsdom: picker, category accordion, header content (schema -// narrowing matrix), conversation join (block cascade, tail-status matrix), -// targeted content fetch, hover linkage, and the focus bridges. - import { act, createElement as h, useState } from 'react' import assert from 'node:assert/strict' import { afterEach, describe, test, vi } from 'vitest' @@ -87,11 +82,9 @@ function props(over: Partial): ContextBrowserProps { return { data: tl({}), headers: null, ...over } } -/** - * Pair metadata-only `contextHeaders` with a fetchHeader serving per-epoch +/** Pair metadata-only `contextHeaders` with a fetchHeader serving per-epoch * CONTENT — the lazy-load contract the browser consumes: the projection - * carries boundaries and token prices, the content arrives on demand. - */ + * carries boundaries and token prices, the content arrives on demand. */ function withEpochContent( headers: ContextHeaders, contents: Record, @@ -504,8 +497,7 @@ describe('ContextBrowser header epochs', () => { // The single system row is already expanded. assert.equal(queryAll(m.container, '.lc-br-content').length, 1) assert.ok(queryAll(m.container, '.lc-ts-desc-md').length >= 1, 'markdown view by default') - // Scope to the detail body: the header's own granularity toggles wear the - // same shared lc-gran classes. + // Scope to the detail body: the header's own granularity toggles wear the same shared lc-gran classes. const rawBtn = queryAll(body, '.lc-gran-btn')[0] assert.equal(text(rawBtn), 'Raw') await click(rawBtn) @@ -687,7 +679,7 @@ describe('ContextBrowser header epochs', () => { test('a legacy content-bearing epoch (pre-#37 wire) still counts the system prompt', async () => { // The value shape a host running the pre-#37 view serves: the system TEXT // rides the epoch and no systemTokens price exists (the real cached row - // that read 0 项 while the breakdown still showed ≈1.6k). Routed through + // that read 0 items while the breakdown still showed ≈1.6k). Routed through // headersOf — the boundary the real callers sanitize the projection with. const legacy = { headers: [{ @@ -739,8 +731,7 @@ describe('ContextBrowser header epochs', () => { }) test('a resolved prompt whose event carries no text explains its absence', async () => { - // The node exists (so the category opens) but the fetched event maps to - // no prompt text — a foreign or truncated envelope. + // The node exists (so the category opens) but the fetched event maps to no prompt text — a foreign or truncated envelope. const data = tl({ current: { system: 30, tools: 0, user: 0, inject: 0, skill: 0, assistant: 0, tool: 0, total: 30 }, systems: [{ seq: 7, time: 700, tokens: 30 }], @@ -924,8 +915,7 @@ describe('ContextBrowser tool schemas', () => { await click(sortBtns[2]) assert.ok(sortBtns[2].className.includes('lc-gran-on')) assert.deepEqual(names(), ['beta', 'delta', 'epsilon', 'gamma', 'mega', 'omega', 'rho', 'theta', 'zeta']) - // Count sort with no tool-result nodes on the surface: all tallies tie at - // zero and break by name. + // Count sort with no tool-result nodes on the surface: all tallies tie at zero and break by name. await click(sortBtns[1]) assert.ok(sortBtns[1].className.includes('lc-gran-on')) assert.deepEqual(names(), ['beta', 'delta', 'epsilon', 'gamma', 'mega', 'omega', 'rho', 'theta', 'zeta']) @@ -973,8 +963,7 @@ describe('ContextBrowser tool schemas', () => { assert.deepEqual(names(), ['beta', 'delta', 'gamma', 'alpha']) assert.deepEqual(hits(), ['×2', '×1', '×1', '×0']) // Picking a past step re-tallies over THAT step's assembled surface: - // only seq < 4 assembles, so beta drops to its one early call; the - // zero-hit tools order by name. + // only seq < 4 assembles, so beta drops to its one early call; the zero-hit tools order by name. await pickStep(m, '4') await click(catRow(m, 'tools')) await flush() @@ -1124,8 +1113,7 @@ describe('ContextBrowser tool schemas', () => { assert.ok(text(query(body, 'pre')).includes('"nope"')) await close('rho') - // omega: the fetched raw entry carries no description and a bare schema — - // only the JSON toggle renders behind the row. + // omega: the fetched raw entry carries no description and a bare schema — only the JSON toggle renders behind the row. body = await open('omega') assert.equal(queryAll(body, '.lc-ts-param-row').length, 0) assert.ok(!text(body).includes('does everything')) @@ -1165,8 +1153,7 @@ describe('ContextBrowser tool schemas', () => { assert.ok(text(chips[1]).includes('mcp:github')) assert.ok((chips[0] as HTMLElement).title.includes('The registering plugin of this tool'), 'the chip carries the i18n tooltip') assert.ok(!text(rows[2]).includes('@'), 'unattributed tools stay untagged') - // The unknown-source sentinel renders the localized tag with the - // boot-timing explanation, never the raw sentinel string. + // The unknown-source sentinel renders the localized tag with the boot-timing explanation, never the raw sentinel string. assert.equal(chips[2].textContent, 'Unknown plugin') assert.ok((chips[2] as HTMLElement).title.includes('registered before the context plugin loaded'), 'unknown chips explain the boot gap') // Layout: the tool name leads the row, the plugin chip trails it directly @@ -1407,8 +1394,7 @@ describe('ContextBrowser message categories', () => { const chips = () => queryAll(m.container, '.lc-br-toolctl .lc-gran-btn') // Counts over ALL of the shown step's rows: thinking rides the join's // reasoning block (seq 68), tools the joined calls (62/63/64/68) plus the - // unjoined node's `calls` stamp (61), answers the joined text blocks plus - // the nodes' own text (61/66/67/68). + // unjoined node's `calls` stamp (61), answers the joined text blocks plus the nodes' own text (61/66/67/68). assert.deepEqual(chips().map(c => text(c)), ['Thinking1', 'Tools5', 'Answer4']) const previews = () => elemRows(m).map(r => text(query(r, '.lc-br-preview'))) assert.equal(elemRows(m).length, 8) @@ -1622,8 +1608,7 @@ describe('ContextBrowser message categories', () => { const data = tl({ current: { system: 0, tools: 0, user: 0, inject: 45, skill: 0, assistant: 0, tool: 0, total: 45 }, nodes: [ - // Stamped rows: the identity the events card names replaces the raw - // content preview (which stays one expand away). + // Stamped rows: the identity the events card names replaces the raw content preview (which stays one expand away). surfaceNode({ seq: 50, cat: 'inject', tokens: 9, form: 'snapshot', name: '@deepseek-ai/dsh-system-prompt', text: 'policy sections' }), surfaceNode({ seq: 51, cat: 'inject', tokens: 9, form: 'instructions', name: 'AGENTS.md', text: ' instructions' }), // Unstamped (rows folded before the stamp existed): content stands. @@ -1690,8 +1675,7 @@ describe('ContextBrowser message categories', () => { }) describe('ContextBrowser tool results', () => { - // The tail-status matrix: dsh settles failing commands as completed calls, - // so trailing markers are the failure signal. + // The tail-status matrix: dsh settles failing commands as completed calls, so trailing markers are the failure signal. const cases: { seq: number; tail: string; err: boolean; label: string }[] = [ { seq: 80, tail: 'boom\n[exit code: 3]', err: true, label: 'Failed · exit 3' }, { seq: 81, tail: '[killed by signal: SIGKILL]', err: true, label: 'Failed' }, @@ -2089,8 +2073,7 @@ describe('ContextBrowser open-category reporting', () => { const onOpenCat = (c: string | null): void => { opens.push(c) } let handled = 0 const m = await mount(h(Browser, props({ data, onOpenCat }))) - // The stats card's Answers figure: assistant open, the answer chip picked — - // the tool-call-only row filters out. + // The stats card's Answers figure: assistant open, the answer chip picked — the tool-call-only row filters out. await m.update(h(Browser, props({ data, onOpenCat, diff --git a/tests/client/components/trendChart.spec.ts b/tests/client/components/trendChart.spec.ts index a7ad6c4..83adcf2 100644 --- a/tests/client/components/trendChart.spec.ts +++ b/tests/client/components/trendChart.spec.ts @@ -169,8 +169,7 @@ describe('TrendChart entrance rise cap', () => { // The window is what rises: every column from its edge on, none before it. assert.deepEqual(stacks.slice(0, 10).map(s => s.className.includes('animate-lc-bar-in')), new Array(10).fill(false)) assert.deepEqual(stacks.slice(10).map(s => s.className.includes('animate-lc-bar-in')), new Array(RISE_CAP).fill(true)) - // The window's own cascade counts from its edge — raw indices would all sit past the stagger cap and - // rise in unison. + // The window's own cascade counts from its edge — raw indices would all sit past the stagger cap and rise in unison. assert.equal(stacks[10].style.getPropertyValue('--lc-i'), '0') await m.unmount() }) @@ -412,7 +411,7 @@ describe('TrendChart turn granularity', () => { assert.deepEqual(turns.map(t => t.style.width), ['14px', '14px']) assert.deepEqual(turns.map(t => t.textContent), ['1', '2']) - // Multi-step aggregate → tip.turn; a single-step aggregate still speaks TURN ("共 1 步"), never the step index. + // Multi-step aggregate → tip.turn; a single-step aggregate still speaks TURN (the step-count wording), never the step index. await m.update(h(TrendChart, propsOf(agg, { granularity: 'turn', hoveredSeq: t1s1.seq }))) assert.ok(query(m.container, '.lc-chart-tip').textContent!.includes(kit.t('tip.turn', { t: 1, n: 2 }))) await m.update(h(TrendChart, propsOf(agg, { granularity: 'turn', hoveredSeq: t2s0.seq }))) @@ -964,8 +963,7 @@ describe('TrendChart scroll anchoring', () => { assert.equal(scroll.scrollLeft, 230, 'selection-only update near the end does not stick') // Turn labels re-center within their visible slice: with the reader at scrollLeft 240, T2 is half-clipped - // at the left → shifted right; T3 is fully visible and centered → no transform; T1 is fully out of view - // → untouched. + // at the left → shifted right; T3 is fully visible and centered → no transform; T1 is fully out of view → untouched. await scrollTo(scroll, 240) const labels = queryAll(m.container, '.lc-turn-label') assert.equal(labels.length, 4) @@ -1147,13 +1145,11 @@ describe('TrendChart hover tip overlay', () => { return out } - /** - * The regression behind the overlay split: the tooltip used to live INSIDE .lc-chart-scroll, and an absolutely + /** The regression behind the overlay split: the tooltip used to live INSIDE .lc-chart-scroll, and an absolutely * positioned child of a scroller contributes to its scrollable overflow — a several-hundred-px reply preview on a * right-edge bar inflated scrollWidth on every hover, flapping the horizontal scrollbar open/closed and jumping the * whole card. The tip now lives beside the scroller (positioned by the wrapper), and syncTip glues it to the bar's - * visible slice on every scroll/commit. - */ + * visible slice on every scroll/commit. */ test('renders outside the scroller, glues to the visible slice while scrolling, and clamps at both edges', async () => { const reqs = manySteps() const { handlers } = makeSpies()