diff --git a/lib/interface/assert.js b/lib/interface/assert.js index e252b8a..7aa03c6 100644 --- a/lib/interface/assert.js +++ b/lib/interface/assert.js @@ -84,6 +84,37 @@ module.exports = function (chai, util) { new Assertion(val, msg).is.ok; }; + + /** + * # .almostEqual(actual, expected, [decimal, message]) + * + * The same as NumPy's assert_almost_equal, for scalars. + * Assert near equality: abs(expected-actual) < 0.5 * 10**(-decimal) + * + * assert.almostEqual(3.1416, 3.14159, 3, 'these numbers are almost equal'); + * + * @name equal + * @param {Number} actual + * @param {Number} expected + * @param {Number} decimal + * @param {String} message + * @api public + */ + + assert.almostEqual = function(act, exp, dec, msg) { + var test = new Assertion(act, msg); + if (null == dec) dec = 7; + + test.assert( + Math.abs(act - exp) < 0.5 * Math.pow(10, -dec) + , "expected #{this} to equal #{exp} up to " + util.inspect(dec) + " decimal places" + , "expected #{this} to not equal #{exp} up to " + util.inspect(dec) + " decimal places" + , exp + , act + ) + }; + + /** * # .equal(actual, expected, [message]) * @@ -189,6 +220,50 @@ module.exports = function (chai, util) { assert.deepEqual = function (act, exp, msg) { new Assertion(act, msg).to.eql(exp); }; + + /** + * # .deepAlmostEqual(actual, expected, [decimal, message]) + * + * The same as NumPy's assert_almost_equal, for objects whose leaves are all numbers. + * Assert near equality: abs(expected-actual) < 0.5 * 10**(-decimal) for every leaf + * + * assert.deepAlmostEqual({pi: 3.1416}, {pi: 3.14159}, 3); + * + * @name equal + * @param {*} actual + * @param {*} expected + * @param {Number} decimal + * @param {String} message + * @api public + */ + + assert.deepAlmostEqual = function(act, exp, dec, msg) { + var test = new Assertion(act, msg); + if (null == dec) dec = 7; + var tol = 0.5 * Math.pow(10, -dec); + + var deepEq = function(act, exp) { + if (Object(act) === act){ + for (var k in act) { + if (!(deepEq(act[k], exp[k]))) { + return false; + } + } + return true; + } + else { + return Math.abs(act - exp) < tol; + } + }; + + test.assert( + deepEq(act, exp) + , "expected #{this} to equal #{exp} up to " + util.inspect(dec) + ' decimal places' + , "expected #{this} to not equal #{exp} up to " + util.inspect(dec) + ' decimal places' + , exp + , act + ); + }; /** * # .notDeepEqual(actual, expected, [message]) diff --git a/test/assert.js b/test/assert.js index 9fc079b..9c28fd7 100644 --- a/test/assert.js +++ b/test/assert.js @@ -1,4 +1,3 @@ - /*! * Module dependencies. * @@ -182,6 +181,32 @@ suite('assert', function () { assert.notDeepEqual({tea: 'chai'}, {tea: 'chai'}); }, "expected { tea: \'chai\' } to not equal { tea: \'chai\' }"); }); + + test('almostEqual', function() { + assert.almostEqual(3.1416, 3.14159, 3); + + err(function () { + assert.almostEqual(3.1416, 3.14159, 6); + }, "expected 3.1416 to equal 3.14159 up to 6 decimal places"); + + err(function () { + assert.almostEqual(3.1416, 3.14159); + }, "expected 3.1416 to equal 3.14159 up to 7 decimal places"); + + }); + + test('deepAlmostEqual', function() { + assert.deepAlmostEqual({pi: 3.1416}, {pi: 3.14159}, 3); + + err(function () { + assert.deepAlmostEqual({pi: 3.1416}, {pi: 3.14159}, 6); + }, "expected { pi: 3.1416 } to equal { pi: 3.14159 } up to 6 decimal places"); + + err(function () { + assert.deepAlmostEqual({pi: 3.1416}, {pi: 3.14159}); + }, "expected { pi: 3.1416 } to equal { pi: 3.14159 } up to 7 decimal places"); + + }); test('isNull', function() { assert.isNull(null);