From 6fe450d206fb50b843b1d560186945897ee327aa Mon Sep 17 00:00:00 2001 From: adonis Date: Sun, 22 Mar 2026 22:05:22 -0300 Subject: [PATCH] test(cli): refactor indexCommand tests for consistency and add new cases --- gitnexus/test/unit/index-repo-command.test.ts | 122 ++++++++++++------ 1 file changed, 82 insertions(+), 40 deletions(-) diff --git a/gitnexus/test/unit/index-repo-command.test.ts b/gitnexus/test/unit/index-repo-command.test.ts index 63f502006..176ffbcde 100644 --- a/gitnexus/test/unit/index-repo-command.test.ts +++ b/gitnexus/test/unit/index-repo-command.test.ts @@ -1,5 +1,5 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest'; -import path from 'node:path'; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import path from "node:path"; const mockAccess = vi.fn(); const mockGetStoragePaths = vi.fn(); @@ -8,26 +8,26 @@ const mockRegisterRepo = vi.fn(); const mockGetGitRoot = vi.fn(); const mockIsGitRepo = vi.fn(); -vi.mock('fs/promises', () => ({ +vi.mock("fs/promises", () => ({ default: { access: mockAccess, }, })); -vi.mock('../../src/storage/repo-manager.js', () => ({ +vi.mock("../../src/storage/repo-manager.js", () => ({ getStoragePaths: mockGetStoragePaths, loadMeta: mockLoadMeta, registerRepo: mockRegisterRepo, })); -vi.mock('../../src/storage/git.js', () => ({ +vi.mock("../../src/storage/git.js", () => ({ getGitRoot: mockGetGitRoot, isGitRepo: mockIsGitRepo, })); -describe('indexCommand', () => { - const resolvedRepo = path.resolve('/repo'); - const resolvedOutside = path.resolve('/outside/path'); +describe("indexCommand", () => { + const resolvedRepo = path.resolve("/repo"); + const resolvedOutside = path.resolve("/outside/path"); beforeEach(() => { vi.clearAllMocks(); @@ -41,8 +41,8 @@ describe('indexCommand', () => { })); mockLoadMeta.mockResolvedValue({ repoPath: resolvedRepo, - lastCommit: 'abc123', - indexedAt: '2026-03-20T00:00:00.000Z', + lastCommit: "abc123", + indexedAt: "2026-03-20T00:00:00.000Z", stats: { nodes: 10, edges: 20 }, }); mockAccess.mockResolvedValue(undefined); @@ -50,74 +50,80 @@ describe('indexCommand', () => { mockIsGitRepo.mockReturnValue(true); }); - it('fails when target path is not a git repository', async () => { - const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + it("fails when target path is not a git repository", async () => { + const logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); mockIsGitRepo.mockReturnValue(false); - const { indexCommand } = await import('../../src/cli/index-repo.js'); - await indexCommand(['/outside/path']); + const { indexCommand } = await import("../../src/cli/index-repo.js"); + await indexCommand(["/outside/path"]); expect(mockRegisterRepo).not.toHaveBeenCalled(); expect(process.exitCode).toBe(1); - expect(logSpy).toHaveBeenCalledWith(` Not a git repository: ${resolvedOutside}`); + expect(logSpy).toHaveBeenCalledWith( + ` Not a git repository: ${resolvedOutside}`, + ); }); - it('fails when .gitnexus folder does not exist', async () => { - const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); - mockAccess.mockRejectedValueOnce(new Error('missing .gitnexus')); + it("fails when .gitnexus folder does not exist", async () => { + const logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); + mockAccess.mockRejectedValueOnce(new Error("missing .gitnexus")); - const { indexCommand } = await import('../../src/cli/index-repo.js'); - await indexCommand(['/repo']); + const { indexCommand } = await import("../../src/cli/index-repo.js"); + await indexCommand(["/repo"]); expect(mockRegisterRepo).not.toHaveBeenCalled(); expect(process.exitCode).toBe(1); - expect(logSpy).toHaveBeenCalledWith(` No .gitnexus/ folder found at: ${resolvedRepo}/.gitnexus`); + expect(logSpy).toHaveBeenCalledWith( + ` No .gitnexus/ folder found at: ${resolvedRepo}/.gitnexus`, + ); }); - it('fails when lbug database does not exist', async () => { - const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + it("fails when lbug database does not exist", async () => { + const logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); mockAccess .mockResolvedValueOnce(undefined) - .mockRejectedValueOnce(new Error('missing lbug')); + .mockRejectedValueOnce(new Error("missing lbug")); - const { indexCommand } = await import('../../src/cli/index-repo.js'); - await indexCommand(['/repo']); + const { indexCommand } = await import("../../src/cli/index-repo.js"); + await indexCommand(["/repo"]); expect(mockRegisterRepo).not.toHaveBeenCalled(); expect(process.exitCode).toBe(1); - expect(logSpy).toHaveBeenCalledWith(' .gitnexus/ folder exists but contains no LadybugDB index.'); + expect(logSpy).toHaveBeenCalledWith( + " .gitnexus/ folder exists but contains no LadybugDB index.", + ); }); - it('fails when meta.json is missing and --force is not set', async () => { + it("fails when meta.json is missing and --force is not set", async () => { mockLoadMeta.mockResolvedValue(null); - const { indexCommand } = await import('../../src/cli/index-repo.js'); - await indexCommand(['/repo']); + const { indexCommand } = await import("../../src/cli/index-repo.js"); + await indexCommand(["/repo"]); expect(mockRegisterRepo).not.toHaveBeenCalled(); expect(process.exitCode).toBe(1); }); - it('registers with minimal metadata when meta is missing and --force is set', async () => { + it("registers with minimal metadata when meta is missing and --force is set", async () => { mockLoadMeta.mockResolvedValue(null); - const { indexCommand } = await import('../../src/cli/index-repo.js'); - await indexCommand(['/repo'], { force: true }); + const { indexCommand } = await import("../../src/cli/index-repo.js"); + await indexCommand(["/repo"], { force: true }); expect(mockRegisterRepo).toHaveBeenCalledTimes(1); expect(mockRegisterRepo).toHaveBeenCalledWith( resolvedRepo, expect.objectContaining({ repoPath: resolvedRepo, - lastCommit: '', + lastCommit: "", }), ); expect(process.exitCode).toBeUndefined(); }); - it('registers successfully with existing metadata', async () => { - const { indexCommand } = await import('../../src/cli/index-repo.js'); - await indexCommand(['/repo']); + it("registers successfully with existing metadata", async () => { + const { indexCommand } = await import("../../src/cli/index-repo.js"); + await indexCommand(["/repo"]); expect(mockRegisterRepo).toHaveBeenCalledTimes(1); expect(mockRegisterRepo).toHaveBeenCalledWith( @@ -127,13 +133,49 @@ describe('indexCommand', () => { expect(process.exitCode).toBeUndefined(); }); - it('registers non-git path when --allow-non-git is set', async () => { + it("registers non-git path when --allow-non-git is set", async () => { mockIsGitRepo.mockReturnValue(false); - const { indexCommand } = await import('../../src/cli/index-repo.js'); - await indexCommand(['/outside/path'], { allowNonGit: true }); + const { indexCommand } = await import("../../src/cli/index-repo.js"); + await indexCommand(["/outside/path"], { allowNonGit: true }); expect(mockRegisterRepo).toHaveBeenCalledTimes(1); expect(process.exitCode).toBeUndefined(); }); + + it("fails when called with no path and cwd is not inside a git repo", async () => { + const logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); + mockGetGitRoot.mockReturnValue(null); + + const { indexCommand } = await import("../../src/cli/index-repo.js"); + await indexCommand(); // no args + + expect(mockRegisterRepo).not.toHaveBeenCalled(); + expect(process.exitCode).toBe(1); + expect(logSpy).toHaveBeenCalledWith( + " Not inside a git repository, try to run git init\n", + ); + }); + + it("registers from cwd when no path is provided", async () => { + // getGitRoot already mocked to return resolvedRepo in beforeEach + const { indexCommand } = await import("../../src/cli/index-repo.js"); + await indexCommand(); // no args + + expect(mockRegisterRepo).toHaveBeenCalledWith( + resolvedRepo, + expect.objectContaining({ repoPath: resolvedRepo }), + ); + expect(process.exitCode).toBeUndefined(); + }); + + it("prints node and edge stats after registration", async () => { + const logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); + + const { indexCommand } = await import("../../src/cli/index-repo.js"); + await indexCommand(["/repo"]); + + expect(logSpy).toHaveBeenCalledWith(" Repository registered: repo"); + expect(logSpy).toHaveBeenCalledWith(" 10 nodes | 20 edges"); + }); });