openvibers/openvibe.examples Commits
npm test no longer counts a skipped test as passed (roadmap WS-Q task 7, the rule of openvibe-shared/test-runner). test/run.js counted every smoke test and repository check that exited 0 as passed, so one that printed that it skipped its work and checked nothing would still read as green. A test now prints "<label>: skipped (<why>)" for what it could not run, and the runner lists it as skip with its reasons and does not count it as passed: the summary reads "13/14 passed, 1 skipped (…)", and only a run with nothing skipped says N/N; --strict (or OV_TEST_STRICT=1) makes a skip fail the run. This repository does not depend on openvibe-shared, so the runner keeps its own loop (examples/*/test/smoke.test.js from each example's directory, then test/*.test.js) with SKIP_RE and skipsIn copied from the module. No test here skips anything. npm test (Node 22) 14/14.
Changes
@@@ -7,15 +7,35 @@** npm test # everything* npm test -- chat oauth # only names containing one of the words++ * npm test -- --strict # a skipped test fails the run too (or OV_TEST_STRICT=1)++ *++ * A test that cannot run something here prints `<label>: skipped (<why>)`: it is listed as `skip`++ * with its reasons and not counted as passed, so the summary reads `20/21 passed, 1 skipped (…)`;++ * only a run with nothing skipped says `N/N passed`. This is the rule of openvibe-shared/test-runner,++ * copied here because this repository does not depend on openvibe-shared.*/const { spawn } = require('node:child_process');const fs = require('node:fs');const path = require('node:path');const ROOT = path.join(__dirname, '..');++const strict = process.argv.includes('--strict') || process.env.OV_TEST_STRICT === '1';const filters = process.argv.slice(2).filter((a) => !a.startsWith('-'));const TIMEOUT_MS = 120000;++/** `<label>: skipped (<why>)` on a line of its own (SKIP_RE from openvibe-shared/test-runner). */++const SKIP_RE = /^[ \t]*[\w .,'()/+#-]{1,120}: skipped \((.+)\)[ \t]*$/gm;++++/** The skip lines in a test's output, in order, without repeats (skipsIn from openvibe-shared/test-runner). */++function skipsIn(output) {++ const out = [];++ for (const m of String(output || '').matchAll(SKIP_RE)) {++ const line = m[0].trim();++ if (!out.includes(line)) out.push(line);++ }++ return out;++}++const tests = [...fs.readdirSync(path.join(ROOT, 'examples')).sort().filter((d) => fs.existsSync(path.join(ROOT, 'examples', d, 'test', 'smoke.test.js')))@@@ -34,7 +54,9 @@ function runOne(t) {const timer = setTimeout(() => { output += `\n[run] timed out after ${TIMEOUT_MS}ms`; child.kill('SIGKILL'); }, TIMEOUT_MS);child.on('close', (code, signal) => {clearTimeout(timer);-- resolve({ ...t, ok: code === 0, code: code ?? signal, ms: Date.now() - started, output });++ const ok = code === 0;++ const skips = ok ? skipsIn(output) : [];++ resolve({ ...t, ok, state: !ok ? 'fail' : skips.length ? 'skip' : 'pass', skips, code: code ?? signal, ms: Date.now() - started, output });});});}@@@ -46,13 +68,18 @@ function runOne(t) {for (const t of tests) {const r = await runOne(t);results.push(r);-- console.log(`${r.ok ? 'ok ' : 'FAIL'} ${r.name.padEnd(34)} ${String(r.ms).padStart(6)}ms`);++ const mark = r.state === 'pass' ? 'ok ' : r.state === 'skip' ? 'skip' : 'FAIL';++ console.log(`${mark} ${r.name.padEnd(34)} ${String(r.ms).padStart(6)}ms${r.state === 'skip' ? ` ${r.skips.join('; ')}` : ''}`);}-- const failed = results.filter((r) => !r.ok);++ const failed = results.filter((r) => r.state === 'fail');++ const skipped = results.filter((r) => r.state === 'skip');for (const r of failed) {console.log(`\n-- ${r.name} (exit ${r.code}) --`);console.log(r.output.split('\n').slice(-60).join('\n'));}-- console.log(`\n${results.length - failed.length}/${results.length} passed`);-- process.exit(failed.length ? 1 : 0);++ const passed = results.length - failed.length - skipped.length;++ console.log(skipped.length++ ? `\n${passed}/${results.length} passed, ${skipped.length} skipped (${skipped.map((r) => `${r.name}: ${r.skips.join('; ')}`).join(' | ')})${strict ? ' — strict: skips fail the run' : ''}`++ : `\n${passed}/${results.length} passed`);++ process.exit(failed.length || (strict && skipped.length) ? 1 : 0);})();
@@ -7,15 +7,35 @@
@@ -7,15 +7,35 @@
*
*
* npm test # everything
* npm test # everything
* npm test -- chat oauth # only names containing one of the words
* npm test -- chat oauth # only names containing one of the words
+ * npm test -- --strict # a skipped test fails the run too (or OV_TEST_STRICT=1)
+ *
+ * A test that cannot run something here prints `<label>: skipped (<why>)`: it is listed as `skip`
+ * with its reasons and not counted as passed, so the summary reads `20/21 passed, 1 skipped (…)`;
+ * only a run with nothing skipped says `N/N passed`. This is the rule of openvibe-shared/test-runner,
+ * copied here because this repository does not depend on openvibe-shared.
*/
*/
const { spawn } = require('node:child_process');
const { spawn } = require('node:child_process');
const fs = require('node:fs');
const fs = require('node:fs');
const path = require('node:path');
const path = require('node:path');
const ROOT = path.join(__dirname, '..');
const ROOT = path.join(__dirname, '..');
+const strict = process.argv.includes('--strict') || process.env.OV_TEST_STRICT === '1';
const filters = process.argv.slice(2).filter((a) => !a.startsWith('-'));
const filters = process.argv.slice(2).filter((a) => !a.startsWith('-'));
const TIMEOUT_MS = 120000;
const TIMEOUT_MS = 120000;
+/** `<label>: skipped (<why>)` on a line of its own (SKIP_RE from openvibe-shared/test-runner). */
+const SKIP_RE = /^[ \t]*[\w .,'()/+#-]{1,120}: skipped \((.+)\)[ \t]*$/gm;
+
+/** The skip lines in a test's output, in order, without repeats (skipsIn from openvibe-shared/test-runner). */
+function skipsIn(output) {
+ const out = [];
+ for (const m of String(output || '').matchAll(SKIP_RE)) {
+ const line = m[0].trim();
+ if (!out.includes(line)) out.push(line);
+ }
+ return out;
+}
+
const tests = [
const tests = [
...fs.readdirSync(path.join(ROOT, 'examples')).sort()
...fs.readdirSync(path.join(ROOT, 'examples')).sort()
.filter((d) => fs.existsSync(path.join(ROOT, 'examples', d, 'test', 'smoke.test.js')))
.filter((d) => fs.existsSync(path.join(ROOT, 'examples', d, 'test', 'smoke.test.js')))
@@ -34,7 +54,9 @@ function runOne(t) {
@@ -34,7 +54,9 @@ function runOne(t) {
const timer = setTimeout(() => { output += `\n[run] timed out after ${TIMEOUT_MS}ms`; child.kill('SIGKILL'); }, TIMEOUT_MS);
const timer = setTimeout(() => { output += `\n[run] timed out after ${TIMEOUT_MS}ms`; child.kill('SIGKILL'); }, TIMEOUT_MS);
child.on('close', (code, signal) => {
child.on('close', (code, signal) => {
clearTimeout(timer);
clearTimeout(timer);
- resolve({ ...t, ok: code === 0, code: code ?? signal, ms: Date.now() - started, output });
+ const ok = code === 0;
+ const skips = ok ? skipsIn(output) : [];
+ resolve({ ...t, ok, state: !ok ? 'fail' : skips.length ? 'skip' : 'pass', skips, code: code ?? signal, ms: Date.now() - started, output });
});
});
});
});
}
}
@@ -46,13 +68,18 @@ function runOne(t) {
@@ -46,13 +68,18 @@ function runOne(t) {
for (const t of tests) {
for (const t of tests) {
const r = await runOne(t);
const r = await runOne(t);
results.push(r);
results.push(r);
- console.log(`${r.ok ? 'ok ' : 'FAIL'} ${r.name.padEnd(34)} ${String(r.ms).padStart(6)}ms`);
+ const mark = r.state === 'pass' ? 'ok ' : r.state === 'skip' ? 'skip' : 'FAIL';
+ console.log(`${mark} ${r.name.padEnd(34)} ${String(r.ms).padStart(6)}ms${r.state === 'skip' ? ` ${r.skips.join('; ')}` : ''}`);
}
}
- const failed = results.filter((r) => !r.ok);
+ const failed = results.filter((r) => r.state === 'fail');
+ const skipped = results.filter((r) => r.state === 'skip');
for (const r of failed) {
for (const r of failed) {
console.log(`\n-- ${r.name} (exit ${r.code}) --`);
console.log(`\n-- ${r.name} (exit ${r.code}) --`);
console.log(r.output.split('\n').slice(-60).join('\n'));
console.log(r.output.split('\n').slice(-60).join('\n'));
}
}
- console.log(`\n${results.length - failed.length}/${results.length} passed`);
- process.exit(failed.length ? 1 : 0);
+ const passed = results.length - failed.length - skipped.length;
+ console.log(skipped.length
+ ? `\n${passed}/${results.length} passed, ${skipped.length} skipped (${skipped.map((r) => `${r.name}: ${r.skips.join('; ')}`).join(' | ')})${strict ? ' — strict: skips fail the run' : ''}`
+ : `\n${passed}/${results.length} passed`);
+ process.exit(failed.length || (strict && skipped.length) ? 1 : 0);
})();
})();