Files
houseplan-card/test/repo-hygiene.test.mjs
2026-09-08 00:31:25 +03:00

49 lines
3.2 KiB
JavaScript

import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import test from 'node:test';
const ROOT = fileURLToPath(new URL('..', import.meta.url));
// The HACS submission check does not read hacs.json to find the integration: it
// globs `*manifest.json` over the whole clone of the DEFAULT branch and exits 1
// unless there is exactly one (hacs/default, scripts/helpers/integration_path.py
// -> "No manifest"). Two stand-only manifests under demo/stand turned the
// Hassfest job of PR #9004 red on 2026-08-11, five weeks into the review queue,
// and the failure said nothing about which file was to blame. Anything that
// needs a second manifest ships it as `manifest.template.json` and renames it at
// install time — see demo/stand/install.sh.
test('the tree carries exactly one *manifest.json: HACS rejects a repository with two', () => {
const tracked = execFileSync('git', ['ls-files', '-z'], { cwd: ROOT })
.toString('utf8').split('\0').filter(Boolean);
const found = tracked.filter((path) => path.split('/').pop().endsWith('manifest.json'));
assert.deepEqual(found, ['custom_components/houseplan/manifest.json']);
});
// #255. Копия бандла для стенда весит 1.16 МБ и переписывается почти каждым
// продуктовым коммитом: 364 версии за семь недель — примерно четверть всего
// репозитория. Она нужна только браузерным прогонам, которые собирают её сами
// (`npm run bundle:sync`), поэтому в дереве её быть не должно. Проверка стоит
// здесь, а не в глазах ревьюера: вернуть файл обратно проще всего случайно,
// одним `git add -A` после локальной сборки.
test('копия бандла для стенда не коммитится (#255)', () => {
const tracked = execFileSync('git', ['ls-files', '-z', 'demo/srv/assets'], { cwd: ROOT })
.toString('utf8').split('\0').filter(Boolean);
const ignored = execFileSync('git', [
'check-ignore',
'demo/srv/assets/houseplan-card.js',
'demo/srv/assets/houseplan-panel.js',
], { cwd: ROOT }).toString('utf8').split(/\r?\n/).filter(Boolean);
assert.deepEqual(ignored, [
'demo/srv/assets/houseplan-card.js',
'demo/srv/assets/houseplan-panel.js',
], 'оба стабильных demo entry должны оставаться локальными build-артефактами');
for (const entry of ['houseplan-card.js', 'houseplan-panel.js']) {
assert.ok(!tracked.includes(`demo/srv/assets/${entry}`),
`demo/srv/assets/${entry} снова в индексе: соберите его \`npm run bundle:sync\`, `
+ 'а из коммита уберите');
}
// Остальное содержимое стенда (иконки, страницы) коммитится и должно остаться.
assert.ok(tracked.length > 0, 'каталог стенда пуст: проверьте, что убрали только бандл');
});