Skip to content

Commit cbd6123

Browse files
committed
Add Mocha-style multi-line string diffs.
Instead of using eyes for strings, use diff to present a colored diff of the expected vs. actual results.
1 parent 6aa9673 commit cbd6123

File tree

2 files changed

+123
-18
lines changed

2 files changed

+123
-18
lines changed

lib/assert/error.js

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,52 @@
11
var stylize = require('../vows/console').stylize;
22
var inspect = require('../vows/console').inspect;
3+
var diff = require('diff');
4+
5+
/**
6+
* Pad the given `str` to `len`.
7+
*
8+
* @param {String} str
9+
* @param {String} len
10+
* @return {String}
11+
* @api private
12+
*/
13+
14+
function pad(str, len) {
15+
str = String(str);
16+
return Array(len - str.length + 1).join(' ') + str;
17+
}
18+
19+
/**
20+
* Color lines for `str`, using the color `name`.
21+
*
22+
* @param {String} name
23+
* @param {String} str
24+
* @return {String}
25+
* @api private
26+
*/
27+
28+
function styleLines(str, name) {
29+
return str.split('\n').map(function(str){
30+
return stylize(str, name);
31+
}).join('\n');
32+
}
33+
34+
/**
35+
* Return a character diff for `err`.
36+
*
37+
* @param {Error} err
38+
* @return {String}
39+
* @api private
40+
*/
41+
42+
function errorDiff(err, type) {
43+
return diff['diff' + type](err.actual, err.expected).map(function(str){
44+
if (/^(\n+)$/.test(str.value)) str.value = Array(++RegExp.$1.length).join('<newline>');
45+
if (str.added) return styleLines(str.value, 'green');
46+
if (str.removed) return styleLines(str.value, 'red');
47+
return str.value;
48+
}).join('');
49+
}
350

451
require('assert').AssertionError.prototype.toString = function () {
552
var that = this,
@@ -10,14 +57,50 @@ require('assert').AssertionError.prototype.toString = function () {
1057
}
1158

1259
function parse(str) {
13-
var actual = inspect(that.actual, {showHidden: that.actual instanceof Error}),
14-
expected;
60+
var actual = that.actual,
61+
expected = that.expected,
62+
msg, len;
63+
64+
if (
65+
'string' === typeof actual &&
66+
'string' === typeof expected
67+
) {
68+
len = Math.max(actual.length, expected.length);
69+
70+
if (len < 20) msg = errorDiff(that, 'Chars');
71+
else msg = errorDiff(that, 'Words');
72+
73+
// linenos
74+
var lines = msg.split('\n');
75+
if (lines.length > 4) {
76+
var width = String(lines.length).length;
77+
msg = lines.map(function(str, i){
78+
return pad(++i, width) + ' |' + ' ' + str;
79+
}).join('\n');
80+
}
81+
82+
// legend
83+
msg = '\n'
84+
+ stylize('actual', 'green')
85+
+ ' '
86+
+ stylize('expected', 'red')
87+
+ '\n\n'
88+
+ msg
89+
+ '\n';
90+
91+
// indent
92+
msg = msg.replace(/^/gm, ' ');
93+
94+
return msg;
95+
}
96+
97+
actual = inspect(actual, {showHidden: actual instanceof Error});
1598

16-
if (that.expected instanceof Function) {
17-
expected = that.expected.name;
99+
if (expected instanceof Function) {
100+
expected = expected.name;
18101
}
19102
else {
20-
expected = inspect(that.expected, {showHidden: that.actual instanceof Error});
103+
expected = inspect(expected, {showHidden: actual instanceof Error});
21104
}
22105

23106
return str.replace(/{actual}/g, actual).

package.json

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,37 @@
11
{
2-
"name" : "vows",
3-
"description" : "Asynchronous BDD & continuous integration for node.js",
4-
"url" : "http://vowsjs.org",
5-
"keywords" : ["testing", "spec", "test", "BDD"],
6-
"author" : "Alexis Sellier <self@cloudhead.net>",
7-
"contributors" : [{ "name": "Charlie Robbins", "email": "charlie.robbins@gmail.com" }],
8-
"dependencies" : {"eyes": ">=0.1.6"},
9-
"main" : "./lib/vows",
10-
"bin" : { "vows": "./bin/vows" },
11-
"directories" : { "test": "./test", "bin": "./bin" },
12-
"version" : "0.6.2",
13-
"scripts" : {"test": "./bin/vows --spec"},
14-
"engines" : {"node": ">=0.2.6"}
2+
"name": "vows",
3+
"description": "Asynchronous BDD & continuous integration for node.js",
4+
"url": "http://vowsjs.org",
5+
"keywords": [
6+
"testing",
7+
"spec",
8+
"test",
9+
"BDD"
10+
],
11+
"author": "Alexis Sellier <self@cloudhead.net>",
12+
"contributors": [
13+
{
14+
"name": "Charlie Robbins",
15+
"email": "charlie.robbins@gmail.com"
16+
}
17+
],
18+
"dependencies": {
19+
"eyes": ">=0.1.6",
20+
"diff": "~1.0.3"
21+
},
22+
"main": "./lib/vows",
23+
"bin": {
24+
"vows": "./bin/vows"
25+
},
26+
"directories": {
27+
"test": "./test",
28+
"bin": "./bin"
29+
},
30+
"version": "0.6.2",
31+
"scripts": {
32+
"test": "./bin/vows --spec"
33+
},
34+
"engines": {
35+
"node": ">=0.2.6"
36+
}
1537
}

0 commit comments

Comments
 (0)