cleanup: diag is actually a tap comment.

Also have runTest and runSuite versions instead of the run*Test
functions.
This commit is contained in:
Jeremy Wall 2024-04-01 12:31:00 -04:00
parent 44feb46f69
commit d26f60241f
2 changed files with 48 additions and 54 deletions

View File

@ -27,7 +27,7 @@ class NodeRenderer {
}) })
} }
diag(lines) { comment(lines) {
for (var line of lines) { for (var line of lines) {
this.out('# ' + line); this.out('# ' + line);
} }
@ -40,7 +40,7 @@ class BrowserRenderer {
// TODO(jeremy): // TODO(jeremy):
} }
diag(lines) { comment(lines) {
// TODO(jeremy): // TODO(jeremy):
} }
} }
@ -98,12 +98,12 @@ class Tap {
}; };
diag(msg){ comment(msg){
if(!msg) { if(!msg) {
msg = " "; msg = " ";
} }
var lines = msg.split("\n"); var lines = msg.split("\n");
this.#renderer.diag(lines); this.#renderer.comment(lines);
}; };
/** Render a pass TAP output message. /** Render a pass TAP output message.
@ -194,7 +194,7 @@ class Tap {
throws_ok(func, msg) { throws_ok(func, msg) {
var errormsg = ' '; var errormsg = ' ';
if (typeof func != 'function') if (typeof func != 'function')
this.diag('throws_ok needs a function to run'); this.comment('throws_ok needs a function to run');
try { try {
func(); func();
@ -214,7 +214,7 @@ class Tap {
var errormsg = ' '; var errormsg = ' ';
var msg = false; var msg = false;
if (typeof func != 'function') if (typeof func != 'function')
this.diag('throws_ok needs a function to run'); this.comment('throws_ok needs a function to run');
try { try {
func(); func();
@ -234,7 +234,7 @@ class Tap {
lives_ok(func, msg) { lives_ok(func, msg) {
var errormsg = true; var errormsg = true;
if (typeof func != 'function') if (typeof func != 'function')
this.diag('throws_ok needs a function to run'); this.comment('throws_ok needs a function to run');
try { try {
func(); func();
@ -259,11 +259,11 @@ class Tap {
var result = typeof eval('obj.prototype.' + arguments[i]); var result = typeof eval('obj.prototype.' + arguments[i]);
if (result == 'undefined') { if (result == 'undefined') {
pass = false; pass = false;
this.diag('Missing ' + arguments[i] + ' method'); this.comment('Missing ' + arguments[i] + ' method');
} }
} else { } else {
pass = false; pass = false;
this.diag('Missing ' + arguments[i] + ' method'); this.comment('Missing ' + arguments[i] + ' method');
} }
} }
desc += ' ' + arguments[i]; desc += ' ' + arguments[i];
@ -338,50 +338,46 @@ class Tap {
* @param {function(Tap)} test * @param {function(Tap)} test
*/ */
function runTest(t, testName, test) { function runTest(t, testName, test) {
t.diag('running ' + testName + ' tests'); t.comment('running ' + testName + ' tests');
try { try {
test(t); test(t);
if (t.planned > t.counter) { summarize(t);
t.diag('looks like you planned ' + t.planned + ' tests but only ran '
+ t.counter + ' tests');
} else if (t.planned < t.counter) {
t.diag('looks like you planned ' + t.planned + ' tests but ran '
+ (t.counter - t.planned) + ' tests extra');
}
t.diag('ran ' + t.counter + ' tests out of ' + t.planned);
t.diag('passed ' + t.passed + ' tests out of ' + t.planned);
t.diag('failed ' + t.failed + ' tests out of ' + t.planned);
} }
catch (err) { catch (err) {
t.diag("Test Suite Crashed!!! (" + err + ")"); t.comment("Test Suite Crashed!!! (" + err + ")");
} }
return t; return t;
} }
/** function summarize(t) {
* Runs a set of TAP tests defined by a function. if (t.planned > t.counter) {
* Uses the NodeRenderer for the test output. t.comment('looks like you planned ' + t.planned + ' tests but only ran '
* + t.counter + ' tests');
* @param {string} testName } else if (t.planned < t.counter) {
* @param {function(Tap)} test t.comment('looks like you planned ' + t.planned + ' tests but ran '
*/ + (t.counter - t.planned) + ' tests extra');
function runNodeTap(testName, test) { }
var t = Tap.Node(); t.comment('ran ' + t.counter + ' tests out of ' + t.planned);
return runTest(t, testName, test); t.comment('passed ' + t.passed + ' tests out of ' + t.planned);
t.comment('failed ' + t.failed + ' tests out of ' + t.planned);
} }
/** /**
* Runs a set of TAP tests defined by a function. * @param {Tap} t
* Uses the Browser renderer for the test output. * @param {Array<{'plan': Number, name: string, 'test': function(Tap)}} suite
*
* @param {string} testName
* @param {function(Tap)} test
*/ */
function runBrowserTap(testName, test) { function runSuite(t, suite) {
var t = Tap.Browser(); const plan = suite.reduce((acc, item) => {
return runTest(t, testName, test); return acc + item.plan
}, 0);
t.plan(plan);
for (var item of suite) {
t.comment('running ' + item.name + ' tests');
item.test(t);
}
summarize(t);
} }
export { Tap, runNodeTap, runBrowserTap }; export { Tap, runTest, runSuite };

