Release 0.5.2

This commit is contained in:
Jake Luer 2012-03-21 07:16:37 -04:00
parent 5124aed0a1
commit 644cc43629
10 changed files with 284 additions and 61 deletions

View file

@ -1,4 +1,14 @@
0.5.2 / 2012-03-21
==================
* browser build
* Merge branch 'feature/assert-fail'
* Added assert.fail. Closes #40
* Merge branch 'bug/operator-msg'
* better error message for assert.operator. Closes #39
* version notes
0.5.1 / 2012-03-14
==================

View file

@ -1079,7 +1079,7 @@ require.register("chai.js", function(module, exports, require){
var used = [];
var exports = module.exports = {};
exports.version = '0.5.1';
exports.version = '0.5.2';
exports.Assertion = require('./assertion');
exports.AssertionError = require('./error');

View file

@ -1079,7 +1079,7 @@ require.register("chai.js", function(module, exports, require){
var used = [];
var exports = module.exports = {};
exports.version = '0.5.1';
exports.version = '0.5.2';
exports.Assertion = require('./assertion');
exports.AssertionError = require('./error');
@ -1187,6 +1187,29 @@ module.exports = function (chai) {
var assert = chai.assert = {};
/**
* # .fail(actual, expect, msg, operator)
*
* Throw a failure. Node.js compatible.
*
* @name fail
* @param {*} actual value
* @param {*} expected value
* @param {String} message
* @param {String} operator
* @api public
*/
assert.fail = function (actual, expected, message, operator) {
throw new chai.AssertionError({
actual: actual
, expected: expected
, message: message
, operator: operator
, stackStartFunction: assert.fail
});
}
/**
* # .ok(object, [message])
*
@ -1714,7 +1737,11 @@ module.exports = function (chai) {
if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) {
throw new Error('Invalid operator "' + operator + '"');
}
new Assertion(eval(val + operator + val2), msg).to.be.true;
var test = new Assertion(eval(val + operator + val2), msg);
test.assert(
true === test.obj
, 'expected ' + inspect(val) + ' to be ' + operator + ' ' + inspect(val2)
, 'expected ' + inspect(val) + ' to not be ' + operator + ' ' + inspect(val2) );
};
/*!

View file

@ -42,6 +42,8 @@ _gaq.push(['_trackPageview']);
<div class="antiscroll-inner">
<div class="box-inner">
<ul class="sections">
<li class="keepcase"><a href="#fail" class="scroll">fail</a>
</li>
<li class="keepcase"><a href="#ok" class="scroll">ok</a>
</li>
<li class="keepcase"><a href="#equal" class="scroll">equal</a>
@ -183,6 +185,43 @@ _gaq.push(['_trackPageview']);
</pre>
</div>
</article>
<article id="fail-section" class="codeblock">
<div class="header"><h1>.fail(actual, expect, msg, operator)</h1>
</div>
<div class="ctx">
<h3>assert.fail()
</h3>
</div>
<div class="tags">
<!-- ignroing this-->
<div class="tag"><span class="type">&#64;param</span><span class="types">&#123; * &#125;</span><span class="name">actual</span><span class="desc">value</span>
</div>
<div class="tag"><span class="type">&#64;param</span><span class="types">&#123; * &#125;</span><span class="name">expected</span><span class="desc">value</span>
</div>
<div class="tag"><span class="type">&#64;param</span><span class="types">&#123; String &#125;</span><span class="name">message</span><span class="desc"></span>
</div>
<div class="tag"><span class="type">&#64;param</span><span class="types">&#123; String &#125;</span><span class="name">operator</span><span class="desc"></span>
</div>
<div class="tag"><span class="type">&#64;api</span><span class="visibility">public</span>
</div>
</div>
<div class="description"><p>Throw a failure. Node.js compatible.</p>
</div>
<div class="view-source">View Source
</div>
<div class="code-wrap">
<pre class="source prettyprint"><code>assert.fail = function (actual, expected, message, operator) {
throw new chai.AssertionError({
actual: actual
, expected: expected
, message: message
, operator: operator
, stackStartFunction: assert.fail
});
}</code>
</pre>
</div>
</article>
<article id="ok-section" class="codeblock">
<div class="header"><h1>.ok(object, [message])</h1>
</div>
@ -1074,7 +1113,11 @@ _gaq.push(['_trackPageview']);
if (!~['==', '===', '&gt;', '&gt;=', '&lt;', '&lt;=', '!=', '!=='].indexOf(operator)) {
throw new Error('Invalid operator &quot;' + operator + '&quot;');
}
new Assertion(eval(val + operator + val2), msg).to.be.true;
var test = new Assertion(eval(val + operator + val2), msg);
test.assert(
true === test.obj
, 'expected ' + inspect(val) + ' to be ' + operator + ' ' + inspect(val2)
, 'expected ' + inspect(val) + ' to not be ' + operator + ' ' + inspect(val2) );
};</code>
</pre>
</div>

File diff suppressed because one or more lines are too long

View file

@ -26,6 +26,12 @@ suite('assert', function () {
assert.match(chai.version, /^\d+\.\d+\.\d+$/ );
});
test('fail', function () {
chai.expect(function () {
assert.fail();
}).to.throw(chai.AssertionError);
});
test('isTrue', function () {
assert.isTrue(true);
@ -296,30 +302,30 @@ suite('assert', function () {
err(function () {
assert.operator(2, '<', 1);
}, "expected false to be true");
}, "expected 2 to be < 1");
err(function () {
assert.operator(1, '>', 2);
}, "expected false to be true");
}, "expected 1 to be > 2");
err(function () {
assert.operator(1, '==', 2);
}, "expected false to be true");
}, "expected 1 to be == 2");
err(function () {
assert.operator(2, '<=', 1);
}, "expected false to be true");
}, "expected 2 to be <= 1");
err(function () {
assert.operator(1, '>=', 2);
}, "expected false to be true");
}, "expected 1 to be >= 2");
err(function () {
assert.operator(1, '!=', 1);
}, "expected false to be true");
}, "expected 1 to be != 1");
err(function () {
assert.operator(1, '!==', '1');
}, "expected false to be true");
}, "expected 1 to be !== \'1\'");
});
});

View file

@ -9,11 +9,13 @@ body {
}
#mocha h1 {
margin-top: 15px;
font-size: 1em;
font-weight: 200;
}
#mocha .suite .suite h1 {
margin-top: 0;
font-size: .8em;
}

View file

@ -57,6 +57,10 @@ module.exports = function(type){
};
}); // module: browser/debug.js
require.register("browser/diff.js", function(module, exports, require){
}); // module: browser/diff.js
require.register("browser/events.js", function(module, exports, require){
/**
@ -854,7 +858,7 @@ require.register("mocha.js", function(module, exports, require){
* Library version.
*/
exports.version = '0.13.0';
exports.version = '0.14.0';
exports.utils = require('./utils');
exports.interfaces = require('./interfaces');
@ -874,7 +878,8 @@ require.register("reporters/base.js", function(module, exports, require){
* Module dependencies.
*/
var tty = require('browser/tty');
var tty = require('browser/tty')
, diff = require('browser/diff');
/**
* Check if both stdio streams are associated with a tty.
@ -915,6 +920,9 @@ exports.colors = {
, 'slow': 31
, 'green': 32
, 'light': 90
, 'diff gutter': 90
, 'diff added': 42
, 'diff removed': 41
};
/**
@ -1002,7 +1010,41 @@ exports.list = function(failures){
, message = err.message || ''
, stack = err.stack || message
, index = stack.indexOf(message) + message.length
, msg = stack.slice(0, index);
, msg = stack.slice(0, index)
, actual = err.actual
, expected = err.expected;
// actual / expected diff
if ('string' == typeof actual && 'string' == typeof expected) {
var len = Math.max(actual.length, expected.length);
if (len < 20) msg = errorDiff(err, 'Chars');
else msg = errorDiff(err, 'Words');
// linenos
var lines = msg.split('\n');
if (lines.length > 4) {
var width = String(lines.length).length;
msg = lines.map(function(str, i){
return pad(++i, width) + ' |' + ' ' + str;
}).join('\n');
}
// legend
msg = '\n'
+ color('diff removed', 'actual')
+ ' '
+ color('diff added', 'expected')
+ '\n\n'
+ msg
+ '\n';
// indent
msg = msg.replace(/^/gm, ' ');
fmt = color('error title', ' %s) %s:\n%s')
+ color('error stack', '\n%s\n');
}
// indent stack trace without msg
stack = stack.slice(index + 1)
@ -1106,6 +1148,51 @@ Base.prototype.epilogue = function(){
console.log();
};
/**
* Pad the given `str` to `len`.
*
* @param {String} str
* @param {String} len
* @return {String}
* @api private
*/
function pad(str, len) {
str = String(str);
return Array(len - str.length + 1).join(' ') + str;
}
/**
* Return a character diff for `err`.
*
* @param {Error} err
* @return {String}
* @api private
*/
function errorDiff(err, type) {
return diff['diff' + type](err.actual, err.expected).map(function(str){
if (str.added) return colorLines('diff added', str.value);
if (str.removed) return colorLines('diff removed', str.value);
return str.value;
}).join('');
}
/**
* Color lines for `str`, using the color `name`.
*
* @param {String} name
* @param {String} str
* @return {String}
* @api private
*/
function colorLines(name, str) {
return str.split('\n').map(function(str){
return color(name, str);
}).join('\n');
}
}); // module: reporters/base.js
require.register("reporters/doc.js", function(module, exports, require){
@ -1337,15 +1424,17 @@ var statsTemplate = '<ul id="stats">'
function HTML(runner) {
Base.call(this, runner);
// TODO: clean up
var self = this
, stats = this.stats
, total = runner.total
, root = $('#mocha')
, root = document.getElementById('mocha')
, stat = fragment(statsTemplate)
, items = stat.getElementsByTagName('li')
, passes = items[1].getElementsByTagName('em')[0]
, failures = items[2].getElementsByTagName('em')[0]
, duration = items[3].getElementsByTagName('em')[0]
, canvas = stat.getElementsByTagName('canvas')[0]
, stack = [root]
, stat = $(statsTemplate).appendTo(root)
, canvas = stat.find('canvas').get(0)
, progress
, ctx
@ -1354,7 +1443,9 @@ function HTML(runner) {
progress = new Progress;
}
if (!root.length) return error('#mocha div missing, add it to your document');
if (!root) return error('#mocha div missing, add it to your document');
root.appendChild(stat);
if (progress) progress.size(40);
@ -1362,12 +1453,12 @@ function HTML(runner) {
if (suite.root) return;
// suite
var el = $('<div class="suite"><h1>' + suite.title + '</h1></div>');
var el = fragment('<div class="suite"><h1>%s</h1></div>', suite.title);
// container
stack[0].append(el);
stack.unshift($('<div>'));
el.append(stack[0]);
stack[0].appendChild(el);
stack.unshift(document.createElement('div'));
el.appendChild(stack[0]);
});
runner.on('suite end', function(suite){
@ -1382,48 +1473,48 @@ function HTML(runner) {
runner.on('test end', function(test){
// TODO: add to stats
var percent = stats.tests / total * 100 | 0;
if (progress) {
progress.update(percent).draw(ctx);
}
if (progress) progress.update(percent).draw(ctx);
// update stats
var ms = new Date - stats.start;
stat.find('.passes em').text(stats.passes);
stat.find('.failures em').text(stats.failures);
stat.find('.duration em').text((ms / 1000).toFixed(2));
text(passes, stats.passes);
text(failures, stats.failures);
text(duration, (ms / 1000).toFixed(2));
// test
if ('passed' == test.state) {
var el = $('<div class="test pass"><h2>' + escape(test.title) + '</h2></div>')
var el = fragment('<div class="test pass"><h2>%e</h2></div>', test.title);
} else if (test.pending) {
var el = $('<div class="test pass pending"><h2>' + escape(test.title) + '</h2></div>')
var el = fragment('<div class="test pass pending"><h2>%e</h2></div>', test.title);
} else {
var el = $('<div class="test fail"><h2>' + escape(test.title) + '</h2></div>');
var el = fragment('<div class="test fail"><h2>%e</h2></div>', test.title);
var str = test.err.stack || test.err;
// <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
// check for the result of the stringifying.
if ('[object Error]' == str) str = test.err.message;
$('<pre class="error">' + escape(str) + '</pre>').appendTo(el);
el.appendChild(fragment('<pre class="error">%e</pre>', str));
}
// toggle code
el.find('h2').toggle(function(){
pre && pre.slideDown('fast');
}, function(){
pre && pre.slideUp('fast');
var h2 = el.getElementsByTagName('h2')[0];
on(h2, 'click', function(){
pre.style.display = 'none' == pre.style.display
? 'block'
: 'none';
});
// code
// TODO: defer
if (!test.pending) {
var code = escape(clean(test.fn.toString()));
var pre = $('<pre><code>' + code + '</code></pre>');
pre.appendTo(el).hide();
var pre = fragment('<pre><code>%e</code></pre>', clean(test.fn.toString()));
el.appendChild(pre);
pre.style.display = 'none';
}
stack[0].append(el);
stack[0].appendChild(el);
});
}
@ -1432,7 +1523,50 @@ function HTML(runner) {
*/
function error(msg) {
$('<div id="error">' + msg + '</div>').appendTo('body');
document.body.appendChild(fragment('<div id="error">%s</div>', msg));
}
/**
* Return a DOM fragment from `html`.
*/
function fragment(html) {
var args = arguments
, div = document.createElement('div')
, i = 1;
div.innerHTML = html.replace(/%([se])/g, function(_, type){
switch (type) {
case 's': return String(args[i++]);
case 'e': return escape(args[i++]);
}
});
return div.firstChild;
}
/**
* Set `el` text to `str`.
*/
function text(el, str) {
if (el.textContent) {
el.textContent = str;
} else {
el.innerText = str;
}
}
/**
* Listen on `event` with callback `fn`.
*/
function on(el, event, fn) {
if (el.addEventListener) {
el.addEventListener(event, fn, false);
} else {
el.attachEvent('on' + event, fn);
}
}
/**
@ -3518,13 +3652,6 @@ window.mocha = require('mocha');
;(function(){
var suite = new mocha.Suite('', new mocha.Context)
, utils = mocha.utils
, Reporter = mocha.reporters.HTML
$(function(){
$('code').each(function(){
$(this).html(highlight($(this).text()));
});
});
/**
* Highlight the given string of `js`.
@ -3535,13 +3662,24 @@ window.mocha = require('mocha');
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
.replace(/('.*')/gm, '<span class="string">$1</span>')
.replace(/('.*?')/gm, '<span class="string">$1</span>')
.replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
.replace(/(\d+)/gm, '<span class="number">$1</span>')
.replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
.replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
}
/**
* Highlight code contents.
*/
function highlightCode() {
var code = document.getElementsByTagName('code');
for (var i = 0, len = code.length; i < len; ++i) {
code[i].innerHTML = highlight(code[i].innerHTML);
}
}
/**
* Parse the given `qs`.
*/
@ -3572,17 +3710,14 @@ window.mocha = require('mocha');
* Run mocha, returning the Runner.
*/
mocha.run = function(){
mocha.run = function(Reporter){
suite.emit('run');
var runner = new mocha.Runner(suite);
Reporter = Reporter || mocha.reporters.HTML;
var reporter = new Reporter(runner);
var query = parse(window.location.search || "");
if (query.grep) runner.grep(new RegExp(query.grep));
runner.on('end', function(){
$('code').each(function(){
$(this).html(highlight($(this).text()));
});
});
runner.on('end', highlightCode);
return runner.run();
};
})();

View file

@ -7,7 +7,7 @@
var used = [];
var exports = module.exports = {};
exports.version = '0.5.1';
exports.version = '0.5.2';
exports.Assertion = require('./assertion');
exports.AssertionError = require('./error');

View file

@ -3,7 +3,7 @@
"name": "chai",
"description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.",
"keywords": [ "test", "assertion", "assert", "testing" ],
"version": "0.5.1",
"version": "0.5.2",
"repository": {
"type": "git",
"url": "https://github.com/logicalparadox/chai"