Skip to content

Commit

Permalink
Merge pull request #621 from lucasfcosta/change-by-delta
Browse files Browse the repository at this point in the history
[WIP] Change by delta (New Assertion)
  • Loading branch information
keithamus committed Feb 23, 2016
2 parents a9b0706 + 10a0bbc commit a97b22f
Show file tree
Hide file tree
Showing 5 changed files with 383 additions and 45 deletions.
108 changes: 83 additions & 25 deletions lib/chai/core/assertions.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ module.exports = function (chai, _) {
[ 'to', 'be', 'been'
, 'is', 'and', 'has', 'have'
, 'with', 'that', 'which', 'at'
, 'of', 'same' ].forEach(function (chain) {
, 'of', 'same', 'but' ].forEach(function (chain) {
Assertion.addProperty(chain, function () {
return this;
});
Expand Down Expand Up @@ -1634,31 +1634,38 @@ module.exports = function (chai, _) {
* @name change
* @alias changes
* @alias Change
* @param {String} object
* @param {String} target
* @param {String} property name _optional_
* @param {String} message _optional_
* @namespace BDD
* @api public
*/

function assertChanges (object, prop, msg) {
function assertChanges (target, prop, msg) {
if (msg) flag(this, 'message', msg);
var fn = flag(this, 'object');
new Assertion(fn).is.a('function');

var initial;
if (!prop) {
new Assertion(object).is.a('function');
initial = object();
new Assertion(target).is.a('function');
initial = target();
} else {
new Assertion(object, msg).to.have.property(prop);
initial = object[prop];
new Assertion(target, msg).to.have.property(prop);
initial = target[prop];
}

fn();

var final = prop === undefined ? object() : object[prop];
var msgObj = prop === undefined ? initial : '.' + prop;
var final = prop === undefined || prop === null ? target() : target[prop];
var msgObj = prop === undefined || prop === null ? initial : '.' + prop;

// This gets flagged because of the .by(delta) assertion
flag(this, 'deltaMsgObj', msgObj);
flag(this, 'initialDeltaValue', initial);
flag(this, 'finalDeltaValue', final);
flag(this, 'deltaBehavior', 'change');
flag(this, 'realDelta', final !== initial);

this.assert(
initial !== final
Expand All @@ -1682,31 +1689,37 @@ module.exports = function (chai, _) {
* @name increase
* @alias increases
* @alias Increase
* @param {String} object
* @param {String} target
* @param {String} property name
* @param {String} message _optional_
* @namespace BDD
* @api public
*/

function assertIncreases (object, prop, msg) {
function assertIncreases (target, prop, msg) {
if (msg) flag(this, 'message', msg);
var fn = flag(this, 'object');
new Assertion(fn).is.a('function');

var initial;
if (!prop) {
new Assertion(object).is.a('function');
initial = object();
new Assertion(target).is.a('function');
initial = target();
} else {
new Assertion(object, msg).to.have.property(prop);
initial = object[prop];
new Assertion(target, msg).to.have.property(prop);
initial = target[prop];
}

fn();

var final = prop === undefined ? object() : object[prop];
var msgObj = prop === undefined ? initial : '.' + prop;
var final = prop === undefined || prop === null ? target() : target[prop];
var msgObj = prop === undefined || prop === null ? initial : '.' + prop;

flag(this, 'deltaMsgObj', msgObj);
flag(this, 'initialDeltaValue', initial);
flag(this, 'finalDeltaValue', final);
flag(this, 'deltaBehavior', 'increase');
flag(this, 'realDelta', final - initial);

this.assert(
final - initial > 0
Expand All @@ -1730,31 +1743,37 @@ module.exports = function (chai, _) {
* @name decrease
* @alias decreases
* @alias Decrease
* @param {String} object
* @param {String} target
* @param {String} property name
* @param {String} message _optional_
* @namespace BDD
* @api public
*/

function assertDecreases (object, prop, msg) {
function assertDecreases (target, prop, msg) {
if (msg) flag(this, 'message', msg);
var fn = flag(this, 'object');
new Assertion(fn).is.a('function');

var initial;
if (!prop) {
new Assertion(object).is.a('function');
initial = object();
new Assertion(target).is.a('function');
initial = target();
} else {
new Assertion(object, msg).to.have.property(prop);
initial = object[prop];
new Assertion(target, msg).to.have.property(prop);
initial = target[prop];
}

fn();

var final = prop === undefined ? object() : object[prop];
var msgObj = prop === undefined ? initial : '.' + prop;
var final = prop === undefined || prop === null ? target() : target[prop];
var msgObj = prop === undefined || prop === null ? initial : '.' + prop;

flag(this, 'deltaMsgObj', msgObj);
flag(this, 'initialDeltaValue', initial);
flag(this, 'finalDeltaValue', final);
flag(this, 'deltaBehavior', 'decrease');
flag(this, 'realDelta', initial - final);

this.assert(
final - initial < 0
Expand All @@ -1766,6 +1785,45 @@ module.exports = function (chai, _) {
Assertion.addChainableMethod('decrease', assertDecreases);
Assertion.addChainableMethod('decreases', assertDecreases);

/**
* ### .by
*
* Defines an amount for increase/decrease assertions.
*
* var obj = { val: 10 };
* var dec = function() { obj.val -= 5 };
* var inc = function() {obj.val += 10};
* expect(dec).to.decrease(obj, 'val').by(5);
* expect(inc).to.increase(obj, 'val').by(10);
*
* @name by
* @namespace BDD
* @api public
*/

function assertDelta(delta) {
var msgObj = flag(this, 'deltaMsgObj');
var initial = flag(this, 'initialDeltaValue');
var final = flag(this, 'finalDeltaValue');
var behavior = flag(this, 'deltaBehavior');
var realDelta = flag(this, 'realDelta');

var expression;
if (behavior === 'change') {
expression = Math.abs(final - initial) === Math.abs(delta);
} else {
expression = realDelta === Math.abs(delta);
}

this.assert(
expression
, 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta
, 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta
);
}

Assertion.addMethod('by', assertDelta);

/**
* ### .extensible
*
Expand Down

0 comments on commit a97b22f

Please sign in to comment.