mirror of
https://github.com/davidkaya/aryx.git
synced 2026-07-24 13:38:43 +02:00
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
269 lines
6.6 KiB
TypeScript
269 lines
6.6 KiB
TypeScript
import { describe, expect, test } from 'bun:test';
|
|
|
|
import type { ProjectGitBaselineFile, ProjectGitWorkingTreeSnapshot } from '@shared/domain/project';
|
|
|
|
import { buildProjectGitRunChangeSummary } from '@main/git/gitRunChangeSummary';
|
|
|
|
const TIMESTAMP = '2026-03-31T00:00:00.000Z';
|
|
|
|
function createPreRunSnapshot(): ProjectGitWorkingTreeSnapshot {
|
|
return {
|
|
scannedAt: TIMESTAMP,
|
|
repoRoot: 'C:\\workspace\\alpha',
|
|
branch: 'main',
|
|
changedFileCount: 2,
|
|
changes: {
|
|
staged: 0,
|
|
unstaged: 1,
|
|
untracked: 1,
|
|
conflicted: 0,
|
|
},
|
|
files: [
|
|
{
|
|
path: 'src\\auth.ts',
|
|
unstagedStatus: 'modified',
|
|
},
|
|
{
|
|
path: 'legacy.tmp',
|
|
unstagedStatus: 'untracked',
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
function createPostRunSnapshot(): ProjectGitWorkingTreeSnapshot {
|
|
return {
|
|
scannedAt: TIMESTAMP,
|
|
repoRoot: 'C:\\workspace\\alpha',
|
|
branch: 'main',
|
|
changedFileCount: 2,
|
|
changes: {
|
|
staged: 0,
|
|
unstaged: 1,
|
|
untracked: 1,
|
|
conflicted: 0,
|
|
},
|
|
files: [
|
|
{
|
|
path: 'src\\auth.ts',
|
|
unstagedStatus: 'modified',
|
|
},
|
|
{
|
|
path: 'notes.txt',
|
|
unstagedStatus: 'untracked',
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
function createPreRunBaselines(): ProjectGitBaselineFile[] {
|
|
return [
|
|
{
|
|
path: 'src\\auth.ts',
|
|
combinedDiff: 'diff --git a/src/auth.ts b/src/auth.ts\n@@ -1 +1 @@\n-old\n+before\n',
|
|
},
|
|
{
|
|
path: 'legacy.tmp',
|
|
untrackedContentBase64: Buffer.from('legacy\n', 'utf8').toString('base64'),
|
|
},
|
|
];
|
|
}
|
|
|
|
function createPostRunBaselines(): ProjectGitBaselineFile[] {
|
|
return [
|
|
{
|
|
path: 'src\\auth.ts',
|
|
combinedDiff: 'diff --git a/src/auth.ts b/src/auth.ts\n@@ -1 +1 @@\n-old\n+after\n',
|
|
},
|
|
{
|
|
path: 'notes.txt',
|
|
untrackedContentBase64: Buffer.from('fresh notes\n', 'utf8').toString('base64'),
|
|
},
|
|
];
|
|
}
|
|
|
|
describe('buildProjectGitRunChangeSummary', () => {
|
|
test('classifies run-created, pre-existing, and cleaned files', () => {
|
|
const summary = buildProjectGitRunChangeSummary({
|
|
generatedAt: TIMESTAMP,
|
|
preRunSnapshot: createPreRunSnapshot(),
|
|
preRunBaselineFiles: createPreRunBaselines(),
|
|
postRunSnapshot: createPostRunSnapshot(),
|
|
postRunBaselineFiles: createPostRunBaselines(),
|
|
});
|
|
|
|
expect(summary).toMatchObject({
|
|
generatedAt: TIMESTAMP,
|
|
branchAtStart: 'main',
|
|
branchAtEnd: 'main',
|
|
fileCount: 3,
|
|
additions: 1,
|
|
deletions: 1,
|
|
counts: {
|
|
added: 0,
|
|
modified: 1,
|
|
deleted: 0,
|
|
renamed: 0,
|
|
copied: 0,
|
|
typeChanged: 0,
|
|
unmerged: 0,
|
|
untracked: 1,
|
|
cleaned: 1,
|
|
},
|
|
});
|
|
|
|
expect(summary?.files).toEqual([
|
|
{
|
|
path: 'notes.txt',
|
|
previousPath: undefined,
|
|
kind: 'untracked',
|
|
origin: 'run-created',
|
|
stagedStatus: undefined,
|
|
unstagedStatus: 'untracked',
|
|
additions: 0,
|
|
deletions: 0,
|
|
canRevert: true,
|
|
preview: {
|
|
path: 'notes.txt',
|
|
previousPath: undefined,
|
|
newFileContents: 'fresh notes\n',
|
|
},
|
|
},
|
|
{
|
|
path: 'legacy.tmp',
|
|
previousPath: undefined,
|
|
kind: 'cleaned',
|
|
origin: 'pre-existing',
|
|
stagedStatus: undefined,
|
|
unstagedStatus: 'untracked',
|
|
additions: 0,
|
|
deletions: 0,
|
|
canRevert: true,
|
|
preview: {
|
|
path: 'legacy.tmp',
|
|
previousPath: undefined,
|
|
newFileContents: 'legacy\n',
|
|
},
|
|
},
|
|
{
|
|
path: 'src\\auth.ts',
|
|
previousPath: undefined,
|
|
kind: 'modified',
|
|
origin: 'pre-existing',
|
|
stagedStatus: undefined,
|
|
unstagedStatus: 'modified',
|
|
additions: 1,
|
|
deletions: 1,
|
|
canRevert: true,
|
|
preview: {
|
|
path: 'src\\auth.ts',
|
|
previousPath: undefined,
|
|
diff: 'diff --git a/src/auth.ts b/src/auth.ts\n@@ -1 +1 @@\n-old\n+after\n',
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
|
|
test('returns undefined when nothing changed across the run', () => {
|
|
const snapshot = createPreRunSnapshot();
|
|
const baselines = createPreRunBaselines();
|
|
|
|
expect(buildProjectGitRunChangeSummary({
|
|
generatedAt: TIMESTAMP,
|
|
preRunSnapshot: snapshot,
|
|
preRunBaselineFiles: baselines,
|
|
postRunSnapshot: snapshot,
|
|
postRunBaselineFiles: baselines,
|
|
})).toBeUndefined();
|
|
});
|
|
|
|
test('marks pre-existing files as non-revertable when the baseline capture has no restore data', () => {
|
|
const summary = buildProjectGitRunChangeSummary({
|
|
generatedAt: TIMESTAMP,
|
|
preRunSnapshot: createPreRunSnapshot(),
|
|
preRunBaselineFiles: [
|
|
{
|
|
path: 'src\\auth.ts',
|
|
},
|
|
],
|
|
postRunSnapshot: createPostRunSnapshot(),
|
|
postRunBaselineFiles: createPostRunBaselines(),
|
|
});
|
|
|
|
expect(summary?.files.find((file) => file.path === 'src\\auth.ts')).toMatchObject({
|
|
path: 'src\\auth.ts',
|
|
origin: 'pre-existing',
|
|
canRevert: false,
|
|
});
|
|
|
|
expect(summary?.files.find((file) => file.path === 'legacy.tmp')).toMatchObject({
|
|
path: 'legacy.tmp',
|
|
kind: 'cleaned',
|
|
canRevert: false,
|
|
});
|
|
});
|
|
|
|
test('preserves empty untracked file previews', () => {
|
|
const summary = buildProjectGitRunChangeSummary({
|
|
generatedAt: TIMESTAMP,
|
|
preRunSnapshot: {
|
|
scannedAt: TIMESTAMP,
|
|
repoRoot: 'C:\\workspace\\alpha',
|
|
branch: 'main',
|
|
changedFileCount: 1,
|
|
changes: {
|
|
staged: 0,
|
|
unstaged: 0,
|
|
untracked: 1,
|
|
conflicted: 0,
|
|
},
|
|
files: [
|
|
{
|
|
path: 'empty.txt',
|
|
unstagedStatus: 'untracked',
|
|
},
|
|
],
|
|
},
|
|
preRunBaselineFiles: [
|
|
{
|
|
path: 'empty.txt',
|
|
untrackedContentBase64: '',
|
|
},
|
|
],
|
|
postRunSnapshot: {
|
|
scannedAt: TIMESTAMP,
|
|
repoRoot: 'C:\\workspace\\alpha',
|
|
branch: 'main',
|
|
changedFileCount: 0,
|
|
changes: {
|
|
staged: 0,
|
|
unstaged: 0,
|
|
untracked: 0,
|
|
conflicted: 0,
|
|
},
|
|
files: [],
|
|
},
|
|
postRunBaselineFiles: [],
|
|
});
|
|
|
|
expect(summary?.files).toEqual([
|
|
{
|
|
path: 'empty.txt',
|
|
previousPath: undefined,
|
|
kind: 'cleaned',
|
|
origin: 'pre-existing',
|
|
stagedStatus: undefined,
|
|
unstagedStatus: 'untracked',
|
|
additions: 0,
|
|
deletions: 0,
|
|
canRevert: true,
|
|
preview: {
|
|
path: 'empty.txt',
|
|
previousPath: undefined,
|
|
newFileContents: '',
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
});
|