View File

@ -1,22 +1,20 @@
/** @implements TapRenderer */ /** @implements TapRenderer */
class FakeRenderer { class FakeRenderer {
output = "nothing yet"; output = "nothing yet";
diagnostic = ""; commentOutput = "";
out(text) { out(text) {
this.output = text; this.output = text;
} }
diag(lines) { comment(lines) {
for (var line of lines) { for (var line of lines) {
this.diagnostic += line; this.commentOutput += line;
} }
} }
} }
import('../src/TAP.mjs').then(m => { import('../src/TAP.mjs').then(m => {
var runNodeTap = m.runNodeTap;
function tapSuite(t) { function tapSuite(t) {
t.plan(23); t.plan(23);
@ -39,7 +37,7 @@ import('../src/TAP.mjs').then(m => {
t.like(renderer.output, /ok 2 - object can \[ run \]/, 'can_ok passed'); t.like(renderer.output, /ok 2 - object can \[ run \]/, 'can_ok passed');
//Now we need to test the whole prototype method assignment thing //Now we need to test the whole prototype method assignment thing
function MockObj() { function MockObj() {
this.attr = 1; this.attr = 1;
} }
@ -47,11 +45,11 @@ import('../src/TAP.mjs').then(m => {
MockObj.prototype.fakeme = function () {}; MockObj.prototype.fakeme = function () {};
f.can_ok(MockObj, 'fakeme'); f.can_ok(MockObj, 'fakeme');
renderer.diagnostic = ''; renderer.commentOutput = '';
t.like(renderer.output, /^ok .* \[ fakeme \]/, t.like(renderer.output, /^ok .* \[ fakeme \]/,
'can_ok recognized prototype methods'); 'can_ok recognized prototype methods');
f.can_ok(MockObj, 'fakeme2'); f.can_ok(MockObj, 'fakeme2');
renderer.diagnostic = ''; renderer.commentOutput = '';
t.like(renderer.output, /^not ok .* \[ fakeme2 \]/, t.like(renderer.output, /^not ok .* \[ fakeme2 \]/,
'can_ok prototype recognization doesnt break methods'); 'can_ok prototype recognization doesnt break methods');
}; };
@ -73,9 +71,9 @@ import('../src/TAP.mjs').then(m => {
var f = new m.Tap(renderer); // the TAP that's failing var f = new m.Tap(renderer); // the TAP that's failing
f.plan(10); f.plan(10);
// begin real tests! // begin real tests!
f.diag("hello"); f.comment("hello");
t.diag(renderer.diagnostic); t.comment(renderer.commentOutput);
t.like(renderer.diagnostic, /hello/, 'got hello'); t.like(renderer.commentOutput, /hello/, 'got hello');
}; };
testDiag(); testDiag();
@ -86,10 +84,10 @@ import('../src/TAP.mjs').then(m => {
// begin real tests! // begin real tests!
f.throws_ok(function() {throw new Error('I made a boo boo')}, 'I made a boo boo'); f.throws_ok(function() {throw new Error('I made a boo boo')}, 'I made a boo boo');
//t.diag(renderer.output); //t.comment(renderer.output);
t.like(renderer.output, /ok 1 - code threw \[Error: I made a boo boo\]/, 'uncaught exception'); t.like(renderer.output, /ok 1 - code threw \[Error: I made a boo boo\]/, 'uncaught exception');
f.throws_ok(function() {}, 'I made a boo boo'); f.throws_ok(function() {}, 'I made a boo boo');
//t.diag(renderer.output); //t.comment(renderer.output);
t.like(renderer.output, /not ok 2 - code threw \[ \]/, 'false failed'); t.like(renderer.output, /not ok 2 - code threw \[ \]/, 'false failed');
}; };
testException(); testException();
@ -160,5 +158,5 @@ import('../src/TAP.mjs').then(m => {
return t; return t;
} }
runNodeTap("Tap dogfood test suite", tapSuite); m.runTest(m.Tap.Node(), "Tap dogfood test suite", tapSuite);
}); });