* feat: Redesign git changes to split stage/unstaged files. Signed-off-by: Paolo Insogna <paolo@cowtech.it> * fixup Signed-off-by: Paolo Insogna <paolo@cowtech.it> * fixup Signed-off-by: Paolo Insogna <paolo@cowtech.it> * refactor: streamline git changes panel * fix: label staged and working diff tabs * fix: isolate staged and working diff files * fix: scope staged and working diff updates * fix: scope git row revert to working changes --------- Signed-off-by: Paolo Insogna <paolo@cowtech.it> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
50 lines
2.2 KiB
JavaScript
50 lines
2.2 KiB
JavaScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import { resolveBaseRefForLog, stageFiles, unstageFiles } from './service.js';
|
|
|
|
describe('resolveBaseRefForLog', () => {
|
|
it('returns the local ref unchanged when it exists, even if origin also exists', async () => {
|
|
// Both local 'main' and 'refs/remotes/origin/main' are present.
|
|
// The local ref takes precedence — callers that ask for 'main' get 'main'.
|
|
const checkRef = async (ref) => ref === 'main' || ref === 'refs/remotes/origin/main';
|
|
expect(await resolveBaseRefForLog('main', checkRef)).toBe('main');
|
|
});
|
|
|
|
it('falls back to origin/<from> when local ref cannot be resolved but origin can', async () => {
|
|
// Local 'main' is absent (e.g. user never checked it out), but origin/main exists.
|
|
const checkRef = async (ref) => ref === 'refs/remotes/origin/main';
|
|
expect(await resolveBaseRefForLog('main', checkRef)).toBe('origin/main');
|
|
});
|
|
|
|
it('returns the original ref when neither local nor origin ref can be resolved', async () => {
|
|
// Neither ref exists; return as-is so git surfaces a meaningful error.
|
|
const checkRef = async () => false;
|
|
expect(await resolveBaseRefForLog('nonexistent-branch', checkRef)).toBe('nonexistent-branch');
|
|
});
|
|
|
|
it('returns undefined when from is undefined', async () => {
|
|
const checkRef = async () => true;
|
|
expect(await resolveBaseRefForLog(undefined, checkRef)).toBeUndefined();
|
|
});
|
|
|
|
it('returns undefined when from is an empty string', async () => {
|
|
const checkRef = async () => true;
|
|
expect(await resolveBaseRefForLog('', checkRef)).toBeUndefined();
|
|
});
|
|
|
|
it('returns undefined when from is a whitespace-only string', async () => {
|
|
const checkRef = async () => true;
|
|
expect(await resolveBaseRefForLog(' ', checkRef)).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('git index path validation', () => {
|
|
it('rejects stage paths outside the repository before invoking git', async () => {
|
|
await expect(stageFiles('/repo', ['../secret.txt'])).rejects.toThrow('Path is outside repository: ../secret.txt');
|
|
});
|
|
|
|
it('rejects unstage paths outside the repository before invoking git', async () => {
|
|
await expect(unstageFiles('/repo', ['../secret.txt'])).rejects.toThrow('Path is outside repository: ../secret.txt');
|
|
});
|
|
});
|