mirror of
https://github.com/stablyai/orca.git
synced 2026-11-14 01:47:24 +00:00
* refactor(tooling): organize test runtime and maintenance owners * test(tooling): preserve relocated runtime fixture dependency edges * refactor(tooling): preserve xterm routing owner checks * ci(tooling): include routing owner in sparse checkout * test(tooling): preserve copied workflow dependency closures * fix(tooling): normalize hashed JSON assets in release parity * fix(tooling): distinguish asset aliases from literal references * fix(tooling): frame normalized asset reference payloads * fix(tooling): normalize decoded JSON asset references * refactor(tooling): organize build, CI and release owners * fix(tooling): align moved generator and workflow path contracts * fix(tooling): update generated plugin bundle owner banners * test(tooling): create relocated mobile verifier fixture directories * test(tooling): copy headless detector dependency closure * test(tooling): align native batch policy fixtures with owner path * fix(tooling): link moved reliability command to historical evidence * fix(tooling): preserve nested sandbox owners and canonical guide source * fix(tooling): target release version owners in checkout fixture
105 lines
4.5 KiB
JavaScript
105 lines
4.5 KiB
JavaScript
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
createAdhocBuildVersion,
|
|
formatAdhocReleaseName,
|
|
normalizeAdhocLabel
|
|
} from './adhoc-build-version.mjs'
|
|
import { createHourlyBuildVersion } from './hourly-build-version.mjs'
|
|
import { compareAppVersions } from '../../../../src/shared/app-version'
|
|
|
|
describe('createAdhocBuildVersion', () => {
|
|
it('stamps the version with a zero-padded UTC timestamp to the second', () => {
|
|
expect(createAdhocBuildVersion('1.4.160', new Date('2026-07-28T04:05:09Z'))).toBe(
|
|
'1.4.160-adhoc.20260728040509'
|
|
)
|
|
})
|
|
|
|
// Concurrent branch builds need second-resolution tags; minute collisions otherwise fail after packaging/notarization.
|
|
it('distinguishes two builds cut in the same minute', () => {
|
|
const first = createAdhocBuildVersion('1.4.160', new Date('2026-07-28T14:05:02Z'))
|
|
const second = createAdhocBuildVersion('1.4.160', new Date('2026-07-28T14:05:41Z'))
|
|
expect(first).not.toBe(second)
|
|
expect(compareAppVersions(first, second)).toBeLessThan(0)
|
|
})
|
|
|
|
it('drops an in-flight rc tail so adhoc builds never outrank the rc series', () => {
|
|
const version = createAdhocBuildVersion('1.4.160-rc.3', new Date('2026-07-28T14:00:00Z'))
|
|
expect(version).toBe('1.4.160-adhoc.20260728140000')
|
|
expect(compareAppVersions(version, '1.4.160-rc.3')).toBeLessThan(0)
|
|
expect(compareAppVersions(version, '1.4.160')).toBeLessThan(0)
|
|
})
|
|
|
|
// Unlanded adhoc builds must sort below routine channels; only explicit pinned jumps may select them.
|
|
it('sorts below the hourly build of the same base version', () => {
|
|
expect(
|
|
compareAppVersions(
|
|
createAdhocBuildVersion('1.4.160', new Date('2026-07-28T23:59:59Z')),
|
|
createHourlyBuildVersion('1.4.160', new Date('2026-07-28T00:00:00Z'))
|
|
)
|
|
).toBeLessThan(0)
|
|
})
|
|
|
|
it('rejects invalid input', () => {
|
|
expect(() => createAdhocBuildVersion('nope', new Date())).toThrow(/valid semver/)
|
|
expect(() => createAdhocBuildVersion('1.4.160', new Date('nope'))).toThrow(/invalid/)
|
|
})
|
|
})
|
|
|
|
describe('normalizeAdhocLabel', () => {
|
|
it('keeps an ordinary branch name intact', () => {
|
|
expect(normalizeAdhocLabel('wasm-terminal')).toBe('wasm-terminal')
|
|
expect(normalizeAdhocLabel('nwparker/wasm-terminal')).toBe('nwparker/wasm-terminal')
|
|
})
|
|
|
|
it('strips the ref prefixes a dispatch input tends to arrive with', () => {
|
|
expect(normalizeAdhocLabel('refs/heads/wasm-terminal')).toBe('wasm-terminal')
|
|
expect(normalizeAdhocLabel('origin/wasm-terminal')).toBe('wasm-terminal')
|
|
})
|
|
|
|
// Dispatch label separators/newlines could forge title fields or GITHUB_OUTPUT lines.
|
|
it('neutralizes characters that would corrupt the title or the output line', () => {
|
|
expect(normalizeAdhocLabel('a • b')).toBe('a-b')
|
|
expect(normalizeAdhocLabel('a\nname=evil')).toBe('a-name-evil')
|
|
expect(normalizeAdhocLabel(' spaced out ')).toBe('spaced-out')
|
|
})
|
|
|
|
it('truncates without leaving a trailing separator', () => {
|
|
expect(normalizeAdhocLabel('a'.repeat(80))).toHaveLength(32)
|
|
expect(normalizeAdhocLabel(`${'a'.repeat(31)}-tail`)).toBe('a'.repeat(31))
|
|
})
|
|
|
|
it('rejects a label with nothing usable in it', () => {
|
|
expect(() => normalizeAdhocLabel('')).toThrow(/no usable characters/)
|
|
expect(() => normalizeAdhocLabel(' ')).toThrow(/no usable characters/)
|
|
expect(() => normalizeAdhocLabel('•••')).toThrow(/no usable characters/)
|
|
expect(() => normalizeAdhocLabel(null)).toThrow(/no usable characters/)
|
|
})
|
|
})
|
|
|
|
describe('formatAdhocReleaseName', () => {
|
|
const name = (iso, label = 'wasm-terminal', commit = 'e698241abcde') =>
|
|
formatAdhocReleaseName('1.4.163-adhoc.x', label, commit, new Date(iso))
|
|
|
|
it('renders version, label, Pacific timestamp, and short sha', () => {
|
|
expect(name('2026-07-31T20:54:00Z')).toBe('1.4.163 • wasm-terminal • Jul 31, 1:54PM • e698241')
|
|
})
|
|
|
|
// Tag is UTC, title is Pacific: test both DST offsets or a seasonal failure stays hidden.
|
|
it('follows the Pacific offset across DST', () => {
|
|
expect(name('2026-01-15T02:30:00Z')).toContain(' Jan 14, 6:30PM ')
|
|
expect(name('2026-07-31T07:00:00Z')).toContain(' Jul 31, 12:00AM ')
|
|
})
|
|
|
|
it('sanitizes the label before it reaches the title', () => {
|
|
expect(name('2026-07-31T20:54:00Z', 'refs/heads/fix • now')).toBe(
|
|
'1.4.163 • fix-now • Jul 31, 1:54PM • e698241'
|
|
)
|
|
})
|
|
|
|
it('rejects an invalid timestamp', () => {
|
|
expect(() => formatAdhocReleaseName('1.4.163', 'x', 'abcdefg', new Date('nope'))).toThrow(
|
|
/invalid/
|
|
)
|
|
})
|
|
})
|