mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-08-29 20:17:08 +00:00
91 lines
3.8 KiB
JavaScript
91 lines
3.8 KiB
JavaScript
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { afterEach, describe, expect, it } from 'vitest';
|
|
import { validateReleaseSourceVersion } from './release-preflight.mjs';
|
|
import { prepareRelease, replaceExactly } from './prepare-release.mjs';
|
|
|
|
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
const temporaryDirectories = [];
|
|
const releaseSourcePaths = [
|
|
'README.md',
|
|
'extension/manifest.base.json',
|
|
'package.json',
|
|
'package-lock.json',
|
|
'shared/constants.js',
|
|
'website/llms.txt',
|
|
'website/template.html',
|
|
'website/version.json'
|
|
];
|
|
|
|
function createReleaseFixture() {
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'koalasync-prepare-release-'));
|
|
temporaryDirectories.push(root);
|
|
for (const relativePath of releaseSourcePaths) {
|
|
const target = path.join(root, relativePath);
|
|
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
fs.copyFileSync(path.join(repoRoot, relativePath), target);
|
|
}
|
|
return root;
|
|
}
|
|
|
|
function readFixture(root) {
|
|
return Object.fromEntries(releaseSourcePaths.map(relativePath => [
|
|
relativePath,
|
|
fs.readFileSync(path.join(root, relativePath), 'utf8')
|
|
]));
|
|
}
|
|
|
|
afterEach(() => {
|
|
for (const directory of temporaryDirectories.splice(0)) {
|
|
fs.rmSync(directory, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
describe('release preparation helpers', () => {
|
|
it('replaces one and only one version marker', () => {
|
|
expect(replaceExactly('version=3.1.4', /version=\d+\.\d+\.\d+/gu, 'version=3.1.5', 'fixture'))
|
|
.toBe('version=3.1.5');
|
|
expect(replaceExactly('New v3.1.4 Release!', /New v\d+\.\d+\.\d+ Release!/gu, 'New v3.1.5 Release!', 'README.md release banner'))
|
|
.toBe('New v3.1.5 Release!');
|
|
expect(() => replaceExactly('none', /version=\d+/gu, 'version=4', 'fixture'))
|
|
.toThrow('fixture must contain exactly one release-version marker');
|
|
expect(() => replaceExactly('version=1 version=2', /version=\d+/gu, 'version=3', 'fixture'))
|
|
.toThrow('fixture must contain exactly one release-version marker');
|
|
});
|
|
|
|
it('updates and validates every release-version source, including both README markers', () => {
|
|
const root = createReleaseFixture();
|
|
prepareRelease('9.8.7', new Date('2030-04-05T06:07:08Z'), root);
|
|
|
|
expect(() => validateReleaseSourceVersion('9.8.7', root)).not.toThrow();
|
|
expect(fs.readFileSync(path.join(root, 'README.md'), 'utf8')).toContain('Release-v9.8.7-blue');
|
|
expect(fs.readFileSync(path.join(root, 'README.md'), 'utf8')).toContain('New v9.8.7 Release!');
|
|
expect(JSON.parse(fs.readFileSync(path.join(root, 'website/version.json'), 'utf8')).date)
|
|
.toBe('2030-04-05T06:07:08Z');
|
|
});
|
|
|
|
it('is deterministic when repeated with the tag timestamp and does not duplicate markers', () => {
|
|
const root = createReleaseFixture();
|
|
const timestamp = new Date('2031-02-03T04:05:06Z');
|
|
|
|
prepareRelease('9.8.7', timestamp, root);
|
|
const once = readFixture(root);
|
|
prepareRelease('9.8.7', timestamp, root);
|
|
|
|
expect(readFixture(root)).toEqual(once);
|
|
expect(once['README.md'].match(/Release-v9\.8\.7-blue/gu)).toHaveLength(1);
|
|
expect(once['README.md'].match(/New v9\.8\.7 Release!/gu)).toHaveLength(1);
|
|
});
|
|
|
|
it('rejects invalid versions before changing release sources', () => {
|
|
const root = createReleaseFixture();
|
|
const before = readFixture(root);
|
|
|
|
expect(() => prepareRelease('9.8.7;echo-unsafe', new Date('2030-01-01T00:00:00Z'), root))
|
|
.toThrow('vMAJOR.MINOR.PATCH');
|
|
expect(readFixture(root)).toEqual(before);
|
|
});
|
|
});
|