108 lines
4.5 KiB
TypeScript
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({});
|
|
});
|
|
});
|