Files
wehub-resource-sync 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
chore: import upstream snapshot with attribution
2026-07-13 12:24:41 +08:00

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)
})
})