├── .gitignore
├── .npmignore
├── LICENSE.md
├── README.md
├── demo
└── index.html
├── index.js
├── lib
└── is-tap-string.js
├── package.json
├── register.js
├── test
├── test-instrument-fail.js
├── test-instrument-pass.js
└── test-plugin.js
└── tool
└── build.js
/.gitignore:
--------------------------------------------------------------------------------
1 | bower_components
2 | node_modules
3 | *.log
4 | .DS_Store
5 | bundle.js
6 | dist
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | bower_components
2 | node_modules
3 | *.log
4 | .DS_Store
5 | bundle.js
6 | test
7 | test.js
8 | demo/
9 | .npmignore
10 | LICENSE.md
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2015 Jam3
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tap-dev-tool
2 |
3 | [](http://github.com/badges/stability-badges)
4 |
5 | [(Click for a live demo)](https://jam3.github.io/tap-dev-tool/demo/)
6 |
7 | Prettify TAP output in Chrome/FireFox DevTools console. Works best with [tape](https://www.npmjs.com/package/tape).
8 |
9 | 
10 |
11 | Comes in the form of a Browserify plugin, so you don't need to change your source code during development. PRs for other integrations (Babel, Webpack) welcome.
12 |
13 | ## Install
14 |
15 | You can install with [npm](https://www.npmjs.com/):
16 |
17 | ```sh
18 | npm install tap-dev-tool --save-dev
19 | ```
20 |
21 | ## Usage
22 |
23 | [](https://www.npmjs.com/package/tap-dev-tool)
24 |
25 | ### browserify
26 |
27 | The preferred way of using this is with a plugin during development. After installing, you can use it with browserify like this:
28 |
29 | ```sh
30 | browserify index.js --plugin tap-dev-tool > bundle.js
31 | ```
32 |
33 | Works well during development with [watchify](https://github.com/substack/watchify) and [budo](https://github.com/mattdesl/budo).
34 |
35 | ### require hook
36 |
37 | If you don't want to use the plugin, you can require the tool somewhere at the start of your application.
38 |
39 | ```js
40 | require('tap-dev-tool/register')
41 |
42 | var test = require('tape')
43 |
44 | test('should do something', function (t) {
45 | ...
46 | })
47 | ```
48 |
49 | ## See Also
50 |
51 | - [budo](https://github.com/mattdesl/budo) - fast browser development
52 | - [hihat](https://github.com/Jam3/hihat) - launches DevTools in a new process
53 | - [tap-browser-el](https://www.npmjs.com/package/tap-browser-el)
54 | - [tap-browser-color](https://www.npmjs.com/package/tap-browser-color)
55 | - [tap-console-parser](https://www.npmjs.com/package/tap-console-parser)
56 |
57 | ## License
58 |
59 | MIT, see [LICENSE.md](http://github.com/Jam3/tap-dev-tool/blob/master/LICENSE.md) for details.
60 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | tap-dev-tool
7 |
8 |
9 | Open the console and reload the page!
10 |
11 |
12 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var through = require('through2')
2 | var fs = require('fs')
3 | var path = require('path')
4 |
5 | var build = path.join(__dirname, 'dist', 'build.js')
6 | var prelude = fs.readFileSync(build)
7 |
8 | module.exports = function tapDevTool (b) {
9 | var written = false
10 | var bundle = b.bundle.bind(b)
11 | b.bundle = function (cb) {
12 | written = false
13 |
14 | var output = through(write)
15 | var pipeline = bundle(cb)
16 | pipeline.pipe(output)
17 | pipeline.on('error', function (err) {
18 | output.emit('error', err)
19 | })
20 | return output
21 | }
22 |
23 | function write (buf, enc, next) {
24 | if (!written) {
25 | this.push(prelude)
26 | written = true
27 | }
28 | this.push(buf)
29 | next()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/is-tap-string.js:
--------------------------------------------------------------------------------
1 | module.exports = function isTapString (str) {
2 | return /^\s*(not )?ok/.test(str) ||
3 | /^TAP version [0-9]+/.test(str) ||
4 | /^[0-9]+\.\.[0-9]+/.test(str) ||
5 | /^\s+(\.\.\.)|(\-\-\-)$/.test(str) ||
6 | /^\s*(actual|operator|expected|at)\:/.test(str) ||
7 | /^\#\s/.test(str)
8 | }
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tap-dev-tool",
3 | "version": "1.3.0",
4 | "description": "prettifies TAP in the browser's console",
5 | "main": "index.js",
6 | "license": "MIT",
7 | "author": {
8 | "name": "Matt DesLauriers",
9 | "email": "dave.des@gmail.com",
10 | "url": "https://github.com/mattdesl"
11 | },
12 | "dependencies": {
13 | "tap-console-parser": "^1.0.2",
14 | "through2": "^0.6.5"
15 | },
16 | "devDependencies": {
17 | "browserify": "^10.2.3",
18 | "budo": "^4.0.0",
19 | "garnish": "^2.1.3",
20 | "standard": "^4.2.0",
21 | "tape": "^4.0.0",
22 | "uglify-js": "^2.4.23"
23 | },
24 | "scripts": {
25 | "test": "standard",
26 | "uglify": "browserify register.js | uglifyjs > dist/build.js",
27 | "build": "npm run uglify && node tool/build.js",
28 | "build-demo": "browserify test/test-plugin.js -p ./ | uglifyjs -cm > demo/bundle.js",
29 | "prepublish": "npm run build",
30 | "start": "budo test/test-plugin.js:bundle.js --dir demo --live --verbose -p ./ | garnish"
31 | },
32 | "standard": {
33 | "ignore": [
34 | "./dist/*.js"
35 | ]
36 | },
37 | "keywords": [
38 | "tap",
39 | "browser",
40 | "visualize",
41 | "tape",
42 | "test",
43 | "tests",
44 | "console",
45 | "log",
46 | "pretty",
47 | "css",
48 | "color",
49 | "colors",
50 | "colour",
51 | "colours"
52 | ],
53 | "repository": {
54 | "type": "git",
55 | "url": "git://github.com/Jam3/tap-dev-tool.git"
56 | },
57 | "homepage": "https://github.com/Jam3/tap-dev-tool",
58 | "bugs": {
59 | "url": "https://github.com/Jam3/tap-dev-tool/issues"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/register.js:
--------------------------------------------------------------------------------
1 | var fails = []
2 | var tests = {}
3 | var start = null
4 | var isTAP = require('./lib/is-tap-string')
5 | var previousLog = ''
6 |
7 | var parser = require('tap-console-parser')()
8 | .on('complete', function (output) {
9 | var time = Date.now() - start
10 | parser.detach()
11 | console.log('\n')
12 |
13 | if (!output.ok) {
14 | console.log('%c\nFailing Tests: ' + output.fail, 'font-weight: bold')
15 | Object.keys(tests).forEach(function (key) {
16 | var test = tests[key]
17 | var asserts = fails[key] || []
18 | if (asserts.length === 0) {
19 | return
20 | }
21 |
22 | console.log('%c ' + test.name, 'color: gray')
23 |
24 | asserts.forEach(function (fail) {
25 | console.log('%c ⨯ ' + fail.name, 'font-weight: bold; color: #c32b2b')
26 |
27 | console.log('%c ---', '')
28 | var str = fail.error.raw
29 | .split('\n')
30 | .map(function (x) {
31 | return ' ' + x
32 | })
33 | .join('\n')
34 |
35 | console.log(str)
36 | console.log('%c ...', '')
37 | })
38 | })
39 | console.log('')
40 | }
41 |
42 | if (output.ok) {
43 | console.log('%c✓ ok', 'color: white; padding: 1px 10px; background: #8eca6c; font-weight: bold')
44 | } else {
45 | console.log('%c⨯ not ok', 'color: white; padding: 1px 10px; background: #c32b2b; font-weight: not ok')
46 | }
47 | if (!output.ok) {
48 | console.log('%c total: ' + output.total, 'font-weight: bold')
49 | }
50 | console.log('%c passing: ' + output.pass, 'color: #72b432; font-weight: bold')
51 | if (!output.ok) {
52 | console.log('%c failing: ' + output.fail, 'color: #c32b2b; font-weight: bold')
53 | }
54 | console.log('%c duration: ' + time + ' ms', 'color: gray')
55 |
56 | start = null
57 | })
58 | .on('assert', function (assert) {
59 | if (assert.ok) {
60 | parser.log('%c ✓', 'color: #8eca6c', assert.name)
61 | } else {
62 | if (fails[assert.test]) {
63 | fails[assert.test].push(assert)
64 | } else {
65 | fails[assert.test] = [ assert ]
66 | }
67 |
68 | parser.log('%c ⨯ ' + assert.name, 'color: #c32b2b; font-weight: bold')
69 | }
70 | })
71 | .on('test', function (test) {
72 | if (start === null) {
73 | start = Date.now()
74 | } else {
75 | parser.log('')
76 | }
77 | parser.log('%c' + test.name, 'color: gray')
78 | tests[test.number] = test
79 | })
80 | .on('log', function (args) {
81 | // allow comments to print as per normal
82 | var str = args.join(' ')
83 | if (str && !isTAP(str)) {
84 | if (!previousLog || !/^\s*(expected|actual|at)\:\s*$/.test(previousLog)) {
85 | parser.log.apply(null, args)
86 | }
87 | }
88 | previousLog = str
89 | })
90 |
--------------------------------------------------------------------------------
/test/test-instrument-fail.js:
--------------------------------------------------------------------------------
1 | require('../register')
2 |
3 | var test = require('tape')
4 |
5 | console.log('This is a regular comment', { foo: 2 })
6 |
7 | test('should test things', function (t) {
8 | t.plan(4)
9 | t.deepEqual([ 2, 3 ], [ 2, 3 ])
10 | t.deepEqual(2, 5)
11 | t.equal('hello', 5)
12 | t.throws(function () {
13 | throw new Error('FOO')
14 | }, 'yep it throws')
15 | })
16 |
17 | test('even more testing of things', function (t) {
18 | t.ok(false, 'this is not ok')
19 | t.end()
20 | })
21 |
--------------------------------------------------------------------------------
/test/test-instrument-pass.js:
--------------------------------------------------------------------------------
1 | require('../register')
2 |
3 | var test = require('tape')
4 |
5 | test('should test things', function (t) {
6 | t.plan(4)
7 | t.deepEqual([ 2, 3 ], [ 2, 3 ])
8 | setTimeout(function () {
9 | t.deepEqual(5, 5)
10 | }, 1000)
11 | t.equal('hello', 'hello')
12 | t.throws(function () {
13 | throw new Error('FOO')
14 | }, 'yep it throws')
15 | })
16 |
17 | test('even more testing of things', function (t) {
18 | t.ok(true, 'this is ok')
19 | t.end()
20 | })
21 |
--------------------------------------------------------------------------------
/test/test-plugin.js:
--------------------------------------------------------------------------------
1 | var test = require('tape')
2 |
3 | test('should test things', function (t) {
4 | t.plan(4)
5 | t.deepEqual([ 2, 3 ], [ 2, 3 ])
6 | setTimeout(function () {
7 | t.deepEqual(5, 5)
8 | }, 1000)
9 | t.equal('hello', 'hello')
10 | t.throws(function () {
11 | throw new Error('FOO')
12 | }, 'yep it throws')
13 | })
14 |
15 | test('even more testing of things', function (t) {
16 | t.ok(true, 'this is ok')
17 | t.end()
18 | })
19 |
--------------------------------------------------------------------------------
/tool/build.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs')
2 | var path = require('path')
3 |
4 | var file = path.resolve(__dirname, '../', 'dist', 'build.js')
5 | fs.readFile(file, 'utf8', function (err, data) {
6 | if (err) throw err
7 | data = data.replace(/[\n\r]/g, '')
8 | fs.writeFile(file, data, function (err) {
9 | if (err) throw err
10 | })
11 | })
12 |
--------------------------------------------------------------------------------