Test.Builder - Back end for building test libraries
var Test = new Test.Builder();
function ok (test, description) {
Test.ok(test, description);
}
Test.Builder provides the buildings block upon which to write test libraries like Test.Simple and Test.More that can work together. All tests are expected to use a plan and to be run in an HTML element with its "id" attribute set to "test". See Test.Simple and Test.More for details. Users of this class, however, are expected to be folks who want to write test functions that interoperate with Test.Simple and Test.More.
var Test = new Test.Builder();
new Test.Builder()
if you need to create a new Test.Builder object to, for example, test a Test.Builder-based test library. var Test = Test.Builder.instance();
Test.Builder.instance()
, you'll get the same object. (This is called a singleton). Test.reset();
These methods are for setting up tests and declaring how many there are. You usually only want to call one of these methods.
Test.plan({ noPlan: true });
Test.plan({ skipAll: reason });
Test.plan({ tests: numTests });
var max = Test.expectedTests();
Test.expectedTests(max);
Test.noPlan();
var plan = Test.hasPlan();
plan
is either null
(no plan has been set) "noPlan" (indeterminate number of tests) or an integer (the number of expected tests). Test.skipAll();
Test.skipAll(reason);
reason
.These methods actually run the tests. The description
argument is always optional.
Test.ok(test, description);
Test.isEq(got, expect, description);
got
is equivalent to expect
. Test.isNum(got, expect, description);
got
is equivalent to the numeric form of expect
as converted by Number(). Test.isntEq(got, dontExpect, description);
isEq()
. Tests to see whether got
is not equivalent to dontExpect
. Test.isntNum(got, dontExpect, description);
isNum()
. Tests to see whether the numeric form of got
is not equivalent to the numeric form of dontExpect
as converted by Number(). Test.like(got, /regex/, description);
Test.like(got, 'regex', description);
got
matches the regular expression in regex
. If a string is passed for the regex
argument, it will be converted to a regular expression object for testing. If <got> is not a string, the test will fail. Test.unlike(got, /regex/, description);
Test.unlike(got, 'regex', description);
unlike()
. Tests to see whether got
does not match the regular expression in regex
. If a string is passed for the regex
argument, it will be converted to a regular expression object for testing. If <got> is not a string, the test will pass. Test.cmpOK(got, op, expect, description);
got
and expect
. Specify any binary comparison operator as a string via the op
argument. In addition to the usual JavaScript operators, cmpOK() also supports the Perl-style string comparison operators:eq
- String equalne
- String not equallt
- String less thangt
- String greater thanle
- String less than or equalge
- String greater than or equal Test.BAILOUT(reason);
Test.skip();
Test.skip(why);
why
. Test.todoSkip();
Test.todoSkip(why);
skip()
, only it will declare the test as failing and TODO. Test.skipRest();
Test.skipRest(reason);
skip()
, only it skips all the rest of the tests you plan to run and terminates the test. Test.useNumbers(onOrOff);
ok 1
ok 2
ok 3
ok
ok
ok
true
. Test.noHeader(noHeader);
true
, no "1..N" header will be printed. Test.noEnding(noEnding);
true
, none of that will be done.Controlling where the test output goes. It's ok for your test to change where document.write
points to; Test.Builder's default output settings will not be affected.
Test.diag(msg);
Test.diag(msg, msg2, msg3);
diag()
is often used in conjunction with a failing test (ok() || diag()
) it "passes through" the failure. return ok(...) || diag(...);
These methods specify where test output and diagnostics will be sent. By default, in a browser they all default to appending to the element with the "test" ID or, failing that, to using document.write
. In Macromedia Director, they use trace
for their output. If you wish to specify other functions that lack the apply()
method, you'll need to supply them instead as custom anonymous functions that take a single argument (multiple arguments will be concatenated before being passed to the output function):
Test.output(function (msg) { foo(msg) });
Test.output(function);
Test.failureOutput(function);
Test.todoOutput(function);
Test.warnOutput(function);
Test.endOutput(function);
var currTest = Test.currentTest();
Test.currentTest(num);
my @tests = Test.summary();
true
for pass, false
for fail. This is a logical pass/fail, so todos are passes. my @tests = Test.details();
tests[testNum - 1] = {
ok: is the test considered a pass?
actual_ok: did it literally say 'ok'?
desc: description of the test (if any)
type: type of test (if any, see below).
reason: reason for the above (if any)
};
currentTest()
is changed. In these cases, Test.Builder doesn't know the result of the test, so it's type is "unknown". The details for these tests are filled in. They are considered ok, but the name and actual_ok is left null
. tests[22] = { // 23 - 1, since arrays start from 0.
ok: 1, // logically, the test passed since it's todo
actual_ok: 0, // in absolute terms, it failed
desc: 'hole count',
type: 'todo',
reason: 'insufficient donuts'
};
TODO: {
Test.todo(why, howMany);
...normal testing code goes here...
}
howMany
tests will be expected to fail and thus marked as "TODO" tests. var package = Test.caller();
my(pack, file, line) = Test.caller();
my(pack, file, line) = Test.caller(height);
var timeout = 3000;
var asyncID = Test.beginAsync(timeout);
window.setTimeout(
function () {
Test.ok(true, "Pass after 2 seconds");
Test.endAsync(asyncID);
}, timeout - 1000
);
window.setTimeout()
or window.setInterval()
in a browser, or by making an XMLHttpRequest call. In such cases, the tests might normally run after the test script has completed, and thus the summary message at the end of the test script will be incorrect--and the test results will appear after the summary. if (typeof JSAN != 'undefined') new JSAN().use('Test.Builder');
else {
if (typeof Test == 'undefined' || typeof Test.Builder == 'undefined')
throw new Error(
"You must load either JSAN or Test.Builder "
+ "before loading Test.Simple"
);
}
Test.Simple = {};
Test.Simple.EXPORT = ['plan', 'ok'];
Test.Simple.EXPORT_TAGS = { ':all': Test.Simple.EXPORT };
Test.Simple.VERSION = '0.21';
// .... Declare exportable functions, then export them.
if (typeof JSAN == 'undefined') Test.Builder.exporter(Test.Simple);
window
object in browsers and the _global
object in Director.CPAN can provide the best examples. Test.Simple and Test.More both use Test.Builder.
Original Perl code by chromatic and maintained by Michael G Schwern <schwern@pobox.com>. Ported to JavaScript by David Wheeler <david@kineticode.com>.
Copyright 2002, 2004 by chromatic <chromatic@wgz.org> and Michael G Schwern <schwern@pobox.com>, 2005 by David Wheeler <david@kineticode.com>.
This program is free software; you can redistribute it and/or modify it under the terms of the Perl Artistic License or the GNU GPL.
See http://www.perl.com/perl/misc/Artistic.html and http://www.gnu.org/copyleft/gpl.html.
Hey! The above document had some coding errors, which are explained below: