Download scripts/tests/get-release-version.test.js from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 7.93 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/scripts/tests/get-release-version.test.js
- Command line
-
hf download hf://SaylorTwift/gemini-cli/scripts/tests/get-release-version.test.js
-
curl -L -o get-release-version.test.js https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/scripts/tests/get-release-version.test.js
7.93 kB
| /** | |
| * @license | |
| * Copyright 2025 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import { vi, describe, it, expect, beforeEach } from 'vitest'; | |
| import { getVersion } from '../get-release-version.js'; | |
| import { execSync } from 'node:child_process'; | |
| import { readFileSync } from 'node:fs'; | |
| vi.mock('node:child_process'); | |
| vi.mock('node:fs'); | |
| describe('getVersion', () => { | |
| beforeEach(() => { | |
| vi.resetAllMocks(); | |
| vi.setSystemTime(new Date('2025-09-17T00:00:00.000Z')); | |
| // Mock package.json being read by getNightlyVersion | |
| vi.mocked(readFileSync).mockReturnValue( | |
| JSON.stringify({ version: '0.8.0' }), | |
| ); | |
| }); | |
| // This is the base mock for a clean state with no conflicts or rollbacks | |
| const mockExecSync = (command) => { | |
| // NPM dist-tags | |
| if (command.includes('npm view') && command.includes('--tag=latest')) | |
| return '0.6.1'; | |
| if (command.includes('npm view') && command.includes('--tag=preview')) | |
| return '0.7.0-preview.1'; | |
| if (command.includes('npm view') && command.includes('--tag=nightly')) | |
| return '0.8.0-nightly.20250916.abcdef'; | |
| // NPM versions list | |
| if (command.includes('npm view') && command.includes('versions --json')) | |
| return JSON.stringify([ | |
| '0.6.0', | |
| '0.6.1', | |
| '0.7.0-preview.0', | |
| '0.7.0-preview.1', | |
| '0.8.0-nightly.20250916.abcdef', | |
| ]); | |
| // Deprecation checks (default to not deprecated) | |
| if (command.includes('deprecated')) return ''; | |
| // Git Tag Mocks | |
| if (command.includes("git tag -l 'v[0-9].[0-9].[0-9]'")) return 'v0.6.1'; | |
| if (command.includes("git tag -l 'v*-preview*'")) return 'v0.7.0-preview.1'; | |
| if (command.includes("git tag -l 'v*-nightly*'")) | |
| return 'v0.8.0-nightly.20250916.abcdef'; | |
| // Git Hash Mock | |
| if (command.includes('git rev-parse --short HEAD')) return 'd3bf8a3d'; | |
| // For doesVersionExist checks - default to not found | |
| if ( | |
| command.includes('npm view') && | |
| command.includes('@google/gemini-cli@') | |
| ) { | |
| throw new Error('NPM version not found'); | |
| } | |
| if (command.includes('git tag -l')) return ''; | |
| if (command.includes('gh release view')) { | |
| throw new Error('GH release not found'); | |
| } | |
| return ''; | |
| }; | |
| describe('Happy Path - Version Calculation', () => { | |
| it('should calculate the next stable version from the latest preview', () => { | |
| vi.mocked(execSync).mockImplementation(mockExecSync); | |
| const result = getVersion({ type: 'stable' }); | |
| expect(result.releaseVersion).toBe('0.7.0'); | |
| expect(result.npmTag).toBe('latest'); | |
| expect(result.previousReleaseTag).toBe('v0.6.1'); | |
| }); | |
| it('should calculate the next preview version from the latest nightly', () => { | |
| vi.mocked(execSync).mockImplementation(mockExecSync); | |
| const result = getVersion({ | |
| type: 'preview', | |
| 'stable-base-version': '0.7.0', | |
| }); | |
| expect(result.releaseVersion).toBe('0.8.0-preview.0'); | |
| expect(result.npmTag).toBe('preview'); | |
| expect(result.previousReleaseTag).toBe('v0.7.0-preview.1'); | |
| }); | |
| it('should calculate the next nightly version from package.json', () => { | |
| vi.mocked(execSync).mockImplementation(mockExecSync); | |
| const result = getVersion({ type: 'nightly' }); | |
| // Note: The base version now comes from package.json, not the previous nightly tag. | |
| expect(result.releaseVersion).toBe('0.8.0-nightly.20250917.gd3bf8a3d'); | |
| expect(result.npmTag).toBe('nightly'); | |
| expect(result.previousReleaseTag).toBe('v0.8.0-nightly.20250916.abcdef'); | |
| }); | |
| it('should calculate the next patch version for a stable release', () => { | |
| vi.mocked(execSync).mockImplementation(mockExecSync); | |
| const result = getVersion({ type: 'patch', 'patch-from': 'stable' }); | |
| expect(result.releaseVersion).toBe('0.6.2'); | |
| expect(result.npmTag).toBe('latest'); | |
| expect(result.previousReleaseTag).toBe('v0.6.1'); | |
| }); | |
| it('should calculate the next patch version for a preview release', () => { | |
| vi.mocked(execSync).mockImplementation(mockExecSync); | |
| const result = getVersion({ type: 'patch', 'patch-from': 'preview' }); | |
| expect(result.releaseVersion).toBe('0.7.0-preview.2'); | |
| expect(result.npmTag).toBe('preview'); | |
| expect(result.previousReleaseTag).toBe('v0.7.0-preview.1'); | |
| }); | |
| }); | |
| describe('Advanced Scenarios', () => { | |
| it('should ignore a deprecated version and use the next highest', () => { | |
| const mockWithDeprecated = (command) => { | |
| // The highest nightly is 0.9.0, but it's deprecated | |
| if (command.includes('npm view') && command.includes('versions --json')) | |
| return JSON.stringify([ | |
| '0.8.0-nightly.20250916.abcdef', | |
| '0.9.0-nightly.20250917.deprecated', // This one is deprecated | |
| ]); | |
| // Mock the deprecation check | |
| if ( | |
| command.includes( | |
| 'npm view @google/[email protected] deprecated', | |
| ) | |
| ) | |
| return 'This version is deprecated'; | |
| // The dist-tag still points to the older, valid version | |
| if (command.includes('npm view') && command.includes('--tag=nightly')) | |
| return '0.8.0-nightly.20250916.abcdef'; | |
| return mockExecSync(command); | |
| }; | |
| vi.mocked(execSync).mockImplementation(mockWithDeprecated); | |
| const result = getVersion({ | |
| type: 'preview', | |
| 'stable-base-version': '0.7.0', | |
| }); | |
| // It should base the preview off 0.8.0, not the deprecated 0.9.0 | |
| expect(result.releaseVersion).toBe('0.8.0-preview.0'); | |
| }); | |
| it('should auto-increment patch version if the calculated one already exists', () => { | |
| const mockWithConflict = (command) => { | |
| // The calculated version 0.7.0 already exists as a git tag | |
| if (command.includes("git tag -l 'v0.7.0'")) return 'v0.7.0'; | |
| // The next version, 0.7.1, is available | |
| if (command.includes("git tag -l 'v0.7.1'")) return ''; | |
| return mockExecSync(command); | |
| }; | |
| vi.mocked(execSync).mockImplementation(mockWithConflict); | |
| const result = getVersion({ type: 'stable' }); | |
| // Should have skipped 0.7.0 and landed on 0.7.1 | |
| expect(result.releaseVersion).toBe('0.7.1'); | |
| }); | |
| it('should auto-increment preview number if the calculated one already exists', () => { | |
| const mockWithConflict = (command) => { | |
| // The calculated preview 0.8.0-preview.0 already exists on NPM | |
| if ( | |
| command.includes( | |
| 'npm view @google/[email protected] version', | |
| ) | |
| ) | |
| return '0.8.0-preview.0'; | |
| // The next one is available | |
| if ( | |
| command.includes( | |
| 'npm view @google/[email protected] version', | |
| ) | |
| ) | |
| throw new Error('Not found'); | |
| return mockExecSync(command); | |
| }; | |
| vi.mocked(execSync).mockImplementation(mockWithConflict); | |
| const result = getVersion({ | |
| type: 'preview', | |
| 'stable-base-version': '0.7.0', | |
| }); | |
| // Should have skipped preview.0 and landed on preview.1 | |
| expect(result.releaseVersion).toBe('0.8.0-preview.1'); | |
| }); | |
| it('should preserve a git hash with a leading zero via the g prefix', () => { | |
| const mockWithLeadingZeroHash = (command) => { | |
| // Return an all-numeric hash with a leading zero | |
| if (command.includes('git rev-parse --short HEAD')) return '017972622'; | |
| return mockExecSync(command); | |
| }; | |
| vi.mocked(execSync).mockImplementation(mockWithLeadingZeroHash); | |
| const result = getVersion({ type: 'nightly' }); | |
| // The 'g' prefix forces semver to treat this as an alphanumeric | |
| // identifier, preventing it from stripping the leading zero. | |
| expect(result.releaseVersion).toBe('0.8.0-nightly.20250917.g017972622'); | |
| }); | |
| }); | |
| }); | |