diff options
Diffstat (limited to 'packages/cli/src/utils/gitUtils.test.ts')
| -rw-r--r-- | packages/cli/src/utils/gitUtils.test.ts | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/packages/cli/src/utils/gitUtils.test.ts b/packages/cli/src/utils/gitUtils.test.ts new file mode 100644 index 00000000..4a29f589 --- /dev/null +++ b/packages/cli/src/utils/gitUtils.test.ts @@ -0,0 +1,115 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { vi, describe, expect, it, afterEach, beforeEach } from 'vitest'; +import * as child_process from 'child_process'; +import { + isGitHubRepository, + getGitRepoRoot, + getLatestGitHubRelease, +} from './gitUtils.js'; + +vi.mock('child_process'); + +describe('isGitHubRepository', async () => { + beforeEach(() => { + vi.resetAllMocks(); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('returns false if the git command fails', async () => { + vi.mocked(child_process.execSync).mockImplementation((): string => { + throw new Error('oops'); + }); + expect(isGitHubRepository()).toBe(false); + }); + + it('returns false if the remote is not github.com', async () => { + vi.mocked(child_process.execSync).mockReturnValueOnce('https://gitlab.com'); + expect(isGitHubRepository()).toBe(false); + }); + + it('returns true if the remote is github.com', async () => { + vi.mocked(child_process.execSync).mockReturnValueOnce(` + origin https://github.com/sethvargo/gemini-cli (fetch) + origin https://github.com/sethvargo/gemini-cli (push) + `); + expect(isGitHubRepository()).toBe(true); + }); +}); + +describe('getGitRepoRoot', async () => { + beforeEach(() => { + vi.resetAllMocks(); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('throws an error if git root cannot be determined', async () => { + vi.mocked(child_process.execSync).mockImplementation((): string => { + throw new Error('oops'); + }); + expect(() => { + getGitRepoRoot(); + }).toThrowError(/oops/); + }); + + it('throws an error if git root is empty', async () => { + vi.mocked(child_process.execSync).mockReturnValueOnce(''); + expect(() => { + getGitRepoRoot(); + }).toThrowError(/Git repo returned empty value/); + }); + + it('returns the root', async () => { + vi.mocked(child_process.execSync).mockReturnValueOnce('/path/to/git/repo'); + expect(getGitRepoRoot()).toBe('/path/to/git/repo'); + }); +}); + +describe('getLatestRelease', async () => { + beforeEach(() => { + vi.resetAllMocks(); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('throws an error if the fetch fails', async () => { + global.fetch = vi.fn(() => Promise.reject('nope')); + expect(getLatestGitHubRelease()).rejects.toThrowError( + /Unable to determine the latest/, + ); + }); + + it('throws an error if the fetch does not return a json body', async () => { + global.fetch = vi.fn(() => + Promise.resolve({ + ok: true, + json: () => Promise.resolve({ foo: 'bar' }), + } as Response), + ); + expect(getLatestGitHubRelease()).rejects.toThrowError( + /Unable to determine the latest/, + ); + }); + + it('returns the release version', async () => { + global.fetch = vi.fn(() => + Promise.resolve({ + ok: true, + json: () => Promise.resolve({ tag_name: 'v1.2.3' }), + } as Response), + ); + expect(getLatestGitHubRelease()).resolves.toBe('v1.2.3'); + }); +}); |
