Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change by delta (New Assertion) #621

Merged
merged 4 commits into from
Feb 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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