#!/usr/bin/env node /* * scripts/test-check-css-vars.js — gates scripts/check-css-vars.js * * Confirms the JS/HTML extension (#1128 followup M3) catches an * undefined CSS variable reference embedded in a JS template literal. * * Strategy: write a tmp file under a tmp dir alongside one CSS file * (so the lint has a defined-vars source set) plus one JS fixture * containing `var(--definitely-undefined-xyz)`. Spawn the lint, assert * exit code 1, assert the offending var is named in stderr. */ 'use strict'; const fs = require('fs'); const os = require('os'); const path = require('path'); const { spawnSync } = require('child_process'); const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'check-css-vars-test-')); const lintPath = path.join(__dirname, 'check-css-vars.js'); let pass = 0, fail = 0; function check(name, cond, info) { if (cond) { console.log('PASS', name); pass++; } else { console.error('FAIL', name, info || ''); fail++; } } try { // 1. Baseline: a CSS file that defines --foo, a JS file that uses it. fs.writeFileSync(path.join(tmp, 'site.css'), ':root { --foo: red; }\n.x { color: var(--foo); }\n'); fs.writeFileSync(path.join(tmp, 'app.js'), 'const s = `
x
`;\n'); let r = spawnSync('node', [lintPath, '--dir', tmp], { encoding: 'utf8' }); check('clean tree exits 0', r.status === 0, r.stderr || r.stdout); // 2. Add a JS file with an undefined var; lint MUST exit 1 and name it. fs.writeFileSync(path.join(tmp, 'broken.js'), 'const s = `x`;\n'); r = spawnSync('node', [lintPath, '--dir', tmp], { encoding: 'utf8' }); check('JS-side undefined var → exit 1', r.status === 1, 'got status=' + r.status); check('error names the offending var', /--definitely-undefined-xyz/.test(r.stderr), 'stderr=' + r.stderr); check('error names the offending file', /broken\.js/.test(r.stderr), 'stderr=' + r.stderr); // 3. HTML inline style is also caught. fs.unlinkSync(path.join(tmp, 'broken.js')); fs.writeFileSync(path.join(tmp, 'page.html'), '
x
\n'); r = spawnSync('node', [lintPath, '--dir', tmp], { encoding: 'utf8' }); check('HTML-side undefined var → exit 1', r.status === 1, 'got status=' + r.status); check('html error names offending var', /--also-undefined-html/.test(r.stderr), r.stderr); // 4. Fallback form is tolerated. fs.unlinkSync(path.join(tmp, 'page.html')); fs.writeFileSync(path.join(tmp, 'safe.js'), 'const s = `
x
`;\n'); r = spawnSync('node', [lintPath, '--dir', tmp], { encoding: 'utf8' }); check('fallback var() form → exit 0', r.status === 0, r.stderr || r.stdout); } finally { // Cleanup tmp dir. for (const f of fs.readdirSync(tmp)) fs.unlinkSync(path.join(tmp, f)); fs.rmdirSync(tmp); } console.log('\n=== test-check-css-vars: ' + pass + ' pass, ' + fail + ' fail ==='); process.exit(fail > 0 ? 1 : 0);