mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-29 01:41:42 +00:00
Integration: - group-graph.test.ts: chain apps/web -> libs/shared -> libs/deep exercises findConnections recursion at depth 1/2/5, plus A -> B -> A cycle guard via the visited set. - auto-discover.test.ts: explicit repoPaths mode (happy path, unindexed- path error, basename fallback when resolveRepo throws). Unit: - cli-group.test.ts: 25 tests mocking LocalBackend/storage/sync across create, auto-discover, repos, add, remove, list, status, sync, graph, query, contracts. - cli-status.test.ts: 6 tests covering git-repo guard, stale-Kuzu prompt, up-to-date vs stale report. - cli-tool.test.ts: 16 tests covering query/context/impact/cypher arg validation, optional-param branches, backend-init failure, EPIPE/EACCES fallbacks in output(). Coverage delta vs main: +1.33% statements, +0.77% branches, +1.22% functions, +1.46% lines — clears the +0.5% review bar on all metrics. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
116 lines
3.8 KiB
TypeScript
116 lines
3.8 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
const mockIsGitRepo = vi.fn();
|
|
const mockGetGitRoot = vi.fn();
|
|
const mockGetCurrentCommit = vi.fn();
|
|
const mockFindRepo = vi.fn();
|
|
const mockGetStoragePaths = vi.fn();
|
|
const mockHasKuzuIndex = vi.fn();
|
|
|
|
vi.mock('../../src/storage/git.js', () => ({
|
|
isGitRepo: mockIsGitRepo,
|
|
getGitRoot: mockGetGitRoot,
|
|
getCurrentCommit: mockGetCurrentCommit,
|
|
}));
|
|
|
|
vi.mock('../../src/storage/repo-manager.js', () => ({
|
|
findRepo: mockFindRepo,
|
|
getStoragePaths: mockGetStoragePaths,
|
|
hasKuzuIndex: mockHasKuzuIndex,
|
|
}));
|
|
|
|
describe('statusCommand', () => {
|
|
let logSpy: ReturnType<typeof vi.spyOn>;
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
mockGetStoragePaths.mockReturnValue({ storagePath: '/repo/.gitnexus' });
|
|
});
|
|
|
|
it('prints "Not a git repository" when cwd is not a git repo', async () => {
|
|
mockIsGitRepo.mockReturnValue(false);
|
|
|
|
const { statusCommand } = await import('../../src/cli/status.js');
|
|
await statusCommand();
|
|
|
|
expect(logSpy).toHaveBeenCalledWith('Not a git repository.');
|
|
expect(mockFindRepo).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('prompts for migration when a stale KuzuDB index exists', async () => {
|
|
mockIsGitRepo.mockReturnValue(true);
|
|
mockFindRepo.mockResolvedValue(null);
|
|
mockGetGitRoot.mockReturnValue('/repo');
|
|
mockHasKuzuIndex.mockResolvedValue(true);
|
|
|
|
const { statusCommand } = await import('../../src/cli/status.js');
|
|
await statusCommand();
|
|
|
|
expect(logSpy).toHaveBeenCalledWith(
|
|
expect.stringContaining('stale KuzuDB index'),
|
|
);
|
|
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('rebuilds the index'));
|
|
});
|
|
|
|
it('prompts to analyze when no index exists at all', async () => {
|
|
mockIsGitRepo.mockReturnValue(true);
|
|
mockFindRepo.mockResolvedValue(null);
|
|
mockGetGitRoot.mockReturnValue('/repo');
|
|
mockHasKuzuIndex.mockResolvedValue(false);
|
|
|
|
const { statusCommand } = await import('../../src/cli/status.js');
|
|
await statusCommand();
|
|
|
|
expect(logSpy).toHaveBeenCalledWith('Repository not indexed.');
|
|
expect(logSpy).toHaveBeenCalledWith('Run: gitnexus analyze');
|
|
});
|
|
|
|
it('falls back to cwd when getGitRoot returns null', async () => {
|
|
mockIsGitRepo.mockReturnValue(true);
|
|
mockFindRepo.mockResolvedValue(null);
|
|
mockGetGitRoot.mockReturnValue(null);
|
|
mockHasKuzuIndex.mockResolvedValue(false);
|
|
|
|
const { statusCommand } = await import('../../src/cli/status.js');
|
|
await statusCommand();
|
|
|
|
expect(mockGetStoragePaths).toHaveBeenCalledWith(process.cwd());
|
|
});
|
|
|
|
it('reports up-to-date when current commit matches indexed commit', async () => {
|
|
mockIsGitRepo.mockReturnValue(true);
|
|
mockFindRepo.mockResolvedValue({
|
|
repoPath: '/repo',
|
|
meta: {
|
|
lastCommit: 'abc1234567',
|
|
indexedAt: '2026-04-01T00:00:00Z',
|
|
},
|
|
});
|
|
mockGetCurrentCommit.mockReturnValue('abc1234567');
|
|
|
|
const { statusCommand } = await import('../../src/cli/status.js');
|
|
await statusCommand();
|
|
|
|
expect(logSpy).toHaveBeenCalledWith('Repository: /repo');
|
|
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('abc1234'));
|
|
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('up-to-date'));
|
|
});
|
|
|
|
it('reports stale when current commit diverges from indexed commit', async () => {
|
|
mockIsGitRepo.mockReturnValue(true);
|
|
mockFindRepo.mockResolvedValue({
|
|
repoPath: '/repo',
|
|
meta: {
|
|
lastCommit: 'old12345',
|
|
indexedAt: '2026-04-01T00:00:00Z',
|
|
},
|
|
});
|
|
mockGetCurrentCommit.mockReturnValue('new67890');
|
|
|
|
const { statusCommand } = await import('../../src/cli/status.js');
|
|
await statusCommand();
|
|
|
|
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('stale'));
|
|
});
|
|
});
|