samsam.js 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@sinonjs/commons'), require('lodash')) :
  3. typeof define === 'function' && define.amd ? define(['exports', '@sinonjs/commons', 'lodash'], factory) :
  4. (factory((global.samsam = {}),global.require$$0,global.lodash));
  5. }(this, (function (exports,require$$0,lodash) { 'use strict';
  6. require$$0 = require$$0 && require$$0.hasOwnProperty('default') ? require$$0['default'] : require$$0;
  7. lodash = lodash && lodash.hasOwnProperty('default') ? lodash['default'] : lodash;
  8. function isNaN(value) {
  9. // Unlike global isNaN, this avoids type coercion
  10. // typeof check avoids IE host object issues, hat tip to
  11. // lodash
  12. var val = value; // JsLint thinks value !== value is "weird"
  13. return typeof value === "number" && value !== val;
  14. }
  15. var isNan = isNaN;
  16. /**
  17. * @name samsam.isNegZero
  18. * @param Object value
  19. *
  20. * Returns ``true`` if ``value`` is ``-0``.
  21. */
  22. function isNegZero(value) {
  23. return value === 0 && 1 / value === -Infinity;
  24. }
  25. var isNegZero_1 = isNegZero;
  26. /**
  27. * @name samsam.equal
  28. * @param Object obj1
  29. * @param Object obj2
  30. *
  31. * Returns ``true`` if two objects are strictly equal. Compared to
  32. * ``===`` there are two exceptions:
  33. *
  34. * - NaN is considered equal to NaN
  35. * - -0 and +0 are not considered equal
  36. */
  37. function identical(obj1, obj2) {
  38. if (obj1 === obj2 || (isNan(obj1) && isNan(obj2))) {
  39. return obj1 !== 0 || isNegZero_1(obj1) === isNegZero_1(obj2);
  40. }
  41. return false;
  42. }
  43. var identical_1 = identical;
  44. var o = Object.prototype;
  45. function getClass(value) {
  46. // Returns the internal [[Class]] by calling Object.prototype.toString
  47. // with the provided value as this. Return value is a string, naming the
  48. // internal class, e.g. "Array"
  49. return o.toString.call(value).split(/[ \]]/)[1];
  50. }
  51. var getClass_1 = getClass;
  52. /**
  53. * @name samsam.isArguments
  54. * @param Object object
  55. *
  56. * Returns ``true`` if ``object`` is an ``arguments`` object,
  57. * ``false`` otherwise.
  58. */
  59. function isArguments(object) {
  60. if (getClass_1(object) === "Arguments") {
  61. return true;
  62. }
  63. if (
  64. typeof object !== "object" ||
  65. typeof object.length !== "number" ||
  66. getClass_1(object) === "Array"
  67. ) {
  68. return false;
  69. }
  70. if (typeof object.callee === "function") {
  71. return true;
  72. }
  73. try {
  74. object[object.length] = 6;
  75. delete object[object.length];
  76. } catch (e) {
  77. return true;
  78. }
  79. return false;
  80. }
  81. var isArguments_1 = isArguments;
  82. var div = typeof document !== "undefined" && document.createElement("div");
  83. /**
  84. * @name samsam.isElement
  85. * @param Object object
  86. *
  87. * Returns ``true`` if ``object`` is a DOM element node. Unlike
  88. * Underscore.js/lodash, this function will return ``false`` if ``object``
  89. * is an *element-like* object, i.e. a regular object with a ``nodeType``
  90. * property that holds the value ``1``.
  91. */
  92. function isElement(object) {
  93. if (!object || object.nodeType !== 1 || !div) {
  94. return false;
  95. }
  96. try {
  97. object.appendChild(div);
  98. object.removeChild(div);
  99. } catch (e) {
  100. return false;
  101. }
  102. return true;
  103. }
  104. var isElement_1 = isElement;
  105. function isSet(val) {
  106. return (typeof Set !== "undefined" && val instanceof Set) || false;
  107. }
  108. var isSet_1 = isSet;
  109. function isDate(value) {
  110. return value instanceof Date;
  111. }
  112. var isDate_1 = isDate;
  113. // Returns true when the value is a regular Object and not a specialized Object
  114. //
  115. // This helps speeding up deepEqual cyclic checks
  116. // The premise is that only Objects are stored in the visited array.
  117. // So if this function returns false, we don't have to do the
  118. // expensive operation of searching for the value in the the array of already
  119. // visited objects
  120. function isObject(value) {
  121. return (
  122. typeof value === "object" &&
  123. value !== null &&
  124. // none of these are collection objects, so we can return false
  125. !(value instanceof Boolean) &&
  126. !(value instanceof Date) &&
  127. !(value instanceof Error) &&
  128. !(value instanceof Number) &&
  129. !(value instanceof RegExp) &&
  130. !(value instanceof String)
  131. );
  132. }
  133. var isObject_1 = isObject;
  134. function isSubset(s1, s2, compare) {
  135. var allContained = true;
  136. s1.forEach(function(v1) {
  137. var includes = false;
  138. s2.forEach(function(v2) {
  139. if (compare(v2, v1)) {
  140. includes = true;
  141. }
  142. });
  143. allContained = allContained && includes;
  144. });
  145. return allContained;
  146. }
  147. var isSubset_1 = isSubset;
  148. var valueToString = require$$0.valueToString;
  149. var re = /function (\w+)\s*\(/;
  150. function getClassName(value) {
  151. if (value.constructor && "name" in value.constructor) {
  152. return value.constructor.name;
  153. }
  154. if (typeof value.constructor === "function") {
  155. var match = valueToString(value.constructor).match(re);
  156. if (match.length > 1) {
  157. return match[1];
  158. }
  159. }
  160. return null;
  161. }
  162. var getClassName_1 = getClassName;
  163. var valueToString$1 = require$$0.valueToString;
  164. var every = Array.prototype.every;
  165. var getTime = Date.prototype.getTime;
  166. var hasOwnProperty = Object.prototype.hasOwnProperty;
  167. var indexOf = Array.prototype.indexOf;
  168. var keys = Object.keys;
  169. /**
  170. * @name samsam.deepEqual
  171. * @param Object first
  172. * @param Object second
  173. *
  174. * Deep equal comparison. Two values are "deep equal" if:
  175. *
  176. * - They are equal, according to samsam.identical
  177. * - They are both date objects representing the same time
  178. * - They are both arrays containing elements that are all deepEqual
  179. * - They are objects with the same set of properties, and each property
  180. * in ``first`` is deepEqual to the corresponding property in ``second``
  181. *
  182. * Supports cyclic objects.
  183. */
  184. function deepEqualCyclic(first, second, match) {
  185. // used for cyclic comparison
  186. // contain already visited objects
  187. var objects1 = [];
  188. var objects2 = [];
  189. // contain pathes (position in the object structure)
  190. // of the already visited objects
  191. // indexes same as in objects arrays
  192. var paths1 = [];
  193. var paths2 = [];
  194. // contains combinations of already compared objects
  195. // in the manner: { "$1['ref']$2['ref']": true }
  196. var compared = {};
  197. // does the recursion for the deep equal check
  198. return (function deepEqual(obj1, obj2, path1, path2) {
  199. // If both are matchers they must be the same instance in order to be
  200. // considered equal If we didn't do that we would end up running one
  201. // matcher against the other
  202. if (match && match.isMatcher(obj2)) {
  203. if (match.isMatcher(obj1)) {
  204. return obj1 === obj2;
  205. }
  206. return obj2.test(obj1);
  207. }
  208. var type1 = typeof obj1;
  209. var type2 = typeof obj2;
  210. // == null also matches undefined
  211. if (
  212. obj1 === obj2 ||
  213. isNan(obj1) ||
  214. isNan(obj2) ||
  215. obj1 == null ||
  216. obj2 == null ||
  217. type1 !== "object" ||
  218. type2 !== "object"
  219. ) {
  220. return identical_1(obj1, obj2);
  221. }
  222. // Elements are only equal if identical(expected, actual)
  223. if (isElement_1(obj1) || isElement_1(obj2)) {
  224. return false;
  225. }
  226. var isDate1 = isDate_1(obj1);
  227. var isDate2 = isDate_1(obj2);
  228. if (isDate1 || isDate2) {
  229. if (
  230. !isDate1 ||
  231. !isDate2 ||
  232. getTime.call(obj1) !== getTime.call(obj2)
  233. ) {
  234. return false;
  235. }
  236. }
  237. if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
  238. if (valueToString$1(obj1) !== valueToString$1(obj2)) {
  239. return false;
  240. }
  241. }
  242. if (obj1 instanceof Error && obj2 instanceof Error) {
  243. return obj1 === obj2;
  244. }
  245. var class1 = getClass_1(obj1);
  246. var class2 = getClass_1(obj2);
  247. var keys1 = keys(obj1);
  248. var keys2 = keys(obj2);
  249. var name1 = getClassName_1(obj1);
  250. var name2 = getClassName_1(obj2);
  251. if (isArguments_1(obj1) || isArguments_1(obj2)) {
  252. if (obj1.length !== obj2.length) {
  253. return false;
  254. }
  255. } else {
  256. if (
  257. type1 !== type2 ||
  258. class1 !== class2 ||
  259. keys1.length !== keys2.length ||
  260. (name1 && name2 && name1 !== name2)
  261. ) {
  262. return false;
  263. }
  264. }
  265. if (isSet_1(obj1) || isSet_1(obj2)) {
  266. if (!isSet_1(obj1) || !isSet_1(obj2) || obj1.size !== obj2.size) {
  267. return false;
  268. }
  269. return isSubset_1(obj1, obj2, deepEqual);
  270. }
  271. return every.call(keys1, function(key) {
  272. if (!hasOwnProperty.call(obj2, key)) {
  273. return false;
  274. }
  275. var value1 = obj1[key];
  276. var value2 = obj2[key];
  277. var isObject1 = isObject_1(value1);
  278. var isObject2 = isObject_1(value2);
  279. // determines, if the objects were already visited
  280. // (it's faster to check for isObject first, than to
  281. // get -1 from getIndex for non objects)
  282. var index1 = isObject1 ? indexOf.call(objects1, value1) : -1;
  283. var index2 = isObject2 ? indexOf.call(objects2, value2) : -1;
  284. // determines the new paths of the objects
  285. // - for non cyclic objects the current path will be extended
  286. // by current property name
  287. // - for cyclic objects the stored path is taken
  288. var newPath1 =
  289. index1 !== -1
  290. ? paths1[index1]
  291. : path1 + "[" + JSON.stringify(key) + "]";
  292. var newPath2 =
  293. index2 !== -1
  294. ? paths2[index2]
  295. : path2 + "[" + JSON.stringify(key) + "]";
  296. var combinedPath = newPath1 + newPath2;
  297. // stop recursion if current objects are already compared
  298. if (compared[combinedPath]) {
  299. return true;
  300. }
  301. // remember the current objects and their paths
  302. if (index1 === -1 && isObject1) {
  303. objects1.push(value1);
  304. paths1.push(newPath1);
  305. }
  306. if (index2 === -1 && isObject2) {
  307. objects2.push(value2);
  308. paths2.push(newPath2);
  309. }
  310. // remember that the current objects are already compared
  311. if (isObject1 && isObject2) {
  312. compared[combinedPath] = true;
  313. }
  314. // End of cyclic logic
  315. // neither value1 nor value2 is a cycle
  316. // continue with next level
  317. return deepEqual(value1, value2, newPath1, newPath2);
  318. });
  319. })(first, second, "$1", "$2");
  320. }
  321. deepEqualCyclic.use = function(match) {
  322. return function(a, b) {
  323. return deepEqualCyclic(a, b, match);
  324. };
  325. };
  326. var deepEqual = deepEqualCyclic;
  327. var slice = require$$0.prototypes.string.slice;
  328. var typeOf = require$$0.typeOf;
  329. var valueToString$2 = require$$0.valueToString;
  330. var iterableToString = function iterableToString(obj) {
  331. var representation = "";
  332. function stringify(item) {
  333. return typeof item === "string"
  334. ? "'" + item + "'"
  335. : valueToString$2(item);
  336. }
  337. function mapToString(map) {
  338. /* eslint-disable-next-line local-rules/no-prototype-methods */
  339. map.forEach(function(value, key) {
  340. representation +=
  341. "[" + stringify(key) + "," + stringify(value) + "],";
  342. });
  343. representation = slice(representation, 0, -1);
  344. return representation;
  345. }
  346. function genericIterableToString(iterable) {
  347. /* eslint-disable-next-line local-rules/no-prototype-methods */
  348. iterable.forEach(function(value) {
  349. representation += stringify(value) + ",";
  350. });
  351. representation = slice(representation, 0, -1);
  352. return representation;
  353. }
  354. if (typeOf(obj) === "map") {
  355. return mapToString(obj);
  356. }
  357. return genericIterableToString(obj);
  358. };
  359. var arrayProto = require$$0.prototypes.array;
  360. var deepEqual$1 = deepEqual.use(match); // eslint-disable-line no-use-before-define
  361. var every$1 = require$$0.every;
  362. var functionName = require$$0.functionName;
  363. var get = lodash.get;
  364. var objectProto = require$$0.prototypes.object;
  365. var stringProto = require$$0.prototypes.string;
  366. var typeOf$1 = require$$0.typeOf;
  367. var valueToString$3 = require$$0.valueToString;
  368. var arrayIndexOf = arrayProto.indexOf;
  369. var arrayEvery = arrayProto.every;
  370. var join = arrayProto.join;
  371. var map = arrayProto.map;
  372. var some = arrayProto.some;
  373. var hasOwnProperty$1 = objectProto.hasOwnProperty;
  374. var isPrototypeOf = objectProto.isPrototypeOf;
  375. var stringIndexOf = stringProto.indexOf;
  376. function assertType(value, type, name) {
  377. var actual = typeOf$1(value);
  378. if (actual !== type) {
  379. throw new TypeError(
  380. "Expected type of " +
  381. name +
  382. " to be " +
  383. type +
  384. ", but was " +
  385. actual
  386. );
  387. }
  388. }
  389. function assertMethodExists(value, method, name, methodPath) {
  390. if (value[method] == null) {
  391. throw new TypeError(
  392. "Expected " + name + " to have method " + methodPath
  393. );
  394. }
  395. }
  396. var matcher = {
  397. toString: function() {
  398. return this.message;
  399. }
  400. };
  401. function isMatcher(object) {
  402. return isPrototypeOf(matcher, object);
  403. }
  404. function matchObject(actual, expectation) {
  405. if (actual === null || actual === undefined) {
  406. return false;
  407. }
  408. return arrayEvery(Object.keys(expectation), function(key) {
  409. var exp = expectation[key];
  410. var act = actual[key];
  411. if (isMatcher(exp)) {
  412. if (!exp.test(act)) {
  413. return false;
  414. }
  415. } else if (typeOf$1(exp) === "object") {
  416. if (!matchObject(act, exp)) {
  417. return false;
  418. }
  419. } else if (!deepEqual$1(act, exp)) {
  420. return false;
  421. }
  422. return true;
  423. });
  424. }
  425. var TYPE_MAP = {
  426. function: function(m, expectation, message) {
  427. m.test = expectation;
  428. m.message = message || "match(" + functionName(expectation) + ")";
  429. },
  430. number: function(m, expectation) {
  431. m.test = function(actual) {
  432. // we need type coercion here
  433. return expectation == actual; // eslint-disable-line eqeqeq
  434. };
  435. },
  436. object: function(m, expectation) {
  437. var array = [];
  438. if (typeof expectation.test === "function") {
  439. m.test = function(actual) {
  440. return expectation.test(actual) === true;
  441. };
  442. m.message = "match(" + functionName(expectation.test) + ")";
  443. return m;
  444. }
  445. array = map(Object.keys(expectation), function(key) {
  446. return key + ": " + valueToString$3(expectation[key]);
  447. });
  448. m.test = function(actual) {
  449. return matchObject(actual, expectation);
  450. };
  451. m.message = "match(" + join(array, ", ") + ")";
  452. return m;
  453. },
  454. regexp: function(m, expectation) {
  455. m.test = function(actual) {
  456. return typeof actual === "string" && expectation.test(actual);
  457. };
  458. },
  459. string: function(m, expectation) {
  460. m.test = function(actual) {
  461. return (
  462. typeof actual === "string" &&
  463. stringIndexOf(actual, expectation) !== -1
  464. );
  465. };
  466. m.message = 'match("' + expectation + '")';
  467. }
  468. };
  469. function match(expectation, message) {
  470. var m = Object.create(matcher);
  471. var type = typeOf$1(expectation);
  472. if (type in TYPE_MAP) {
  473. TYPE_MAP[type](m, expectation, message);
  474. } else {
  475. m.test = function(actual) {
  476. return deepEqual$1(actual, expectation);
  477. };
  478. }
  479. if (!m.message) {
  480. m.message = "match(" + valueToString$3(expectation) + ")";
  481. }
  482. return m;
  483. }
  484. matcher.or = function(m2) {
  485. if (!arguments.length) {
  486. throw new TypeError("Matcher expected");
  487. } else if (!isMatcher(m2)) {
  488. m2 = match(m2);
  489. }
  490. var m1 = this;
  491. var or = Object.create(matcher);
  492. or.test = function(actual) {
  493. return m1.test(actual) || m2.test(actual);
  494. };
  495. or.message = m1.message + ".or(" + m2.message + ")";
  496. return or;
  497. };
  498. matcher.and = function(m2) {
  499. if (!arguments.length) {
  500. throw new TypeError("Matcher expected");
  501. } else if (!isMatcher(m2)) {
  502. m2 = match(m2);
  503. }
  504. var m1 = this;
  505. var and = Object.create(matcher);
  506. and.test = function(actual) {
  507. return m1.test(actual) && m2.test(actual);
  508. };
  509. and.message = m1.message + ".and(" + m2.message + ")";
  510. return and;
  511. };
  512. match.isMatcher = isMatcher;
  513. match.any = match(function() {
  514. return true;
  515. }, "any");
  516. match.defined = match(function(actual) {
  517. return actual !== null && actual !== undefined;
  518. }, "defined");
  519. match.truthy = match(function(actual) {
  520. return !!actual;
  521. }, "truthy");
  522. match.falsy = match(function(actual) {
  523. return !actual;
  524. }, "falsy");
  525. match.same = function(expectation) {
  526. return match(function(actual) {
  527. return expectation === actual;
  528. }, "same(" + valueToString$3(expectation) + ")");
  529. };
  530. match.in = function(arrayOfExpectations) {
  531. if (typeOf$1(arrayOfExpectations) !== "array") {
  532. throw new TypeError("array expected");
  533. }
  534. return match(function(actual) {
  535. return some(arrayOfExpectations, function(expectation) {
  536. return expectation === actual;
  537. });
  538. }, "in(" + valueToString$3(arrayOfExpectations) + ")");
  539. };
  540. match.typeOf = function(type) {
  541. assertType(type, "string", "type");
  542. return match(function(actual) {
  543. return typeOf$1(actual) === type;
  544. }, 'typeOf("' + type + '")');
  545. };
  546. match.instanceOf = function(type) {
  547. if (
  548. typeof Symbol === "undefined" ||
  549. typeof Symbol.hasInstance === "undefined"
  550. ) {
  551. assertType(type, "function", "type");
  552. } else {
  553. assertMethodExists(
  554. type,
  555. Symbol.hasInstance,
  556. "type",
  557. "[Symbol.hasInstance]"
  558. );
  559. }
  560. return match(function(actual) {
  561. return actual instanceof type;
  562. }, "instanceOf(" +
  563. (functionName(type) || Object.prototype.toString.call(type)) +
  564. ")");
  565. };
  566. function createPropertyMatcher(propertyTest, messagePrefix) {
  567. return function(property, value) {
  568. assertType(property, "string", "property");
  569. var onlyProperty = arguments.length === 1;
  570. var message = messagePrefix + '("' + property + '"';
  571. if (!onlyProperty) {
  572. message += ", " + valueToString$3(value);
  573. }
  574. message += ")";
  575. return match(function(actual) {
  576. if (
  577. actual === undefined ||
  578. actual === null ||
  579. !propertyTest(actual, property)
  580. ) {
  581. return false;
  582. }
  583. return onlyProperty || deepEqual$1(actual[property], value);
  584. }, message);
  585. };
  586. }
  587. match.has = createPropertyMatcher(function(actual, property) {
  588. if (typeof actual === "object") {
  589. return property in actual;
  590. }
  591. return actual[property] !== undefined;
  592. }, "has");
  593. match.hasOwn = createPropertyMatcher(function(actual, property) {
  594. return hasOwnProperty$1(actual, property);
  595. }, "hasOwn");
  596. match.hasNested = function(property, value) {
  597. assertType(property, "string", "property");
  598. var onlyProperty = arguments.length === 1;
  599. var message = 'hasNested("' + property + '"';
  600. if (!onlyProperty) {
  601. message += ", " + valueToString$3(value);
  602. }
  603. message += ")";
  604. return match(function(actual) {
  605. if (
  606. actual === undefined ||
  607. actual === null ||
  608. get(actual, property) === undefined
  609. ) {
  610. return false;
  611. }
  612. return onlyProperty || deepEqual$1(get(actual, property), value);
  613. }, message);
  614. };
  615. match.every = function(predicate) {
  616. if (!isMatcher(predicate)) {
  617. throw new TypeError("Matcher expected");
  618. }
  619. return match(function(actual) {
  620. if (typeOf$1(actual) === "object") {
  621. return every$1(Object.keys(actual), function(key) {
  622. return predicate.test(actual[key]);
  623. });
  624. }
  625. return (
  626. !!actual &&
  627. typeOf$1(actual.forEach) === "function" &&
  628. every$1(actual, function(element) {
  629. return predicate.test(element);
  630. })
  631. );
  632. }, "every(" + predicate.message + ")");
  633. };
  634. match.some = function(predicate) {
  635. if (!isMatcher(predicate)) {
  636. throw new TypeError("Matcher expected");
  637. }
  638. return match(function(actual) {
  639. if (typeOf$1(actual) === "object") {
  640. return !every$1(Object.keys(actual), function(key) {
  641. return !predicate.test(actual[key]);
  642. });
  643. }
  644. return (
  645. !!actual &&
  646. typeOf$1(actual.forEach) === "function" &&
  647. !every$1(actual, function(element) {
  648. return !predicate.test(element);
  649. })
  650. );
  651. }, "some(" + predicate.message + ")");
  652. };
  653. match.array = match.typeOf("array");
  654. match.array.deepEquals = function(expectation) {
  655. return match(function(actual) {
  656. // Comparing lengths is the fastest way to spot a difference before iterating through every item
  657. var sameLength = actual.length === expectation.length;
  658. return (
  659. typeOf$1(actual) === "array" &&
  660. sameLength &&
  661. every$1(actual, function(element, index) {
  662. var expected = expectation[index];
  663. return typeOf$1(expected) === "array" &&
  664. typeOf$1(element) === "array"
  665. ? match.array.deepEquals(expected).test(element)
  666. : deepEqual$1(expected, element);
  667. })
  668. );
  669. }, "deepEquals([" + iterableToString(expectation) + "])");
  670. };
  671. match.array.startsWith = function(expectation) {
  672. return match(function(actual) {
  673. return (
  674. typeOf$1(actual) === "array" &&
  675. every$1(expectation, function(expectedElement, index) {
  676. return actual[index] === expectedElement;
  677. })
  678. );
  679. }, "startsWith([" + iterableToString(expectation) + "])");
  680. };
  681. match.array.endsWith = function(expectation) {
  682. return match(function(actual) {
  683. // This indicates the index in which we should start matching
  684. var offset = actual.length - expectation.length;
  685. return (
  686. typeOf$1(actual) === "array" &&
  687. every$1(expectation, function(expectedElement, index) {
  688. return actual[offset + index] === expectedElement;
  689. })
  690. );
  691. }, "endsWith([" + iterableToString(expectation) + "])");
  692. };
  693. match.array.contains = function(expectation) {
  694. return match(function(actual) {
  695. return (
  696. typeOf$1(actual) === "array" &&
  697. every$1(expectation, function(expectedElement) {
  698. return arrayIndexOf(actual, expectedElement) !== -1;
  699. })
  700. );
  701. }, "contains([" + iterableToString(expectation) + "])");
  702. };
  703. match.map = match.typeOf("map");
  704. match.map.deepEquals = function mapDeepEquals(expectation) {
  705. return match(function(actual) {
  706. // Comparing lengths is the fastest way to spot a difference before iterating through every item
  707. var sameLength = actual.size === expectation.size;
  708. return (
  709. typeOf$1(actual) === "map" &&
  710. sameLength &&
  711. every$1(actual, function(element, key) {
  712. return expectation.has(key) && expectation.get(key) === element;
  713. })
  714. );
  715. }, "deepEquals(Map[" + iterableToString(expectation) + "])");
  716. };
  717. match.map.contains = function mapContains(expectation) {
  718. return match(function(actual) {
  719. return (
  720. typeOf$1(actual) === "map" &&
  721. every$1(expectation, function(element, key) {
  722. return actual.has(key) && actual.get(key) === element;
  723. })
  724. );
  725. }, "contains(Map[" + iterableToString(expectation) + "])");
  726. };
  727. match.set = match.typeOf("set");
  728. match.set.deepEquals = function setDeepEquals(expectation) {
  729. return match(function(actual) {
  730. // Comparing lengths is the fastest way to spot a difference before iterating through every item
  731. var sameLength = actual.size === expectation.size;
  732. return (
  733. typeOf$1(actual) === "set" &&
  734. sameLength &&
  735. every$1(actual, function(element) {
  736. return expectation.has(element);
  737. })
  738. );
  739. }, "deepEquals(Set[" + iterableToString(expectation) + "])");
  740. };
  741. match.set.contains = function setContains(expectation) {
  742. return match(function(actual) {
  743. return (
  744. typeOf$1(actual) === "set" &&
  745. every$1(expectation, function(element) {
  746. return actual.has(element);
  747. })
  748. );
  749. }, "contains(Set[" + iterableToString(expectation) + "])");
  750. };
  751. match.bool = match.typeOf("boolean");
  752. match.number = match.typeOf("number");
  753. match.string = match.typeOf("string");
  754. match.object = match.typeOf("object");
  755. match.func = match.typeOf("function");
  756. match.regexp = match.typeOf("regexp");
  757. match.date = match.typeOf("date");
  758. match.symbol = match.typeOf("symbol");
  759. var matcher_1 = match;
  760. var valueToString$4 = require$$0.valueToString;
  761. var deepEqual$2 = deepEqual.use(match$1); // eslint-disable-line no-use-before-define
  762. function arrayContains(array, subset, compare) {
  763. if (subset.length === 0) {
  764. return true;
  765. }
  766. var i, l, j, k;
  767. for (i = 0, l = array.length; i < l; ++i) {
  768. if (compare(array[i], subset[0])) {
  769. for (j = 0, k = subset.length; j < k; ++j) {
  770. if (i + j >= l) {
  771. return false;
  772. }
  773. if (!compare(array[i + j], subset[j])) {
  774. return false;
  775. }
  776. }
  777. return true;
  778. }
  779. }
  780. return false;
  781. }
  782. /**
  783. * @name samsam.match
  784. * @param Object object
  785. * @param Object matcher
  786. *
  787. * Compare arbitrary value ``object`` with matcher.
  788. */
  789. function match$1(object, matcher) {
  790. if (matcher && typeof matcher.test === "function") {
  791. return matcher.test(object);
  792. }
  793. if (typeof matcher === "function") {
  794. return matcher(object) === true;
  795. }
  796. if (typeof matcher === "string") {
  797. matcher = matcher.toLowerCase();
  798. var notNull = typeof object === "string" || !!object;
  799. return (
  800. notNull &&
  801. valueToString$4(object)
  802. .toLowerCase()
  803. .indexOf(matcher) >= 0
  804. );
  805. }
  806. if (typeof matcher === "number") {
  807. return matcher === object;
  808. }
  809. if (typeof matcher === "boolean") {
  810. return matcher === object;
  811. }
  812. if (typeof matcher === "undefined") {
  813. return typeof object === "undefined";
  814. }
  815. if (matcher === null) {
  816. return object === null;
  817. }
  818. if (object === null) {
  819. return false;
  820. }
  821. if (isSet_1(object)) {
  822. return isSubset_1(matcher, object, match$1);
  823. }
  824. if (getClass_1(object) === "Array" && getClass_1(matcher) === "Array") {
  825. return arrayContains(object, matcher, match$1);
  826. }
  827. if (isDate_1(matcher)) {
  828. return isDate_1(object) && object.getTime() === matcher.getTime();
  829. }
  830. if (matcher && typeof matcher === "object") {
  831. if (matcher === object) {
  832. return true;
  833. }
  834. if (typeof object !== "object") {
  835. return false;
  836. }
  837. var prop;
  838. // eslint-disable-next-line guard-for-in
  839. for (prop in matcher) {
  840. var value = object[prop];
  841. if (
  842. typeof value === "undefined" &&
  843. typeof object.getAttribute === "function"
  844. ) {
  845. value = object.getAttribute(prop);
  846. }
  847. if (
  848. matcher[prop] === null ||
  849. typeof matcher[prop] === "undefined"
  850. ) {
  851. if (value !== matcher[prop]) {
  852. return false;
  853. }
  854. } else if (
  855. typeof value === "undefined" ||
  856. !deepEqual$2(value, matcher[prop])
  857. ) {
  858. return false;
  859. }
  860. }
  861. return true;
  862. }
  863. throw new Error(
  864. "Matcher was not a string, a number, a " +
  865. "function, a boolean or an object"
  866. );
  867. }
  868. Object.keys(matcher_1).forEach(function(key) {
  869. match$1[key] = matcher_1[key];
  870. });
  871. var match_1 = match$1;
  872. var deepEqualCyclic$1 = deepEqual.use(match_1);
  873. var samsam = {
  874. createMatcher: matcher_1,
  875. deepEqual: deepEqualCyclic$1,
  876. identical: identical_1,
  877. isArguments: isArguments_1,
  878. isElement: isElement_1,
  879. isNegZero: isNegZero_1,
  880. isSet: isSet_1,
  881. match: match_1
  882. };
  883. var samsam_1 = samsam.createMatcher;
  884. var samsam_2 = samsam.deepEqual;
  885. var samsam_3 = samsam.identical;
  886. var samsam_4 = samsam.isArguments;
  887. var samsam_5 = samsam.isElement;
  888. var samsam_6 = samsam.isNegZero;
  889. var samsam_7 = samsam.isSet;
  890. var samsam_8 = samsam.match;
  891. exports.default = samsam;
  892. exports.createMatcher = samsam_1;
  893. exports.deepEqual = samsam_2;
  894. exports.identical = samsam_3;
  895. exports.isArguments = samsam_4;
  896. exports.isElement = samsam_5;
  897. exports.isNegZero = samsam_6;
  898. exports.isSet = samsam_7;
  899. exports.match = samsam_8;
  900. Object.defineProperty(exports, '__esModule', { value: true });
  901. })));