mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
Windows portability (the three red tests on the owner's machine at green CI):
- scripts/spawn-portable.mjs: isMainModule via pathToFileURL (the
`file://${argv[1]}` form gives file:///C:/C:/... and the CLI stays silent);
portableCommand — a shell only for npm/npx/.cmd, node and git run directly
(spawn via shell dropped the quotes of `node -e "…"`). Applied to
classify-changes, mutation-gate-report, review-doc-guard, check-inputs,
merge-candidate, gate-small, rebase-on-dev.
- the rebase-on-dev test pins core.autocrlf=false / core.eol=lf through
GIT_CONFIG_* for its temp repository instead of touching the user's git
config; test/windows-portability.test.mjs forbids both anti-patterns.
Pins: scripts/toolchain-pins.mjs reads Node/Python from validate.yml, the HA
stack from tests_backend/requirements.txt, Playwright/Chromium from the
lockfile — no second dictionary; `npm run toolchain:check` compares the
machine; .nvmrc/.python-version are derived and tested equal;
scripts/wsl-setup.sh provisions WSL/Linux with those pins.
scripts/task-packet.mjs: one derived view of an issue (status, rights, owner
decisions, branch vs dev, Validate on the tip, previous verdict with recorded
tree, AC → evidence, unwitnessed). scripts/wait-verdict.mjs: polls labels,
pipeline comments and optionally Validate, prints only on state change, exit
0/3/4, writes nothing.
gate:small --smokes: after build the browser phase runs bundle-sync and then
the directly matched and registered smokes, two at a time; broad matches stay
with the reviewer. package.json changed, so the bundle is rebuilt here.
Issue: #496
User-Visible: no
39 lines
2.3 KiB
JavaScript
39 lines
2.3 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { readFileSync } from 'node:fs';
|
|
import { compareToolchain, pinsFromSources } from '../scripts/toolchain-pins.mjs';
|
|
|
|
// #496: пины toolchain читаются из файлов CI, а не объявляются вторым словарём.
|
|
// .nvmrc/.python-version — производные и обязаны совпадать.
|
|
|
|
test('пины читаются из workflow, requirements и lockfile; .nvmrc/.python-version совпадают (#496)', () => {
|
|
const pins = pinsFromSources();
|
|
assert.match(pins.node, /^\d+$/);
|
|
assert.match(pins.python, /^\d+\.\d+$/);
|
|
assert.match(pins.homeassistant, /^\d{4}\.\d+\.\d+$/);
|
|
assert.match(pins.playwright, /^\d+\.\d+\.\d+$/);
|
|
assert.equal(readFileSync(new URL('../.nvmrc', import.meta.url), 'utf8').trim(), pins.node);
|
|
assert.equal(readFileSync(new URL('../.python-version', import.meta.url), 'utf8').trim(), pins.python);
|
|
assert.equal(JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).scripts['toolchain:check'],
|
|
'node scripts/toolchain-pins.mjs --check');
|
|
});
|
|
|
|
test('разнобой пинов в источниках — ошибка, а не «первое попавшееся» (#496)', () => {
|
|
assert.throws(() => pinsFromSources({
|
|
validateYml: 'node-version: 22\nnode-version: 24\npython-version: "3.14"',
|
|
}), /node-version: ожидался один пин, найдено 2/);
|
|
assert.throws(() => pinsFromSources({
|
|
validateYml: 'node-version: 22\n',
|
|
}), /python-version/);
|
|
});
|
|
|
|
test('сравнение: мажор Node, minor Python, HA-стек точно и только если установлен (#496)', () => {
|
|
const pins = { node: '22', python: '3.14', homeassistant: '2026.8.3', pytestHomeAssistant: '0.13.357', playwright: '1.62.0' };
|
|
const good = compareToolchain(pins, { node: '22.19.0', python: '3.14.2', homeassistant: null, pytestHomeAssistant: null, playwright: '1.62.0' });
|
|
assert.equal(good.ok, true);
|
|
assert.ok(good.lines.some((l) => l.startsWith('warn') && l.includes('homeassistant')));
|
|
const bad = compareToolchain(pins, { node: '24.1.0', python: '3.13.1', homeassistant: '2026.2.3', pytestHomeAssistant: '0.13.357', playwright: '1.62.0' });
|
|
assert.equal(bad.ok, false);
|
|
assert.deepEqual(bad.failures, ['node', 'python', 'homeassistant']);
|
|
});
|