Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit 6f8b468198c0604fa61db826878edaa936de4bae @kriszyp committed Jul 5, 2010
Showing with 161 additions and 0 deletions.
  1. +55 −0 README.md
  2. +83 −0 lib/runner.js
  3. +23 −0 package.json
@@ -0,0 +1,55 @@
+Promised-based Asynchronous Test Runner (patr) is a very simple, easy-to-use test
+runner that support asynchronous JavaScript testing with promises. Patr is based on
+the premise that testing should be as simple as creating an object with
+methods to perform tests. Objects can be nested to create subgroups of tests.
+Patr relies on the system's "assert" module for making assertions. An example test:
+
+ var assert = require("assert");
+ require("patr/runner").run({testMath: function(){
+ assert.equal(3, Math.min(3, 5));
+ });
+
+The suggested pattern for writing test files is to define the tests on the
+exports object and running the test runner if the module is the main module.
+This allows for direct execution of test files and easy inclusion of tests
+into other test groups. For example, we could define "my-math-test.js":
+
+ var assert = require("assert");
+ exports.testMath = function(){
+ assert.equal(3, Math.min(3, 5));
+ };
+
+ if(require.main == module)
+ require("patr/runner").run(exports);
+
+Now we can directly execute "my-math-test.js" or we could include it in another
+test file:
+
+ exports.mathTests = require("my-math-test");
+ exports.otherTests = require("other-tests");
+
+ if(require.main == module)
+ require("patr/runner").run(exports);
+
+With these aggregate test module, each test file's tests are included in a nested object
+that will be tested as a subgroup of tests.
+
+= Using Promises for Asynchronous Testing =
+
+Promises make asynchronous testing very simple. You simply return a promise from
+your test to indicate when a test is completed. When using promise-based coding this
+is super simple. For example, to test the contents of file loaded asynchronously using
+promised-io's fs module:
+
+ var fs = require("promised-io/fs");
+
+ exports.testFile = function(){
+ return fs.readFile("testfile").then(function(contents){
+ assert.equal(contents.toString(), "expected contents");
+ });
+ };
+ ...
+
+Patr is part of the Persevere project, and therefore is licensed under the
+AFL or BSD license. The Persevere project is administered under the Dojo foundation,
+and all contributions require a Dojo CLA.
@@ -0,0 +1,83 @@
+var when = require("promised-io/promise").when,
+ print = require("promised-io/sys").print,
+ onError;
+exports.run = function(tests){
+ print("Running tests");
+ doTests(compileTests(tests));
+};
+
+function doTests(tests, prefix){
+ prefix = prefix || "";
+ function doTest(index){
+ var done;
+ try{
+ var test = tests[index++];
+ if(!test){
+ onError = false;
+ return {failed: 0, total: tests.length};
+ }
+ if(test.children){
+ print(prefix + "Group " + test.name);
+ return when(doTests(test.children, prefix + " "), function(childrenResults){
+ return when(doTest(index), function(results){
+ results.failed += childrenResults.failed;
+ results.total += childrenResults.total - 1;
+ return results;
+ });
+ });
+ }
+ onError = function(e){
+ print("onError");
+ testFailed(e);
+ done = true;
+ }
+ return when(test.test(), function(){
+ if(!done){
+ print(prefix + test.name + ": passed");
+ return doTest(index);
+ }
+ }, testFailed);
+ }catch(e){
+ return testFailed(e);
+ }
+ function testFailed(e){
+ if(!done){
+ print(prefix + test.name + ": failed");
+ print(e.stack || e);
+ return when(doTest(index), function(results){ results.failed++; return results;});
+ }
+ }
+
+ }
+ return when(doTest(0), function(results){
+ print(prefix + "passed: " + (results.total - results.failed) + "/" + results.total);
+ return results;
+ });
+}
+
+function compileTests(tests){
+ var listOfTests = [];
+ for(var i in tests){
+ if(typeof tests[i] == "function"){
+ listOfTests.push({
+ name: i,
+ test: tests[i]
+ });
+ }
+ if(typeof tests[i] == "object"){
+ listOfTests.push({
+ name: i,
+ children: compileTests(tests[i])
+ });
+ }
+ }
+ return listOfTests;
+}
+
+if(typeof process !== "undefined"){
+ process.addListener("uncaughtException", function(e){
+ if(onError){
+ onError(e);
+ }
+ });
+}
@@ -0,0 +1,23 @@
+{
+ "name": "patr",
+ "author": "Kris Zyp",
+ "dependencies": ["promised-io"],
+ "contributors": [],
+ "keywords": [
+ "test",
+ "promise"
+ ],
+ "mappings": {
+ "promised-io": "jar:http://github.com/kriszyp/promised-io/zipball/master!/lib/"
+ },
+ "githubName": "patr",
+ "type": "zip",
+ "location": "http://github.com/kriszyp/patr/zipball/master",
+ "overlay": {
+ "npm": {
+ "dependencies": {
+ "promised-io": "*"
+ }
+ }
+ }
+}

0 comments on commit 6f8b468

Please sign in to comment.