Makelore 2.0 initial clean snapshot
This commit is contained in:
161
tests/unit/generated-files.test.ts
Normal file
161
tests/unit/generated-files.test.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
computeLineStats,
|
||||
extractGeneratedFiles,
|
||||
supportsInlineDiff,
|
||||
supportsInlineDocumentPreview,
|
||||
type GeneratedFile,
|
||||
type GeneratedFileBaseline,
|
||||
} from '@/lib/generated-files';
|
||||
import type { RawMessage } from '@/types/chat';
|
||||
|
||||
function makeWriteFile(overrides: Partial<GeneratedFile> = {}): GeneratedFile {
|
||||
return {
|
||||
filePath: '/tmp/example.ts',
|
||||
fileName: 'example.ts',
|
||||
ext: '.ts',
|
||||
mimeType: 'text/typescript',
|
||||
contentType: 'code',
|
||||
action: 'modified',
|
||||
fullContent: 'const value = 2\nconsole.log(value)\n',
|
||||
lastSeenIndex: 1,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe('generated-files utilities', () => {
|
||||
it('computes write line stats from an existing-file baseline', () => {
|
||||
const stats = computeLineStats(
|
||||
makeWriteFile({
|
||||
baseline: { status: 'ok', content: 'const value = 1\nconsole.log(value)\n' },
|
||||
}),
|
||||
);
|
||||
|
||||
expect(stats).toEqual({ added: 1, removed: 1 });
|
||||
});
|
||||
|
||||
it('treats missing baseline as a new file for line stats', () => {
|
||||
const stats = computeLineStats(
|
||||
makeWriteFile({
|
||||
action: 'created',
|
||||
baseline: { status: 'missing' },
|
||||
fullContent: 'line 1\nline 2\n',
|
||||
}),
|
||||
);
|
||||
|
||||
expect(stats).toEqual({ added: 2, removed: 0 });
|
||||
});
|
||||
|
||||
it('refuses to fake precise line stats when baseline is unavailable', () => {
|
||||
const stats = computeLineStats(
|
||||
makeWriteFile({
|
||||
baseline: { status: 'unavailable', reason: 'outsideSandbox' },
|
||||
}),
|
||||
);
|
||||
|
||||
expect(stats).toBeNull();
|
||||
});
|
||||
|
||||
it('routes pdf/spreadsheet to rich-doc preview but never to text diff', () => {
|
||||
expect(supportsInlineDocumentPreview('.md')).toBe(true);
|
||||
// PDFs and spreadsheets now render through dedicated viewers, so they
|
||||
// qualify for inline preview...
|
||||
expect(supportsInlineDocumentPreview('.pdf')).toBe(true);
|
||||
expect(supportsInlineDocumentPreview('.xlsx')).toBe(true);
|
||||
// ...but diffing binary content is still meaningless, so the diff
|
||||
// tab stays hidden for these formats.
|
||||
expect(supportsInlineDiff({ ext: '.pdf', contentType: 'document' })).toBe(false);
|
||||
expect(supportsInlineDiff({ ext: '.xlsx', contentType: 'document' })).toBe(false);
|
||||
expect(supportsInlineDiff({ ext: '.docx', contentType: 'document' })).toBe(false);
|
||||
|
||||
const stats = computeLineStats({
|
||||
filePath: '/tmp/report.pdf',
|
||||
fileName: 'report.pdf',
|
||||
ext: '.pdf',
|
||||
mimeType: 'application/pdf',
|
||||
contentType: 'document',
|
||||
action: 'modified',
|
||||
fullContent: 'pretend text payload',
|
||||
baseline: { status: 'ok', content: 'older pretend text payload' },
|
||||
lastSeenIndex: 1,
|
||||
});
|
||||
|
||||
expect(stats).toBeNull();
|
||||
});
|
||||
|
||||
it('extracts write files with per-run baseline state and action', () => {
|
||||
const messages: RawMessage[] = [
|
||||
{ role: 'user', content: 'update file', timestamp: 1 },
|
||||
{
|
||||
role: 'assistant',
|
||||
content: [{
|
||||
type: 'tool_use',
|
||||
id: 'write-1',
|
||||
name: 'Write',
|
||||
input: {
|
||||
file_path: '/tmp/example.ts',
|
||||
content: 'const value = 2\n',
|
||||
},
|
||||
}],
|
||||
},
|
||||
];
|
||||
|
||||
const baselineByPath = new Map<string, GeneratedFileBaseline>([
|
||||
['/tmp/example.ts', { status: 'ok', content: 'const value = 1\n' }],
|
||||
]);
|
||||
|
||||
const files = extractGeneratedFiles(messages, 0, 1, (filePath) => baselineByPath.get(filePath));
|
||||
|
||||
expect(files).toHaveLength(1);
|
||||
expect(files[0]).toMatchObject({
|
||||
filePath: '/tmp/example.ts',
|
||||
action: 'modified',
|
||||
baseline: { status: 'ok', content: 'const value = 1\n' },
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps new-file writes marked as created when the baseline says missing', () => {
|
||||
const messages: RawMessage[] = [
|
||||
{ role: 'user', content: 'create file', timestamp: 1 },
|
||||
{
|
||||
role: 'assistant',
|
||||
content: [{
|
||||
type: 'tool_use',
|
||||
id: 'write-1',
|
||||
name: 'Write',
|
||||
input: {
|
||||
file_path: '/tmp/new-file.ts',
|
||||
content: 'export const created = true\n',
|
||||
},
|
||||
}],
|
||||
},
|
||||
];
|
||||
|
||||
const files = extractGeneratedFiles(messages, 0, 1, () => ({ status: 'missing' }));
|
||||
|
||||
expect(files).toHaveLength(1);
|
||||
expect(files[0]).toMatchObject({
|
||||
filePath: '/tmp/new-file.ts',
|
||||
action: 'created',
|
||||
baseline: { status: 'missing' },
|
||||
});
|
||||
});
|
||||
|
||||
it('computes edit snippet stats from joined edit hunks', () => {
|
||||
const stats = computeLineStats({
|
||||
filePath: '/tmp/example.ts',
|
||||
fileName: 'example.ts',
|
||||
ext: '.ts',
|
||||
mimeType: 'text/typescript',
|
||||
contentType: 'code',
|
||||
action: 'modified',
|
||||
edits: [
|
||||
{ old: 'alpha\n', new: 'beta\n' },
|
||||
{ old: 'gamma\n', new: 'delta\n' },
|
||||
],
|
||||
lastSeenIndex: 1,
|
||||
});
|
||||
|
||||
expect(stats).toEqual({ added: 2, removed: 2 });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user