diff --git a/scripts/smoke-test-update-version-logic.js b/scripts/smoke-test-update-version-logic.js index 1848a16..127c660 100644 --- a/scripts/smoke-test-update-version-logic.js +++ b/scripts/smoke-test-update-version-logic.js @@ -4,7 +4,7 @@ const { normalizeUpdateVersion, compareUpdateVersions, isNewerUpdateVersion -} = require(path.join(process.cwd(), 'dist', 'update-version-utils.js')); +} = require(path.join(process.cwd(), 'dist', 'main', 'domain', 'update-version-utils.js')); function run() { const failures = []; diff --git a/src/main.ts b/src/main.ts index 925840c..eb496c9 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,7 +5,7 @@ import { spawn, ChildProcess, execSync, spawnSync } from 'child_process'; import { connect as tlsConnect, TLSSocket } from 'node:tls'; import axios from 'axios'; import { autoUpdater } from 'electron-updater'; -import { compareUpdateVersions, isNewerUpdateVersion, normalizeUpdateVersion } from './update-version-utils'; +import { compareUpdateVersions, isNewerUpdateVersion, normalizeUpdateVersion } from './main/domain/update-version-utils'; import { CustomClip, MergeGroupItem, MergeGroup, QueueItem, DownloadProgress, DownloadResult } from './types'; import { setDebugLogFn, initToolDirs, diff --git a/src/main/domain/update-version-utils.test.ts b/src/main/domain/update-version-utils.test.ts new file mode 100644 index 0000000..d27f8fc --- /dev/null +++ b/src/main/domain/update-version-utils.test.ts @@ -0,0 +1,66 @@ +import { test, expect, describe } from 'vitest'; +import { + normalizeUpdateVersion, + compareUpdateVersions, + isNewerUpdateVersion, +} from './update-version-utils'; + +describe('normalizeUpdateVersion', () => { + test('strips v-prefix lowercase', () => { + expect(normalizeUpdateVersion('v1.2.3')).toBe('1.2.3'); + }); + test('strips V-prefix uppercase', () => { + expect(normalizeUpdateVersion('V1.2.3')).toBe('1.2.3'); + }); + test('trims whitespace', () => { + expect(normalizeUpdateVersion(' 1.2.3 ')).toBe('1.2.3'); + }); + test('handles null and undefined as empty string', () => { + expect(normalizeUpdateVersion(null)).toBe(''); + expect(normalizeUpdateVersion(undefined)).toBe(''); + }); + test('passes plain version unchanged', () => { + expect(normalizeUpdateVersion('4.6.155')).toBe('4.6.155'); + }); +}); + +describe('compareUpdateVersions', () => { + test('older < newer in same minor', () => { + expect(compareUpdateVersions('4.1.10', '4.1.18')).toBeLessThan(0); + }); + test('newer > older in same minor', () => { + expect(compareUpdateVersions('4.1.18', '4.1.10')).toBeGreaterThan(0); + }); + test('equal versions return 0', () => { + expect(compareUpdateVersions('4.6.155', '4.6.155')).toBe(0); + }); + test('v-prefix is normalized away', () => { + expect(compareUpdateVersions('v4.1.12', '4.1.12')).toBe(0); + }); + test('extra trailing part is newer', () => { + expect(compareUpdateVersions('4.1.12', '4.1.12.1')).toBeLessThan(0); + }); + test('major bump wins', () => { + expect(compareUpdateVersions('5.0.0', '4.99.99')).toBeGreaterThan(0); + }); + test('null versions sort lowest', () => { + expect(compareUpdateVersions(null, '1.0.0')).toBeLessThan(0); + expect(compareUpdateVersions('1.0.0', null)).toBeGreaterThan(0); + }); + test('both null returns 0', () => { + expect(compareUpdateVersions(null, null)).toBe(0); + expect(compareUpdateVersions('', '')).toBe(0); + }); +}); + +describe('isNewerUpdateVersion', () => { + test('strictly newer returns true', () => { + expect(isNewerUpdateVersion('4.1.18', '4.1.17')).toBe(true); + }); + test('equal returns false', () => { + expect(isNewerUpdateVersion('4.1.18', '4.1.18')).toBe(false); + }); + test('older returns false', () => { + expect(isNewerUpdateVersion('4.1.17', '4.1.18')).toBe(false); + }); +}); diff --git a/src/update-version-utils.ts b/src/main/domain/update-version-utils.ts similarity index 100% rename from src/update-version-utils.ts rename to src/main/domain/update-version-utils.ts