doctap v0.0.2
console.log(actual) // expected
Functionally test readme snippets.
Transforms markdown code blocks to serially executed tape tests. Use trailing comments to specify the expected result of console.log()
calls and pipe to a TAP reporter of your choice. Requires Node.js 6.8.0+.
usage: doctap [file, ..]
Let's test the snippets in this very readme.
const pkg = require('./package.json')
const floor = Math.floor
console.log('hello') // 'hello'
console.log(pkg.name) // 'doctap'
console.log(floor(1.2)) // 1
doctap *.md
TAP version 13
# readme.md:12
ok 1 'hello' == 'hello'
ok 2 pkg.name == 'doctap'
ok 3 floor(1.2) == 1
Output continued below.
asynchronicity
const glob = require('glob')
glob('*.md', { cwd: __dirname }, (err, files) => {
console.log(files) // ['readme.md']
})
# readme.md:36
ok 4 files == ['readme.md']
comments are javascript too
const name = 'doctap'
console.log(2 * 3) // 2 + 4
console.log('doctap') // name
# readme.md:51
ok 5 2 * 3 == 2 + 4
ok 6 'doctap' == name
repeated calls
for(let value of [1, 2, 3]) {
console.log(value * 2) // 2, 4, 6
}
# readme.md:65
ok 7 value * 2 == 2 1/3
ok 8 value * 2 == 4 2/3
ok 9 value * 2 == 6 3/3
require
As you may have noticed above: require()
is relative to the markdown file.
Provided there's a nearby package.json
, you can also require your own package by name.
const doctap = require('doctap')
shared scope
If one snippet declares a variable in the top-most scope (like glob
above), subsequent snippets can reference it. This is most useful to require shared things in your first snippet, and avoid repeating yourself.
console.log(glob.sync('*.md')) // ['readme.md']
# readme.md:92
ok 10 glob.sync('*.md') == ['readme.md']
matches your style
console.log('hello') // 'hello'
console.log("world") // `world`
# readme.md:103
ok 11 'hello' == 'hello'
ok 12 "world" == `world`
multiple arguments
console.log('hello %s', 'world') // 'hello world'
console.log(1, 2) // '1 2'
# readme.md:116
ok 13 'hello %s', 'world' == 'hello world'
ok 14 1, 2 == '1 2'
errors
An attempt is made to rewrite stack traces, but it's not effective in all places right now, and not applied to failing tape
assertions either.
function please () {
throw new Error('no')
}
console.log(false) // true
console.log(please())
# readme.md:131
not ok 15 false == true
---
operator: deepEqual
expected: true
actual: false
at: Test.test (/doctap/readme131.js:26:11)
...
/doctap/readme131.js:19
throw new Error('no')
^
Error: no
at please (/doctap/readme.md:133:9)
at Test.test (/doctap/readme.md:137:13)
at Test.bound [as _cb] (/doctap/node_modules/tape/lib/test.js:65:32)
at ...
install
With npm do:
npm install doctap --global
license
MIT © Vincent Weevers
8 years ago