|
6 | 6 | // 1. dist/ is up to date with src/ (rebuilds to a temp dir, compares bytes) |
7 | 7 | // 2. The SHA-384 integrity attributes in www/docs/getting-started.md match |
8 | 8 | // the current dist files |
| 9 | +// 3. dist/platform/node-hyperscript.js boots and validates a fixture without |
| 10 | +// crashing (guards against broken relative imports like #667) |
9 | 11 | // |
10 | 12 | // Exits 0 on success, 1 on any failure. Does NOT mutate dist/ or the docs. |
11 | 13 |
|
12 | 14 | import { createHash } from 'node:crypto' |
13 | | -import { readFileSync, rmSync, mkdtempSync, readdirSync, statSync } from 'node:fs' |
| 15 | +import { readFileSync, rmSync, mkdtempSync, readdirSync, statSync, writeFileSync } from 'node:fs' |
14 | 16 | import { tmpdir } from 'node:os' |
15 | 17 | import { join, relative, sep } from 'node:path' |
16 | 18 | import { fileURLToPath } from 'node:url' |
@@ -131,6 +133,52 @@ while ((m = tagRe.exec(docs)) !== null) { |
131 | 133 | if (found === 0) fail(`no integrity="sha384-..." attributes found in ${relative(repoRoot, docsFile)}`) |
132 | 134 | else if (failures === 0) ok(`all ${found} integrity attributes match`) |
133 | 135 |
|
| 136 | +// ----------------------------------------------------------------------------- |
| 137 | +// Check 3: dist/platform/node-hyperscript.js actually runs |
| 138 | +// ----------------------------------------------------------------------------- |
| 139 | + |
| 140 | +section('Smoke-testing dist/platform/node-hyperscript.js...') |
| 141 | + |
| 142 | +const nodeBin = join(distDir, 'platform', 'node-hyperscript.js') |
| 143 | +const smokeDir = mkdtempSync(join(tmpdir(), 'hs-smoke-')) |
| 144 | +try { |
| 145 | + writeFileSync(join(smokeDir, 'ok.html'), '<div _="on click log 1"></div>\n') |
| 146 | + writeFileSync(join(smokeDir, 'bad.html'), '<div _="on click log"></div>\n') |
| 147 | + |
| 148 | + // Valid fixture: validator should boot and exit 0 |
| 149 | + let booted = false |
| 150 | + try { |
| 151 | + execSync(`node "${nodeBin}" --validate --quiet "${join(smokeDir, 'ok.html')}"`, { stdio: 'pipe' }) |
| 152 | + ok('validator boots and exits 0 on a valid fixture') |
| 153 | + booted = true |
| 154 | + } catch (e) { |
| 155 | + const stderr = e.stderr?.toString().trim() || e.message |
| 156 | + fail(`validator failed on valid fixture: ${stderr.split('\n')[0]}`) |
| 157 | + if (stderr.includes('ERR_MODULE_NOT_FOUND')) { |
| 158 | + console.error(' (this is the #667 class of bug — a broken import in dist/platform/)') |
| 159 | + } |
| 160 | + } |
| 161 | + |
| 162 | + // Invalid fixture: validator should exit 1 and print an error to stderr. |
| 163 | + // Only meaningful if the previous check passed — if the script crashes at |
| 164 | + // startup it also exits 1, and we'd mistake that for "detected a parse error". |
| 165 | + if (booted) { |
| 166 | + try { |
| 167 | + execSync(`node "${nodeBin}" --validate --quiet "${join(smokeDir, 'bad.html')}"`, { stdio: 'pipe' }) |
| 168 | + fail('validator did not detect parse error in bad fixture (exit 0)') |
| 169 | + } catch (e) { |
| 170 | + if (e.status === 1) { |
| 171 | + ok('validator detects parse errors (exit 1 on a bad fixture)') |
| 172 | + } else { |
| 173 | + const stderr = e.stderr?.toString().trim() || e.message |
| 174 | + fail(`validator crashed on bad fixture (exit ${e.status}): ${stderr.split('\n')[0]}`) |
| 175 | + } |
| 176 | + } |
| 177 | + } |
| 178 | +} finally { |
| 179 | + rmSync(smokeDir, { recursive: true, force: true }) |
| 180 | +} |
| 181 | + |
134 | 182 | // ----------------------------------------------------------------------------- |
135 | 183 |
|
136 | 184 | console.log('') |
|
0 commit comments