diff options
Diffstat (limited to 'packages/create-turbo/__tests__/git.test.ts')
| -rw-r--r-- | packages/create-turbo/__tests__/git.test.ts | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/packages/create-turbo/__tests__/git.test.ts b/packages/create-turbo/__tests__/git.test.ts new file mode 100644 index 0000000..27ac118 --- /dev/null +++ b/packages/create-turbo/__tests__/git.test.ts @@ -0,0 +1,239 @@ +import path from "path"; +import { + DEFAULT_IGNORE, + GIT_REPO_COMMAND, + HG_REPO_COMMAND, + isInGitRepository, + isInMercurialRepository, + tryGitInit, +} from "../src/utils/git"; +import childProcess from "child_process"; +import { setupTestFixtures } from "@turbo/test-utils"; + +describe("git", () => { + // just to make sure this doesn't get lost + it("default .gitignore includes .turbo", async () => { + expect(DEFAULT_IGNORE).toContain(".turbo"); + }); + + describe("isInGitRepository", () => { + it("returns true when in a repo", async () => { + const mockExecSync = jest + .spyOn(childProcess, "execSync") + .mockReturnValue("true"); + + const result = isInGitRepository(); + expect(result).toBe(true); + + expect(mockExecSync).toHaveBeenCalledWith(GIT_REPO_COMMAND, { + stdio: "ignore", + }); + mockExecSync.mockRestore(); + }); + + it("returns false when not in a repo", async () => { + const mockExecSync = jest + .spyOn(childProcess, "execSync") + .mockImplementation(() => { + throw new Error( + "fatal: not a git repository (or any of the parent directories): .git" + ); + }); + + const result = isInGitRepository(); + expect(result).toBe(false); + + expect(mockExecSync).toHaveBeenCalledWith(GIT_REPO_COMMAND, { + stdio: "ignore", + }); + mockExecSync.mockRestore(); + }); + + it("returns false on error", async () => { + const mockExecSync = jest + .spyOn(childProcess, "execSync") + .mockImplementation(() => { + throw new Error("unknown error"); + }); + + const result = isInGitRepository(); + expect(result).toBe(false); + + expect(mockExecSync).toHaveBeenCalledWith(GIT_REPO_COMMAND, { + stdio: "ignore", + }); + mockExecSync.mockRestore(); + }); + }); + + describe("isInMercurialRepository", () => { + it("returns true when in a repo", async () => { + const mockExecSync = jest + .spyOn(childProcess, "execSync") + .mockReturnValue("true"); + + const result = isInMercurialRepository(); + expect(result).toBe(true); + + expect(mockExecSync).toHaveBeenCalledWith(HG_REPO_COMMAND, { + stdio: "ignore", + }); + mockExecSync.mockRestore(); + }); + + it("returns false when not in a repo", async () => { + const mockExecSync = jest + .spyOn(childProcess, "execSync") + .mockImplementation(() => { + throw new Error("abort: no repository found (.hg not found)"); + }); + + const result = isInMercurialRepository(); + expect(result).toBe(false); + + expect(mockExecSync).toHaveBeenCalledWith(HG_REPO_COMMAND, { + stdio: "ignore", + }); + mockExecSync.mockRestore(); + }); + + it("returns false on error", async () => { + const mockExecSync = jest + .spyOn(childProcess, "execSync") + .mockImplementation(() => { + throw new Error("unknown error"); + }); + + const result = isInMercurialRepository(); + expect(result).toBe(false); + + expect(mockExecSync).toHaveBeenCalledWith(HG_REPO_COMMAND, { + stdio: "ignore", + }); + mockExecSync.mockRestore(); + }); + }); + + describe("tryGitInit", () => { + const { useFixture } = setupTestFixtures({ + directory: path.join(__dirname, "../"), + }); + + it("inits a repo succesfully", async () => { + const { root } = useFixture({ fixture: `git` }); + const mockExecSync = jest + .spyOn(childProcess, "execSync") + .mockReturnValueOnce("git version 2.38.1") + .mockImplementationOnce(() => { + throw new Error( + "fatal: not a git repository (or any of the parent directories): .git" + ); + }) + .mockImplementationOnce(() => { + throw new Error("abort: no repository found (.hg not found)"); + }) + .mockReturnValue("success"); + + const result = tryGitInit(root, "test commit"); + expect(result).toBe(true); + + const calls = [ + "git --version", + "git init", + "git checkout -b main", + "git add -A", + 'git commit -m "test commit"', + ]; + expect(mockExecSync).toHaveBeenCalledTimes(calls.length + 2); + calls.forEach((call) => { + expect(mockExecSync).toHaveBeenCalledWith(call, { + stdio: "ignore", + }); + }); + mockExecSync.mockRestore(); + }); + + it("skips init if already in a repo", async () => { + const { root } = useFixture({ fixture: `git` }); + const mockExecSync = jest + .spyOn(childProcess, "execSync") + .mockReturnValueOnce("git version 2.38.1") + .mockReturnValueOnce("true") + .mockReturnValue("success"); + + const result = tryGitInit(root, "test commit"); + expect(result).toBe(false); + + const calls = ["git --version"]; + + // 1 call for git --version, 1 call for isInGitRepository + expect(mockExecSync).toHaveBeenCalledTimes(calls.length + 1); + calls.forEach((call) => { + expect(mockExecSync).toHaveBeenCalledWith(call, { + stdio: "ignore", + }); + }); + mockExecSync.mockRestore(); + }); + + it("returns false on unexpected error", async () => { + const { root } = useFixture({ fixture: `git` }); + const mockExecSync = jest + .spyOn(childProcess, "execSync") + .mockImplementationOnce(() => { + throw new Error("fatal: unknown command git"); + }); + + const result = tryGitInit(root, "test commit"); + expect(result).toBe(false); + + const calls = ["git --version"]; + + expect(mockExecSync).toHaveBeenCalledTimes(calls.length); + calls.forEach((call) => { + expect(mockExecSync).toHaveBeenCalledWith(call, { + stdio: "ignore", + }); + }); + mockExecSync.mockRestore(); + }); + + it("cleans up from partial init on failure", async () => { + const { root } = useFixture({ fixture: `git` }); + const mockExecSync = jest + .spyOn(childProcess, "execSync") + .mockReturnValueOnce("git version 2.38.1") + .mockImplementationOnce(() => { + throw new Error( + "fatal: not a git repository (or any of the parent directories): .git" + ); + }) + .mockImplementationOnce(() => { + throw new Error("abort: no repository found (.hg not found)"); + }) + .mockReturnValueOnce("success") + .mockReturnValueOnce("success") + .mockImplementationOnce(() => { + throw new Error("fatal: could not add files"); + }); + + const result = tryGitInit(root, "test commit"); + expect(result).toBe(false); + + const calls = [ + "git --version", + "git init", + "git checkout -b main", + "git add -A", + ]; + + expect(mockExecSync).toHaveBeenCalledTimes(calls.length + 2); + calls.forEach((call) => { + expect(mockExecSync).toHaveBeenCalledWith(call, { + stdio: "ignore", + }); + }); + mockExecSync.mockRestore(); + }); + }); +}); |
