Files
wehub-resource-sync 6db8fca185
docmd CI verification / verify (push) Failing after 0s
chore: import upstream snapshot with attribution
2026-07-13 12:31:55 +08:00

116 lines
4.7 KiB
JavaScript

/**
* --------------------------------------------------------------------
* docmd : the zero-config documentation engine.
*
* N-2 — `docmd deploy --force` flag must do something.
*
* Before the fix, `--force` was accepted in the CLI flags but never
* read in the deployer. Every `docmd deploy --docker` silently
* overwrote an existing `Dockerfile`. The fix: `--force` opts in to
* overwriting; the default behaviour skips existing files with a
* clear `TUI` line.
*
* Run: `node tests/runner.js --only=deploy`
* --------------------------------------------------------------------
*/
import {
DOCMD,
setup,
writeFile,
runTestFile
} from '../shared.js';
import { execSync } from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
let passed = 0;
let failed = 0;
const failures = [];
function assert(condition, message) {
if (!condition) {
failed++;
failures.push(message);
console.log(` ❌ ${message}`);
} else {
passed++;
console.log(` ✅ ${message}`);
}
}
export const test = runTestFile({
name: 'Deploy --force honours overwrite (N-2)',
emoji: '🚢',
run: () => {
// N-2 — without --force, an existing Dockerfile is preserved.
{
const dir = setup('deploy-29-n2-no-force-skip');
writeFile(dir, 'docs/index.md', '# Hi\n');
writeFile(dir, 'docmd.config.json', JSON.stringify({ title: 'N2', src: './docs', out: './site' }, null, 2) + '\n');
// Pre-seed a Dockerfile so the deployer would overwrite it.
const existing = 'FROM existing:keep-me\n';
writeFile(dir, 'Dockerfile', existing);
let output = '';
try {
output = execSync(`node ${DOCMD} deploy --docker`, { cwd: dir, stdio: 'pipe', encoding: 'utf8' });
} catch (e) {
output = (typeof e.stdout === 'string' ? e.stdout : (e.stdout ? e.stdout.toString() : '')) +
(typeof e.stderr === 'string' ? e.stderr : (e.stderr ? e.stderr.toString() : ''));
}
const after = fs.readFileSync(path.join(dir, 'Dockerfile'), 'utf8');
assert(after === existing, 'N-2: without --force, existing Dockerfile is preserved');
assert(/skipped.*--force/i.test(output), 'N-2: TUI mentions --force when skipping');
}
// N-2 — with --force, an existing Dockerfile is overwritten.
{
const dir = setup('deploy-29-n2-force-overwrite');
writeFile(dir, 'docs/index.md', '# Hi\n');
writeFile(dir, 'docmd.config.json', JSON.stringify({ title: 'N2', src: './docs', out: './site' }, null, 2) + '\n');
writeFile(dir, 'Dockerfile', 'FROM existing:keep-me\n');
execSync(`node ${DOCMD} deploy --docker --force`, { cwd: dir, stdio: 'pipe' });
const after = fs.readFileSync(path.join(dir, 'Dockerfile'), 'utf8');
assert(after !== 'FROM existing:keep-me\n', 'N-2: with --force, existing Dockerfile is overwritten');
assert(/FROM .+/.test(after), 'N-2: overwritten Dockerfile contains a real FROM directive');
}
// N-2 — without --force and no existing file, the deployer writes
// a fresh Dockerfile (regression guard for the skip path).
{
const dir = setup('deploy-29-n2-no-force-fresh');
writeFile(dir, 'docs/index.md', '# Hi\n');
writeFile(dir, 'docmd.config.json', JSON.stringify({ title: 'N2', src: './docs', out: './site' }, null, 2) + '\n');
execSync(`node ${DOCMD} deploy --docker`, { cwd: dir, stdio: 'pipe' });
assert(fs.existsSync(path.join(dir, 'Dockerfile')), 'N-2: without --force and no existing file, Dockerfile is created');
}
// T-Z9 — generated `netlify.toml` must NOT contain a SPA catch-all
// redirect with `from = "/*" status = 200`. That pattern soft-404s
// every missing route by serving the home page with HTTP 200, which
// hides errors and hurts SEO. docmd generates real HTML per route,
// so the redirect is unnecessary — Netlify serves the bundled
// 404.html with 404 status for any path that doesn't have a file.
{
const dir = setup('deploy-29-tz9-no-soft-404');
writeFile(dir, 'docs/index.md', '# Hi\n');
writeFile(dir, 'docmd.config.json', JSON.stringify({ title: 'TZ9', src: './docs', out: './site', layout: { spa: true } }, null, 2) + '\n');
execSync(`node ${DOCMD} deploy --netlify`, { cwd: dir, stdio: 'pipe' });
const toml = fs.readFileSync(path.join(dir, 'netlify.toml'), 'utf8');
assert(!/\[\[redirects\]\]/.test(toml), 'T-Z9: no [[redirects]] block in generated netlify.toml');
assert(!/from\s*=\s*"\/\*"\s*\n\s*to\s*=\s*"\/index\.html"/m.test(toml), 'T-Z9: no catch-all redirect to /index.html');
}
}
});
export const results = {
get passed() { return passed; },
get failed() { return failed; },
get failures() { return [...failures]; }
};