Skip to content
Browse files

Move documentation from READMe to HTML in 'docs' folder

  • Loading branch information...
1 parent b2eb527 commit 813bf6f38e93d4fcf834da2813c035b1d9e41186 Benjamin Thomas committed Oct 27, 2010
Showing with 1,457 additions and 444 deletions.
  1. +0 −76 API.md
  2. +32 −324 README.md
  3. +2 −2 bin/test-output.sh
  4. BIN docs/assets/icon.png
  5. +193 −0 docs/assets/icon.svg
  6. +188 −0 docs/assets/style.css
  7. +120 −0 docs/index.html
  8. +376 −0 docs/running-tests.html
  9. +417 −0 docs/writing-tests.html
  10. +1 −1 package.json
  11. +128 −0 test/test-overview.js
  12. +0 −41 test/test-simple.js
View
76 API.md
@@ -1,76 +0,0 @@
-The events that are called by `testing.runFiles` and/or `testing.runSuite` make
-it possible to write your own test runners and format the output however you'd
-like. See `lib/console-runner.js` or `lib/web-runner.js` for examples of how
-all these functions work.
-
-Events
-------
-+ `onStart`: called when `runFiles` starts running suites. This gets 1 argument:
- the number of suites being ran.
-
-+ `onDone`: called when `runFiles` finishes running the suites. This gets 2
- arguments: an array of suite results (see below), and the duration in seconds
- that it took to run all the suites.
-
-+ `onSuiteStart`: called when a suite is started. This gets 1 optional argument:
- the name of the suite. A suite might not have name.
-
-+ `onSuiteDone`: called when a suite finishes. This gets 1 argument: the suite
- result object for the specific suite. See below.
-
-+ `onTestStart`: called when a test is started. This gets 1 argument: the name of
- the test.
-
- Carefull! The test runner will think errors thrown in this function belong to
- the test suite and you'll get inaccurate results. Basically, make sure you
- don't throw any errors in this listener.
-
-+ `onTestDone`: Called when a test finishes. This gets 1 argument, the test
- result object for the specific test. See below.
-
- Carefull! The test runner will think errors thrown in this function belong to
- the test suite and you'll get inaccurate results. Basically, make sure you
- don't throw any errors in this listener.
-
-+ `onPrematureExit`: called when the process exits and there are still tests that
- haven't finished. This occurs when people forget to finish their tests or their
- tests don't work like they expected. This gets 1 argument: an array of the
- names of the tests that haven't finished.
-
-Suite Result
-------------
-A suite result is an object that looks like this:
-
- { name: suite name (if applicable)
- , results: an array of test results for each test ran (see below)
- , duration: how long the suite took
- , numFailures: number of failures
- , numSuccesses: number of successes
- }
-
-Note: even if a suite has many tests, the array of tests results might not have
-them all if a specific test was requested. So a Suite Result could have the
-results of 0 tests.
-
-Test Result
------------
-A test result is an object that looks like one of the following:
-
-success: the test completed successfully
-
- { duration: how long the test took
- , name: test name
- , numAssertions: number of assertions
- }
-
-failure: the test failed in some way
-
- { duration: how long the test took
- , name: test name
- , failure: the error or array of error candidates
- }
-
-If the tests are running in parallel and an error is thrown, sometimes it cannot
-reliably be determined which test went with which error. If that is the case
-then the 'failure' will be an array of all the errors that could have gone with
-this test.
View
356 README.md
@@ -1,337 +1,45 @@
-node-async-testing
-==================
-
-A simple test runner for testing asynchronous code
-
-Goals of the project:
-
-+ Tests should just be functions. Simple and intuitive.
-+ You shouldn't have to learn new assertion functions. Use the assertion module
- that comes with Node. If you are familiar with it you won't have any problems.
-+ Test files should be executable by Node. No preprocessors or eval. If your
- test file is called "my_test_file.js" then "node my_test_file.js" should run
- the tests.
-+ Node is asynchronous, so testing should be too.
-+ Not another Behavior Driven Development testing framework. I don't
- like specifications and what not. They only add verbosity.
-+ Make no assumptions about the code being tested. You should be able to test
- any code, and all aspects of it.
-+ Be able to run tests in parallel or serially. Running tests in parallel is
- much quicker, but makes it harder to deal with errors.
-
-Feedback/suggestions encouraged!
-
-Example
--------
-
-**examples/test-suite.js**:
-
- exports['asynchronous test'] = function(test) {
- setTimeout(function() {
- test.ok(true);
- test.finish();
- },500);
- };
-
- exports['synchronous test'] = function(test) {
- test.ok(true);
- test.finish();
- };
- exports['test assertions expected'] = function(test) {
- test.numAssertions = 1;
+ _ _ _ _
+ | | | | | | (_)
+ _ __ ___ __| | ___ __ _ ___ _ _ _ __ ___ | |_ ___ ___| |_ _ _ __ __ _
+ | '_ \ / _ \ / _` |/ _ \ / _` / __| | | | '_ \ / __| | __|/ _ | __| __| | '_ \ / _` |
+ | | | | (_) | (_| | __/ | (_| \__ \ |_| | | | | (__ | |_| __|__ \ |_| | | | | (_| |
+ |_| |_|\___/ \__,_|\___| \__,_|___/\__, |_| |_|\___| \__|\___|___/\__|_|_| |_|\__, |
+ __/ | __/ |
+ |___/ |___/
- test.ok(true);
- test.finish();
- }
+
+ Simple, intuitive testing for node.js
+
+----------------------------------------------------------------------------------------------
- exports['test catch async error'] = function(test) {
- var e = new Error();
-
- test.uncaughtExceptionHandler = function(err) {
- test.equal(e, err);
- test.finish();
- }
+node-async-testing
+==================
- setTimeout(function() {
- throw e;
- }, 500);
- };
+A simple test runner for testing asynchronous code. **node-async-testing**...
- // if this module is the script being run, then run the tests:
- if (module == require.main) {
- require('async_testing').run(__filename, process.ARGV);
- }
++ fully embraces Node's async environoment
++ supports parallel test execution
++ has true test _and_ suite setup and teardown functions
++ helps your organize your suites by allowing you to group different tests together
+ in sub-suites
++ allows you to easily add your own custom assertion methods
++ let's you customize test output for your particular needs
-The above file can be run on the command line with:
+See [bentomas.github.com/node-async-testing](http://bentomas.github.com/node-async-testing)
+for the full details.
- node examples/test-suite.js
+Feedback/suggestions encouraged!
Installing
----------
-
-**node-async-testing** can be installed using npm
+
+With npm:
npm install async_testing
+
+By hand:
-Detailed Overview
------------------
-
-The hard part of writing a test suite for asynchronous code is that when a test
-fails, you don't know which test it was that failed. Errors won't get caught by
-`try`/`catch` statements.
-
-**node-async-testing** addresses that by
-
-1. Giving each test its own unique assert object. This way you know which
- assertions correspond to which tests.
-2. Running (by default) the tests one at a time. This way it is possible to
- add a global exceptionHandler to the process and catch the errors whenever
- they happen.
-3. Requiring you to tell the test runner when the test is finished. This way
- you don't have any doubt as to whether or not an asynchronous test still
- has code to run.
-4. Allowing you to declare how many assertions should take place in a test.
- This way you can ensure that your callbacks aren't being called too many
- or too few times.
-
-**node-async-testing** tests are just a functions:
-
- function asynchronousTest(test) {
- setTimeout(function() {
- // make an assertion (these are just regular Node assertions)
- test.ok(true);
- // finish the test
- test.finish();
- });
- }
-
-As you can see, these test functions receive a `test` object, which is where all
-the action takes place. You make your assertions using this object (`test.ok()`,
-`test.deepEquals()`, etc) and use it to finish the test (`test.finish()`).
-Basically, all the actions that are directly related to a test use this object.
-
-**node-async-testing** makes no assumptions about tests, so even if your test is
-not asynchronous you still have to finish it:
-
- function synchronousTest(test) {
- test.ok(true);
- test.finish();
- };
-
-**node-async-testing** is written for running suites of tests, not individual
-tests. A test suite is just an object with test functions:
-
- var suite = {
- asynchronousTest: function(test) {
- setTimeout(function() {
- test.ok(true);
- test.finish();
- });
- },
- synchronousTest: function(test) {
- test.ok(true);
- test.finish();
- }
- }
-
-**node-async-testing** lets you be explicit about the number of assertions run
-in a given test: set `numAssertions` on the test object. This can be
-very helpful in asynchronous tests where you want to be sure all callbacks
-get fired:
-
- suite['test assertions expected'] = function(test) {
- test.numAssertions = 1;
-
- test.ok(true);
- test.finish();
- }
-
-**node-async-testing** lets you deal with uncaught errors. If you expect an
-error to be thrown asynchronously in your code somewhere (this is not good
-practice, but sometimes when using other people's code you have no choice. Or
-maybe _it is_ what you want to happen, who am I to judge?), you can set an
-`uncaughtExceptionHandler` on the test object:
-
- suite['test catch async error'] = function(test) {
- var e = new Error();
-
- test.uncaughtExceptionHandler = function(err) {
- test.equal(e, err);
- test.finish();
- }
-
- setTimeout(function() {
- throw e;
- }, 500);
- };
-
-**node-async-testing** comes with a convenience function for wrapping all tests
-in an object with setup/teardown functions. This funciton is called `wrap`:
-
- function setup(test, done) {
- test.extra1 = 1
- test.extra2 = 2;
-
- // setup functions can of course be asynchronous. when done setting up,
- // call `done`. This is required of setup and teardown functions.
- done();
- }
-
- var suite =
- { 'wrapped test': function(test) {
- test.equal(1, test.extra1);
- test.equal(2, test.extra2);
- test.finish();
- }
- };
-
- // actually wrap the suite
- require('async_testing').wrap({suite: suite, setup: setup});
-
-See `test/test-wrap_tests.js` for more examples of wrapping in action.
-
-Or for that matter, check out any of the files in the `test` directory to see
-all that **node-async-testing** has to offer.
-
-Running Test Suites
--------------------
-
-**node-async-testing** assumes you are going to have a one to one mapping
-between suites and files. So, to run a test suite, you actually tell it to run
-the file:
-
- require('async_testing').run('test-suite.js');
-
-The `run` method can take a file name or a directory name (it
-recursively searches directories for javascript files that start with `test-`)
-or an array of any combination of those two options.
-
-In order for **node-async-testing** to run a _file_, the exports object of the
-file needs to be the test suite:
-
- exports['first test'] = function(test) { ... };
- exports['second test'] = function(test) { ... };
- exports['third test'] = function(test) { ... };
-
- // or
-
- module.exports = {
- 'first test': function(test) { ... },
- 'second test': function(test) { ... },
- 'third test': function(test) { ... }
- };
-
-We want to be able to run suites via the `node` command. Here's
-how to make a script executable by Node. Some where in the file put
-this code:
-
- // if this module is the script being run, then run the tests:
- if (module === require.main) {
- require('async_testing').run(__filename);
- }
-
-That suite can now be run by executing the following on the command line (if it
-were in a file called `test-suite.js`):
-
- node test-suite.js
-
-Or, the `run` method can be passed the `process.ARGV` array of command
-line arguments, so **node-async-testing** settings can be altered at run time:
-
- exports['first test'] = function(test) { ... };
- exports['second test'] = function(test) { ... };
- exports['third test'] = function(test) { ... };
-
- if (module === require.main) {
- require('async_testing').run(__filename, process.ARGV);
- }
-
-Now, you can tell **node-async-testing** to run the tests in parallel:
-
- node test-suite.js --parallel
-
-Or to only run specific tests:
-
- node test-suite.js --test-name "first test" --test-name "third test"
-
-Use the `help` flag to see all the options:
-
- node test-suite.js --help
-
-**node-async-testing** can run multiple files at once this way, because of
-`process.ARGV`:
-
- node test-suite.js test-suite2.js
-
-For example, you can run all the tests in the `test` directory by saying:
-
- node test/*
-
-With this arrangement, **node-async-testing**'s `run` method will exit the
-process when done with the number of tests that didn't succeed. See
-`lib/running.js` for more details or if you want to disable that.
-
-If you want to organize your tests in a different manner and not have them
-organized by file, you are going to have to write your own test runner. See
-`runSuite()` in `lib/async_testing.js` for more details.
-
-Web Test Runner
----------------
-
-**node-async-testing** comes with a "web" test runner. This runner launches a
-web server which can be used to run suites manually. Launch it with the
-`--web` flag:
-
- node test/test-suite.js --web
-
-Or
-
- node-async-test --web tests-directory
-
-Once the server is started, from a browser you can pick and choose which suites
-to run, and run them as many times as you like. **node-async-testing** reloads
-the suites (and any code they use) from scratch each time they are run so you
-can leave the web server running and switch back and forth between editing tests
-or code and running the tests. Very handy!
-
-To use the web runner you also need to install [Socket.IO][socket] and
-[node-webworker][webwork]:
-
- npm install socket.io webworker
-
-\[The server is known to work in the lastest versions of Safari, Chrome and
-Firefox. Any help in getting it to work in Opera would be much appreciated. I
-don't have means of testing in IE.\]
-
-Custom Assertion Functions
---------------------------
-It is possible to write your own assertion functions that are fully supported
-by **node-async-testing**. You can't just use any assert function at any time
-because **node-async-testing** needs to know which assertions go with which
-tests. As such each test is given its own unique wrapped assertion methods. To
-add your own assertion function use the `registerAssertion()` method.
-
- var async_testing = require('async_testing');
- async_testing.registerAssertion('assertionName', function() { ... });
-
- exports['test assert'] = function(test) {
- test.assertionName();
- test.finish();
- }
-
-See `test/test-custom_assertions.js` for a working example.
-
-Custom Reporting
-----------------
-
-It is possible to write your own test runners. See `node-async-test`,
-`lib/console-runner.js` or `lib/web-runner.js` for examples, or `API.markdown`
-for a description of the different events and what arguments they receive.
-
-This feature is directly inspired by Caolan McMahon's [nodeunit]. Which is an
-awesome library.
-
-[nodeunit]: http://github.com/caolan/nodeunit
-[socket]: http://github.com/LearnBoost/Socket.IO-node
-[webwork]: http://github.com/pgriess/node-webworker
+ mkdir -p ~/.node_libraries
+ cd ~/.node_libraries
+ git clone --recursive git://github.com/bentomas/node-async-testing.git async_testing
View
4 bin/test-output.sh
@@ -33,8 +33,8 @@ run "node test/test-all_passing.js -0" \
"node test/test-all_passing.js -1"
group "all passing, multiple suites"
-run "node test/test-all_passing.js test/test-simple.js -0" \
- "node test/test-all_passing.js test/test-simple.js -1"
+run "node test/test-all_passing.js test/test-overview.js -0" \
+ "node test/test-all_passing.js test/test-overview.js -1"
group "some failing, one suite"
run "node test/test-sync_assertions.js -0" \
View
BIN docs/assets/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
193 docs/assets/icon.svg
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="99.5"
+ height="130.5"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.47 r22583"
+ sodipodi:docname="icon.svg">
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="49.75"
+ inkscape:cy="65.25"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1398"
+ inkscape:window-height="1021"
+ inkscape:window-x="1440"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-17,-872.36218)">
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3640"
+ width="98.5"
+ height="129.5"
+ x="17.5"
+ y="872.86218" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 87.353954,939.5516 c 1.328353,3.7046 18.178576,36.2032 7.742724,36.2032 -10.435844,4.8276 -46.23383,5.3723 -56.669674,0 -10.435844,0 6.308059,-32.4986 7.636412,-36.2032"
+ style="fill:#0000ff;stroke:none"
+ id="path3595"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#000080;stroke:#000000"
+ id="path3601"
+ sodipodi:cx="41.461498"
+ sodipodi:cy="1018.1299"
+ sodipodi:rx="21.47493"
+ sodipodi:ry="3.1893461"
+ d="m 62.936428,1018.1299 c 0,1.7614 -9.614654,3.1893 -21.47493,3.1893 -11.860276,0 -21.47493,-1.4279 -21.47493,-3.1893 0,-1.7614 9.614654,-3.1894 21.47493,-3.1894 11.860276,0 21.47493,1.428 21.47493,3.1894 z"
+ transform="translate(25.292925,-77.457888)"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ id="path2820"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ d="m 77.805504,898.93265 c 0.628699,7.3817 0.940674,20.22684 1.886602,22.86492 1.328353,3.70463 24.167464,48.89369 15.397154,53.95723 -11.105063,6.41151 -45.956667,6.18516 -56.669674,0 -8.796378,-5.07859 14.068801,-50.2526 15.397154,-53.95723 0.945928,-2.63808 1.257903,-15.48322 1.886602,-22.86492"
+ sodipodi:nodetypes="cssssc"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:3"
+ id="path3599"
+ sodipodi:cx="3.6145921"
+ sodipodi:cy="967.84454"
+ sodipodi:rx="11.906892"
+ sodipodi:ry="2.232542"
+ d="m 15.521484,967.84454 c 0,1.233 -5.330897,2.23255 -11.9068919,2.23255 -6.5759948,0 -11.9068918,-0.99955 -11.9068918,-2.23255 0,-1.233 5.330897,-2.23254 11.9068918,-2.23254 6.5759949,0 11.9068919,0.99954 11.9068919,2.23254 z"
+ transform="translate(63.139831,-70.866573)"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 37.718065,963.4226 4.465084,0.8505 0,0"
+ id="path3603"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3605"
+ d="m 38.837502,959.3308 4.465084,0.8505 0,0"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.000596,955.239 4.465084,0.8505 0,0"
+ id="path3607"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3622"
+ d="m 41.567107,951.1471 4.465084,0.8505 0,0"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 43.033641,947.05531 4.465084,0.8505 0,0"
+ id="path3624"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3626"
+ d="m 44.734626,942.96349 4.465084,0.8505 0,0"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3628"
+ d="m 46.270148,938.8717 4.465084,0.8505 0,0"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 48.092938,934.7798 4.465084,0.8505 0,0"
+ id="path3630"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3632"
+ d="m 49.412333,930.68802 4.465084,0.8505 0,0"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 50.900694,926.5962 4.465084,0.8505 0,0"
+ id="path3634"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="/Users/benjamin/Programming/tools/node/async-testing/docs/icon.png"
+ inkscape:export-xdpi="101.4273"
+ inkscape:export-ydpi="101.4273" />
+ </g>
+</svg>
View
188 docs/assets/style.css
@@ -0,0 +1,188 @@
+
+body {
+ color: #222;
+ font-family: 'Helvetica', 'Arial', sans-serif;
+ line-height: 1.4em;
+ margin: 0;
+ padding: 0;
+}
+
+a {
+ color: #0000FF;
+ font-weight: bold;
+ text-decoration: none;
+}
+a:hover {
+ text-decoration: underline;
+}
+
+header, section, nav {
+ display: block;
+}
+
+#container {
+ margin: auto;
+ max-width: 708px;
+}
+
+#main-header {
+ background: url(icon.png) no-repeat 0 100%;
+ padding: 50px 0 5px 90px;
+ margin: 0 0 -5px 140px;
+}
+#main-header h1 {
+ margin: 0;
+ padding: 30px 0 0;
+}
+#main-header h2 {
+ font-size: 1.2em;
+ font-weight: 1.2em;
+ margin: 0;
+ padding: 5px 0 5px;
+ text-transform: lowercase;
+}
+
+nav ul {
+ list-style-type: none;
+ margin: 25px 0 -25px;
+ padding: 0;
+ text-align: center;
+}
+nav li {
+ display: inline;
+ margin: 15px;
+}
+nav a {
+ color: black;
+ font-weight: bold;
+ text-decoration: none;
+ text-transform: lowercase;
+}
+nav a:hover {
+ text-decoration: underline;
+}
+nav .current a {
+ color: #0000FF;
+}
+
+section {
+ margin: 50px 0;
+}
+section h1 {
+ font-size: 20px;
+ font-weight: normal;
+ margin-left: -15px;
+}
+section h2 {
+ font-size: 15px;
+}
+section h2 code {
+ font-weight: normal;
+}
+#opinions h2 {
+ margin-bottom: 0;
+}
+#opinions h2+p {
+ margin-top: 0;
+}
+
+
+code {
+ background: #F8F8FF;
+ border: 1px solid #DEDEDE;
+ color: #444;
+ font-size: 1.1em;
+ padding: 0 2px 2px;
+}
+h1 code {
+ font-size: .9em;
+}
+
+video#demo {
+ margin: 0 -50px;
+}
+
+.toc {
+ list-style-type: disc;
+ line-height: 1.6em;
+ padding: 0 0 0 20px;
+ margin-left: 0;
+}
+.toc ul {
+ list-style-type: square;
+ padding: 0 0 0 20px;
+ margin-left: 0;
+}
+
+dd {
+ margin: 5px 0 10px 20px;
+}
+
+.highlight {
+ background: #F8F8FF;
+ border: 1px solid #DEDEDE;
+ padding: 5px 10px;
+}
+.highlight pre { margin: 0; }
+.highlight .hll { background-color: #ffffcc }
+.highlight .c { color: #60a0b0; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #007020; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #007020 } /* Comment.Preproc */
+.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #808080 } /* Generic.Output */
+.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0040D0 } /* Generic.Traceback */
+.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #007020 } /* Keyword.Pseudo */
+.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #902000 } /* Keyword.Type */
+.highlight .m { color: #40a070 } /* Literal.Number */
+.highlight .s { color: #4070a0 } /* Literal.String */
+.highlight .na { color: #4070a0 } /* Name.Attribute */
+.highlight .nb { color: #007020 } /* Name.Builtin */
+.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
+.highlight .no { color: #60add5 } /* Name.Constant */
+.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #007020 } /* Name.Exception */
+.highlight .nf { color: #06287e } /* Name.Function */
+.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
+.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #bb60d5 } /* Name.Variable */
+.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #40a070 } /* Literal.Number.Float */
+.highlight .mh { color: #40a070 } /* Literal.Number.Hex */
+.highlight .mi { color: #40a070 } /* Literal.Number.Integer */
+.highlight .mo { color: #40a070 } /* Literal.Number.Oct */
+.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
+.highlight .sc { color: #4070a0 } /* Literal.String.Char */
+.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
+.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
+.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
+.highlight .sx { color: #c65d09 } /* Literal.String.Other */
+.highlight .sr { color: #235388 } /* Literal.String.Regex */
+.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
+.highlight .ss { color: #517918 } /* Literal.String.Symbol */
+.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
+.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
+.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
+.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */
+
View
120 docs/index.html
@@ -0,0 +1,120 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <title>node-async-testing &mdash; simple intuitive testing for node.js</title>
+ <link rel="stylesheet" href="assets/style.css">
+ </head>
+ <body>
+ <div id="container">
+ <header id="main-header">
+ <h1>node-async-testing</h1>
+ <h2>Simple, intuitive testing for node.js</h2>
+ </header>
+
+ <nav>
+ <ul>
+ <li class="current"><a href="index.html">Home</a></li>
+ <li><a href="writing-tests.html">Writing Tests</a></li>
+ <li><a href="running-tests.html">Running Tests</a></li>
+ </ul>
+ </nav>
+
+ <section id="intro">
+ <h1>Overview:</h1>
+ <p>
+ <b>node-async-testing</b> is a fast, extendable uniting testing module for
+ <a href="http://nodejs.org/">Node.js</a>. It...
+ </p>
+
+ <ul>
+ <li>fully embraces Node's async environoment</li>
+ <li>supports parallel test execution</li>
+ <li>has true test <i>and</i> suite setup and teardown functions</li>
+ <li>
+ helps your organize your suites by allowing you to group different
+ tests together in sub-suites
+ </li>
+ <li>allows you to easily add your own custom assertion methods</li>
+ <li>let's you customize test output for your particular needs</li>
+ </ul>
+
+ </section>
+
+ <section id="opinions">
+ <h1><b>node-async-testing's</b> <del>biases</del> opinions:</h1>
+
+ <h2>Node is asynchronous, so testing should be too</h2>
+ <p>
+ This applies to everything: assertions, errors, callbacks, setup, teardown,
+ reports, and so on.
+ </p>
+
+ <h2>You should be able to run tests in parallel or serially</h2>
+ <p>
+ Running tests in parallel is much faster, but makes it impossible to
+ accurately deal with errors.
+ </p>
+
+ <h2>You should be able to test any code, and all aspects of it</h2>
+ <p>Make no assumptions about the code being tested.</p>
+
+ <h2>You shouldn't have to learn new assertion functions</h2>
+ <p>
+ The assertion module that comes with Node is great. If you are familiar with
+ it you won't have any problems, no need to learn new functions.
+ </p>
+
+ <h2>No specifications, and no natural language suites</h2>
+ <p>
+ Not another Behavior Driven Development testing framework. I don't like
+ specifications and what not. They only add verbosity. "Text X" followed
+ by a function is just right.
+ </p>
+
+ <h2>Test files should be executable by Node</h2>
+ <p>
+ No preprocessors or custom scripts. If your test file is called
+ "my_test_file.js" then <code>node my_test_file.js</code> should run it.
+ </p>
+
+ </section>
+
+
+ <section id="installing">
+ <h1>Installing:</h1>
+
+ <p>With npm:</p>
+
+ <div class="highlight"><pre>npm install async_testing</pre></div>
+
+ <p>By hand:</p>
+ <div class="highlight"><pre>
+mkdir -p ~/.node_libraries
+<span class="nb">cd</span> ~/.node_libraries
+git clone --recursive git://github.com/bentomas/node-async-testing.git async_testing</pre></div>
+ </section>
+
+ <section id="getting-started">
+ <h1>Getting started:</h1>
+
+ <p>
+ Read about <a href="writing-tests.html">writing tests and suites</a> or
+ <a href="running-tests.html">how to run your suites</a>.
+ </p>
+
+ <p>
+ Check out <a href="http://github.com/bentomas/node-async-testing/tree/master/test/">the examples</a>.
+ I recommend looking at <a href="http://github.com/bentomas/node-async-testing/blob/master/test/test-overview.js">test/test-overview.js</a> first.
+ </p>
+
+ <p>Watch this brief screencast:</p>
+
+ <video id="demo" width="808" height="540" controls preload>
+ <source src="http://media.benjaminthomas.org/node-async-testing/screencast.m4v" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
+ </video>
+ </section>
+
+ </div>
+ </body>
+</html>
View
376 docs/running-tests.html
@@ -0,0 +1,376 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <title>node-async-testing &mdash; simple intuitive testing for node.js</title>
+ <link rel="stylesheet" href="assets/style.css">
+ </head>
+ <body>
+ <div id="container">
+ <header id="main-header">
+ <h1>node-async-testing</h1>
+ <h2>Simple, intuitive testing for node.js</h2>
+ </header>
+
+ <nav>
+ <ul>
+ <li><a href="index.html">Home</a></li>
+ <li><a href="writing-tests.html">Writing Tests</a></li>
+ <li class="current"><a href="running-tests.html">Running Tests</a></li>
+ </ul>
+ </nav>
+
+ <section id="tests">
+ <h1>Running Test Suites</h1>
+
+ <p>
+ <b>node-async-testing</b> includes two different means of running suites:
+ A simple, streamlined interface for running suite files and a low-level API
+ (which is used by the previous method) which gives you fine-grained control.
+ </p>
+
+ <h2>Page outline:</h2>
+
+ <ul>
+ <li><a href="#suite-files">Running Suite Files</a></li>
+ <li><a href="#running-api">Running Suites using the API</a></li>
+ <li><a href="#running-events">Description of event callbacks</a></li>
+ </ul>
+ </section>
+
+ <section id="suite-files">
+ <h1>Running Suite Files</h1>
+
+ <p>
+ <b>node-async-testing</b> assumes you are going to have a one to one mapping
+ between suites and files. So, to run a test suite, you actually tell it to
+ run a file:
+ </p>
+
+ <div class="highlight"><pre>require<span class="o">(</span><span class="s1">&#39;async_testing&#39;</span><span class="o">)</span>.run<span class="o">(</span><span class="s1">&#39;test-suite.js&#39;</span><span class="o">)</span>;</pre></div>
+
+ <p>
+ The <code>run</code> method can take a file name or a directory name (it
+ recursively searches directories for javascript files that start with <code>test-</code>)
+ or an array of any combination of those two options.
+ </p>
+
+ <p>
+ In order for <b>node-async-testing</b> to run a <i>file</i>, the exports object of the
+ file needs to be the test suite:
+ </p>
+
+ <div class="highlight"><pre>
+<span class="nx">exports</span><span class="p">[</span><span class="s1">&#39;first test&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">};</span>
+<span class="nx">exports</span><span class="p">[</span><span class="s1">&#39;second test&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">};</span>
+<span class="nx">exports</span><span class="p">[</span><span class="s1">&#39;third test&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">};</span>
+
+<span class="c1">// or</span>
+
+<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
+ <span class="s1">&#39;first test&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">},</span>
+ <span class="s1">&#39;second test&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">},</span>
+ <span class="s1">&#39;third test&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
+<span class="p">};</span></pre></div>
+
+ <p>
+ To make a file easy to execute with the <code>node</code> command, we need
+ how to make our file run the suite when it is the script being ran. Some where
+ in the file we put this code:
+ </p>
+
+ <div class="highlight"><pre>
+<span class="c1">// if this module is the script being run, then run the tests:</span>
+<span class="k">if</span> <span class="p">(</span><span class="nx">module</span> <span class="o">===</span> <span class="nx">require</span><span class="p">.</span><span class="nx">main</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;async_testing&#39;</span><span class="p">).</span><span class="nx">run</span><span class="p">(</span><span class="nx">__filename</span><span class="p">);</span>
+<span class="p">}</span></pre></div>
+
+ <p>
+ Assuming we put that suite in a file called <code>test-suite.js</code>, we can now
+ execute the it by running the following on the command line:
+ </p>
+
+ <div class="highlight"><pre>node <span class="nb">test</span>-suite.js</pre></div>
+
+ <p>
+ The <code>run</code> method can also be passed the <code>process.ARGV</code>
+ array of command line arguments, so <b>node-async-testing</b> settings can
+ be altered at run time:
+ </p>
+
+ <div class="highlight"><pre>
+<span class="nx">exports</span><span class="p">[</span><span class="s1">&#39;first test&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">};</span>
+<span class="nx">exports</span><span class="p">[</span><span class="s1">&#39;second test&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">};</span>
+<span class="nx">exports</span><span class="p">[</span><span class="s1">&#39;third test&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">};</span>
+
+<span class="k">if</span> <span class="p">(</span><span class="nx">module</span> <span class="o">===</span> <span class="nx">require</span><span class="p">.</span><span class="nx">main</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;async_testing&#39;</span><span class="p">).</span><span class="nx">run</span><span class="p">(</span><span class="nx">__filename</span><span class="p">,</span> <span class="nx">process</span><span class="p">.</span><span class="nx">ARGV</span><span class="p">);</span>
+<span class="p">}</span></pre></div>
+
+ <p>
+ Now, you can tell <b>node-async-testing</b> to run the tests in parallel:
+ </p>
+
+ <div class="highlight"><pre>node <span class="nb">test</span>-suite.js --parallel</pre></div>
+
+ <p>
+ Or to only run specific tests:
+ </p>
+
+ <div class="highlight"><pre>node <span class="nb">test</span>-suite.js --test-name <span class="s2">&quot;first test&quot;</span> --test-name <span class="s2">&quot;third test&quot;</span></pre></div>
+
+ <p>
+ Use the <code>help</code> flag to see all the options:
+ </p>
+
+ <div class="highlight"><pre>node <span class="nb">test</span>-suite.js --help</pre></div>
+
+ <p>
+ <b>node-async-testing</b> can run multiple files at once this way, because
+ additional files will get passed with <code>process.ARGV</code>:
+ </p>
+
+ <div class="highlight"><pre>node <span class="nb">test</span>-suite.js <span class="nb">test</span>-suite2.js</pre></div>
+
+ <p>
+ For example, you can run all the tests in a <code>test</code> directory by saying:
+ </p>
+
+ <div class="highlight"><pre>node <span class="nb">test</span>/*</pre></div>
+
+ <p>
+ With this arrangement, the exit code of the process will be the number of tests
+ that didn't succeed.
+ </p>
+
+ <p>
+ <b>node-async-testing</b> comes with a "web" test runner. This runner launches a
+ web server which can be used to run suites manually. Launch it with the
+ <code>--web</code> flag:
+ </p>
+
+ <div class="highlight"><pre>node test/* --web</pre></div>
+
+ <p>
+ Once the server is started, in a browser you can pick and choose which suites
+ to run, and run them as many times as you like. <b>node-async-testing</b> reloads
+ the suites (and any code they use) from scratch each time they are run so you
+ can leave the web server running and switch back and forth between editing tests
+ or code and running the tests. Very handy!
+ </p>
+
+ <p>
+ To use the web runner you also need to install
+ <a href="http://github.com/LearnBoost/Socket.IO-node">Socket.IO</a>
+ and
+ <a href="http://github.com/pgriess/node-webworker">node-webworker</a>:
+ </p>
+
+ <div class="highlight"><pre>npm install socket.io webworker</pre></div>
+
+ <p>
+ [The server is known to work in the lastest versions of Safari, Chrome and
+ Firefox. Any help in getting it to work in Opera would be much appreciated. I
+ don't have means of testing in IE, so I can't tell you how it performs there.]
+ </p>
+
+ <section id="running-api">
+ <h1>Running suites using the API</h1>
+ <p>
+ If you want to organize your suites in a different manner (and say not have them
+ organized by file), or don't like the included test runners, you are going to
+ have to run your suites manually or write your own runner.
+ </p>
+
+ <p>
+ <b>node-async-testing</b> comes with the following methods for running suites
+ and test runners:
+ </p>
+
+ <ul>
+ <li><a href="#runSuite">runSuite()</a></li>
+ <li><a href="#expandFiles">expandFiles()</a></li>
+ <li><a href="#registerRunner">registerRunner()</a></li>
+ </ul>
+
+ <dl>
+ <dt id="runSuite"><code>runSuite(suiteObject, options)</code></dt>
+ <dd>
+ <p>
+ The <code>runSuite</code> function is the heart of <b>node-async-testing</b>.
+ It receives two arguments.
+ </p>
+
+ <p>
+ The first argument is the actual suite that you want to run. See
+ <a href="writing-tests.html">Writing Tests</a> for the details of writing
+ a suite.
+ </p>
+
+ <p>
+ The second argument is an object with options for running the suite.
+ This object can have the following properties:
+ </p>
+
+ <dl>
+ <dt><code>name</code></dt>
+ <dd>
+ This is the name of the test suite being run. This is optional, as it
+ doesn't affect the running of the suite at all. If it is provided it
+ is passed to the <code>onSuiteStart</code> <a href="#running-events">event callback</a>.
+ </dd>
+ <dt><code>parallel</code></dt>
+ <dd>
+ If this property is present and &ldquo;truethy&rdquo;, then the tests
+ will be run in parallel. Otherwise, <code>runSuite</code> won't start
+ another test until the previous one has completely finished.
+ </dd>
+ <dt><code>testName</code></dt>
+ <dd>
+ This should be either a String or an Array of Strings. If this property
+ is present then only those tests whose names match it will be ran. Use
+ this to only run specific tests.
+ </dd>
+ </dl>
+
+ In addition to those properties, any of the options in the
+ <a href="#running-events">events callbacks</a> section are supported.
+ </dd>
+
+ <dt id="expandFiles"><code>expandFiles(list, [filter], callback)</code></dt>
+ <dd>
+ <p>
+ The <code>expandFiles</code> function takes a list of files and or
+ directories and returns a list of just files. It recursively searches
+ through any directories for files that begin with <code>test-</code>. It
+ is useful for expanding a user supplied list of files and directories. It
+ takes three properties:
+ </p>
+
+ <ol>
+ <li>
+ A String or an Array of Strings, the list of files and directories to
+ expand.
+ </li>
+ <li>
+ A String or an Array of Strings, a list of file names by which you want
+ to filter the found files. This makes it so you can specify specific
+ file names that you want to find. This is optional.
+ </li>
+ <li>
+ Callback, which will get called with the found files when
+ <code>expandFiles</code> is done.
+ </li>
+ </ol>
+
+ <p>
+ It returns an array of objects which have the following properties:
+ </p>
+
+ <dl>
+ <dt><code>name</code></dt>
+ <dd>This is the file name that was passed in.</dd>
+ <dt><code>path</code></dt>
+ <dd>This is an absolute path to the file.</dd>
+ </dl>
+ </dd>
+
+ <dt id="registerRunner"><code>registerRunner(modulePath, [default])</code></dt>
+ <dd>
+ <p>
+ Use this function to add your own custom runners to <b>node-async-testing</b>.
+ See <a href="http://github.com/bentomas/node-async-testing/blob/master/lib/console-runner.js">lib/console-runner.js</a>
+ for an example of how to write a runner.
+ </p>
+ <p>
+ The first argument is the path to the runner which you are registering.
+ The second variable is for whether or not you want this to be the
+ default runner.
+ </p>
+ </dd>
+ </dl>
+ </section>
+
+ <section id="running-events">
+ <h1>Description of event callbacks</h1>
+ <p>
+ The <code>runSuite</code> method can be given event callbacks for outputing
+ the results of the tests. Using these callbacks it is possible to write your
+ own test runners and format the output however you'd like. These callbacks
+ are not for manipulating tests, but purely for reporting.
+ </p>
+
+ <h2>Events</h2>
+
+ <dl>
+ <dt><code>onSuiteStart([suiteName])</code></dt>
+ <dd>Called when a suite is started. A suite might not
+ have name, depending how it is ran.
+ </dd>
+
+ <dt><code>onSuiteDone(suiteResult)</code></dt>
+ <dd>
+ Called when a suite finishes. See <a href="#suite-result">Suite result</a>
+ below.
+ </dd>
+
+ <dt><code>onTestStart(testName)</code></dt>
+ <dd>Called when a test is started.
+ </dd>
+
+ <dt><code>onTestDone(testResult)</code></dt>
+ <dd>
+ Called when a test finishes. See <a href="#test-result">Test result</a>
+ below.
+ </dd>
+
+ <dt><code>onError(err, testNames)</code></dt>
+ <dd>
+ Called when an uncaught error is thrown from a test. The first argument is
+ the error, the second argument is an array of the names of the tests that
+ could have thrown it.
+ </dd>
+
+ <dt><code>onPrematureExit(testNames)</code></dt>
+ <dd>
+ Called when the process exits and there are still tests that haven't
+ finished. This occurs when people forget to finish their tests or their
+ tests don't work like they expected. This gets one argument: an array of
+ the names of the tests that haven't finished.
+ </dd>
+ </dl>
+
+ <h2 id="suite-result">Suite Result</h2>
+ <p>A suite result is an object that has the following properties:</p>
+
+ <dl>
+ <dt><code>name</code></dt>
+ <dd>suite name (if applicable)</dd>
+ <dt><code>results</code></dt>
+ <dd>an Array of <a href="#test-results">test results</a> for each test that completed</dd>
+ <dt><code>numFailures</code></dt>
+ <dd>the number of tests that failed</dd>
+ <dt><code>numSuccesses</code></dt>
+ <dd>the number of tests that passed</dd>
+ </dl>
+
+
+ <h2 id="test-result">Test Result</h2>
+ <p> A test result is an object that looks like one of the following:</p>
+
+ <p>Success: the test completed successfully</p>
+
+ <div class="highlight"><pre>
+{ name: test name
+, numAssertions: number of assertions completed successfully
+}</pre></div>
+
+ <p>Failure: the test failed in some way</p>
+ <div class="highlight"><pre>
+{ name: test name
+, failure: the assertion failure
+}</pre></div>
+ </section>
+ </div>
+ </body>
+</html>
View
417 docs/writing-tests.html
@@ -0,0 +1,417 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <title>node-async-testing &mdash; simple intuitive testing for node.js</title>
+ <link rel="stylesheet" href="assets/style.css">
+ </head>
+ <body>
+ <div id="container">
+ <header id="main-header">
+ <h1>node-async-testing</h1>
+ <h2>Simple, intuitive testing for node.js</h2>
+ </header>
+
+ <nav>
+ <ul>
+ <li><a href="index.html">Home</a></li>
+ <li class="current"><a href="writing-tests.html">Writing Tests</a></li>
+ <li><a href="running-tests.html">Running Tests</a></li>
+ </ul>
+ </nav>
+
+ <section id="writing-test-suites">
+ <h1>Writing Test Suites</h1>
+
+ <p>
+ The hard part of writing a test suite for asynchronous code is figuring out
+ when a test is done, and feeling confident that all the code was ran.
+ </p>
+
+ <p>
+ <b>node-async-testing</b> addresses that by...
+ </p>
+
+ <ol>
+ <li>giving each test its own unique assert object. This way you know which
+ assertions correspond to which tests.
+ </li>
+ <li>allowing you to run the tests one at a time. This way it is possible to
+ add a global exception handler to the process and know exactly which test
+ cause an error.
+ </li>
+ <li>requiring you to tell the test runner when the test is finished. This way
+ you don't have any doubt as to whether or not an asynchronous test still
+ has code to run.
+ </li>
+ <li>allowing you to declare how many assertions should take place in a test.
+ This way you can ensure that your callbacks aren't being called too many
+ or too few times.
+ </li>
+ </ol>
+
+ <p>
+ All of the examples in this page can be seen in the
+ <a href="http://github.com/bentomas/node-async-testing/blob/master/test/test-overview.js">test/test-overview.js</a>
+ suite and can be executed by running the following command from within the
+ <b>node-async-testing</b> directory:
+ </p>
+
+ <div class="highlight"><pre>node test/test-overview.js</pre></div>
+
+ <h2>Page outline:</h2>
+ <ul class="toc">
+ <li>
+ <a href="#tests">Tests</a>
+ <ul>
+ <li><a href="#test.finish">test.finish()</a></li>
+ <li><a href="#test.numAssertions">test.numAssertions</a></li>
+ <li><a href="#test.uncaughtExceptionHandler">test.uncaughtExceptionHandler</a></li>
+ <li><a href="#assertions">Assertions</a></li>
+ <li><a href="#custom-assertions">Custom Assertions</a></li>
+ </ul>
+ </li>
+ <li>
+ <a href="#suites">Suites</a>
+ <ul>
+ <li><a href="#sub-suites">Sub-suites</a></li>
+ <li><a href="#wrap">wrap()</a></li>
+ </ul>
+ </li>
+ </ul>
+
+
+ <section id="tests">
+ <h1 id="tests">Tests</h1>
+ <p>
+ <b>node-async-testing</b> tests are just a functions that take a &lsquo;test object&rsquo;:
+ </p>
+
+ <div class="highlight"><pre>
+<span class="kd">function</span> <span class="nx">asynchronousTest</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// make an assertion (these are just regular Node assertions)</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
+
+ <span class="c1">// finish the test</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">finish</span><span class="p">();</span>
+ <span class="p">});</span>
+<span class="p">}</span></pre></div>
+
+ <p>
+ The test object is where all the action takes place. You make your assertions
+ using this object (<code>test.ok()</code>, <code>test.deepEquals()</code>,
+ etc) and use it to finish the test (<code>test.finish()</code>). Basically,
+ all the actions that are directly related to a test use this object.
+ </p>
+
+ <p>
+ Test objects have the following properties:
+ </p>
+
+ <dl>
+ <dt id="test.finish"><code>test.finish()</code></dt>
+ <dd>
+ <p>
+ <b>node-async-testing</b> assumes all tests are asynchronous. So in
+ order for it to know that a given test has completed, you have to
+ &lsquo;finish&rsquo; the test by calling <code>test.finish()</code>.
+ This let's the test runner know that that particular test doesn't have
+ any more asynchronous code running.
+ </p>
+
+ <p>
+ Even if a test is not asynchronous you still have to finish it:
+ </p>
+
+ <div class="highlight"><pre>
+ <span class="kd">function</span> <span class="nx">synchronousTest</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">finish</span><span class="p">();</span>
+ <span class="p">}</span></pre></div>
+
+ <p>
+ <b>Note:</b> it is important that no code from this test is ran after
+ this function is called, otherwise, <b>node-async-testing</b> will think
+ that code corresponds to a different test. Be careful!
+ </p>
+ </dd>
+
+ <dt id="test.numAssertions"><code>test.numAssertions</code></dt>
+ <dd>
+ <p>
+ <b>node-async-testing</b> lets you be explicit about the number of
+ assertions run in a given test: set <code>numAssertions</code> on the test
+ object. This can be very helpful in asynchronous tests where you want to
+ be sure all callbacks get fired:
+ </p>
+
+ <div class="highlight"><pre>
+ <span class="nx">suite</span><span class="p">[</span><span class="s1">&#39;test assertions expected&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">numAssertions</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
+
+ <span class="nx">test</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">finish</span><span class="p">();</span>
+ <span class="p">}</span></pre></div>
+ </dd>
+
+ <dt id="test.uncaughtExceptionHandler"><code>test.uncaughtExceptionHandler</code></dt>
+ <dd>
+ <p>
+ <b>node-async-testing</b> lets you deal with uncaught errors. If you
+ expect an error to be thrown asynchronously in your code somewhere (this
+ is not good practice, but sometimes when using other people's code you
+ have no choice. Or maybe <i>it is</i> what you want to happen, who am I
+ to judge?), you can set an <code>uncaughtExceptionHandler</code> on the
+ test object:
+ </p>
+
+ <div class="highlight"><pre>
+ <span class="nx">suite</span><span class="p">[</span><span class="s1">&#39;test catch async error&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span>
+ <span class="kd">var</span> <span class="nx">e</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">();</span>
+
+ <span class="nx">test</span><span class="p">.</span><span class="nx">uncaughtExceptionHandler</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="nx">e</span><span class="p">,</span> <span class="nx">err</span><span class="p">);</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">finish</span><span class="p">();</span>
+ <span class="p">}</span>
+
+ <span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">throw</span> <span class="nx">e</span><span class="p">;</span>
+ <span class="p">},</span> <span class="mi">500</span><span class="p">);</span>
+ <span class="p">};</span></pre></div>
+
+ <p>
+ This property can only be set when running suites serially, because
+ otherwise <b>node-async-testing</b> wouldn't know for which test it
+ was catching the error.
+ </p>
+ </dd>
+ </dl>
+
+ <h2 id="assertions">Assertions</h2>
+ <p>
+ Additionally, the test object has all of the assertion functions that
+ come with the <a href="http://nodejs.org/api.html#assert-292">assert module</a>
+ bundled with Node.
+ </p>
+
+ <p>
+ These methods are bound to the test object so <b>node-async-testing</b>
+ can know which assertions correspond to which tests.
+ </p>
+
+ <dl>
+ <dt><code>test.ok(value, [message])</code></dt>
+ <dd>Tests if <b>value</b> is a true value, it is equivalent to <code>assert.equal(true, value, message);</code>.</dd>
+
+ <dt><code>test.equal(actual, expected, [message])</code></dt>
+ <dd>Tests shallow, coercive equality with the equal comparison operator ( <code>==</code> ).</dd>
+
+ <dt><code>test.notEqual(actual, expected, [message])</code></dt>
+ <dd>Tests shallow, coercive non-equality with the not equal comparison operator ( <code>!=</code> ).</dd>
+
+ <dt><code>test.deepEqual(actual, expected, [message])</code></dt>
+ <dd>Tests for deep equality.</dd>
+
+ <dt><code>test.notDeepEqual(actual, expected, [message])</code></dt>
+ <dd>Tests for any deep inequality.</dd>
+
+ <dt><code>test.strictEqual(actual, expected, [message])</code></dt>
+ <dd>Tests strict equality, as determined by the strict equality operator ( <code>===</code> )</dd>
+
+ <dt><code>test.notStrictEqual(actual, expected, [message])</code></dt>
+ <dd>Tests strict non-equality, as determined by the strict not equal operator ( <code>!==</code> )</dd>
+
+ <dt><code>test.throws(block, [error], [message])</code></dt>
+ <dd>Expects <b>block</b> to throw an error.</dd>
+
+ <dt><code>test.doesNotThrow(block, [error], [message])</code></dt>
+ <dd>Expects <b>block</b> not to throw an error.</dd>
+
+ <dt><code>test.ifError(value, [message])</code></dt>
+ <dd>Tests if <b>value</b> is not a false value, throws if it is a true value. Useful when testing the first argument, error in callbacks.</dd>
+ </dl>
+
+ <h2 id="custom-assertions">Custom assertions</h2>
+ <p>
+ Because <b>node-async-testing</b> needs to bind the assertion methods to the
+ test object, you can't just use any assertion you have lying around. You have to
+ first register it:
+ </p>
+
+ <div class="highlight"><pre>
+<span class="kd">var</span> <span class="nx">async_testing</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;async_testing&#39;</span><span class="p">);</span>
+<span class="nx">async_testing</span><span class="p">.</span><span class="nx">registerAssertion</span><span class="p">(</span><span class="s1">&#39;customAssertion&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>
+
+<span class="nx">exports</span><span class="p">[</span><span class="s1">&#39;test assert&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">customAssertion</span><span class="p">();</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">finish</span><span class="p">();</span>
+<span class="p">}</span></pre></div>
+
+ <p>
+ Check out
+ <a href="http://github.com/bentomas/node-async-testing/blob/master/test/test-custom_assertions.js">test/test-custom_assertions.js</a>
+ for a working example.
+ </p>
+
+ </section>
+
+ <section id="suites">
+ <h1>Suites</h1>
+ <p>
+ <b>node-async-testing</b> is written for running suites of tests, not individual
+ tests. A test suite is just an object with test functions:
+ </p>
+
+ <div class="highlight"><pre>
+<span class="kd">var</span> <span class="nx">suite</span> <span class="o">=</span> <span class="p">{</span>
+ <span class="s1">&#39;asynchronous test&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">finish</span><span class="p">();</span>
+ <span class="p">});</span>
+ <span class="p">},</span>
+ <span class="s1">&#39;synchronous test&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">finish</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span></pre></div>
+
+ <h2 id="sub-suites">Sub-suites</h2>
+ <p>
+ <b>node-async-testing</b> allows you to namespace your tests by putting them
+ in a sub-suite:
+ </p>
+
+ <div class="highlight"><pre>
+<span class="kd">var</span> <span class="nx">suite</span> <span class="o">=</span>
+ <span class="p">{</span> <span class="s1">&#39;namespace 1&#39;</span><span class="o">:</span>
+ <span class="p">{</span> <span class="s1">&#39;test A&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
+ <span class="p">,</span> <span class="s1">&#39;test B&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="p">,</span> <span class="s1">&#39;namespace 2&#39;</span><span class="o">:</span>
+ <span class="p">{</span> <span class="s1">&#39;test A&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
+ <span class="p">,</span> <span class="s1">&#39;test B&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="p">,</span> <span class="s1">&#39;namespace 3&#39;</span><span class="o">:</span>
+ <span class="p">{</span> <span class="s1">&#39;test A&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
+ <span class="p">,</span> <span class="s1">&#39;test B&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="p">};</span></pre></div>
+
+ <p>
+ Suites can be nested arbitrarily deep:
+ </p>
+
+ <div class="highlight"><pre>
+<span class="kd">var</span> <span class="nx">suite</span> <span class="o">=</span>
+ <span class="p">{</span> <span class="s1">&#39;namespace 1&#39;</span><span class="o">:</span>
+ <span class="p">{</span> <span class="s1">&#39;namespace 2&#39;</span><span class="o">:</span>
+ <span class="p">{</span> <span class="s1">&#39;namespace 3&#39;</span><span class="o">:</span>
+ <span class="p">{</span> <span class="s1">&#39;test A&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
+ <span class="p">,</span> <span class="s1">&#39;test B&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
+ <span class="p">,</span> <span class="s1">&#39;test C&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="p">};</span></pre></div>
+
+ <h2 id="wrap"><code>wrap()</code></h2>
+ <p>
+ <b>node-async-testing</b> comes with a convenience function for wrapping all tests
+ in an object with setup/teardown functions. This function is called <code>wrap</code>
+ and it takes one argument which is an object with the following properties:
+ </p>
+
+ <dl>
+ <dt><code>suite</code></dt>
+ <dd>This property is required and should be the suite object you want to wrap.</dd>
+
+ <dt><code>setup(test, done)</code></dt>
+ <dd>
+ This function is run before every single test in the suite. The first
+ argument is the test object for which this setup is being run. If you want
+ to pass additional data/objects to the test, you should set them on the
+ <code>test</code> object directly. Because <code>setup</code> might need
+ to be asynchronous, you have to call the second argument, <code>done()</code>,
+ when it is finished.
+ </dd>
+
+ <dt><code>teardown(test, done)</code></dt>
+ <dd>
+ This function is run after every single test in the suite. <code>teardown</code>
+ functions are called regardless of whether or not the test succeeds or
+ fails. It gets the same arguments as <code>setup</code>.
+ </dd>
+
+ <dt><code>suiteSetup(done)</code></dt>
+ <dd>
+ This function is run <i>once</i> before any test in the suite. Because
+ <code>suiteSetup</code> might need to be asynchronous, you have to call the
+ only argument, <code>done()</code>, when it is finished.
+ </dd>
+
+ <dt><code>suiteTeardown(done)</code></dt>
+ <dd>
+ This function is run <i>once</i> after all tests in the suite have
+ finished. <code>suiteTeardown</code>
+ functions are called regardless of whether or not the tests in the suite
+ succeed or fail. It gets the same arguments as <code>suiteSetup</code>.
+ </dd>
+ </dl>
+
+ <p>An example:</p>
+
+ <div class="highlight"><pre>
+<span class="kd">var</span> <span class="nx">wrap</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;async_testing&#39;</span><span class="p">).</span><span class="nx">wrap</span><span class="p">;</span>
+
+<span class="kd">var</span> <span class="nx">suiteSetupCount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+
+<span class="kd">var</span> <span class="nx">suite</span> <span class="o">=</span> <span class="nx">wrap</span><span class="p">(</span>
+ <span class="p">{</span> <span class="nx">suiteSetup</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">done</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">suiteSetupCount</span><span class="o">++</span><span class="p">;</span>
+ <span class="nx">done</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">,</span> <span class="nx">setup</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">,</span> <span class="nx">done</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">extra1</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">extra2</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
+ <span class="nx">done</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">,</span> <span class="nx">suite</span><span class="o">:</span>
+ <span class="p">{</span> <span class="s1">&#39;wrapped test 1&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nx">suiteSetupCount</span><span class="p">);</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nx">test</span><span class="p">.</span><span class="nx">extra1</span><span class="p">);</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">test</span><span class="p">.</span><span class="nx">extra2</span><span class="p">);</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">finish</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">,</span> <span class="s1">&#39;wrapped test 2&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nx">suiteSetupCount</span><span class="p">);</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nx">test</span><span class="p">.</span><span class="nx">extra1</span><span class="p">);</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">test</span><span class="p">.</span><span class="nx">extra2</span><span class="p">);</span>
+ <span class="nx">test</span><span class="p">.</span><span class="nx">finish</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="p">,</span> <span class="nx">teardown</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">test</span><span class="p">,</span> <span class="nx">done</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// not that you need to delete these variables here, they&#39;ll get cleaned up</span>
+ <span class="c1">// automatically, we&#39;re just doing it here as an example of running code</span>
+ <span class="c1">// after some tests</span>
+ <span class="k">delete</span> <span class="nx">test</span><span class="p">.</span><span class="nx">extra1</span><span class="p">;</span>
+ <span class="k">delete</span> <span class="nx">test</span><span class="p">.</span><span class="nx">extra2</span><span class="p">;</span>
+ <span class="nx">done</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">,</span> <span class="nx">suiteTeardown</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">done</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">delete</span> <span class="nx">suiteSetupCount</span><span class="p">;</span>
+ <span class="nx">done</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">})</span>
+<span class="p">})</span></pre></div>
+
+ <p>
+ You can use a combination of sub-suites and wrapping to provide setup/teardown
+ functions for certain tests.
+ </p>
+ </section>
+
+ </div>
+ </body>
+</html>
View
2 package.json
@@ -2,7 +2,7 @@
, "description": "A simple Node testing library."
, "version": "0.3.2"
, "author": "Benjamin Thomas"
-, "main": "./index"
+, "main": "./lib/async_testing"
, "directories": {"lib":"./lib"}
, "repository":
{ "type": "git"
View
128 test/test-overview.js
@@ -0,0 +1,128 @@
+var wrap = require('../lib/async_testing').wrap;
+
+var suiteSetupCount = 0;
+
+module.exports = {
+ 'asynchronous test': function(test) {
+ setTimeout(function() {
+ // make an assertion (these are just regular assertions)
+ test.ok(true);
+ // finish the test
+ test.finish();
+ },500);
+ },
+
+ 'synchronous test': function(test) {
+ test.ok(true);
+ test.finish();
+ },
+
+ 'test assertions expected': function(test) {
+ test.numAssertions = 1;
+
+ test.ok(true);
+ test.finish();
+ },
+
+ 'test catch async error': function(test) {
+ var e = new Error();
+
+ test.uncaughtExceptionHandler = function(err) {
+ test.equal(e, err);
+ test.finish();
+ }
+
+ setTimeout(function() {
+ throw e;
+ }, 500);
+ }
+
+ , 'namespace 1':
+ { 'test A': function(test) {
+ test.ok(true);
+ test.finish();
+ }
+ , 'test B': function(test) {
+ test.ok(true);
+ test.finish();
+ }
+ }
+ , 'namespace 2':
+ { 'test A': function(test) {
+ test.ok(true);
+ test.finish();
+ }
+ , 'test B': function(test) {
+ test.ok(true);
+ test.finish();
+ }
+ }
+ , 'namespace 3':
+ { 'test A': function(test) {
+ test.ok(true);
+ test.finish();
+ }
+ , 'test B': function(test) {
+ test.ok(true);
+ test.finish();
+ }
+ }
+
+ , 'namespace 4':
+ { 'namespace 5':
+ { 'namespace 6':
+ { 'test A': function(test) {
+ test.ok(true);
+ test.finish();
+ }
+ , 'test B': function(test) {
+ test.ok(true);
+ test.finish();
+ }
+ }
+ }
+ }
+
+ , 'wrapped suite': wrap(
+ { suiteSetup: function(done) {
+ suiteSetupCount++;
+ done();
+ }
+ , setup: function(test, done) {
+ test.extra1 = 1;
+ test.extra2 = 2;
+ done();
+ }
+ , suite:
+ { 'wrapped test 1': function(test) {
+ test.equal(1, suiteSetupCount);
+ test.equal(1, test.extra1);
+ test.equal(2, test.extra2);
+ test.finish();
+ }
+ , 'wrapped test 2': function(test) {
+ test.equal(1, suiteSetupCount);
+ test.equal(1, test.extra1);
+ test.equal(2, test.extra2);
+ test.finish();
+ }
+ }
+ , teardown: function(test, done) {
+ // not that you need to delete these variables here, they'll get cleaned up
+ // automatically, we're just doing it here as an example of running code
+ // after some tests
+ delete test.extra1;
+ delete test.extra2;
+ done();
+ }
+ , suiteTeardown: function(done) {
+ delete suiteSetupCount;
+ done();
+ }
+ })
+};
+
+// if this module is the script being run, then run the tests:
+if (module == require.main) {
+ require('../lib/async_testing').run(__filename, process.ARGV);
+}
View
41 test/test-simple.js
@@ -1,41 +0,0 @@
-
-module.exports = {
- 'asynchronousTest': function(test) {
- setTimeout(function() {
- // make an assertion (these are just regular assertions)
- test.ok(true);
- // finish the test
- test.finish();
- },500);
- },
-
- 'synchronousTest': function(test) {
- test.ok(true);
- test.finish();
- },
-
- 'test assertions expected': function(test) {
- test.numAssertions = 1;
-
- test.ok(true);
- test.finish();
- },
-
- 'test catch async error': function(test) {
- var e = new Error();
-
- test.uncaughtExceptionHandler = function(err) {
- test.equal(e, err);
- test.finish();
- }
-
- setTimeout(function() {
- throw e;
- }, 500);
- }
-};
-
-// if this module is the script being run, then run the tests:
-if (module == require.main) {
- require('../lib/async_testing').run(__filename, process.ARGV);
-}

0 comments on commit 813bf6f

Please sign in to comment.
Something went wrong with that request. Please try again.