d18ada4ee7
Docker Publish / docker (web, apps/web/Dockerfile, web) (push) Failing after 0s
Docker Publish / docker (api, apps/api/Dockerfile, api) (push) Failing after 1s
Publish Extension / detect-version (push) Has been skipped
Publish Extension / submit (push) Has been cancelled
157 lines
4.8 KiB
TypeScript
157 lines
4.8 KiB
TypeScript
import { mkdtempSync, readFileSync, writeFileSync } from 'node:fs'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
checkUpgrade,
|
|
compareSemver,
|
|
defaultCachePath,
|
|
readCliVersion
|
|
} from '../src/local-info'
|
|
|
|
describe('readCliVersion', () => {
|
|
it('returns the @vidbee/cli package.json version when found', () => {
|
|
const info = readCliVersion()
|
|
// The version comes from apps/cli/package.json
|
|
expect(info.cli).toMatch(/^\d+\.\d+\.\d+/)
|
|
expect(info.contract).toEqual(info.cli)
|
|
expect(info.changelog).toContain('CHANGELOG')
|
|
})
|
|
|
|
it('falls back to a marker when no candidate matches', () => {
|
|
const info = readCliVersion(['/path/that/definitely/does/not/exist.json'])
|
|
expect(info.cli).toBe('0.0.0-dev')
|
|
expect(info.contract).toBe('0.0.0-dev')
|
|
})
|
|
|
|
it('skips package.json files with the wrong name', () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'vidbee-cli-version-'))
|
|
const wrong = join(dir, 'wrong.json')
|
|
const right = join(dir, 'right.json')
|
|
writeFileSync(wrong, JSON.stringify({ name: 'something-else', version: '9.9.9' }))
|
|
writeFileSync(
|
|
right,
|
|
JSON.stringify({ name: '@vidbee/cli', version: '1.2.3' })
|
|
)
|
|
const info = readCliVersion([wrong, right])
|
|
expect(info.cli).toBe('1.2.3')
|
|
})
|
|
})
|
|
|
|
describe('compareSemver', () => {
|
|
it('orders by major/minor/patch', () => {
|
|
expect(compareSemver('0.1.0', '0.2.0')).toBeLessThan(0)
|
|
expect(compareSemver('1.0.0', '0.9.9')).toBeGreaterThan(0)
|
|
expect(compareSemver('1.2.3', '1.2.3')).toBe(0)
|
|
})
|
|
it('treats prerelease as smaller than release', () => {
|
|
expect(compareSemver('0.1.0-rc.1', '0.1.0')).toBeLessThan(0)
|
|
expect(compareSemver('0.1.0', '0.1.0-rc.1')).toBeGreaterThan(0)
|
|
})
|
|
})
|
|
|
|
describe('checkUpgrade', () => {
|
|
let cachePath: string
|
|
beforeEach(() => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'vidbee-cli-upgrade-'))
|
|
cachePath = join(dir, 'cli-upgrade-check.json')
|
|
})
|
|
afterEach(() => {
|
|
// tmpdir gets cleaned by the OS; nothing else to do.
|
|
})
|
|
|
|
it('reports out-of-date when registry returns a newer version', async () => {
|
|
const result = await checkUpgrade({
|
|
current: '0.1.0',
|
|
cachePath,
|
|
fetchLatest: async () => ({ version: '0.2.0', fetchedAt: 1000 })
|
|
})
|
|
expect(result.upToDate).toBe(false)
|
|
expect(result.latest).toBe('0.2.0')
|
|
expect(result.cached).toBe(false)
|
|
expect(result.installCommands.npm).toContain('@vidbee/cli')
|
|
// Cache should be written
|
|
const cached = JSON.parse(readFileSync(cachePath, 'utf-8'))
|
|
expect(cached.version).toBe('0.2.0')
|
|
})
|
|
|
|
it('reports up-to-date when installed >= registry', async () => {
|
|
const result = await checkUpgrade({
|
|
current: '0.2.0',
|
|
cachePath,
|
|
fetchLatest: async () => ({ version: '0.2.0', fetchedAt: 1000 })
|
|
})
|
|
expect(result.upToDate).toBe(true)
|
|
})
|
|
|
|
it('uses a fresh cache and skips fetch', async () => {
|
|
writeFileSync(
|
|
cachePath,
|
|
JSON.stringify({ version: '0.5.0', fetchedAt: 1_000_000 })
|
|
)
|
|
let fetched = false
|
|
const result = await checkUpgrade({
|
|
current: '0.4.0',
|
|
cachePath,
|
|
now: () => 1_000_000 + 24 * 60 * 60 * 1000, // 1 day later
|
|
fetchLatest: async () => {
|
|
fetched = true
|
|
return { version: '0.6.0', fetchedAt: 2_000_000 }
|
|
}
|
|
})
|
|
expect(fetched).toBe(false)
|
|
expect(result.cached).toBe(true)
|
|
expect(result.latest).toBe('0.5.0')
|
|
expect(result.upToDate).toBe(false)
|
|
})
|
|
|
|
it('refreshes the cache after the TTL expires', async () => {
|
|
writeFileSync(
|
|
cachePath,
|
|
JSON.stringify({ version: '0.5.0', fetchedAt: 0 })
|
|
)
|
|
let fetched = false
|
|
const result = await checkUpgrade({
|
|
current: '0.4.0',
|
|
cachePath,
|
|
now: () => 31 * 24 * 60 * 60 * 1000, // 31 days later
|
|
fetchLatest: async () => {
|
|
fetched = true
|
|
return { version: '0.6.0', fetchedAt: 99 }
|
|
}
|
|
})
|
|
expect(fetched).toBe(true)
|
|
expect(result.cached).toBe(false)
|
|
expect(result.latest).toBe('0.6.0')
|
|
})
|
|
|
|
it('--force bypasses the cache', async () => {
|
|
writeFileSync(
|
|
cachePath,
|
|
JSON.stringify({ version: '0.5.0', fetchedAt: Date.now() })
|
|
)
|
|
let fetched = false
|
|
const result = await checkUpgrade({
|
|
current: '0.4.0',
|
|
cachePath,
|
|
force: true,
|
|
fetchLatest: async () => {
|
|
fetched = true
|
|
return { version: '0.7.0', fetchedAt: Date.now() }
|
|
}
|
|
})
|
|
expect(fetched).toBe(true)
|
|
expect(result.cached).toBe(false)
|
|
expect(result.latest).toBe('0.7.0')
|
|
})
|
|
})
|
|
|
|
describe('defaultCachePath', () => {
|
|
it('returns a non-empty platform-specific path', () => {
|
|
const p = defaultCachePath()
|
|
expect(p).toContain('cli-upgrade-check.json')
|
|
expect(p.length).toBeGreaterThan('cli-upgrade-check.json'.length)
|
|
})
|
|
})
|