mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-08-28 05:25:25 +00:00
- 59 test files covering unit and integration tests - vitest config with coverage thresholds and fork pooling - Test fixtures (mini-repo + multi-language sample code) - Add vitest + coverage-v8 to devDependencies - Add test scripts (test, test:integration, test:all, test:watch, test:coverage) - Move typescript to devDependencies where it belongs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
89 lines
2.9 KiB
TypeScript
89 lines
2.9 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { execSync } from 'child_process';
|
|
import { isGitRepo, getCurrentCommit, getGitRoot } from '../../src/storage/git.js';
|
|
|
|
// Mock child_process.execSync
|
|
vi.mock('child_process', () => ({
|
|
execSync: vi.fn(),
|
|
}));
|
|
|
|
const mockExecSync = vi.mocked(execSync);
|
|
|
|
describe('git utilities', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('isGitRepo', () => {
|
|
it('returns true when inside a git work tree', () => {
|
|
mockExecSync.mockReturnValueOnce(Buffer.from(''));
|
|
expect(isGitRepo('/project')).toBe(true);
|
|
expect(mockExecSync).toHaveBeenCalledWith(
|
|
'git rev-parse --is-inside-work-tree',
|
|
{ cwd: '/project', stdio: 'ignore' }
|
|
);
|
|
});
|
|
|
|
it('returns false when not a git repo', () => {
|
|
mockExecSync.mockImplementationOnce(() => { throw new Error('not a git repo'); });
|
|
expect(isGitRepo('/not-a-repo')).toBe(false);
|
|
});
|
|
|
|
it('passes the correct cwd', () => {
|
|
mockExecSync.mockReturnValueOnce(Buffer.from(''));
|
|
isGitRepo('/some/path');
|
|
expect(mockExecSync).toHaveBeenCalledWith(
|
|
expect.any(String),
|
|
expect.objectContaining({ cwd: '/some/path' })
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('getCurrentCommit', () => {
|
|
it('returns trimmed commit hash', () => {
|
|
mockExecSync.mockReturnValueOnce(Buffer.from('abc123def\n'));
|
|
expect(getCurrentCommit('/project')).toBe('abc123def');
|
|
});
|
|
|
|
it('returns empty string on error', () => {
|
|
mockExecSync.mockImplementationOnce(() => { throw new Error('not a git repo'); });
|
|
expect(getCurrentCommit('/not-a-repo')).toBe('');
|
|
});
|
|
|
|
it('trims whitespace from output', () => {
|
|
mockExecSync.mockReturnValueOnce(Buffer.from(' sha256hash \n'));
|
|
expect(getCurrentCommit('/project')).toBe('sha256hash');
|
|
});
|
|
});
|
|
|
|
describe('getGitRoot', () => {
|
|
it('returns resolved path on success', () => {
|
|
mockExecSync.mockReturnValueOnce(Buffer.from('/d/Projects/MyRepo\n'));
|
|
const result = getGitRoot('/d/Projects/MyRepo/src');
|
|
expect(result).toBeTruthy();
|
|
// path.resolve normalizes the git output
|
|
expect(typeof result).toBe('string');
|
|
});
|
|
|
|
it('returns null when not in a git repo', () => {
|
|
mockExecSync.mockImplementationOnce(() => { throw new Error('not a git repo'); });
|
|
expect(getGitRoot('/not-a-repo')).toBeNull();
|
|
});
|
|
|
|
it('calls git rev-parse --show-toplevel', () => {
|
|
mockExecSync.mockReturnValueOnce(Buffer.from('/repo\n'));
|
|
getGitRoot('/repo/src');
|
|
expect(mockExecSync).toHaveBeenCalledWith(
|
|
'git rev-parse --show-toplevel',
|
|
expect.objectContaining({ cwd: '/repo/src' })
|
|
);
|
|
});
|
|
|
|
it('trims output before resolving path', () => {
|
|
mockExecSync.mockReturnValueOnce(Buffer.from(' /repo \n'));
|
|
const result = getGitRoot('/repo/src');
|
|
expect(result).not.toBeNull();
|
|
expect(result!.trim()).toBe(result);
|
|
});
|
|
});
|
|
});
|