import { describe, expect, it, vi, beforeEach } from 'vitest';
import { StreamingMessageParser, type ActionCallback, type ArtifactCallback } from './message-parser';
import { EnhancedStreamingMessageParser } from './enhanced-message-parser';
interface ExpectedResult {
output: string;
callbacks?: {
onArtifactOpen?: number;
onArtifactClose?: number;
onActionOpen?: number;
onActionClose?: number;
};
}
describe('StreamingMessageParser', () => {
it('should pass through normal text', () => {
const parser = new StreamingMessageParser();
expect(parser.parse('test_id', 'Hello, world!')).toBe('Hello, world!');
});
it('should allow normal HTML tags', () => {
const parser = new StreamingMessageParser();
expect(parser.parse('test_id', 'Hello world!')).toBe('Hello world!');
});
describe('no artifacts', () => {
it.each<[string | string[], ExpectedResult | string]>([
['Foo bar', 'Foo bar'],
['Foo bar <', 'Foo bar '],
['Foo bar
some text'], 'Foo bar some text'],
])('should correctly parse chunks and strip out bolt artifacts (%#)', (input, expected) => {
runTest(input, expected);
});
});
describe('invalid or incomplete artifacts', () => {
it.each<[string | string[], ExpectedResult | string]>([
['Foo bar ', 'Foo bar '],
['Before foo After', 'Before foo After'],
['Before foo After', 'Before foo After'],
])('should correctly parse chunks and strip out bolt artifacts (%#)', (input, expected) => {
runTest(input, expected);
});
});
describe('valid artifacts without actions', () => {
it.each<[string | string[], ExpectedResult | string]>([
[
'Some text before foo bar Some more text',
{
output: 'Some text before Some more text',
callbacks: { onArtifactOpen: 1, onArtifactClose: 1, onActionOpen: 0, onActionClose: 0 },
},
],
[
[
'Some text before foo Some more text',
],
{
output: 'Some text before Some more text',
callbacks: { onArtifactOpen: 1, onArtifactClose: 1, onActionOpen: 0, onActionClose: 0 },
},
],
[
[
'Some text before ',
'foo Some more text',
],
{
output: 'Some text before Some more text',
callbacks: { onArtifactOpen: 1, onArtifactClose: 1, onActionOpen: 0, onActionClose: 0 },
},
],
[
[
'Some text before fo',
'o Some more text',
],
{
output: 'Some text before Some more text',
callbacks: { onArtifactOpen: 1, onArtifactClose: 1, onActionOpen: 0, onActionClose: 0 },
},
],
[
[
'Some text before fo',
'o',
'<',
'/boltArtifact> Some more text',
],
{
output: 'Some text before Some more text',
callbacks: { onArtifactOpen: 1, onArtifactClose: 1, onActionOpen: 0, onActionClose: 0 },
},
],
[
[
'Some text before fo',
'o<',
'/boltArtifact> Some more text',
],
{
output: 'Some text before Some more text',
callbacks: { onArtifactOpen: 1, onArtifactClose: 1, onActionOpen: 0, onActionClose: 0 },
},
],
[
'Before foo After',
{
output: 'Before After',
callbacks: { onArtifactOpen: 1, onArtifactClose: 1, onActionOpen: 0, onActionClose: 0 },
},
],
])('should correctly parse chunks and strip out bolt artifacts (%#)', (input, expected) => {
runTest(input, expected);
});
});
describe('valid artifacts with actions', () => {
it.each<[string | string[], ExpectedResult | string]>([
[
'Before npm install After',
{
output: 'Before After',
callbacks: { onArtifactOpen: 1, onArtifactClose: 1, onActionOpen: 1, onActionClose: 1 },
},
],
[
'Before npm installsome content After',
{
output: 'Before After',
callbacks: { onArtifactOpen: 1, onArtifactClose: 1, onActionOpen: 2, onActionClose: 2 },
},
],
])('should correctly parse chunks and strip out bolt artifacts (%#)', (input, expected) => {
runTest(input, expected);
});
});
});
describe('EnhancedStreamingMessageParser', () => {
it('should detect shell commands in code blocks', () => {
const callbacks = {
onArtifactOpen: vi.fn(),
onArtifactClose: vi.fn(),
onActionOpen: vi.fn(),
onActionClose: vi.fn(),
};
const parser = new EnhancedStreamingMessageParser({
callbacks,
});
const input = '```bash\nnpm install && npm run dev\n```';
parser.parse('test_id', input);
expect(callbacks.onActionOpen).toHaveBeenCalledWith(
expect.objectContaining({
action: expect.objectContaining({
type: 'shell',
content: 'npm install && npm run dev',
}),
}),
);
});
it('should detect file creation from code blocks with context', () => {
const callbacks = {
onArtifactOpen: vi.fn(),
onArtifactClose: vi.fn(),
onActionOpen: vi.fn(),
onActionClose: vi.fn(),
};
const parser = new EnhancedStreamingMessageParser({
callbacks,
});
const input =
'Create a new file called index.js:\n\n```javascript\nfunction hello() {\n console.log("Hello World");\n}\n```';
parser.parse('test_id', input);
expect(callbacks.onArtifactOpen).toHaveBeenCalledWith(
expect.objectContaining({
id: expect.stringContaining('test_id-'),
title: 'index.js',
}),
);
});
it('should not create actions for code blocks without context', () => {
const callbacks = {
onArtifactOpen: vi.fn(),
onArtifactClose: vi.fn(),
onActionOpen: vi.fn(),
onActionClose: vi.fn(),
};
const parser = new EnhancedStreamingMessageParser({
callbacks,
});
const input = 'Here is some code:\n\n```javascript\nfunction test() {}\n```';
parser.parse('test_id', input);
expect(callbacks.onArtifactOpen).not.toHaveBeenCalled();
expect(callbacks.onActionOpen).not.toHaveBeenCalled();
});
describe('AI Model Output Patterns Integration Tests', () => {
let callbacks: {
onArtifactOpen: any;
onArtifactClose: any;
onActionOpen: any;
onActionClose: any;
};
let parser: EnhancedStreamingMessageParser;
beforeEach(() => {
callbacks = {
onArtifactOpen: vi.fn(),
onArtifactClose: vi.fn(),
onActionOpen: vi.fn(),
onActionClose: vi.fn(),
};
parser = new EnhancedStreamingMessageParser({ callbacks });
});
describe('GPT-4 style outputs', () => {
it('should handle file creation with explicit path', () => {
const input = `I'll create a React component for you.
app/components/Button.tsx:
\`\`\`tsx
import React from 'react';
interface ButtonProps {
children: React.ReactNode;
onClick: () => void;
}
export const Button: React.FC = ({ children, onClick }) => {
return (
);
};
\`\`\``;
parser.parse('test_gpt4_1', input);
expect(callbacks.onArtifactOpen).toHaveBeenCalledWith(
expect.objectContaining({
title: 'Button.tsx',
}),
);
expect(callbacks.onActionOpen).toHaveBeenCalledWith(
expect.objectContaining({
action: expect.objectContaining({
type: 'file',
filePath: '/app/components/Button.tsx',
}),
}),
);
});
it('should handle package.json updates', () => {
const input = `Update your package.json file:
package.json:
\`\`\`json
{
"name": "my-app",
"version": "1.0.0",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"dependencies": {
"react": "^18.0.0"
}
}
\`\`\``;
parser.parse('test_gpt4_2', input);
expect(callbacks.onArtifactOpen).toHaveBeenCalled();
expect(callbacks.onActionOpen).toHaveBeenCalledWith(
expect.objectContaining({
action: expect.objectContaining({
type: 'file',
filePath: '/package.json',
}),
}),
);
});
});
describe('Claude style outputs', () => {
it('should handle create file instructions', () => {
const input = `I'll create a new configuration file for you.
Create a file called \`config.ts\`:
\`\`\`typescript
export const config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
};
\`\`\``;
parser.parse('test_claude_1', input);
expect(callbacks.onArtifactOpen).toHaveBeenCalledWith(
expect.objectContaining({
title: 'config.ts',
}),
);
expect(callbacks.onActionOpen).toHaveBeenCalledWith(
expect.objectContaining({
action: expect.objectContaining({
type: 'file',
filePath: '/config.ts',
}),
}),
);
});
it('should handle "Here\'s the file" pattern', () => {
const input = `Here's styles.css:
\`\`\`css
.container {
display: flex;
justify-content: center;
align-items: center;
}
.button {
padding: 10px 20px;
border: none;
border-radius: 4px;
}
\`\`\``;
parser.parse('test_claude_2', input);
expect(callbacks.onArtifactOpen).toHaveBeenCalledWith(
expect.objectContaining({
title: 'styles.css',
}),
);
});
});
describe('Gemini style outputs', () => {
it('should handle file comments in code', () => {
const input = `Here's your component:
\`\`\`javascript
// filename: utils/helper.js
function formatDate(date) {
return new Intl.DateTimeFormat('en-US').format(date);
}
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
export { formatDate, debounce };
\`\`\``;
parser.parse('test_gemini_1', input);
expect(callbacks.onArtifactOpen).toHaveBeenCalledWith(
expect.objectContaining({
title: 'helper.js',
}),
);
expect(callbacks.onActionOpen).toHaveBeenCalledWith(
expect.objectContaining({
action: expect.objectContaining({
type: 'file',
filePath: '/utils/helper.js',
}),
}),
);
});
it('should handle "update filename.ext" pattern', () => {
const input = `Update server.js:
\`\`\`javascript
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
\`\`\``;
parser.parse('test_gemini_2', input);
expect(callbacks.onArtifactOpen).toHaveBeenCalledWith(
expect.objectContaining({
title: 'server.js',
}),
);
});
});
describe('Shell Command Detection', () => {
it('should detect npm commands', () => {
const input = `Run these commands:
\`\`\`bash
npm install express cors
npm run dev
\`\`\``;
parser.parse('test_shell_1', input);
expect(callbacks.onActionOpen).toHaveBeenCalledWith(
expect.objectContaining({
action: expect.objectContaining({
type: 'shell',
content: 'npm install express cors\nnpm run dev',
}),
}),
);
});
it('should detect git commands', () => {
const input = `Initialize your repository:
\`\`\`bash
git init
git add .
git commit -m "Initial commit"
\`\`\``;
parser.parse('test_shell_2', input);
expect(callbacks.onActionOpen).toHaveBeenCalledWith(
expect.objectContaining({
action: expect.objectContaining({
type: 'shell',
content: 'git init\ngit add .\ngit commit -m "Initial commit"',
}),
}),
);
});
it('should detect docker commands', () => {
const input = `Build and run the Docker container:
\`\`\`bash
docker build -t myapp .
docker run -p 3000:3000 myapp
\`\`\``;
parser.parse('test_shell_3', input);
expect(callbacks.onActionOpen).toHaveBeenCalledWith(
expect.objectContaining({
action: expect.objectContaining({
type: 'shell',
content: 'docker build -t myapp .\ndocker run -p 3000:3000 myapp',
}),
}),
);
});
it('should detect webcontainer commands', () => {
const input = `Check your files:
\`\`\`bash
ls -la
cat package.json
mkdir src
\`\`\``;
parser.parse('test_shell_4', input);
expect(callbacks.onActionOpen).toHaveBeenCalledWith(
expect.objectContaining({
action: expect.objectContaining({
type: 'shell',
content: 'ls -la\ncat package.json\nmkdir src',
}),
}),
);
});
});
describe('Edge Cases and False Positive Prevention', () => {
it('should not create artifacts for generic code examples', () => {
const input = `Here's an example of how functions work:
\`\`\`javascript
function example() {
console.log("This is just an example");
}
\`\`\``;
parser.parse('test_edge_1', input);
expect(callbacks.onArtifactOpen).not.toHaveBeenCalled();
expect(callbacks.onActionOpen).not.toHaveBeenCalled();
});
it('should ignore temp and test file patterns', () => {
const input = `Create temp/test.js:
\`\`\`javascript
console.log("temporary test");
\`\`\``;
parser.parse('test_edge_2', input);
expect(callbacks.onArtifactOpen).not.toHaveBeenCalled();
expect(callbacks.onActionOpen).not.toHaveBeenCalled();
});
it('should handle multiple code blocks with mixed content', () => {
const input = `First, create the component:
components/Header.tsx:
\`\`\`tsx
import React from 'react';
export const Header = () => Header
;
\`\`\`
Then install dependencies:
\`\`\`bash
npm install react-router-dom
\`\`\`
Here's an example of usage:
\`\`\`javascript
// This is just an example
function usage() {
return ;
}
\`\`\``;
parser.parse('test_edge_3', input);
// Should create artifact for Header.tsx
expect(callbacks.onArtifactOpen).toHaveBeenCalledWith(
expect.objectContaining({
title: 'Header.tsx',
}),
);
// Should create shell action for npm install
expect(callbacks.onActionOpen).toHaveBeenCalledWith(
expect.objectContaining({
action: expect.objectContaining({
type: 'shell',
content: 'npm install react-router-dom',
}),
}),
);
// Should not create action for the example usage
const fileActions = callbacks.onActionOpen.mock.calls.filter((call: any) => call[0].action.type === 'file');
expect(fileActions).toHaveLength(1); // Only Header.tsx
});
it('should validate file extensions', () => {
const input = `Create invalidfile:
\`\`\`
console.log("no extension");
\`\`\``;
parser.parse('test_edge_4', input);
expect(callbacks.onArtifactOpen).not.toHaveBeenCalled();
expect(callbacks.onActionOpen).not.toHaveBeenCalled();
});
it('should handle complex file paths correctly', () => {
const input = `Create the nested component:
src/components/ui/Button/index.tsx:
\`\`\`tsx
import React from 'react';
export { Button } from './Button';
\`\`\``;
parser.parse('test_edge_5', input);
expect(callbacks.onActionOpen).toHaveBeenCalledWith(
expect.objectContaining({
action: expect.objectContaining({
type: 'file',
filePath: '/src/components/ui/Button/index.tsx',
}),
}),
);
});
});
describe('Performance and Deduplication', () => {
it('should handle incremental parsing correctly', () => {
// Parse incrementally (simulating streaming)
const chunks = ['Create config.js:\n\n\`\`\`javascript\n', "const config = { api: 'test' };\n\`\`\`"];
let fullInput = '';
for (const chunk of chunks) {
fullInput += chunk;
parser.parse('test_perf_1', fullInput);
}
// Should create artifact when complete
expect(callbacks.onArtifactOpen).toHaveBeenCalledWith(
expect.objectContaining({
title: 'config.js',
}),
);
});
it('should handle streaming input correctly', () => {
const chunks = [
'Create the file:\n\n',
'app.js:\n\n',
'\`\`\`javascript\n',
'const app = ',
'express();\n',
'app.listen(3000);\n',
'\`\`\`',
];
let fullInput = '';
for (const chunk of chunks) {
fullInput += chunk;
parser.parse('test_stream_1', fullInput);
}
expect(callbacks.onArtifactOpen).toHaveBeenCalledWith(
expect.objectContaining({
title: 'app.js',
}),
);
});
});
describe('Performance Benchmarks', () => {
it('should perform well with enhanced parsing', () => {
const testInputs = [
`Create app.tsx:\n\n\`\`\`tsx\nimport React from 'react';\nexport const App = () => Hello
;\n\`\`\``,
`Run commands:\n\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\``,
`Here's config.json:\n\n\`\`\`json\n{"name": "test"}\n\`\`\``,
`Example code:\n\n\`\`\`javascript\nfunction example() {}\n\`\`\``,
];
// Benchmark enhanced parser
const enhancedCallbacks = {
onArtifactOpen: vi.fn(),
onArtifactClose: vi.fn(),
onActionOpen: vi.fn(),
onActionClose: vi.fn(),
};
const enhancedParser = new EnhancedStreamingMessageParser({
callbacks: enhancedCallbacks,
});
const startTime = performance.now();
const iterations = 100;
for (let i = 0; i < iterations; i++) {
testInputs.forEach((input, index) => {
enhancedParser.parse(`perf_test_${i}_${index}`, input);
});
enhancedParser.reset();
}
const endTime = performance.now();
const duration = endTime - startTime;
const avgTimePerOp = duration / (iterations * testInputs.length);
// Should complete quickly (less than 1ms average per operation)
expect(avgTimePerOp).toBeLessThan(1.0);
// Should detect artifacts appropriately
expect(enhancedCallbacks.onArtifactOpen.mock.calls.length).toBeGreaterThan(0);
console.log(`Performance: ${avgTimePerOp.toFixed(4)}ms per operation`);
console.log(`Artifacts detected: ${enhancedCallbacks.onArtifactOpen.mock.calls.length}`);
console.log(`Actions detected: ${enhancedCallbacks.onActionOpen.mock.calls.length}`);
});
});
});
});
function runTest(input: string | string[], outputOrExpectedResult: string | ExpectedResult) {
let expected: ExpectedResult;
if (typeof outputOrExpectedResult === 'string') {
expected = { output: outputOrExpectedResult };
} else {
expected = outputOrExpectedResult;
}
const callbacks = {
onArtifactOpen: vi.fn((data) => {
expect(data).toMatchSnapshot('onArtifactOpen');
}),
onArtifactClose: vi.fn((data) => {
expect(data).toMatchSnapshot('onArtifactClose');
}),
onActionOpen: vi.fn((data) => {
expect(data).toMatchSnapshot('onActionOpen');
}),
onActionClose: vi.fn((data) => {
expect(data).toMatchSnapshot('onActionClose');
}),
};
const parser = new StreamingMessageParser({
artifactElement: () => '',
callbacks,
});
let message = '';
let result = '';
const chunks = Array.isArray(input) ? input : input.split('');
for (const chunk of chunks) {
message += chunk;
result += parser.parse('message_1', message);
}
for (const name in expected.callbacks) {
const callbackName = name;
expect(callbacks[callbackName as keyof typeof callbacks]).toHaveBeenCalledTimes(
expected.callbacks[callbackName as keyof typeof expected.callbacks] ?? 0,
);
}
expect(result).toEqual(expected.output);
}