Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"pre-commit": "node scripts/pre-commit.js"
},
"overrides": {
"ink": "npm:@jrichman/ink@6.4.8",
"ink": "npm:@jrichman/ink@6.4.9",
"wrap-ansi": "9.0.2",
"cliui": {
"wrap-ansi": "7.0.0"
Expand Down Expand Up @@ -124,7 +124,7 @@
"yargs": "^17.7.2"
},
"dependencies": {
"ink": "npm:@jrichman/ink@6.4.8",
"ink": "npm:@jrichman/ink@6.4.9",
"latest-version": "^9.0.0",
"simple-git": "^3.28.0"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"fzf": "^0.5.2",
"glob": "^12.0.0",
"highlight.js": "^11.11.1",
"ink": "npm:@jrichman/ink@6.4.8",
"ink": "npm:@jrichman/ink@6.4.9",
"ink-gradient": "^3.0.0",
"ink-spinner": "^5.0.0",
"latest-version": "^9.0.0",
Expand Down
182 changes: 182 additions & 0 deletions packages/cli/src/ui/utils/TableRenderer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,186 @@ describe('TableRenderer', () => {
expect(output).toContain('Data 3.4');
expect(output).toMatchSnapshot();
});

it('wraps long cell content correctly', () => {
const headers = ['Col 1', 'Col 2'];
const rows = [
[
'Short',
'This is a very long cell content that should wrap to multiple lines',
],
];
const terminalWidth = 40;

const { lastFrame } = renderWithProviders(
<TableRenderer
headers={headers}
rows={rows}
terminalWidth={terminalWidth}
/>,
);

const output = lastFrame();
expect(output).toContain('This is a very');
expect(output).toContain('long cell');
expect(output).toMatchSnapshot();
});

it('wraps all long columns correctly', () => {
const headers = ['Col 1', 'Col 2'];
const rows = [
[
'This is a very long text that needs wrapping in column 1',
'This is also a very long text that needs wrapping in column 2',
],
];
const terminalWidth = 50;

const { lastFrame } = renderWithProviders(
<TableRenderer
headers={headers}
rows={rows}
terminalWidth={terminalWidth}
/>,
);

const output = lastFrame();
expect(output).toContain('wrapping in');
expect(output).toMatchSnapshot();
});

it('wraps mixed long and short columns correctly', () => {
const headers = ['Short', 'Long'];
const rows = [
[
'Tiny',
'This is a very long text that definitely needs to wrap to the next line',
],
];
const terminalWidth = 40;

const { lastFrame } = renderWithProviders(
<TableRenderer
headers={headers}
rows={rows}
terminalWidth={terminalWidth}
/>,
);

const output = lastFrame();
expect(output).toContain('Tiny');
expect(output).toContain('definitely needs');
expect(output).toMatchSnapshot();
});

it('wraps columns with punctuation correctly', () => {
const headers = ['Punctuation'];
const rows = [
['Start. Stop. Comma, separated. Exclamation! Question? hyphen-ated'],
];
const terminalWidth = 30;

const { lastFrame } = renderWithProviders(
<TableRenderer
headers={headers}
rows={rows}
terminalWidth={terminalWidth}
/>,
);

const output = lastFrame();
expect(output).toContain('Start. Stop.');
expect(output).toMatchSnapshot();
});

it('strips bold markers from headers and renders them correctly', () => {
const headers = ['**Bold Header**', 'Normal Header'];
const rows = [['Data 1', 'Data 2']];
const terminalWidth = 40;

const { lastFrame } = renderWithProviders(
<TableRenderer
headers={headers}
rows={rows}
terminalWidth={terminalWidth}
/>,
);

const output = lastFrame();
// The output should NOT contain the literal '**'
expect(output).not.toContain('**Bold Header**');
expect(output).toContain('Bold Header');
expect(output).toMatchSnapshot();
});

it('handles wrapped bold headers without showing markers', () => {
const headers = ['**Very Long Bold Header That Will Wrap**'];
const rows = [['Data']];
const terminalWidth = 20;

const { lastFrame } = renderWithProviders(
<TableRenderer
headers={headers}
rows={rows}
terminalWidth={terminalWidth}
/>,
);

const output = lastFrame();
// Markers should be gone
expect(output).not.toContain('**');
expect(output).toContain('Very Long');
expect(output).toMatchSnapshot();
});

it('renders a complex table with mixed content lengths correctly', () => {
const headers = [
'Comprehensive Architectural Specification for the Distributed Infrastructure Layer',
'Implementation Details for the High-Throughput Asynchronous Message Processing Pipeline with Extended Scalability Features and Redundancy Protocols',
'Longitudinal Performance Analysis Across Multi-Regional Cloud Deployment Clusters',
'Strategic Security Framework for Mitigating Sophisticated Cross-Site Scripting Vulnerabilities',
'Key',
'Status',
'Version',
'Owner',
];
const rows = [
[
'The primary architecture utilizes a decoupled microservices approach, leveraging container orchestration for scalability and fault tolerance in high-load scenarios.\n\nThis layer provides the fundamental building blocks for service discovery, load balancing, and inter-service communication via highly efficient protocol buffers.\n\nAdvanced telemetry and logging integrations allow for real-time monitoring of system health and rapid identification of bottlenecks within the service mesh.',
'Each message is processed through a series of specialized workers that handle data transformation, validation, and persistent storage using a persistent queue.\n\nThe pipeline features built-in retry mechanisms with exponential backoff to ensure message delivery integrity even during transient network or service failures.\n\nHorizontal autoscaling is triggered automatically based on the depth of the processing queue, ensuring consistent performance during unexpected traffic spikes.',
'Historical data indicates a significant reduction in tail latency when utilizing edge computing nodes closer to the geographic location of the end-user base.\n\nMonitoring tools have captured a steady increase in throughput efficiency since the introduction of the vectorized query engine in the primary data warehouse.\n\nResource utilization metrics demonstrate that the transition to serverless compute for intermittent tasks has resulted in a thirty percent cost optimization.',
'A multi-layered defense strategy incorporates content security policies, input sanitization libraries, and regular automated penetration testing routines.\n\nDevelopers are required to undergo mandatory security training focusing on the OWASP Top Ten to ensure that security is integrated into the initial design phase.\n\nThe implementation of a robust Identity and Access Management system ensures that the principle of least privilege is strictly enforced across all environments.',
'INF',
'Active',
'v2.4',
'J. Doe',
],
];

const terminalWidth = 160;

const { lastFrame } = renderWithProviders(
<TableRenderer
headers={headers}
rows={rows}
terminalWidth={terminalWidth}
/>,
);

const output = lastFrame();

expect(output).toContain('Comprehensive Architectural');
expect(output).toContain('protocol buffers');
expect(output).toContain('exponential backoff');
expect(output).toContain('vectorized query engine');
expect(output).toContain('OWASP Top Ten');
expect(output).toContain('INF');
expect(output).toContain('Active');
expect(output).toContain('v2.4');
// "J. Doe" might wrap due to column width constraints
expect(output).toContain('J.');
expect(output).toContain('Doe');

expect(output).toMatchSnapshot();
});
});
Loading
Loading