BX.use('brixy', 'modules/tester/Result.jsxinc');
BX.use('brixy', 'modules/tester/Assert.jsxinc');
BX.use('brixy', 'modules/tester/Specials.jsxinc');
/**
* @module 'brixy.tester.It'
*/
BX.module.define('brixy.tester.It', function() {
var Asserts = BX.module('brixy.tester.Assert').Asserts,
Specials = BX.module('brixy.tester.Specials').Me,
Result = BX.module('brixy.tester.Result').Me,
STATUS = BX.module('brixy.tester.Result').STATUS;
/**
* It object.
* @class
* @alias module:'brixy.tester.It'~It
* @param {module:'brixy.tester.Job'~Job} job - Reference to the job instance.
* @param {int} [comparisonDepth=10] - Nesting level of the comparison of the objects.
*/
function It(job, comparisonDepth) {
this._specials = null;
this._job = job;
comparisonDepth = parseInt(comparisonDepth);
this._comparisonDepth = isNaN(comparisonDepth) ? 10 : comparisonDepth;
}
/**
* Returns a string representation of the object.
* @method
* @return {string}
*/
It.prototype.toString = BX.toString;
/**
* Adds new special type definition. Methods `isLike()` and `notLike()` compares own properties of tested objects.
* Special types allows to define own values to be used in testing.
*
* @example
* // Before using a special type definition:
* // test passed because Date doesn't have own properties,
* // but dates are different
* it.isLike('', new Date(), new Date(1000));
*
* // Let's define Date as a special type:
* it.addSpecialType(
* Date,
* function(val) { return val.getTime(); },
* function(val) { return 'Date("' + val.toLocaleString() + '")'; }
* );
* it.notLike('', new Date(), new Date(1000));
* it.isLike('', new Date(1000), new Date(1000));
* // and that we wished
*
* @param {Function} Type - Object's constructor.
* @param {Function} valueCallback - `function(val){ return val.something; }` returns a value for testing.
* @param {Function} captionCallback - `function(val){ return val.toString(); }` returns a string to show in report dialog.
*/
It.prototype.addSpecialType = function(Type, valueCallback, captionCallback) {
if (!this._specials)
this._specials = new Specials();
this._specials.addType(Type, valueCallback, captionCallback);
};
/**
* Adds new special type definition.
* @param {Object} def - `{constr: Type, value: Function, caption: Function}`
* @throws Exception
*/
It.prototype.addSpecialTypeDef = function(def) {
try {
this.addSpecialType(def.constr, def.value, def.caption);
}
catch (e) {
throw BX.error('brixy.tester.It.addSpecialTypeDef()', Error('Cannot add new special type definition.'), e);
}
};
/*
* Creates a result of the test, sends it to the job.
* @param {module:'brixy.tester.Assert'~Rating} rating
* @param {string} testName
* @param {string} descO - Description of the successful test.
* @param {string} descF - Description of the failed test.
*/
It.prototype._evaluate = function(rating, testName, descO, descF) {
var description = '';
switch (rating.status) {
case STATUS.OK:
description = (descO + '') || 'OK';
break;
case STATUS.FAILED:
description = (descF + '') || 'Failed';
break;
case STATUS.SKIPPED:
description = 'Incomplete test.';
break;
}
if (rating.note)
description = description + ' ' + rating.note;
description = description.replace('%a', rating.actual.caption).replace('%e', rating.expected.caption);
var result = new Result(rating.status, testName, description);
this._job.onResult(result, rating.actual, rating.expected, rating.depth);
};
/* Test methods */
/**
* Tests if values are identical.
* @param {string} name
* @param {*} actual
* @param {*} expected
*/
It.prototype.is = function(name, actual, expected) {
this._evaluate(
Asserts.is(actual, expected),
name || 'is',
'%a is %e.',
'%a should be %e.'
);
};
/**
* Tests if values are not identical.
* @param {string} name
* @param {*} actual
* @param {*} expected
*/
It.prototype.isNot = function(name, actual, expected) {
this._evaluate(
Asserts.isNot(actual, expected),
name || 'isNot',
'%a is not %e.',
'%a should not be %e.'
);
};
/**
* Tests if actual value is member of the expected value.
* @param {string} name
* @param {*} actual
* @param {*} expected
*/
It.prototype.isMember = function(name, actual, expected) {
this._evaluate(
Asserts.isMember(actual, expected),
name || 'is a member',
'%a is a member of the %e.',
'%a should be a member of the %e.'
);
};
/**
* Tests if actual value is not member of the expected value.
* @param {string} name
* @param {*} actual
* @param {*} expected
*/
It.prototype.notMember = function(name, actual, expected) {
this._evaluate(
Asserts.notMember(actual, expected),
name || 'is not a member',
'%a is not a member of the %e.',
'%a should not be a member of the %e.'
);
};
/**
* Tests if values are equal.
* @param {string} name
* @param {*} actual
* @param {*} expected
* @param {int} [depth=10] - Nesting level of the comparison of the objects.
*/
It.prototype.isLike = function(name, actual, expected, depth) {
depth = toDepth(depth, this._comparisonDepth);
this._evaluate(
Asserts.isLike(actual, expected, depth, this._specials),
name || 'isLike',
'%a is like a %e. Max comparison depth: ' + depth + '.',
'%a should be like a %e. Max comparison depth: ' + depth + '.'
);
};
/**
* Tests if values are not equal.
* @param {string} name
* @param {*} actual
* @param {*} expected
* @param {int} [depth=10] - Nesting level of the comparison of the objects.
*/
It.prototype.notLike = function(name, actual, expected, depth) {
depth = toDepth(depth, this._comparisonDepth);
this._evaluate(
Asserts.notLike(actual, expected, depth, this._specials),
name || 'notLike',
'%a is not like a %e. Max comparison depth: ' + depth + '.',
'%a should not be like a %e. Max comparison depth: ' + depth + '.'
);
};
/**
* Tests if actual function throws exception.
* @param {string} name
* @param {function} actual
* @param {*} [expected]
*/
It.prototype.isThrown = function(name, actual, expected) {
this._evaluate(
Asserts.isThrown(actual, expected),
name || 'isThrown',
'%a throws exception' + (expected ? ': ' + expected : '.'),
'%a should throw exception' + (expected ? ': ' + expected : '.')
);
};
/**
* Tests if actual function doesn't throw exception.
* @param {string} name
* @param {function} actual
* @param {*} [expected]
*/
It.prototype.notThrown = function(name, actual, expected) {
this._evaluate(
Asserts.notThrown(actual, expected),
name || 'notThrown',
'%a does not throw exception' + (expected ? ': ' + expected : '.'),
'%a should not throw exception' + (expected ? ': ' + expected : '.')
);
};
function toDepth(depth, defDepth) {
depth = parseInt(depth);
if (isNaN(depth)) {
depth = defDepth;
}
return (depth < 0) ? 0 : depth;
}
// publish
return {
/**
* It class.
* @memberOf module:'brixy.tester.It'
* @type {module:'brixy.tester.It'~It}
*/
Me: It
};
});
►