Comparing version 0.7.2 to 0.7.3
@@ -19,2 +19,10 @@ var QUnit = require('qunitjs'), | ||
// send ping messages to when child is blocked. | ||
// after I sent the first ping, testrunner will start to except the next ping | ||
// within maxBlockDuration, otherwise this process will be killed | ||
process.send({event: 'ping'}); | ||
setInterval(function() { | ||
process.send({event: 'ping'}); | ||
}, Math.floor(options.maxBlockDuration / 2)); | ||
process.on('uncaughtException', function(err) { | ||
@@ -172,1 +180,2 @@ if (QUnit.config.current) { | ||
}); | ||
@@ -48,3 +48,6 @@ var fs = require('fs'), | ||
// define namespace your code will be attached to on global['your namespace'] | ||
namespace: null | ||
namespace: null, | ||
// max amount of ms child can be blocked, after that we assume running an infinite loop | ||
maxBlockDuration: 1000 | ||
}; | ||
@@ -59,2 +62,3 @@ | ||
var child; | ||
var pingCheckTimeoutId; | ||
@@ -72,24 +76,40 @@ child = cp.fork( | ||
function complete(err, data) { | ||
kill(); | ||
clearTimeout(pingCheckTimeoutId); | ||
callback(err, data) | ||
} | ||
child.on('message', function(msg) { | ||
if (msg.event === 'assertionDone') { | ||
log.add('assertions', msg.data); | ||
} else if (msg.event === 'testDone') { | ||
log.add('tests', msg.data); | ||
} else if (msg.event === 'done') { | ||
msg.data.code = opts.code.path; | ||
log.add('summaries', msg.data); | ||
if (opts.coverage) { | ||
coverage.add(msg.data.coverage); | ||
msg.data.coverage = coverage.get(); | ||
msg.data.coverage.code = msg.data.code; | ||
log.add('coverages', msg.data.coverage); | ||
} | ||
if (opts.log.testing) { | ||
console.log('done'); | ||
} | ||
callback(null, msg.data); | ||
kill(); | ||
} else if (msg.event === 'uncaughtException') { | ||
callback(_.extend(new Error(), msg.data)); | ||
kill(); | ||
switch (msg.event) { | ||
case 'ping': | ||
clearTimeout(pingCheckTimeoutId); | ||
pingCheckTimeoutId = setTimeout(function() { | ||
complete(new Error('Process blocked for too long')); | ||
}, opts.maxBlockDuration); | ||
break; | ||
case 'assertionDone': | ||
log.add('assertions', msg.data); | ||
break; | ||
case 'testDone': | ||
log.add('tests', msg.data); | ||
break; | ||
case 'done': | ||
clearTimeout(pingCheckTimeoutId); | ||
msg.data.code = opts.code.path; | ||
log.add('summaries', msg.data); | ||
if (opts.coverage) { | ||
coverage.add(msg.data.coverage); | ||
msg.data.coverage = coverage.get(); | ||
msg.data.coverage.code = msg.data.code; | ||
log.add('coverages', msg.data.coverage); | ||
} | ||
if (opts.log.testing) { | ||
console.log('done'); | ||
} | ||
complete(null, msg.data); | ||
break; | ||
case 'uncaughtException': | ||
complete(_.extend(new Error(), msg.data)); | ||
break; | ||
} | ||
@@ -96,0 +116,0 @@ }); |
{ | ||
"name": "qunit", | ||
"description": "QUnit testing framework for nodejs", | ||
"version": "0.7.2", | ||
"version": "0.7.3", | ||
"author": "Oleg Slobodskoi <oleg008@gmail.com>", | ||
@@ -6,0 +6,0 @@ "contributors": [ |
320
readme.md
@@ -22,3 +22,5 @@ ## QUnit testing framework for nodejs. | ||
npm i qunit | ||
```bash | ||
$ npm i qunit | ||
``` | ||
@@ -31,5 +33,7 @@ ### API | ||
// Separate tests into modules. | ||
// Use `QUnit` namespace, because `module` is reserved for node. | ||
QUnit.module(name, lifecycle) | ||
```javascript | ||
// Separate tests into modules. | ||
// Use `QUnit` namespace, because `module` is reserved for node. | ||
QUnit.module(name, lifecycle) | ||
``` | ||
@@ -42,5 +46,7 @@ ### Usage | ||
$ qunit -h | ||
```bash | ||
$ qunit -h | ||
$ qunit -c ./code.js -t ./tests.js | ||
$ qunit -c ./code.js -t ./tests.js | ||
``` | ||
@@ -51,127 +57,134 @@ By default, code and dependencies are added to the global scope. To specify | ||
$ qunit -c code:./code.js -d utils:utilmodule -t ./time.js | ||
```bash | ||
$ qunit -c code:./code.js -d utils:utilmodule -t ./time.js | ||
``` | ||
#### via api | ||
var testrunner = require("qunit"); | ||
```javascript | ||
var testrunner = require("qunit"); | ||
Defaults: | ||
// Defaults: | ||
{ | ||
// logging options | ||
log: { | ||
{ | ||
// logging options | ||
log: { | ||
// log assertions overview | ||
assertions: true, | ||
// log assertions overview | ||
assertions: true, | ||
// log expected and actual values for failed tests | ||
errors: true, | ||
// log expected and actual values for failed tests | ||
errors: true, | ||
// log tests overview | ||
tests: true, | ||
// log tests overview | ||
tests: true, | ||
// log summary | ||
summary: true, | ||
// log summary | ||
summary: true, | ||
// log global summary (all files) | ||
globalSummary: true, | ||
// log global summary (all files) | ||
globalSummary: true, | ||
// log coverage | ||
coverage: true, | ||
// log coverage | ||
coverage: true, | ||
// log global coverage (all files) | ||
globalCoverage: true, | ||
// log global coverage (all files) | ||
globalCoverage: true, | ||
// log currently testing code file | ||
testing: true | ||
}, | ||
// log currently testing code file | ||
testing: true | ||
}, | ||
// run test coverage tool | ||
coverage: false, | ||
// run test coverage tool | ||
coverage: false, | ||
// define dependencies, which are required then before code | ||
deps: null, | ||
// define dependencies, which are required then before code | ||
deps: null, | ||
// define namespace your code will be attached to on global['your namespace'] | ||
namespace: null, | ||
// define namespace your code will be attached to on global['your namespace'] | ||
namespace: null | ||
} | ||
// max amount of ms child can be blocked, after that we assume running an infinite loop | ||
maxBlockDuration: 1000 | ||
} | ||
``` | ||
```javascript | ||
// change any option for all tests globally | ||
testrunner.options.optionName = value; | ||
// change any option for all tests globally | ||
testrunner.options.optionName = value; | ||
// or use setup function | ||
testrunner.setup({ | ||
log: { | ||
summary: true | ||
} | ||
}); | ||
// or use setup function | ||
testrunner.setup({ | ||
log: { | ||
summary: true | ||
} | ||
}); | ||
// one code and tests file | ||
testrunner.run({ | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
// one code and tests file | ||
testrunner.run({ | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
// require code into a namespace object, rather than globally | ||
testrunner.run({ | ||
code: {path: "/path/to/your/code.js", namespace: "code"}, | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
// require code into a namespace object, rather than globally | ||
testrunner.run({ | ||
code: {path: "/path/to/your/code.js", namespace: "code"}, | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
// one code and multiple tests file | ||
testrunner.run({ | ||
code: "/path/to/your/code.js", | ||
tests: ["/path/to/your/tests.js", "/path/to/your/tests1.js"] | ||
}, callback); | ||
// one code and multiple tests file | ||
testrunner.run({ | ||
// array of code and test files | ||
testrunner.run([ | ||
{ | ||
code: "/path/to/your/code.js", | ||
tests: ["/path/to/your/tests.js", "/path/to/your/tests1.js"] | ||
}, callback); | ||
// array of code and test files | ||
testrunner.run([ | ||
{ | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, | ||
{ | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
} | ||
], callback); | ||
// using testrunner callback | ||
testrunner.run({ | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, function(err, report) { | ||
console.dir(report); | ||
}); | ||
// specify dependency | ||
testrunner.run({ | ||
deps: "/path/to/your/dependency.js", | ||
}, | ||
{ | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
} | ||
], callback); | ||
// dependencies can be modules or files | ||
testrunner.run({ | ||
deps: "modulename", | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
// using testrunner callback | ||
testrunner.run({ | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, function(err, report) { | ||
console.dir(report); | ||
}); | ||
// dependencies can required into a namespace object | ||
testrunner.run({ | ||
deps: {path: "utilmodule", namespace: "utils"}, | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
// specify dependency | ||
testrunner.run({ | ||
deps: "/path/to/your/dependency.js", | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
// specify multiple dependencies | ||
testrunner.run({ | ||
deps: ["/path/to/your/dependency1.js", "/path/to/your/dependency2.js"], | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
// dependencies can be modules or files | ||
testrunner.run({ | ||
deps: "modulename", | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
// dependencies can required into a namespace object | ||
testrunner.run({ | ||
deps: {path: "utilmodule", namespace: "utils"}, | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
// specify multiple dependencies | ||
testrunner.run({ | ||
deps: ["/path/to/your/dependency1.js", "/path/to/your/dependency2.js"], | ||
code: "/path/to/your/code.js", | ||
tests: "/path/to/your/tests.js" | ||
}, callback); | ||
``` | ||
### Writing tests | ||
@@ -183,67 +196,72 @@ | ||
```javascript | ||
test("a basic test example", function () { | ||
ok(true, "this test is fine"); | ||
var value = "hello"; | ||
equal("hello", value, "We expect value to be hello"); | ||
}); | ||
test("a basic test example", function () { | ||
ok(true, "this test is fine"); | ||
var value = "hello"; | ||
equal("hello", value, "We expect value to be hello"); | ||
}); | ||
QUnit.module("Module A"); | ||
QUnit.module("Module A"); | ||
test("first test within module", 1, function () { | ||
ok(true, "a dummy"); | ||
}); | ||
test("first test within module", 1, function () { | ||
ok(true, "a dummy"); | ||
}); | ||
test("second test within module", 2, function () { | ||
ok(true, "dummy 1 of 2"); | ||
ok(true, "dummy 2 of 2"); | ||
}); | ||
test("second test within module", 2, function () { | ||
ok(true, "dummy 1 of 2"); | ||
ok(true, "dummy 2 of 2"); | ||
}); | ||
QUnit.module("Module B", { | ||
setup: function () { | ||
// do some initial stuff before every test for this module | ||
}, | ||
teardown: function () { | ||
// do some stuff after every test for this module | ||
} | ||
}); | ||
QUnit.module("Module B", { | ||
setup: function () { | ||
// do some initial stuff before every test for this module | ||
}, | ||
teardown: function () { | ||
// do some stuff after every test for this module | ||
} | ||
}); | ||
test("some other test", function () { | ||
expect(2); | ||
equal(true, false, "failing test"); | ||
equal(true, true, "passing test"); | ||
}); | ||
test("some other test", function () { | ||
expect(2); | ||
equal(true, false, "failing test"); | ||
equal(true, true, "passing test"); | ||
}); | ||
QUnit.module("Module C", { | ||
setup: function() { | ||
// setup a shared environment for each test | ||
this.options = { test: 123 }; | ||
} | ||
}); | ||
QUnit.module("Module C", { | ||
setup: function() { | ||
// setup a shared environment for each test | ||
this.options = { test: 123 }; | ||
} | ||
}); | ||
test("this test is using shared environment", 1, function () { | ||
deepEqual({ test: 123 }, this.options, "passing test"); | ||
}); | ||
test("this test is using shared environment", 1, function () { | ||
deepEqual({ test: 123 }, this.options, "passing test"); | ||
}); | ||
test("this is an async test example", function () { | ||
expect(2); | ||
stop(); | ||
setTimeout(function () { | ||
ok(true, "finished async test"); | ||
strictEqual(true, true, "Strict equal assertion uses ==="); | ||
start(); | ||
}, 100); | ||
}); | ||
``` | ||
test("this is an async test example", function () { | ||
expect(2); | ||
stop(); | ||
setTimeout(function () { | ||
ok(true, "finished async test"); | ||
strictEqual(true, true, "Strict equal assertion uses ==="); | ||
start(); | ||
}, 100); | ||
}); | ||
### Generators support | ||
test("my async test with generators", function* () { | ||
var data = yield asyncFn(); | ||
equal(data, {a: 1}, 'generators work'); | ||
}); | ||
```javascript | ||
test("my async test with generators", function* () { | ||
var data = yield asyncFn(); | ||
equal(data, {a: 1}, 'generators work'); | ||
}); | ||
``` | ||
### Run tests | ||
npm i | ||
npm test | ||
```bash | ||
$ npm i | ||
$ npm test | ||
``` | ||
@@ -250,0 +268,0 @@ ### Coverage |
@@ -156,2 +156,12 @@ var a = require('assert'), | ||
chain.add('infinite loop', function() { | ||
tr.run({ | ||
code: fixtures + '/infinite-loop-code.js', | ||
tests: fixtures + '/infinite-loop-test.js', | ||
}, function(err, res) { | ||
a.ok(err instanceof Error, 'error was forwarded'); | ||
chain.next(); | ||
}); | ||
}); | ||
chain.add('coverage', function() { | ||
@@ -158,0 +168,0 @@ tr.options.coverage = true; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
44266
31
1156
266