/dist/matchers.js

https://gitlab.com/warmsys-public/warmsys-jasmine-matchers · JavaScript · 434 lines · 405 code · 28 blank · 1 comment · 66 complexity · e2f4ab668895aee0991ac29c426ff7a7 MD5 · raw file

  1. var getTextForJQueryElement = function($element)
  2. {
  3. var text = 'null';
  4. var element;
  5. if(element = $element.get(0))
  6. {
  7. text = element.nodeName.toLowerCase();
  8. if(element.id)
  9. {
  10. text += "#"+element.id;
  11. }
  12. if(element.className)
  13. {
  14. text += "."+element.className.replace(/\s+/g, ".");
  15. }
  16. }
  17. return text;
  18. };
  19. var objectContains = function(expected, actual, identifier)
  20. {
  21. var result = {pass: false};
  22. var mismatchedExpects = {};
  23. _.each(expected, function(value, key)
  24. {
  25. if(!_.isEqual(actual[key], value))
  26. {
  27. mismatchedExpects[key] = actual[key] === undefined ? "undefined" : actual[key];
  28. }
  29. });
  30. result.pass = _.isEmpty(mismatchedExpects);
  31. if(result.pass)
  32. {
  33. result.message = 'Expected '+ identifier + ' not to have been called with '+JSON.stringify(expected)+', called with '+JSON.stringify(actual)+', missing matches for '+JSON.stringify(mismatchedExpects);
  34. }
  35. else
  36. {
  37. result.message = 'Expected '+ identifier + ' to have been called with at least '+JSON.stringify(expected)+', called with '+JSON.stringify(actual)+', missing matches for '+JSON.stringify(mismatchedExpects);
  38. }
  39. return result;
  40. };
  41. var customMatchers = {
  42. toBeArray: function (util, customEqualityTesters) {
  43. return {
  44. compare: function (actual, expected) {
  45. if (expected === undefined) {
  46. expected = '';
  47. }
  48. var result = {};
  49. result.pass = actual instanceof Array;
  50. if (result.pass)
  51. {
  52. result.message = "Expected " + actual + " not to be array";
  53. }
  54. else
  55. {
  56. result.message = "Expected " + actual + " to be array";
  57. }
  58. return result;
  59. }
  60. };
  61. },
  62. toBeNumber: function (util, customEqualityTesters)
  63. {
  64. return {
  65. compare: function (actual)
  66. {
  67. var result = {};
  68. result.pass = Object.prototype.toString.call(actual) == '[object Number]';
  69. if(result.pass)
  70. {
  71. result.message = "Expected " + actual + " not to be number";
  72. }
  73. else
  74. {
  75. result.message = "Expected " + actual + " to be number";
  76. }
  77. return result;
  78. }
  79. };
  80. },
  81. toBeObject: function (util, customEqualityTesters)
  82. {
  83. return {
  84. compare: function (actual)
  85. {
  86. var result = {};
  87. result.pass = Object.prototype.toString.call(actual) == '[object Object]';
  88. if(result.pass)
  89. {
  90. result.message = "Expected " + actual + " not to be plain object";
  91. }
  92. else
  93. {
  94. result.message = "Expected " + actual + " to be plain object";
  95. }
  96. return result;
  97. }
  98. };
  99. },
  100. toBeString: function (util, customEqualityTesters)
  101. {
  102. return {
  103. compare: function (actual)
  104. {
  105. var result = {};
  106. result.pass = Object.prototype.toString.call(actual) == '[object String]';
  107. if(result.pass)
  108. {
  109. result.message = "Expected " + actual + " not to be string";
  110. }
  111. else
  112. {
  113. result.message = "Expected " + actual + " to be string";
  114. }
  115. return result;
  116. }
  117. };
  118. },
  119. toBeInstanceOf: function (util, customEqualityTesters) {
  120. return {
  121. compare: function (actual, expected) {
  122. var result = {};
  123. result.pass = actual instanceof expected;
  124. if (result.pass) {
  125. result.message = "Expected " + actual + " not to be instance of " + expected;
  126. } else {
  127. result.message = "Expected " + actual + " to be instance of " + expected;
  128. }
  129. return result;
  130. }
  131. };
  132. },
  133. toBeInRange: function (util, customEqualityTesters) {
  134. return {
  135. compare: function (actual, a, b) {
  136. var result = {};
  137. result.pass = actual <= b && actual >= a;
  138. if (result.pass) {
  139. result.message = "Expected " + actual + " not to be in range " + a + " - " + b;
  140. } else {
  141. result.message = "Expected " + actual + " to be in range " + a + " - " + b;
  142. }
  143. return result;
  144. }
  145. };
  146. },
  147. toBePresent: function (util, customEqualityTesters) {
  148. return {
  149. compare: function (actual) {
  150. var result = {};
  151. if((actual instanceof jQuery) === false)
  152. {
  153. result.pass = false;
  154. result.message = 'Expected '+actual+' to be a jQuery object';
  155. }
  156. else
  157. {
  158. if(jQuery.contains(document, actual[0]))
  159. {
  160. result.pass = actual.is(':visible');
  161. }
  162. else
  163. {
  164. result.pass = actual.length === 1 && actual.css('display') !== 'none';
  165. }
  166. if (result.pass) {
  167. result.message = "Expected " + actual.selector + " not to be present";
  168. } else {
  169. result.message = "Expected " + actual.selector + " to be present";
  170. }
  171. }
  172. return result;
  173. }
  174. };
  175. },
  176. toBeHidden: function (util, customEqualityTesters) {
  177. return {
  178. compare: function (actual) {
  179. var result = {};
  180. if((actual instanceof jQuery) === false)
  181. {
  182. result.pass = false;
  183. result.message = 'Expected '+actual+' to be a jQuery object';
  184. }
  185. else
  186. {
  187. if(jQuery.contains(document, actual[0]))
  188. {
  189. result.pass = actual.is(':hidden');
  190. }
  191. else
  192. {
  193. result.pass = actual.length === 1 && actual.css('display') === 'none';
  194. }
  195. if (result.pass) {
  196. result.message = "Expected " + actual.selector + " not to be hidden";
  197. } else {
  198. result.message = "Expected " + actual.selector + " to be hidden";
  199. }
  200. }
  201. return result;
  202. }
  203. };
  204. },
  205. toContainAtleast: function ()
  206. {
  207. return {
  208. compare: function (actual, expected) {
  209. return objectContains(expected, actual, "object");
  210. }
  211. };
  212. },
  213. toHaveBeenCalledWithAtleast: function () {
  214. return {
  215. compare: function() {
  216. var args = Array.prototype.slice.call(arguments, 0);
  217. var actual = args[0];
  218. var expectedOptions = args.slice(1).pop();
  219. var result = {pass: false};
  220. var identity = _.isFunction(actual.and.identity) ? actual.and.identity() : actual.and.identity;
  221. if (arguments.length > 2) {
  222. throw new Error('toHaveBeenCalledWithAtleast does not take more than 1 argument');
  223. }
  224. if (!jasmine.isSpy(actual)) {
  225. throw new Error('Expected a spy, but got ' + jasmine.pp(actual) + '.');
  226. }
  227. if (!actual.calls.any()) {
  228. result.message = "Expected spy " + identity + " to have been called with " + jasmine.pp(expectedOptions) + " but it was never called.";
  229. return result;
  230. }
  231. var calledArgs = actual.calls.mostRecent().args[0] || {};
  232. return objectContains(expectedOptions, calledArgs, "spy " + identity);
  233. }
  234. };
  235. },
  236. toContainJQueryElement: function (util, customEqualityTesters) {
  237. return {
  238. compare: function (haystack, needle) {
  239. var result = {};
  240. if((haystack instanceof jQuery) == false)
  241. {
  242. result.pass = false;
  243. result.message = 'Expected '+haystack+' to be a jQuery object';
  244. }
  245. else if((needle instanceof jQuery) == false)
  246. {
  247. result.pass = false;
  248. result.message = 'Expected '+needle+' to be a jQuery object';
  249. }
  250. else
  251. {
  252. result.pass = jQuery.contains(haystack.get(0), needle.get(0));
  253. var getTextForJQueryElement = function(parentElement)
  254. {
  255. var text = 'null';
  256. if(needle.get(0))
  257. {
  258. var element = parentElement.get(0);
  259. text = element.nodeName.toLowerCase();
  260. if(element.id)
  261. {
  262. text += "#"+element.id;
  263. }
  264. if(element.className)
  265. {
  266. text += "."+element.className.replace(/\s+/g, ".");
  267. }
  268. }
  269. return text;
  270. };
  271. var haystackText = getTextForJQueryElement(haystack);
  272. var needleText = getTextForJQueryElement(needle);
  273. if (result.pass) {
  274. result.message = "Expected " + needleText + " not to be found within "+haystackText;
  275. } else {
  276. result.message = "Expected " + needleText + " to be found within "+haystackText;
  277. }
  278. }
  279. return result;
  280. }
  281. };
  282. },
  283. toBeJQueryElement: function (util, customEqualityTesters) {
  284. return {
  285. compare: function (expected, actual) {
  286. var result = {};
  287. if((expected instanceof jQuery) == false)
  288. {
  289. result.pass = false;
  290. result.message = 'Expected '+expected+' to be a jQuery object';
  291. }
  292. else if((actual instanceof jQuery) == false)
  293. {
  294. result.pass = false;
  295. result.message = 'Expected '+actual+' to be a jQuery object';
  296. }
  297. else
  298. {
  299. result.pass = expected.is(actual);
  300. var expectedText = getTextForJQueryElement(expected);
  301. var actualText = getTextForJQueryElement(actual);
  302. if (result.pass) {
  303. result.message = "Expected " + actualText + " not to be " + expectedText;
  304. } else {
  305. result.message = "Expected " + actualText + " to be " + expectedText;
  306. }
  307. }
  308. return result;
  309. }
  310. };
  311. },
  312. toHaveBeenCalledXTimes: function (util, customEqualityTesters) {
  313. return {
  314. compare: function (spy, expectedCount) {
  315. var result = {};
  316. var actualCount = spy.calls.count();
  317. result.pass = actualCount == expectedCount;
  318. if (result.pass) {
  319. result.message = "Expected spy not to have been called " + expectedCount + " times";
  320. } else {
  321. result.message = "Expected spy to have been called " + expectedCount + " times, was called " + actualCount + " times";
  322. }
  323. return result;
  324. }
  325. };
  326. },
  327. toBeAJQueryPromise: function (util, customEqualityTesters)
  328. {
  329. return {
  330. compare: function (actual, oneOf)
  331. {
  332. var result = {
  333. pass: true
  334. };
  335. if(!_.isObject(actual) || !_.isFunction(actual['then']) || !_.isFunction(actual['fail']) || !_.isFunction(actual['done']) || !_.isFunction(actual['always']) || !_.isFunction(actual['progress']))
  336. {
  337. result.pass = false;
  338. }
  339. if(result.pass)
  340. {
  341. result.message = "Expected " + actual + " not to be a JQuery Promise";
  342. }
  343. else
  344. {
  345. result.message = "Expected " + actual + " to be a JQuery Promise";
  346. }
  347. return result;
  348. }
  349. }
  350. },
  351. toHaveOwnProperties: function (util, customEqualityTesters)
  352. {
  353. return {
  354. compare: function (actual)
  355. {
  356. var result = {};
  357. var args = [].splice.call(arguments, 0);
  358. //remove first argument
  359. args.splice(0, 1);
  360. var missing = [];
  361. result.pass = true;
  362. args.forEach(function (propertyName)
  363. {
  364. if (!(propertyName in actual))
  365. {
  366. result.pass = false;
  367. missing.push(propertyName);
  368. }
  369. });
  370. if (!result.pass)
  371. {
  372. result.message = "Expected object to contain " + missing.join(', ') + ' but they contained ' + Object.keys(actual).join(', ');
  373. }
  374. return result;
  375. }
  376. }
  377. },
  378. toBeOneOf: function (util, customEqualityTesters)
  379. {
  380. return {
  381. compare: function (actual, oneOf)
  382. {
  383. var result = {};
  384. var match = 0;
  385. result.pass = true;
  386. oneOf.forEach(function (oneOfString)
  387. {
  388. if (oneOfString == actual)
  389. {
  390. match++;
  391. }
  392. });
  393. if(!match)
  394. {
  395. result.pass = false;
  396. result.message = "Expected object to contain " + missing.join(', ') + ' but they contained ' + Object.keys(actual).join(', ');
  397. }
  398. return result;
  399. }
  400. }
  401. }
  402. };
  403. beforeEach(function()
  404. {
  405. jasmine.addMatchers(customMatchers);
  406. });