eql.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * Should
  3. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  4. * MIT Licensed
  5. */
  6. var eql = require('should-equal');
  7. var type = require('should-type');
  8. var util = require('../util');
  9. function formatEqlResult(r, a, b) {
  10. return ((r.path.length > 0 ? 'at ' + r.path.map(util.formatProp).join(' -> ') : '') +
  11. (r.a === a ? '' : ', A has ' + util.format(r.a)) +
  12. (r.b === b ? '' : ' and B has ' + util.format(r.b)) +
  13. (r.showReason ? ' because ' + r.reason : '')).trim();
  14. }
  15. module.exports = function(should, Assertion) {
  16. /**
  17. * Deep object equality comparison. For full spec see [`should-equal tests`](https://github.com/shouldjs/equal/blob/master/test.js).
  18. *
  19. * @name eql
  20. * @memberOf Assertion
  21. * @category assertion equality
  22. * @alias Assertion#deepEqual
  23. * @param {*} val Expected value
  24. * @param {string} [description] Optional message
  25. * @example
  26. *
  27. * (10).should.be.eql(10);
  28. * ('10').should.not.be.eql(10);
  29. * (-0).should.not.be.eql(+0);
  30. *
  31. * NaN.should.be.eql(NaN);
  32. *
  33. * ({ a: 10}).should.be.eql({ a: 10 });
  34. * [ 'a' ].should.not.be.eql({ '0': 'a' });
  35. */
  36. Assertion.add('eql', function(val, description) {
  37. this.params = {operator: 'to equal', expected: val, message: description};
  38. var result = eql(this.obj, val, should.config);
  39. this.params.details = result.result ? '' : formatEqlResult(result, this.obj, val);
  40. this.params.showDiff = eql(type(this.obj), type(val)).result;
  41. this.assert(result.result);
  42. });
  43. /**
  44. * Exact comparison using ===.
  45. *
  46. * @name equal
  47. * @memberOf Assertion
  48. * @category assertion equality
  49. * @alias Assertion#exactly
  50. * @param {*} val Expected value
  51. * @param {string} [description] Optional message
  52. * @example
  53. *
  54. * 10.should.be.equal(10);
  55. * 'a'.should.be.exactly('a');
  56. *
  57. * should(null).be.exactly(null);
  58. */
  59. Assertion.add('equal', function(val, description) {
  60. this.params = {operator: 'to be', expected: val, message: description};
  61. this.params.showDiff = eql(type(this.obj), type(val)).result;
  62. this.assert(val === this.obj);
  63. });
  64. Assertion.alias('equal', 'exactly');
  65. Assertion.alias('eql', 'deepEqual');
  66. function addOneOf(name, message, method) {
  67. Assertion.add(name, function(vals) {
  68. if(arguments.length !== 1) {
  69. vals = Array.prototype.slice.call(arguments);
  70. } else {
  71. should(vals).be.Array();
  72. }
  73. this.params = {operator: message, expected: vals};
  74. var obj = this.obj;
  75. var found = false;
  76. util.forEach(vals, function(val) {
  77. try {
  78. should(val)[method](obj);
  79. found = true;
  80. return false;
  81. } catch(e) {
  82. if(e instanceof should.AssertionError) {
  83. return;//do nothing
  84. }
  85. throw e;
  86. }
  87. });
  88. this.assert(found);
  89. });
  90. }
  91. /**
  92. * Exact comparison using === to be one of supplied objects.
  93. *
  94. * @name equalOneOf
  95. * @memberOf Assertion
  96. * @category assertion equality
  97. * @param {Array|*} vals Expected values
  98. * @example
  99. *
  100. * 'ab'.should.be.equalOneOf('a', 10, 'ab');
  101. * 'ab'.should.be.equalOneOf(['a', 10, 'ab']);
  102. */
  103. addOneOf('equalOneOf', 'to be equals one of', 'equal');
  104. /**
  105. * Exact comparison using .eql to be one of supplied objects.
  106. *
  107. * @name oneOf
  108. * @memberOf Assertion
  109. * @category assertion equality
  110. * @param {Array|*} vals Expected values
  111. * @example
  112. *
  113. * ({a: 10}).should.be.oneOf('a', 10, 'ab', {a: 10});
  114. * ({a: 10}).should.be.oneOf(['a', 10, 'ab', {a: 10}]);
  115. */
  116. addOneOf('oneOf', 'to be one of', 'eql');
  117. };