Files
deepseek-harness/packages/client/ui-tool/tests/tool-row-styles.client.spec.ts
T
Chinesezjc b462d5fd69 Merge remote-tracking branch 'origin/master' into feat/web-message-feedback-ui
Adapt to two contract changes master introduced:

- The generated Remote face now wraps every business result in
  RemoteResult, folding carrier failures into an ok:false branch instead
  of rejecting. The controller reads that envelope at its three call
  sites and maps a carrier failure onto the same settled shape the
  controls already render; three specs cover the new branch.
- Client packages split their tsconfig into host and client halves, and
  the host aggregate now compiles any test not named *.client.spec.*.
  Rename this package's specs to the client convention and drop the
  ../connection project reference, which pointed at a solution file that
  no longer carries the client sources.

Keep master's mount loop with its rollback-on-failure in api-remotes and
add messageFeedbackRemote to it.
2026-08-12 10:43:23 +08:00

46 lines
2.1 KiB
TypeScript

/**
* The one-line contract of the ToolRow summary line as CSS text. jsdom has no
* layout, so the rendering specs (chat-tool-row.spec.tsx) can pin which spans
* exist but not whether a narrow row still fits on one line; these read the
* declarations the layout depends on.
*/
import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { describe, expect, it } from 'vitest'
const css = readFileSync(fileURLToPath(new URL('../src/client/tool/components/ToolRow.module.css', import.meta.url)), 'utf8')
/** Declarations only: the sheet's prose names the properties it explains. */
const declarationText = css.replace(/\/\*[\s\S]*?\*\//g, ' ')
function declarations(selector: string): string[] {
// Anchored at a rule boundary: an unanchored match would silently read a
// compound rule that merely contains the selector (`.root:hover .summarySuffix`)
// if one ever lands above the base rule.
const rule = new RegExp(`(?:^|\\})\\s*\\${selector}\\s*\\{([^{}]*)\\}`).exec(declarationText)
if (rule === null) throw new Error(`ToolRow.module.css has no \`${selector}\` rule`)
return (rule[1] ?? '').split(';').map(part => part.trim()).filter(Boolean)
}
describe('ToolRow.module.css summary line', () => {
it('keeps the summary suffix on one line and unshrunk', () => {
// `flex: none` stops the box shrinking, not the text wrapping: without
// `nowrap`, a row too narrow for title + separator + suffix wraps the `+n`
// onto a second line — the exact case the slot exists to survive.
expect(declarations('.summarySuffix')).toEqual(expect.arrayContaining([
'flex: none',
'white-space: nowrap',
]))
})
it('leaves the truncation to the summary text alone', () => {
// The suffix must never ellipsize: a clipped count reads as a smaller
// number rather than as missing information.
expect(declarations('.summary')).toEqual(expect.arrayContaining([
'overflow: hidden',
'text-overflow: ellipsis',
'white-space: nowrap',
]))
expect(declarations('.summarySuffix')).not.toEqual(expect.arrayContaining(['text-overflow: ellipsis']))
})
})