diff --git a/src/__tests__/version-check.test.ts b/src/__tests__/version-check.test.ts index d6984b0..3d8938a 100644 --- a/src/__tests__/version-check.test.ts +++ b/src/__tests__/version-check.test.ts @@ -1,6 +1,11 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import { compareSemver, getUpdateType, checkForUpdates } from '../utils/version-check'; +import { compareSemver, getUpdateType, checkForUpdates, getInstalledVersion } from '../utils/version-check'; import { logger } from '../utils/logger'; +import { readFileSync } from 'node:fs'; + +vi.mock('node:fs', () => ({ + readFileSync: vi.fn(() => JSON.stringify({ version: '1.2.2' })), +})); vi.mock('../utils/logger', () => ({ logger: { @@ -98,4 +103,68 @@ describe('version-check utilities', () => { expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('v9.9.9')); }); }); + + describe('getInstalledVersion', () => { + afterEach(() => { + vi.mocked(readFileSync).mockReset(); + }); + + it('should resolve and return the version if package.json in production path is valid', () => { + vi.mocked(readFileSync).mockImplementation((path) => { + if (typeof path === 'string' && path.endsWith('src/package.json')) { + return JSON.stringify({ version: '2.3.4' }); + } + throw new Error('File not found'); + }); + + expect(getInstalledVersion()).toBe('2.3.4'); + }); + + it('should resolve and return the version if production path fails but development path succeeds', () => { + vi.mocked(readFileSync).mockImplementation((path) => { + if (typeof path === 'string' && path.endsWith('package.json') && !path.endsWith('src/package.json')) { + return JSON.stringify({ version: '1.2.3' }); + } + throw new Error('File not found'); + }); + + expect(getInstalledVersion()).toBe('1.2.3'); + }); + + it('should advance to the next path if JSON is malformed', () => { + vi.mocked(readFileSync).mockImplementation((path) => { + if (typeof path === 'string' && path.endsWith('src/package.json')) { + return '{ malformed json'; + } + if (typeof path === 'string' && path.endsWith('package.json') && !path.endsWith('src/package.json')) { + return JSON.stringify({ version: '1.2.9' }); + } + throw new Error('File not found'); + }); + + expect(getInstalledVersion()).toBe('1.2.9'); + }); + + it('should advance to next path if version is not a string or missing', () => { + vi.mocked(readFileSync).mockImplementation((path) => { + if (typeof path === 'string' && path.endsWith('src/package.json')) { + return JSON.stringify({ version: 12345 }); // non-string version + } + if (typeof path === 'string' && path.endsWith('package.json') && !path.endsWith('src/package.json')) { + return JSON.stringify({ version: '1.2.8' }); + } + throw new Error('File not found'); + }); + + expect(getInstalledVersion()).toBe('1.2.8'); + }); + + it('should fallback to 0.0.0 if both paths fail', () => { + vi.mocked(readFileSync).mockImplementation(() => { + throw new Error('Read failed'); + }); + + expect(getInstalledVersion()).toBe('0.0.0'); + }); + }); }); diff --git a/src/utils/version-check.ts b/src/utils/version-check.ts index 528f1f1..8323a87 100644 --- a/src/utils/version-check.ts +++ b/src/utils/version-check.ts @@ -8,14 +8,20 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Read the actual package.json version at runtime -function getInstalledVersion(): string { - const pkgPath = join(__dirname, '..', '..', 'package.json'); - try { - const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')); - return pkg.version || '0.0.0'; - } catch { - return '0.0.0'; +export function getInstalledVersion(): string { + const paths = [ + join(__dirname, '..', 'package.json'), // production: dist/../package.json + join(__dirname, '..', '..', 'package.json') // development: src/utils/../../package.json + ]; + for (const pkgPath of paths) { + try { + const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')); + if (typeof pkg.version === 'string' && pkg.version) return pkg.version; + } catch { + // Try next path + } } + return '0.0.0'; } // Compare two semver strings; returns 'lt' if a < b, 'gt' if a > b, 'eq' if equal