diff --git a/config/rollup.coverage.config.mjs b/config/rollup.coverage.config.mjs new file mode 100644 index 0000000..286bebc --- /dev/null +++ b/config/rollup.coverage.config.mjs @@ -0,0 +1,23 @@ +/** + * Coverage build: the ESM module instrumented with Istanbul, written to a separate file the node + * test suite imports when DOMFORTIFY_COV is set. Mirrors DOMPurify's instrument-then-nyc approach; + * Istanbul's per-file counters accumulate correctly across the suite's fresh-module-per-test imports, + * where V8 coverage would fragment on the cache-busting query. + */ +import { createRequire } from 'node:module'; +import typescript from '@rollup/plugin-typescript'; +import replace from '@rollup/plugin-replace'; +import istanbul from 'rollup-plugin-istanbul'; + +const require = createRequire(import.meta.url); +const pkg = require('../package.json'); + +export default { + input: 'src/index.ts', + output: { file: 'dist/fortify.cov.es.mjs', format: 'es', sourcemap: true }, + plugins: [ + replace({ preventAssignment: true, values: { __VERSION__: pkg.version } }), + typescript({ tsconfig: './config/tsconfig.build.json' }), + istanbul({ include: ['src/**/*.ts'] }), + ], +}; diff --git a/scripts/coverage.mjs b/scripts/coverage.mjs new file mode 100644 index 0000000..f32d04b --- /dev/null +++ b/scripts/coverage.mjs @@ -0,0 +1,20 @@ +/** + * Runs the node QUnit suite against the Istanbul-instrumented build and writes the collected counters + * to .nyc_output so `nyc report` can render them. DOMFORTIFY_COV is set before the suite is imported + * (dynamic import, so it is read in time) to select the instrumented module. + */ +process.env.DOMFORTIFY_COV = '1'; + +const QUnit = (await import('qunit')).default; +const { mkdirSync, writeFileSync } = await import('node:fs'); +await import('../test/test-suite.mjs'); + +QUnit.on('runEnd', (data) => { + if (globalThis.__coverage__) { + mkdirSync('.nyc_output', { recursive: true }); + writeFileSync('.nyc_output/out.json', JSON.stringify(globalThis.__coverage__)); + } + if (data.testCounts.failed > 0) process.exitCode = 1; +}); + +QUnit.start();