assertions.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*!
  2. * chai
  3. * http://chaijs.com
  4. * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
  5. * MIT Licensed
  6. */
  7. module.exports = function (chai, _) {
  8. var Assertion = chai.Assertion
  9. , toString = Object.prototype.toString
  10. , flag = _.flag;
  11. /**
  12. * ### Language Chains
  13. *
  14. * The following are provided as chainable getters to
  15. * improve the readability of your assertions. They
  16. * do not provide testing capabilities unless they
  17. * have been overwritten by a plugin.
  18. *
  19. * **Chains**
  20. *
  21. * - to
  22. * - be
  23. * - been
  24. * - is
  25. * - that
  26. * - which
  27. * - and
  28. * - has
  29. * - have
  30. * - with
  31. * - at
  32. * - of
  33. * - same
  34. *
  35. * @name language chains
  36. * @api public
  37. */
  38. [ 'to', 'be', 'been'
  39. , 'is', 'and', 'has', 'have'
  40. , 'with', 'that', 'which', 'at', 'does'
  41. , 'of', 'same' ].forEach(function (chain) {
  42. Assertion.addProperty(chain, function () {
  43. flag(this, chain, true);
  44. return this;
  45. });
  46. });
  47. /**
  48. * ### .not
  49. *
  50. * Negates any of assertions following in the chain.
  51. *
  52. * expect(foo).to.not.equal('bar');
  53. * expect(goodFn).to.not.throw(Error);
  54. * expect({ foo: 'baz' }).to.have.property('foo')
  55. * .and.not.equal('bar');
  56. *
  57. * @name not
  58. * @api public
  59. */
  60. Assertion.addProperty('not', function () {
  61. flag(this, 'negate', true);
  62. });
  63. /**
  64. * ### .deep
  65. *
  66. * Sets the `deep` flag, later used by the `equal` and
  67. * `property` assertions.
  68. *
  69. * expect(foo).to.deep.equal({ bar: 'baz' });
  70. * expect({ foo: { bar: { baz: 'quux' } } })
  71. * .to.have.deep.property('foo.bar.baz', 'quux');
  72. *
  73. * `.deep.property` special characters can be escaped
  74. * by adding two slashes before the `.` or `[]`.
  75. *
  76. * var deepCss = { '.link': { '[target]': 42 }};
  77. * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42);
  78. *
  79. * @name deep
  80. * @api public
  81. */
  82. Assertion.addProperty('deep', function () {
  83. flag(this, 'deep', true);
  84. });
  85. /**
  86. * ### .any
  87. *
  88. * Sets the `any` flag, (opposite of the `all` flag)
  89. * later used in the `keys` assertion.
  90. *
  91. * expect(foo).to.have.any.keys('bar', 'baz');
  92. *
  93. * @name any
  94. * @api public
  95. */
  96. Assertion.addProperty('any', function () {
  97. flag(this, 'any', true);
  98. flag(this, 'all', false)
  99. });
  100. /**
  101. * ### .all
  102. *
  103. * Sets the `all` flag (opposite of the `any` flag)
  104. * later used by the `keys` assertion.
  105. *
  106. * expect(foo).to.have.all.keys('bar', 'baz');
  107. *
  108. * @name all
  109. * @api public
  110. */
  111. Assertion.addProperty('all', function () {
  112. flag(this, 'all', true);
  113. flag(this, 'any', false);
  114. });
  115. /**
  116. * ### .include(value)
  117. *
  118. * The `include` and `contain` assertions can be used as either property
  119. * based language chains or as methods to assert the inclusion of an object
  120. * in an array or a substring in a string. When used as language chains,
  121. * they toggle the `contains` flag for the `keys` assertion.
  122. *
  123. * expect([1,2,3]).to.include(2);
  124. * expect('foobar').to.contain('foo');
  125. * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');
  126. *
  127. * @name include
  128. * @alias contain
  129. * @alias includes
  130. * @alias contains
  131. * @param {Object|String|Number} obj
  132. * @param {String} message _optional_
  133. * @api public
  134. */
  135. function includeChainingBehavior () {
  136. flag(this, 'contains', true);
  137. }
  138. function include (val, msg) {
  139. if (msg) {
  140. flag(this, 'message', msg);
  141. }
  142. flag(this, 'contains', val);
  143. var obj = flag(this, 'attributeFlag') ||
  144. flag(this, 'textFlag') ||
  145. flag(this, 'cssFlag') ||
  146. flag(this, 'valueFlag');
  147. if (!obj) {
  148. throw new Error('Expect expression error: attribute, value or text is missing.');
  149. }
  150. }
  151. Assertion.addChainableMethod('include', include, includeChainingBehavior);
  152. Assertion.addChainableMethod('contain', include, includeChainingBehavior);
  153. Assertion.addChainableMethod('contains', include, includeChainingBehavior);
  154. Assertion.addChainableMethod('includes', include, includeChainingBehavior);
  155. function startWith (val, msg) {
  156. if (msg) {
  157. flag(this, 'message', msg);
  158. }
  159. flag(this, 'startsWith', val);
  160. var obj = flag(this, 'attributeFlag') ||
  161. flag(this, 'textFlag') ||
  162. flag(this, 'cssFlag') ||
  163. flag(this, 'valueFlag');
  164. if (!obj) {
  165. throw new Error('Expect expression error: attribute, value or text is missing.');
  166. }
  167. }
  168. Assertion.addMethod('startWith', startWith);
  169. Assertion.addMethod('startsWith', startWith);
  170. function endWidth (val, msg) {
  171. if (msg) {
  172. flag(this, 'message', msg);
  173. }
  174. flag(this, 'endsWidth', val);
  175. var obj = flag(this, 'attributeFlag') ||
  176. flag(this, 'textFlag') ||
  177. flag(this, 'cssFlag') ||
  178. flag(this, 'valueFlag');
  179. if (!obj) {
  180. throw new Error('Expect expression error: attribute, value or text is missing.');
  181. }
  182. }
  183. Assertion.addMethod('endWidth', endWidth);
  184. Assertion.addMethod('endsWidth', endWidth);
  185. /**
  186. * ### .match(regexp)
  187. *
  188. * Asserts that the target matches a regular expression.
  189. *
  190. * expect('foobar').to.match(/^foo/);
  191. *
  192. * @name match
  193. * @param {RegExp} RegularExpression
  194. * @param {String} message _optional_
  195. * @api public
  196. */
  197. function matches(re, msg) {
  198. if (!(re instanceof RegExp)) {
  199. throw new Error('matches requires first paramter to be a RegExp. ' + (typeof re) + ' given.');
  200. }
  201. if (msg) {
  202. flag(this, 'message', msg);
  203. }
  204. flag(this, 'matches', re);
  205. var obj = flag(this, 'attributeFlag') ||
  206. flag(this, 'textFlag') ||
  207. flag(this, 'cssFlag') ||
  208. flag(this, 'valueFlag');
  209. if (!obj) {
  210. throw new Error('Expect expression error: attribute, value or text is missing.');
  211. }
  212. }
  213. Assertion.addMethod('match', matches);
  214. Assertion.addMethod('matches', matches);
  215. /**
  216. * ### .equal(value)
  217. *
  218. * Asserts that the target is strictly equal (`===`) to `value`.
  219. * Alternately, if the `deep` flag is set, asserts that
  220. * the target is deeply equal to `value`.
  221. *
  222. * expect('hello').to.equal('hello');
  223. * expect(42).to.equal(42);
  224. * expect(1).to.not.equal(true);
  225. * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });
  226. * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });
  227. *
  228. * @name equal
  229. * @alias equals
  230. * @alias eq
  231. * @alias deep.equal
  232. * @param {Mixed} value
  233. * @param {String} message _optional_
  234. * @api public
  235. */
  236. function assertEqual (val, msg) {
  237. if (msg) {
  238. flag(this, 'message', msg);
  239. }
  240. flag(this, 'equal', val);
  241. }
  242. Assertion.addMethod('equal', assertEqual);
  243. Assertion.addMethod('equals', assertEqual);
  244. Assertion.addMethod('eq', assertEqual);
  245. };