UNPKG

cloudboost-tv

Version:

Database Service that does Storage, Search, Real-time and a whole lot more.

165 lines (145 loc) 5.91 kB
/*! * Should * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca> * MIT Licensed */ var util = require('../util'); var eql = require('should-equal'); module.exports = function(should, Assertion) { var i = should.format; /** * Asserts if given object match `other` object, using some assumptions: * First object matched if they are equal, * If `other` is a regexp and given object is a string check on matching with regexp * If `other` is a regexp and given object is an array check if all elements matched regexp * If `other` is a regexp and given object is an object check values on matching regexp * If `other` is a function check if this function throws AssertionError on given object or return false - it will be assumed as not matched * If `other` is an object check if the same keys matched with above rules * All other cases failed * * @name match * @memberOf Assertion * @category assertion matching * @param {*} other Object to match * @param {string} [description] Optional message * @example * 'foobar'.should.match(/^foo/); * 'foobar'.should.not.match(/^bar/); * * ({ a: 'foo', c: 'barfoo' }).should.match(/foo$/); * * ['a', 'b', 'c'].should.match(/[a-z]/); * * (5).should.not.match(function(n) { * return n < 0; * }); * (5).should.not.match(function(it) { * it.should.be.an.Array; * }); * ({ a: 10, b: 'abc', c: { d: 10 }, d: 0 }).should * .match({ a: 10, b: /c$/, c: function(it) { * return it.should.have.property('d', 10); * }}); * * [10, 'abc', { d: 10 }, 0].should * .match({ '0': 10, '1': /c$/, '2': function(it) { * return it.should.have.property('d', 10); * }}); */ Assertion.add('match', function(other, description) { this.params = {operator: 'to match ' + i(other), message: description}; if(!eql(this.obj, other).result) { if(other instanceof RegExp) { // something - regex if(typeof this.obj == 'string') { this.assert(other.exec(this.obj)); } else if(util.isIndexable(this.obj)) { util.forEach(this.obj, function(item) { this.assert(other.exec(item));// should we try to convert to String and exec? }, this); } else if(null != this.obj && typeof this.obj == 'object') { var notMatchedProps = [], matchedProps = []; util.forEach(this.obj, function(value, name) { if(other.exec(value)) matchedProps.push(util.formatProp(name)); else notMatchedProps.push(util.formatProp(name) + ' (' + i(value) + ')'); }, this); if(notMatchedProps.length) this.params.operator += '\n not matched properties: ' + notMatchedProps.join(', '); if(matchedProps.length) this.params.operator += '\n matched properties: ' + matchedProps.join(', '); this.assert(notMatchedProps.length == 0); } // should we try to convert to String and exec? } else if(typeof other == 'function') { var res; res = other(this.obj); //if(res instanceof Assertion) { // this.params.operator += '\n ' + res.getMessage(); //} //if we throw exception ok - it is used .should inside if(typeof res == 'boolean') { this.assert(res); // if it is just boolean function assert on it } } else if(other != null && typeof other == 'object') { // try to match properties (for Object and Array) notMatchedProps = []; matchedProps = []; util.forEach(other, function(value, key) { try { should(this.obj[key]).match(value); matchedProps.push(util.formatProp(key)); } catch(e) { if(e instanceof should.AssertionError) { notMatchedProps.push(util.formatProp(key) + ' (' + i(this.obj[key]) + ')'); } else { throw e; } } }, this); if(notMatchedProps.length) this.params.operator += '\n not matched properties: ' + notMatchedProps.join(', '); if(matchedProps.length) this.params.operator += '\n matched properties: ' + matchedProps.join(', '); this.assert(notMatchedProps.length == 0); } else { this.assert(false); } } }); /** * Asserts if given object values or array elements all match `other` object, using some assumptions: * First object matched if they are equal, * If `other` is a regexp - matching with regexp * If `other` is a function check if this function throws AssertionError on given object or return false - it will be assumed as not matched * All other cases check if this `other` equal to each element * * @name matchEach * @memberOf Assertion * @category assertion matching * @param {*} other Object to match * @param {string} [description] Optional message * @example * [ 'a', 'b', 'c'].should.matchEach(/\w+/); * [ 'a', 'a', 'a'].should.matchEach('a'); * * [ 'a', 'a', 'a'].should.matchEach(function(value) { value.should.be.eql('a') }); * * { a: 'a', b: 'a', c: 'a' }.should.matchEach(function(value) { value.should.be.eql('a') }); */ Assertion.add('matchEach', function(other, description) { this.params = {operator: 'to match each ' + i(other), message: description}; var f = other; if(other instanceof RegExp) f = function(it) { return !!other.exec(it); }; else if(typeof other != 'function') f = function(it) { return eql(it, other).result; }; util.forEach(this.obj, function(value, key) { var res = f(value, key); //if we throw exception ok - it is used .should inside if(typeof res == 'boolean') { this.assert(res); // if it is just boolean function assert on it } }, this); }); };