parent
08c3b291c6
commit
78eeb2b365
4 changed files with 121 additions and 6 deletions
|
|
@ -32,6 +32,7 @@
|
||||||
#### Ospec improvements:
|
#### Ospec improvements:
|
||||||
|
|
||||||
- Added support for async functions and promises in tests - ([#1928](https://github.com/MithrilJS/mithril.js/pull/1928))
|
- Added support for async functions and promises in tests - ([#1928](https://github.com/MithrilJS/mithril.js/pull/1928))
|
||||||
|
- Added support for custom reporters ([#2009](https://github.com/MithrilJS/mithril.js/pull/2020))
|
||||||
- Error handling for async tests with `done` callbacks supports error as first argument
|
- Error handling for async tests with `done` callbacks supports error as first argument
|
||||||
- Error messages which include newline characters do not swallow the stack trace ([#1495](https://github.com/MithrilJS/mithril.js/issues/1495))
|
- Error messages which include newline characters do not swallow the stack trace ([#1495](https://github.com/MithrilJS/mithril.js/issues/1495))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ Noiseless testing framework
|
||||||
- `before`/`after`/`beforeEach`/`afterEach` hooks
|
- `before`/`after`/`beforeEach`/`afterEach` hooks
|
||||||
- test exclusivity (i.e. `.only`)
|
- test exclusivity (i.e. `.only`)
|
||||||
- async tests and hooks
|
- async tests and hooks
|
||||||
- explicitly disallows test-space configuration to encourage focus on testing, and to provide uniform test suites across projects
|
- explicitly regulates test-space configuration to encourage focus on testing, and to provide uniform test suites across projects
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
|
@ -437,9 +437,17 @@ The arguments that were passed to the function in the last time it was called
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### void o.run()
|
### void o.run([Function reporter])
|
||||||
|
|
||||||
Runs the test suite
|
Runs the test suite. By default passing test results are printed using
|
||||||
|
`console.log` and failing test results are printed using `console.error`.
|
||||||
|
|
||||||
|
If you have custom continuous integration needs then you can use a
|
||||||
|
reporter to process [test result data](#result-data) yourself.
|
||||||
|
|
||||||
|
If running in Node.js, ospec will call `process.exit` after reporting
|
||||||
|
results by default. If you specify a reporter, ospec will not do this
|
||||||
|
and allow your reporter to respond to results in its own way.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -455,6 +463,74 @@ $o("a test", function() {
|
||||||
$o.run()
|
$o.run()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Result data
|
||||||
|
|
||||||
|
Test results are available by reference for integration purposes. You
|
||||||
|
can use custom reporters in `o.run()` to process these results.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
o.run(function(results) {
|
||||||
|
// results is an array
|
||||||
|
|
||||||
|
results.forEach(function(result) {
|
||||||
|
// ...
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Boolean result.pass
|
||||||
|
|
||||||
|
True if the test passed. **No other keys will exist on the result if this value is true.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Error result.error
|
||||||
|
|
||||||
|
The value of the stack property from the `Error` object explaining the reason behind a failure.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### String result.message
|
||||||
|
|
||||||
|
If an exception was thrown inside the corresponding test, this will equal that Error's `message`. Otherwise, this will be a preformatted message in [SVO form](https://en.wikipedia.org/wiki/Subject%E2%80%93verb%E2%80%93object). More specifically, `${subject}\n${verb}\n${object}`.
|
||||||
|
|
||||||
|
As an example, the following test's result message will be `"false\nshould equal\ntrue"`.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
o.spec("message", function() {
|
||||||
|
o(false).equals(true)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
If you specify an assertion description, that description will appear two lines above the subject.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
o.spec("message", function() {
|
||||||
|
o(false).equals(true)("Candyland") // result.message === "Candyland\n\nfalse\nshould equal\ntrue"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### String result.context
|
||||||
|
|
||||||
|
A `>`-separated string showing the structure of the test specification.
|
||||||
|
In the below example, `result.context` would be `testing > rocks`.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
o.spec("testing", function() {
|
||||||
|
o.spec("rocks", function() {
|
||||||
|
o(false).equals(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|
@ -462,8 +538,8 @@ $o.run()
|
||||||
- Do the most common things that the mocha/chai/sinon triad does without having to install 3 different libraries and several dozen dependencies
|
- Do the most common things that the mocha/chai/sinon triad does without having to install 3 different libraries and several dozen dependencies
|
||||||
- Disallow configuration in test-space:
|
- Disallow configuration in test-space:
|
||||||
- Disallow ability to pick between API styles (BDD/TDD/Qunit, assert/should/expect, etc)
|
- Disallow ability to pick between API styles (BDD/TDD/Qunit, assert/should/expect, etc)
|
||||||
- Disallow ability to pick between different reporters
|
|
||||||
- Disallow ability to add custom assertion types
|
- Disallow ability to add custom assertion types
|
||||||
|
- Provide a default simple reporter
|
||||||
- Make assertion code terse, readable and self-descriptive
|
- Make assertion code terse, readable and self-descriptive
|
||||||
- Have as few assertion types as possible for a workable usage pattern
|
- Have as few assertion types as possible for a workable usage pattern
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"use strict"
|
"use strict"
|
||||||
|
|
||||||
module.exports = new function init(name) {
|
module.exports = new function init(name) {
|
||||||
var spec = {}, subjects = [], results, only = null, ctx = spec, start, stack = 0, nextTickish, hasProcess = typeof process === "object", hasOwn = ({}).hasOwnProperty
|
var spec = {}, subjects = [], results, only = null, ctx = spec, start, stack = 0, nextTickish, hasProcess = typeof process === "object", reporter, hasOwn = ({}).hasOwnProperty
|
||||||
|
|
||||||
if (name != null) spec[name] = ctx = {}
|
if (name != null) spec[name] = ctx = {}
|
||||||
|
|
||||||
|
|
@ -52,9 +52,10 @@ module.exports = new function init(name) {
|
||||||
o.cleanStackTrace = function(stack) {
|
o.cleanStackTrace = function(stack) {
|
||||||
return stack.match(/^(?:(?!Error|[\/\\]ospec[\/\\]ospec\.js).)*$/gm).pop()
|
return stack.match(/^(?:(?!Error|[\/\\]ospec[\/\\]ospec\.js).)*$/gm).pop()
|
||||||
}
|
}
|
||||||
o.run = function() {
|
o.run = function(_reporter) {
|
||||||
results = []
|
results = []
|
||||||
start = new Date
|
start = new Date
|
||||||
|
reporter = _reporter
|
||||||
test(spec, [], [], report)
|
test(spec, [], [], report)
|
||||||
|
|
||||||
function test(spec, pre, post, finalize) {
|
function test(spec, pre, post, finalize) {
|
||||||
|
|
@ -236,6 +237,9 @@ module.exports = new function init(name) {
|
||||||
|
|
||||||
function report() {
|
function report() {
|
||||||
var status = 0
|
var status = 0
|
||||||
|
|
||||||
|
if (typeof reporter === "function") return reporter(results)
|
||||||
|
|
||||||
for (var i = 0, r; r = results[i]; i++) {
|
for (var i = 0, r; r = results[i]; i++) {
|
||||||
if (!r.pass) {
|
if (!r.pass) {
|
||||||
var stackTrace = o.cleanStackTrace(r.error)
|
var stackTrace = o.cleanStackTrace(r.error)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,40 @@ new function(o) {
|
||||||
o.run()
|
o.run()
|
||||||
}(o)
|
}(o)
|
||||||
|
|
||||||
|
new function(o) {
|
||||||
|
var clone = o.new()
|
||||||
|
|
||||||
|
clone.spec("clone", function() {
|
||||||
|
clone("fail", function() {
|
||||||
|
clone(true).equals(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
clone("pass", function() {
|
||||||
|
clone(true).equals(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Predicate test passing on clone results
|
||||||
|
o.spec("reporting", function() {
|
||||||
|
o("reports per instance", function(done, timeout) {
|
||||||
|
timeout(100) // Waiting on clone
|
||||||
|
|
||||||
|
clone.run(function(results) {
|
||||||
|
o(typeof results).equals("object")
|
||||||
|
o("length" in results).equals(true)
|
||||||
|
o(results.length).equals(2)("Two results")
|
||||||
|
|
||||||
|
o("error" in results[0] && "pass" in results[0]).equals(true)("error and pass keys present in failing result")
|
||||||
|
o(!("error" in results[1]) && "pass" in results[1]).equals(true)("only pass key present in passing result")
|
||||||
|
o(results[0].pass).equals(false)("Test meant to fail has failed")
|
||||||
|
o(results[1].pass).equals(true)("Test meant to pass has passed")
|
||||||
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}(o)
|
||||||
|
|
||||||
o.spec("ospec", function() {
|
o.spec("ospec", function() {
|
||||||
o.spec("sync", function() {
|
o.spec("sync", function() {
|
||||||
var a = 0, b = 0, illegalAssertionThrows = false
|
var a = 0, b = 0, illegalAssertionThrows = false
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue