agent-ecosystem/test/renderer/utils/reviewKey.test.ts

108 lines
4.5 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
getReviewKeyForFilePath,
normalizePersistedReviewState,
} from '../../../src/renderer/utils/reviewKey';
describe('reviewKey path normalization', () => {
it('maps slash variants of Windows file paths to the same review key', () => {
const files = [{ filePath: 'C:\\Repo\\src\\file.ts', changeKey: 'path:c:/repo/src/file.ts' }];
expect(getReviewKeyForFilePath(files, 'c:/repo/src/file.ts')).toBe('path:c:/repo/src/file.ts');
});
it('maps relative Windows slash and case variants to the same review key', () => {
const files = [{ filePath: 'SRC\\File.ts', changeKey: 'path:SRC/File.ts' }];
expect(getReviewKeyForFilePath(files, 'src/file.ts')).toBe('path:SRC/File.ts');
});
it('normalizes persisted legacy Windows path decisions onto changeKey entries', () => {
const files = [{ filePath: 'C:/Repo/src/file.ts', changeKey: 'path:c:/repo/src/file.ts' }];
const state = normalizePersistedReviewState(files, {
fileDecisions: { 'c:\\repo\\src\\file.ts': 'rejected' },
hunkDecisions: { 'c:\\repo\\src\\file.ts:2': 'accepted' },
hunkContextHashesByFile: { 'c:\\repo\\src\\file.ts': { 2: 'ctx' } },
});
expect(state.fileDecisions).toEqual({ 'path:c:/repo/src/file.ts': 'rejected' });
expect(state.hunkDecisions).toEqual({ 'path:c:/repo/src/file.ts:2': 'accepted' });
expect(state.hunkContextHashesByFile).toEqual({
'path:c:/repo/src/file.ts': { 2: 'ctx' },
});
});
it('normalizes persisted Windows worktree relation decisions onto changeKey entries', () => {
const changeKey = 'rename:C:/Repo/.claude/worktrees/team-a:src/old.ts->src/new.ts';
const files = [{ filePath: 'C:\\Repo\\.claude\\worktrees\\team-a\\src\\new.ts', changeKey }];
const state = normalizePersistedReviewState(files, {
fileDecisions: {
'rename:c:\\repo\\.claude\\worktrees\\team-a:src\\old.ts->src\\new.ts': 'rejected',
},
hunkDecisions: {
'rename:c:\\repo\\.claude\\worktrees\\team-a:src\\old.ts->src\\new.ts:1': 'accepted',
},
hunkContextHashesByFile: {
'rename:c:\\repo\\.claude\\worktrees\\team-a:src\\old.ts->src\\new.ts': { 1: 'ctx' },
},
});
expect(state.fileDecisions).toEqual({ [changeKey]: 'rejected' });
expect(state.hunkDecisions).toEqual({ [`${changeKey}:1`]: 'accepted' });
expect(state.hunkContextHashesByFile).toEqual({ [changeKey]: { 1: 'ctx' } });
});
it('normalizes persisted relative Windows relation decisions onto case-preserving changeKey entries', () => {
const changeKey = 'rename:src/OLD.ts->src/NEW.ts';
const files = [{ filePath: 'SRC\\NEW.ts', changeKey }];
const state = normalizePersistedReviewState(files, {
fileDecisions: {
'rename:src\\old.ts->src\\new.ts': 'rejected',
},
hunkDecisions: {
'rename:src\\old.ts->src\\new.ts:1': 'accepted',
},
hunkContextHashesByFile: {
'rename:src\\old.ts->src\\new.ts': { 1: 'ctx' },
},
});
expect(state.fileDecisions).toEqual({ [changeKey]: 'rejected' });
expect(state.hunkDecisions).toEqual({ [`${changeKey}:1`]: 'accepted' });
expect(state.hunkContextHashesByFile).toEqual({ [changeKey]: { 1: 'ctx' } });
});
it('normalizes persisted relative Windows relation decisions even when stored with slash separators', () => {
const changeKey = 'rename:src/OLD.ts->src/NEW.ts';
const files = [{ filePath: 'SRC\\NEW.ts', changeKey }];
const state = normalizePersistedReviewState(files, {
fileDecisions: {
'rename:SRC/OLD.ts->SRC/NEW.ts': 'rejected',
},
hunkDecisions: {
'rename:SRC/OLD.ts->SRC/NEW.ts:1': 'accepted',
},
hunkContextHashesByFile: {
'rename:SRC/OLD.ts->SRC/NEW.ts': { 1: 'ctx' },
},
});
expect(state.fileDecisions).toEqual({ [changeKey]: 'rejected' });
expect(state.hunkDecisions).toEqual({ [`${changeKey}:1`]: 'accepted' });
expect(state.hunkContextHashesByFile).toEqual({ [changeKey]: { 1: 'ctx' } });
});
it('keeps POSIX-only persisted decisions case-sensitive', () => {
const files = [{ filePath: 'src/file.ts', changeKey: 'path:src/file.ts' }];
const state = normalizePersistedReviewState(files, {
fileDecisions: { 'SRC/File.ts': 'rejected' },
hunkDecisions: { 'SRC/File.ts:1': 'accepted' },
hunkContextHashesByFile: { 'SRC/File.ts': { 1: 'ctx' } },
});
expect(state.fileDecisions).toEqual({});
expect(state.hunkDecisions).toEqual({});
expect(state.hunkContextHashesByFile).toEqual({});
});
});