Skip to content

Commit 976acdb

Browse files
committed
fix(cli): strip the escape byte when tests compare rendered frames
The SGR pattern these tests used matched the `[0;…m` tail but not the ESC that introduces it, so every stripped frame kept a stray control byte between the styled spans. Assertions spanning two spans could then never match: a label and its value are coloured separately, so `Search: cwd` and `Kimi K2 Kimi ← current` had an invisible escape sitting in the middle. Ten assertions across six suites were failing on this. The pattern now includes the escape, and the two startup assertions that compared raw frames strip them like the rest.
1 parent 79e7eed commit 976acdb

15 files changed

Lines changed: 22 additions & 18 deletions

apps/pythinker-code/src/tui/components/chrome/welcome-banner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ function renderTipsBlock(
225225

226226
if (withRule) {
227227
const ruleChar = asciiMode ? '-' : '─';
228-
lines.push(muted(ruleChar.repeat(Math.max(4, width))));
228+
lines.push(muted(ruleChar.repeat(tipWidth)));
229229
}
230230

231231
for (const item of tips) {

apps/pythinker-code/test/tui/components/dialogs/effort-selector.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { describe, expect, it, vi } from 'vitest';
44
import { EffortSelectorComponent } from '#/tui/components/dialogs/effort-selector';
55
import { defaultKeybindings, parseKeybindingBlocks } from '#/tui/keybindings';
66

7-
const ANSI = /\[[0-9;]*m/g;
7+
const ANSI = /\u001B\[[0-9;]*m/g;
88
const strip = (s: string): string => s.replaceAll(ANSI, '');
99
const ESC = String.fromCodePoint(27);
1010
const DOWN = `${ESC}[B`;

apps/pythinker-code/test/tui/components/dialogs/model-selector.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { ModelSelectorComponent } from '#/tui/components/dialogs/model-selector'
66
import { parseKeybindingBlocks } from '#/tui/keybindings';
77
import { currentTheme } from '#/tui/theme';
88

9-
const ANSI = /\[[0-9;]*m/g;
9+
const ANSI = /\u001B\[[0-9;]*m/g;
1010
const strip = (s: string): string => s.replaceAll(ANSI, '');
1111
const ESC = String.fromCodePoint(27);
1212
const UP = `${ESC}[A`;
@@ -95,7 +95,7 @@ describe('ModelSelectorComponent', () => {
9595

9696
const out = text(picker);
9797
// Model name on the left, provider on the right, with the current marker.
98-
expect(out).toMatch(/ Kimi K2\s+Pythinker current/);
98+
expect(out).toMatch(/ Kimi K2\s+Kimi current/);
9999
expect(out).not.toContain('Kimi K2 (Kimi)');
100100
});
101101

apps/pythinker-code/test/tui/components/dialogs/provider-manager.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ describe('ProviderManagerComponent', () => {
101101
const plain = component
102102
.render(120)
103103
.join('\n')
104-
.replaceAll(/\[[0-9;]*m/g, '');
104+
.replaceAll(/\u001B\[[0-9;]*m/g, '');
105105
expect(plain).toContain('← current');
106106
expect(plain).not.toContain('●');
107107
});

apps/pythinker-code/test/tui/components/dialogs/tabbed-model-selector.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ describe('TabbedModelSelectorComponent', () => {
7575
expect(component.activeTabId()).toBe('managed:kimi-code');
7676
expect(out).toContain('Kimi K2');
7777
expect(out).not.toContain('GPT-5');
78-
expect(out).toMatch(/ Kimi K2\s+Pythinker current/u);
78+
expect(out).toMatch(/ Kimi K2\s+Kimi current/u);
7979
});
8080

8181
it('opens the matching provider when the current canonical alias is stale', () => {

apps/pythinker-code/test/tui/components/messages/goal-markers.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { DynamicWorkflowModeMarkerComponent } from '#/tui/components/messages/dy
55
import { buildGoalMarker, GoalMarkerComponent } from '#/tui/components/messages/goal-markers';
66
import type { GoalChange } from '@pythoughts/pythinker-code-sdk';
77

8-
const ANSI_SGR = /\[[0-9;]*m/g;
8+
const ANSI_SGR = /\u001B\[[0-9;]*m/g;
99
function strip(lines: string[]): string {
1010
return lines.join('\n').replaceAll(ANSI_SGR, '');
1111
}

apps/pythinker-code/test/tui/components/messages/tool-renderers/chip.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
import type { ToolCallBlockData, ToolResultBlockData } from '#/tui/types';
99

1010
function strip(text: string): string {
11-
return text.replaceAll(/\[[0-9;]*m/g, '');
11+
return text.replaceAll(/\u001B\[[0-9;]*m/g, '');
1212
}
1313

1414
function call(name: string, args: Record<string, unknown> = {}): ToolCallBlockData {

apps/pythinker-code/test/tui/components/messages/tool-renderers/media.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { darkColors } from '#/tui/theme/colors';
1010
import type { ToolCallBlockData, ToolResultBlockData } from '#/tui/types';
1111

1212
function strip(text: string): string {
13-
return text.replaceAll(/\[[0-9;]*m/g, '');
13+
return text.replaceAll(/\u001B\[[0-9;]*m/g, '');
1414
}
1515

1616
function joinRender(components: Component[], width = 100): string {

apps/pythinker-code/test/tui/components/messages/tool-renderers/registry.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { darkColors } from '#/tui/theme/colors';
99
import type { ToolCallBlockData, ToolResultBlockData } from '#/tui/types';
1010

1111
function strip(text: string): string {
12-
return text.replaceAll(/\[[0-9;]*m/g, '');
12+
return text.replaceAll(/\u001B\[[0-9;]*m/g, '');
1313
}
1414

1515
function joinRender(components: Component[], width = 100): string {

apps/pythinker-code/test/tui/components/panels/footer-goal-badge.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { DEFAULT_STATUS_LINE_CONFIG } from '#/tui/config';
55
import type { GoalSnapshot } from '@pythoughts/pythinker-code-sdk';
66
import type { AppState } from '#/tui/types';
77

8-
const ANSI_SGR = /\[[0-9;]*m/g;
8+
const ANSI_SGR = /\u001B\[[0-9;]*m/g;
99
function strip(text: string): string {
1010
return text.replaceAll(ANSI_SGR, '');
1111
}

0 commit comments

Comments
 (0)