"use strict"; var valueToString = require("@sinonjs/commons").valueToString; var deepEqual = require("./deep-equal").use(match); // eslint-disable-line no-use-before-define var getClass = require("./get-class"); var isDate = require("./is-date"); var isSet = require("./is-set"); var isSubset = require("./is-subset"); var createMatcher = require("./matcher"); function arrayContains(array, subset, compare) { if (subset.length === 0) { return true; } var i, l, j, k; for (i = 0, l = array.length; i < l; ++i) { if (compare(array[i], subset[0])) { for (j = 0, k = subset.length; j < k; ++j) { if (i + j >= l) { return false; } if (!compare(array[i + j], subset[j])) { return false; } } return true; } } return false; } /** * @name samsam.match * @param Object object * @param Object matcher * * Compare arbitrary value ``object`` with matcher. */ function match(object, matcher) { if (matcher && typeof matcher.test === "function") { return matcher.test(object); } if (typeof matcher === "function") { return matcher(object) === true; } if (typeof matcher === "string") { matcher = matcher.toLowerCase(); var notNull = typeof object === "string" || !!object; return ( notNull && valueToString(object) .toLowerCase() .indexOf(matcher) >= 0 ); } if (typeof matcher === "number") { return matcher === object; } if (typeof matcher === "boolean") { return matcher === object; } if (typeof matcher === "undefined") { return typeof object === "undefined"; } if (matcher === null) { return object === null; } if (object === null) { return false; } if (isSet(object)) { return isSubset(matcher, object, match); } if (getClass(object) === "Array" && getClass(matcher) === "Array") { return arrayContains(object, matcher, match); } if (isDate(matcher)) { return isDate(object) && object.getTime() === matcher.getTime(); } if (matcher && typeof matcher === "object") { if (matcher === object) { return true; } if (typeof object !== "object") { return false; } var prop; // eslint-disable-next-line guard-for-in for (prop in matcher) { var value = object[prop]; if ( typeof value === "undefined" && typeof object.getAttribute === "function" ) { value = object.getAttribute(prop); } if ( matcher[prop] === null || typeof matcher[prop] === "undefined" ) { if (value !== matcher[prop]) { return false; } } else if ( typeof value === "undefined" || !deepEqual(value, matcher[prop]) ) { return false; } } return true; } throw new Error( "Matcher was not a string, a number, a " + "function, a boolean or an object" ); } Object.keys(createMatcher).forEach(function(key) { match[key] = createMatcher[key]; }); module.exports = match;