should.js 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797
  1. 'use strict';
  2. function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
  3. var getType = _interopDefault(require('should-type'));
  4. var eql = _interopDefault(require('should-equal'));
  5. var sformat = _interopDefault(require('should-format'));
  6. var shouldTypeAdaptors = require('should-type-adaptors');
  7. var shouldUtil = require('should-util');
  8. /*
  9. * should.js - assertion library
  10. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  11. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  12. * MIT Licensed
  13. */
  14. function isWrapperType(obj) {
  15. return obj instanceof Number ||
  16. obj instanceof String ||
  17. obj instanceof Boolean;
  18. }
  19. // XXX make it more strict: numbers, strings, symbols - and nothing else
  20. function convertPropertyName(name) {
  21. return (typeof name === 'symbol') ? name : String(name);
  22. }
  23. var functionName = sformat.functionName;
  24. /*
  25. * should.js - assertion library
  26. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  27. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  28. * MIT Licensed
  29. */
  30. var config = {
  31. typeAdaptors: shouldTypeAdaptors.defaultTypeAdaptorStorage,
  32. getFormatter: function(opts) {
  33. return new sformat.Formatter(opts || config);
  34. }
  35. };
  36. function format(value, opts) {
  37. return config.getFormatter(opts).format(value);
  38. }
  39. function formatProp(value) {
  40. var formatter = config.getFormatter();
  41. return sformat.formatPlainObjectKey.call(formatter, value);
  42. }
  43. /*
  44. * should.js - assertion library
  45. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  46. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  47. * MIT Licensed
  48. */
  49. /**
  50. * should AssertionError
  51. * @param {Object} options
  52. * @constructor
  53. * @memberOf should
  54. * @static
  55. */
  56. function AssertionError(options) {
  57. shouldUtil.merge(this, options);
  58. if (!options.message) {
  59. Object.defineProperty(this, 'message', {
  60. get: function() {
  61. if (!this._message) {
  62. this._message = this.generateMessage();
  63. this.generatedMessage = true;
  64. }
  65. return this._message;
  66. },
  67. configurable: true,
  68. enumerable: false
  69. }
  70. );
  71. }
  72. if (Error.captureStackTrace) {
  73. Error.captureStackTrace(this, this.stackStartFunction);
  74. } else {
  75. // non v8 browsers so we can have a stacktrace
  76. var err = new Error();
  77. if (err.stack) {
  78. var out = err.stack;
  79. if (this.stackStartFunction) {
  80. // try to strip useless frames
  81. var fn_name = functionName(this.stackStartFunction);
  82. var idx = out.indexOf('\n' + fn_name);
  83. if (idx >= 0) {
  84. // once we have located the function frame
  85. // we need to strip out everything before it (and its line)
  86. var next_line = out.indexOf('\n', idx + 1);
  87. out = out.substring(next_line + 1);
  88. }
  89. }
  90. this.stack = out;
  91. }
  92. }
  93. }
  94. var indent = ' ';
  95. function prependIndent(line) {
  96. return indent + line;
  97. }
  98. function indentLines(text) {
  99. return text.split('\n').map(prependIndent).join('\n');
  100. }
  101. // assert.AssertionError instanceof Error
  102. AssertionError.prototype = Object.create(Error.prototype, {
  103. name: {
  104. value: 'AssertionError'
  105. },
  106. generateMessage: {
  107. value: function() {
  108. if (!this.operator && this.previous) {
  109. return this.previous.message;
  110. }
  111. var actual = format(this.actual);
  112. var expected = 'expected' in this ? ' ' + format(this.expected) : '';
  113. var details = 'details' in this && this.details ? ' (' + this.details + ')' : '';
  114. var previous = this.previous ? '\n' + indentLines(this.previous.message) : '';
  115. return 'expected ' + actual + (this.negate ? ' not ' : ' ') + this.operator + expected + details + previous;
  116. }
  117. }
  118. });
  119. /*
  120. * should.js - assertion library
  121. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  122. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  123. * MIT Licensed
  124. */
  125. // a bit hacky way how to get error to do not have stack
  126. function LightAssertionError(options) {
  127. shouldUtil.merge(this, options);
  128. if (!options.message) {
  129. Object.defineProperty(this, 'message', {
  130. get: function() {
  131. if (!this._message) {
  132. this._message = this.generateMessage();
  133. this.generatedMessage = true;
  134. }
  135. return this._message;
  136. }
  137. });
  138. }
  139. }
  140. LightAssertionError.prototype = {
  141. generateMessage: AssertionError.prototype.generateMessage
  142. };
  143. /**
  144. * should Assertion
  145. * @param {*} obj Given object for assertion
  146. * @constructor
  147. * @memberOf should
  148. * @static
  149. */
  150. function Assertion(obj) {
  151. this.obj = obj;
  152. this.anyOne = false;
  153. this.negate = false;
  154. this.params = {actual: obj};
  155. }
  156. Assertion.prototype = {
  157. constructor: Assertion,
  158. /**
  159. * Base method for assertions.
  160. *
  161. * Before calling this method need to fill Assertion#params object. This method usually called from other assertion methods.
  162. * `Assertion#params` can contain such properties:
  163. * * `operator` - required string containing description of this assertion
  164. * * `obj` - optional replacement for this.obj, it usefull if you prepare more clear object then given
  165. * * `message` - if this property filled with string any others will be ignored and this one used as assertion message
  166. * * `expected` - any object used when you need to assert relation between given object and expected. Like given == expected (== is a relation)
  167. * * `details` - additional string with details to generated message
  168. *
  169. * @memberOf Assertion
  170. * @category assertion
  171. * @param {*} expr Any expression that will be used as a condition for asserting.
  172. * @example
  173. *
  174. * var a = new should.Assertion(42);
  175. *
  176. * a.params = {
  177. * operator: 'to be magic number',
  178. * }
  179. *
  180. * a.assert(false);
  181. * //throws AssertionError: expected 42 to be magic number
  182. */
  183. assert: function(expr) {
  184. if (expr) {
  185. return this;
  186. }
  187. var params = this.params;
  188. if ('obj' in params && !('actual' in params)) {
  189. params.actual = params.obj;
  190. } else if (!('obj' in params) && !('actual' in params)) {
  191. params.actual = this.obj;
  192. }
  193. params.stackStartFunction = params.stackStartFunction || this.assert;
  194. params.negate = this.negate;
  195. params.assertion = this;
  196. if (this.light) {
  197. throw new LightAssertionError(params);
  198. } else {
  199. throw new AssertionError(params);
  200. }
  201. },
  202. /**
  203. * Shortcut for `Assertion#assert(false)`.
  204. *
  205. * @memberOf Assertion
  206. * @category assertion
  207. * @example
  208. *
  209. * var a = new should.Assertion(42);
  210. *
  211. * a.params = {
  212. * operator: 'to be magic number',
  213. * }
  214. *
  215. * a.fail();
  216. * //throws AssertionError: expected 42 to be magic number
  217. */
  218. fail: function() {
  219. return this.assert(false);
  220. }
  221. };
  222. /**
  223. * Assertion used to delegate calls of Assertion methods inside of Promise.
  224. * It has almost all methods of Assertion.prototype
  225. *
  226. * @param {Promise} obj
  227. */
  228. function PromisedAssertion(/* obj */) {
  229. Assertion.apply(this, arguments);
  230. }
  231. /**
  232. * Make PromisedAssertion to look like promise. Delegate resolve and reject to given promise.
  233. *
  234. * @private
  235. * @returns {Promise}
  236. */
  237. PromisedAssertion.prototype.then = function(resolve, reject) {
  238. return this.obj.then(resolve, reject);
  239. };
  240. /**
  241. * Way to extend Assertion function. It uses some logic
  242. * to define only positive assertions and itself rule with negative assertion.
  243. *
  244. * All actions happen in subcontext and this method take care about negation.
  245. * Potentially we can add some more modifiers that does not depends from state of assertion.
  246. *
  247. * @memberOf Assertion
  248. * @static
  249. * @param {String} name Name of assertion. It will be used for defining method or getter on Assertion.prototype
  250. * @param {Function} func Function that will be called on executing assertion
  251. * @example
  252. *
  253. * Assertion.add('asset', function() {
  254. * this.params = { operator: 'to be asset' }
  255. *
  256. * this.obj.should.have.property('id').which.is.a.Number()
  257. * this.obj.should.have.property('path')
  258. * })
  259. */
  260. Assertion.add = function(name, func) {
  261. Object.defineProperty(Assertion.prototype, name, {
  262. enumerable: true,
  263. configurable: true,
  264. value: function() {
  265. var context = new Assertion(this.obj, this, name);
  266. context.anyOne = this.anyOne;
  267. context.onlyThis = this.onlyThis;
  268. // hack
  269. context.light = true;
  270. try {
  271. func.apply(context, arguments);
  272. } catch (e) {
  273. // check for fail
  274. if (e instanceof AssertionError || e instanceof LightAssertionError) {
  275. // negative fail
  276. if (this.negate) {
  277. this.obj = context.obj;
  278. this.negate = false;
  279. return this;
  280. }
  281. if (context !== e.assertion) {
  282. context.params.previous = e;
  283. }
  284. // positive fail
  285. context.negate = false;
  286. // hack
  287. context.light = false;
  288. context.fail();
  289. }
  290. // throw if it is another exception
  291. throw e;
  292. }
  293. // negative pass
  294. if (this.negate) {
  295. context.negate = true; // because .fail will set negate
  296. context.params.details = 'false negative fail';
  297. // hack
  298. context.light = false;
  299. context.fail();
  300. }
  301. // positive pass
  302. if (!this.params.operator) {
  303. this.params = context.params; // shortcut
  304. }
  305. this.obj = context.obj;
  306. this.negate = false;
  307. return this;
  308. }
  309. });
  310. Object.defineProperty(PromisedAssertion.prototype, name, {
  311. enumerable: true,
  312. configurable: true,
  313. value: function() {
  314. var args = arguments;
  315. this.obj = this.obj.then(function(a) {
  316. return a[name].apply(a, args);
  317. });
  318. return this;
  319. }
  320. });
  321. };
  322. /**
  323. * Add chaining getter to Assertion like .a, .which etc
  324. *
  325. * @memberOf Assertion
  326. * @static
  327. * @param {string} name name of getter
  328. * @param {function} [onCall] optional function to call
  329. */
  330. Assertion.addChain = function(name, onCall) {
  331. onCall = onCall || function() {};
  332. Object.defineProperty(Assertion.prototype, name, {
  333. get: function() {
  334. onCall.call(this);
  335. return this;
  336. },
  337. enumerable: true
  338. });
  339. Object.defineProperty(PromisedAssertion.prototype, name, {
  340. enumerable: true,
  341. configurable: true,
  342. get: function() {
  343. this.obj = this.obj.then(function(a) {
  344. return a[name];
  345. });
  346. return this;
  347. }
  348. });
  349. };
  350. /**
  351. * Create alias for some `Assertion` property
  352. *
  353. * @memberOf Assertion
  354. * @static
  355. * @param {String} from Name of to map
  356. * @param {String} to Name of alias
  357. * @example
  358. *
  359. * Assertion.alias('true', 'True')
  360. */
  361. Assertion.alias = function(from, to) {
  362. var desc = Object.getOwnPropertyDescriptor(Assertion.prototype, from);
  363. if (!desc) {
  364. throw new Error('Alias ' + from + ' -> ' + to + ' could not be created as ' + from + ' not defined');
  365. }
  366. Object.defineProperty(Assertion.prototype, to, desc);
  367. var desc2 = Object.getOwnPropertyDescriptor(PromisedAssertion.prototype, from);
  368. if (desc2) {
  369. Object.defineProperty(PromisedAssertion.prototype, to, desc2);
  370. }
  371. };
  372. /**
  373. * Negation modifier. Current assertion chain become negated. Each call invert negation on current assertion.
  374. *
  375. * @name not
  376. * @property
  377. * @memberOf Assertion
  378. * @category assertion
  379. */
  380. Assertion.addChain('not', function() {
  381. this.negate = !this.negate;
  382. });
  383. /**
  384. * Any modifier - it affect on execution of sequenced assertion to do not `check all`, but `check any of`.
  385. *
  386. * @name any
  387. * @property
  388. * @memberOf Assertion
  389. * @category assertion
  390. */
  391. Assertion.addChain('any', function() {
  392. this.anyOne = true;
  393. });
  394. /**
  395. * Only modifier - currently used with .keys to check if object contains only exactly this .keys
  396. *
  397. * @name only
  398. * @property
  399. * @memberOf Assertion
  400. * @category assertion
  401. */
  402. Assertion.addChain('only', function() {
  403. this.onlyThis = true;
  404. });
  405. // implement assert interface using already written peaces of should.js
  406. // http://wiki.commonjs.org/wiki/Unit_Testing/1.0
  407. //
  408. // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
  409. //
  410. // Originally from narwhal.js (http://narwhaljs.org)
  411. // Copyright (c) 2009 Thomas Robinson <280north.com>
  412. //
  413. // Permission is hereby granted, free of charge, to any person obtaining a copy
  414. // of this software and associated documentation files (the 'Software'), to
  415. // deal in the Software without restriction, including without limitation the
  416. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  417. // sell copies of the Software, and to permit persons to whom the Software is
  418. // furnished to do so, subject to the following conditions:
  419. //
  420. // The above copyright notice and this permission notice shall be included in
  421. // all copies or substantial portions of the Software.
  422. //
  423. // THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  424. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  425. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  426. // AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  427. // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  428. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  429. // when used in node, this will actually load the util module we depend on
  430. // versus loading the builtin util module as happens otherwise
  431. // this is a bug in node module loading as far as I am concerned
  432. var pSlice = Array.prototype.slice;
  433. // 1. The assert module provides functions that throw
  434. // AssertionError's when particular conditions are not met. The
  435. // assert module must conform to the following interface.
  436. var assert = ok;
  437. // 3. All of the following functions must throw an AssertionError
  438. // when a corresponding condition is not met, with a message that
  439. // may be undefined if not provided. All assertion methods provide
  440. // both the actual and expected values to the assertion error for
  441. // display purposes.
  442. /**
  443. * Node.js standard [`assert.fail`](http://nodejs.org/api/assert.html#assert_assert_fail_actual_expected_message_operator).
  444. * @static
  445. * @memberOf should
  446. * @category assertion assert
  447. * @param {*} actual Actual object
  448. * @param {*} expected Expected object
  449. * @param {string} message Message for assertion
  450. * @param {string} operator Operator text
  451. */
  452. function fail(actual, expected, message, operator, stackStartFunction) {
  453. var a = new Assertion(actual);
  454. a.params = {
  455. operator: operator,
  456. expected: expected,
  457. message: message,
  458. stackStartFunction: stackStartFunction || fail
  459. };
  460. a.fail();
  461. }
  462. // EXTENSION! allows for well behaved errors defined elsewhere.
  463. assert.fail = fail;
  464. // 4. Pure assertion tests whether a value is truthy, as determined
  465. // by !!guard.
  466. // assert.ok(guard, message_opt);
  467. // This statement is equivalent to assert.equal(true, !!guard,
  468. // message_opt);. To test strictly for the value true, use
  469. // assert.strictEqual(true, guard, message_opt);.
  470. /**
  471. * Node.js standard [`assert.ok`](http://nodejs.org/api/assert.html#assert_assert_value_message_assert_ok_value_message).
  472. * @static
  473. * @memberOf should
  474. * @category assertion assert
  475. * @param {*} value
  476. * @param {string} [message]
  477. */
  478. function ok(value, message) {
  479. if (!value) {
  480. fail(value, true, message, '==', assert.ok);
  481. }
  482. }
  483. assert.ok = ok;
  484. // 5. The equality assertion tests shallow, coercive equality with
  485. // ==.
  486. // assert.equal(actual, expected, message_opt);
  487. /**
  488. * Node.js standard [`assert.equal`](http://nodejs.org/api/assert.html#assert_assert_equal_actual_expected_message).
  489. * @static
  490. * @memberOf should
  491. * @category assertion assert
  492. * @param {*} actual
  493. * @param {*} expected
  494. * @param {string} [message]
  495. */
  496. assert.equal = function equal(actual, expected, message) {
  497. if (actual != expected) {
  498. fail(actual, expected, message, '==', assert.equal);
  499. }
  500. };
  501. // 6. The non-equality assertion tests for whether two objects are not equal
  502. // with != assert.notEqual(actual, expected, message_opt);
  503. /**
  504. * Node.js standard [`assert.notEqual`](http://nodejs.org/api/assert.html#assert_assert_notequal_actual_expected_message).
  505. * @static
  506. * @memberOf should
  507. * @category assertion assert
  508. * @param {*} actual
  509. * @param {*} expected
  510. * @param {string} [message]
  511. */
  512. assert.notEqual = function notEqual(actual, expected, message) {
  513. if (actual == expected) {
  514. fail(actual, expected, message, '!=', assert.notEqual);
  515. }
  516. };
  517. // 7. The equivalence assertion tests a deep equality relation.
  518. // assert.deepEqual(actual, expected, message_opt);
  519. /**
  520. * Node.js standard [`assert.deepEqual`](http://nodejs.org/api/assert.html#assert_assert_deepequal_actual_expected_message).
  521. * But uses should.js .eql implementation instead of Node.js own deepEqual.
  522. *
  523. * @static
  524. * @memberOf should
  525. * @category assertion assert
  526. * @param {*} actual
  527. * @param {*} expected
  528. * @param {string} [message]
  529. */
  530. assert.deepEqual = function deepEqual(actual, expected, message) {
  531. if (eql(actual, expected).length !== 0) {
  532. fail(actual, expected, message, 'deepEqual', assert.deepEqual);
  533. }
  534. };
  535. // 8. The non-equivalence assertion tests for any deep inequality.
  536. // assert.notDeepEqual(actual, expected, message_opt);
  537. /**
  538. * Node.js standard [`assert.notDeepEqual`](http://nodejs.org/api/assert.html#assert_assert_notdeepequal_actual_expected_message).
  539. * But uses should.js .eql implementation instead of Node.js own deepEqual.
  540. *
  541. * @static
  542. * @memberOf should
  543. * @category assertion assert
  544. * @param {*} actual
  545. * @param {*} expected
  546. * @param {string} [message]
  547. */
  548. assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
  549. if (eql(actual, expected).result) {
  550. fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
  551. }
  552. };
  553. // 9. The strict equality assertion tests strict equality, as determined by ===.
  554. // assert.strictEqual(actual, expected, message_opt);
  555. /**
  556. * Node.js standard [`assert.strictEqual`](http://nodejs.org/api/assert.html#assert_assert_strictequal_actual_expected_message).
  557. * @static
  558. * @memberOf should
  559. * @category assertion assert
  560. * @param {*} actual
  561. * @param {*} expected
  562. * @param {string} [message]
  563. */
  564. assert.strictEqual = function strictEqual(actual, expected, message) {
  565. if (actual !== expected) {
  566. fail(actual, expected, message, '===', assert.strictEqual);
  567. }
  568. };
  569. // 10. The strict non-equality assertion tests for strict inequality, as
  570. // determined by !==. assert.notStrictEqual(actual, expected, message_opt);
  571. /**
  572. * Node.js standard [`assert.notStrictEqual`](http://nodejs.org/api/assert.html#assert_assert_notstrictequal_actual_expected_message).
  573. * @static
  574. * @memberOf should
  575. * @category assertion assert
  576. * @param {*} actual
  577. * @param {*} expected
  578. * @param {string} [message]
  579. */
  580. assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
  581. if (actual === expected) {
  582. fail(actual, expected, message, '!==', assert.notStrictEqual);
  583. }
  584. };
  585. function expectedException(actual, expected) {
  586. if (!actual || !expected) {
  587. return false;
  588. }
  589. if (Object.prototype.toString.call(expected) == '[object RegExp]') {
  590. return expected.test(actual);
  591. } else if (actual instanceof expected) {
  592. return true;
  593. } else if (expected.call({}, actual) === true) {
  594. return true;
  595. }
  596. return false;
  597. }
  598. function _throws(shouldThrow, block, expected, message) {
  599. var actual;
  600. if (typeof expected == 'string') {
  601. message = expected;
  602. expected = null;
  603. }
  604. try {
  605. block();
  606. } catch (e) {
  607. actual = e;
  608. }
  609. message = (expected && expected.name ? ' (' + expected.name + ')' : '.') +
  610. (message ? ' ' + message : '.');
  611. if (shouldThrow && !actual) {
  612. fail(actual, expected, 'Missing expected exception' + message);
  613. }
  614. if (!shouldThrow && expectedException(actual, expected)) {
  615. fail(actual, expected, 'Got unwanted exception' + message);
  616. }
  617. if ((shouldThrow && actual && expected && !expectedException(actual, expected)) || (!shouldThrow && actual)) {
  618. throw actual;
  619. }
  620. }
  621. // 11. Expected to throw an error:
  622. // assert.throws(block, Error_opt, message_opt);
  623. /**
  624. * Node.js standard [`assert.throws`](http://nodejs.org/api/assert.html#assert_assert_throws_block_error_message).
  625. * @static
  626. * @memberOf should
  627. * @category assertion assert
  628. * @param {Function} block
  629. * @param {Function} [error]
  630. * @param {String} [message]
  631. */
  632. assert.throws = function(/*block, error, message*/) {
  633. _throws.apply(this, [true].concat(pSlice.call(arguments)));
  634. };
  635. // EXTENSION! This is annoying to write outside this module.
  636. /**
  637. * Node.js standard [`assert.doesNotThrow`](http://nodejs.org/api/assert.html#assert_assert_doesnotthrow_block_message).
  638. * @static
  639. * @memberOf should
  640. * @category assertion assert
  641. * @param {Function} block
  642. * @param {String} [message]
  643. */
  644. assert.doesNotThrow = function(/*block, message*/) {
  645. _throws.apply(this, [false].concat(pSlice.call(arguments)));
  646. };
  647. /**
  648. * Node.js standard [`assert.ifError`](http://nodejs.org/api/assert.html#assert_assert_iferror_value).
  649. * @static
  650. * @memberOf should
  651. * @category assertion assert
  652. * @param {Error} err
  653. */
  654. assert.ifError = function(err) {
  655. if (err) {
  656. throw err;
  657. }
  658. };
  659. /*
  660. * should.js - assertion library
  661. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  662. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  663. * MIT Licensed
  664. */
  665. var assertExtensions = function(should) {
  666. var i = should.format;
  667. /*
  668. * Expose assert to should
  669. *
  670. * This allows you to do things like below
  671. * without require()ing the assert module.
  672. *
  673. * should.equal(foo.bar, undefined);
  674. *
  675. */
  676. shouldUtil.merge(should, assert);
  677. /**
  678. * Assert _obj_ exists, with optional message.
  679. *
  680. * @static
  681. * @memberOf should
  682. * @category assertion assert
  683. * @alias should.exists
  684. * @param {*} obj
  685. * @param {String} [msg]
  686. * @example
  687. *
  688. * should.exist(1);
  689. * should.exist(new Date());
  690. */
  691. should.exist = should.exists = function(obj, msg) {
  692. if (null == obj) {
  693. throw new AssertionError({
  694. message: msg || ('expected ' + i(obj) + ' to exist'), stackStartFunction: should.exist
  695. });
  696. }
  697. };
  698. should.not = {};
  699. /**
  700. * Asserts _obj_ does not exist, with optional message.
  701. *
  702. * @name not.exist
  703. * @static
  704. * @memberOf should
  705. * @category assertion assert
  706. * @alias should.not.exists
  707. * @param {*} obj
  708. * @param {String} [msg]
  709. * @example
  710. *
  711. * should.not.exist(null);
  712. * should.not.exist(void 0);
  713. */
  714. should.not.exist = should.not.exists = function(obj, msg) {
  715. if (null != obj) {
  716. throw new AssertionError({
  717. message: msg || ('expected ' + i(obj) + ' to not exist'), stackStartFunction: should.not.exist
  718. });
  719. }
  720. };
  721. };
  722. /*
  723. * should.js - assertion library
  724. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  725. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  726. * MIT Licensed
  727. */
  728. var chainAssertions = function(should, Assertion) {
  729. /**
  730. * Simple chaining to improve readability. Does nothing.
  731. *
  732. * @memberOf Assertion
  733. * @name be
  734. * @property {should.Assertion} be
  735. * @alias Assertion#an
  736. * @alias Assertion#of
  737. * @alias Assertion#a
  738. * @alias Assertion#and
  739. * @alias Assertion#been
  740. * @alias Assertion#have
  741. * @alias Assertion#has
  742. * @alias Assertion#with
  743. * @alias Assertion#is
  744. * @alias Assertion#which
  745. * @alias Assertion#the
  746. * @alias Assertion#it
  747. * @category assertion chaining
  748. */
  749. ['an', 'of', 'a', 'and', 'be', 'been', 'has', 'have', 'with', 'is', 'which', 'the', 'it'].forEach(function(name) {
  750. Assertion.addChain(name);
  751. });
  752. };
  753. /*
  754. * should.js - assertion library
  755. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  756. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  757. * MIT Licensed
  758. */
  759. var booleanAssertions = function(should, Assertion) {
  760. /**
  761. * Assert given object is exactly `true`.
  762. *
  763. * @name true
  764. * @memberOf Assertion
  765. * @category assertion bool
  766. * @alias Assertion#True
  767. * @param {string} [message] Optional message
  768. * @example
  769. *
  770. * (true).should.be.true();
  771. * false.should.not.be.true();
  772. *
  773. * ({ a: 10}).should.not.be.true();
  774. */
  775. Assertion.add('true', function(message) {
  776. this.is.exactly(true, message);
  777. });
  778. Assertion.alias('true', 'True');
  779. /**
  780. * Assert given object is exactly `false`.
  781. *
  782. * @name false
  783. * @memberOf Assertion
  784. * @category assertion bool
  785. * @alias Assertion#False
  786. * @param {string} [message] Optional message
  787. * @example
  788. *
  789. * (true).should.not.be.false();
  790. * false.should.be.false();
  791. */
  792. Assertion.add('false', function(message) {
  793. this.is.exactly(false, message);
  794. });
  795. Assertion.alias('false', 'False');
  796. /**
  797. * Assert given object is truthy according javascript type conversions.
  798. *
  799. * @name ok
  800. * @memberOf Assertion
  801. * @category assertion bool
  802. * @example
  803. *
  804. * (true).should.be.ok();
  805. * ''.should.not.be.ok();
  806. * should(null).not.be.ok();
  807. * should(void 0).not.be.ok();
  808. *
  809. * (10).should.be.ok();
  810. * (0).should.not.be.ok();
  811. */
  812. Assertion.add('ok', function() {
  813. this.params = { operator: 'to be truthy' };
  814. this.assert(this.obj);
  815. });
  816. };
  817. /*
  818. * should.js - assertion library
  819. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  820. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  821. * MIT Licensed
  822. */
  823. var numberAssertions = function(should, Assertion) {
  824. /**
  825. * Assert given object is NaN
  826. * @name NaN
  827. * @memberOf Assertion
  828. * @category assertion numbers
  829. * @example
  830. *
  831. * (10).should.not.be.NaN();
  832. * NaN.should.be.NaN();
  833. */
  834. Assertion.add('NaN', function() {
  835. this.params = { operator: 'to be NaN' };
  836. this.assert(this.obj !== this.obj);
  837. });
  838. /**
  839. * Assert given object is not finite (positive or negative)
  840. *
  841. * @name Infinity
  842. * @memberOf Assertion
  843. * @category assertion numbers
  844. * @example
  845. *
  846. * (10).should.not.be.Infinity();
  847. * NaN.should.not.be.Infinity();
  848. */
  849. Assertion.add('Infinity', function() {
  850. this.params = { operator: 'to be Infinity' };
  851. this.is.a.Number()
  852. .and.not.a.NaN()
  853. .and.assert(!isFinite(this.obj));
  854. });
  855. /**
  856. * Assert given number between `start` and `finish` or equal one of them.
  857. *
  858. * @name within
  859. * @memberOf Assertion
  860. * @category assertion numbers
  861. * @param {number} start Start number
  862. * @param {number} finish Finish number
  863. * @param {string} [description] Optional message
  864. * @example
  865. *
  866. * (10).should.be.within(0, 20);
  867. */
  868. Assertion.add('within', function(start, finish, description) {
  869. this.params = { operator: 'to be within ' + start + '..' + finish, message: description };
  870. this.assert(this.obj >= start && this.obj <= finish);
  871. });
  872. /**
  873. * Assert given number near some other `value` within `delta`
  874. *
  875. * @name approximately
  876. * @memberOf Assertion
  877. * @category assertion numbers
  878. * @param {number} value Center number
  879. * @param {number} delta Radius
  880. * @param {string} [description] Optional message
  881. * @example
  882. *
  883. * (9.99).should.be.approximately(10, 0.1);
  884. */
  885. Assertion.add('approximately', function(value, delta, description) {
  886. this.params = { operator: 'to be approximately ' + value + ' ±' + delta, message: description };
  887. this.assert(Math.abs(this.obj - value) <= delta);
  888. });
  889. /**
  890. * Assert given number above `n`.
  891. *
  892. * @name above
  893. * @alias Assertion#greaterThan
  894. * @memberOf Assertion
  895. * @category assertion numbers
  896. * @param {number} n Margin number
  897. * @param {string} [description] Optional message
  898. * @example
  899. *
  900. * (10).should.be.above(0);
  901. */
  902. Assertion.add('above', function(n, description) {
  903. this.params = { operator: 'to be above ' + n, message: description };
  904. this.assert(this.obj > n);
  905. });
  906. /**
  907. * Assert given number below `n`.
  908. *
  909. * @name below
  910. * @alias Assertion#lessThan
  911. * @memberOf Assertion
  912. * @category assertion numbers
  913. * @param {number} n Margin number
  914. * @param {string} [description] Optional message
  915. * @example
  916. *
  917. * (0).should.be.below(10);
  918. */
  919. Assertion.add('below', function(n, description) {
  920. this.params = { operator: 'to be below ' + n, message: description };
  921. this.assert(this.obj < n);
  922. });
  923. Assertion.alias('above', 'greaterThan');
  924. Assertion.alias('below', 'lessThan');
  925. /**
  926. * Assert given number above `n`.
  927. *
  928. * @name aboveOrEqual
  929. * @alias Assertion#greaterThanOrEqual
  930. * @memberOf Assertion
  931. * @category assertion numbers
  932. * @param {number} n Margin number
  933. * @param {string} [description] Optional message
  934. * @example
  935. *
  936. * (10).should.be.aboveOrEqual(0);
  937. * (10).should.be.aboveOrEqual(10);
  938. */
  939. Assertion.add('aboveOrEqual', function(n, description) {
  940. this.params = { operator: 'to be above or equal' + n, message: description };
  941. this.assert(this.obj >= n);
  942. });
  943. /**
  944. * Assert given number below `n`.
  945. *
  946. * @name belowOrEqual
  947. * @alias Assertion#lessThanOrEqual
  948. * @memberOf Assertion
  949. * @category assertion numbers
  950. * @param {number} n Margin number
  951. * @param {string} [description] Optional message
  952. * @example
  953. *
  954. * (0).should.be.belowOrEqual(10);
  955. * (0).should.be.belowOrEqual(0);
  956. */
  957. Assertion.add('belowOrEqual', function(n, description) {
  958. this.params = { operator: 'to be below or equal' + n, message: description };
  959. this.assert(this.obj <= n);
  960. });
  961. Assertion.alias('aboveOrEqual', 'greaterThanOrEqual');
  962. Assertion.alias('belowOrEqual', 'lessThanOrEqual');
  963. };
  964. /*
  965. * should.js - assertion library
  966. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  967. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  968. * MIT Licensed
  969. */
  970. var typeAssertions = function(should, Assertion) {
  971. /**
  972. * Assert given object is number
  973. * @name Number
  974. * @memberOf Assertion
  975. * @category assertion types
  976. */
  977. Assertion.add('Number', function() {
  978. this.params = {operator: 'to be a number'};
  979. this.have.type('number');
  980. });
  981. /**
  982. * Assert given object is arguments
  983. * @name arguments
  984. * @alias Assertion#Arguments
  985. * @memberOf Assertion
  986. * @category assertion types
  987. */
  988. Assertion.add('arguments', function() {
  989. this.params = {operator: 'to be arguments'};
  990. this.have.class('Arguments');
  991. });
  992. Assertion.alias('arguments', 'Arguments');
  993. /**
  994. * Assert given object has some type using `typeof`
  995. * @name type
  996. * @memberOf Assertion
  997. * @param {string} type Type name
  998. * @param {string} [description] Optional message
  999. * @category assertion types
  1000. */
  1001. Assertion.add('type', function(type, description) {
  1002. this.params = {operator: 'to have type ' + type, message: description};
  1003. should(typeof this.obj).be.exactly(type);
  1004. });
  1005. /**
  1006. * Assert given object is instance of `constructor`
  1007. * @name instanceof
  1008. * @alias Assertion#instanceOf
  1009. * @memberOf Assertion
  1010. * @param {Function} constructor Constructor function
  1011. * @param {string} [description] Optional message
  1012. * @category assertion types
  1013. */
  1014. Assertion.add('instanceof', function(constructor, description) {
  1015. this.params = {operator: 'to be an instance of ' + functionName(constructor), message: description};
  1016. this.assert(Object(this.obj) instanceof constructor);
  1017. });
  1018. Assertion.alias('instanceof', 'instanceOf');
  1019. /**
  1020. * Assert given object is function
  1021. * @name Function
  1022. * @memberOf Assertion
  1023. * @category assertion types
  1024. */
  1025. Assertion.add('Function', function() {
  1026. this.params = {operator: 'to be a function'};
  1027. this.have.type('function');
  1028. });
  1029. /**
  1030. * Assert given object is object
  1031. * @name Object
  1032. * @memberOf Assertion
  1033. * @category assertion types
  1034. */
  1035. Assertion.add('Object', function() {
  1036. this.params = {operator: 'to be an object'};
  1037. this.is.not.null().and.have.type('object');
  1038. });
  1039. /**
  1040. * Assert given object is string
  1041. * @name String
  1042. * @memberOf Assertion
  1043. * @category assertion types
  1044. */
  1045. Assertion.add('String', function() {
  1046. this.params = {operator: 'to be a string'};
  1047. this.have.type('string');
  1048. });
  1049. /**
  1050. * Assert given object is array
  1051. * @name Array
  1052. * @memberOf Assertion
  1053. * @category assertion types
  1054. */
  1055. Assertion.add('Array', function() {
  1056. this.params = {operator: 'to be an array'};
  1057. this.have.class('Array');
  1058. });
  1059. /**
  1060. * Assert given object is boolean
  1061. * @name Boolean
  1062. * @memberOf Assertion
  1063. * @category assertion types
  1064. */
  1065. Assertion.add('Boolean', function() {
  1066. this.params = {operator: 'to be a boolean'};
  1067. this.have.type('boolean');
  1068. });
  1069. /**
  1070. * Assert given object is error
  1071. * @name Error
  1072. * @memberOf Assertion
  1073. * @category assertion types
  1074. */
  1075. Assertion.add('Error', function() {
  1076. this.params = {operator: 'to be an error'};
  1077. this.have.instanceOf(Error);
  1078. });
  1079. /**
  1080. * Assert given object is a date
  1081. * @name Date
  1082. * @memberOf Assertion
  1083. * @category assertion types
  1084. */
  1085. Assertion.add('Date', function() {
  1086. this.params = {operator: 'to be a date'};
  1087. this.have.instanceOf(Date);
  1088. });
  1089. /**
  1090. * Assert given object is null
  1091. * @name null
  1092. * @alias Assertion#Null
  1093. * @memberOf Assertion
  1094. * @category assertion types
  1095. */
  1096. Assertion.add('null', function() {
  1097. this.params = {operator: 'to be null'};
  1098. this.assert(this.obj === null);
  1099. });
  1100. Assertion.alias('null', 'Null');
  1101. /**
  1102. * Assert given object has some internal [[Class]], via Object.prototype.toString call
  1103. * @name class
  1104. * @alias Assertion#Class
  1105. * @memberOf Assertion
  1106. * @category assertion types
  1107. */
  1108. Assertion.add('class', function(cls) {
  1109. this.params = {operator: 'to have [[Class]] ' + cls};
  1110. this.assert(Object.prototype.toString.call(this.obj) === '[object ' + cls + ']');
  1111. });
  1112. Assertion.alias('class', 'Class');
  1113. /**
  1114. * Assert given object is undefined
  1115. * @name undefined
  1116. * @alias Assertion#Undefined
  1117. * @memberOf Assertion
  1118. * @category assertion types
  1119. */
  1120. Assertion.add('undefined', function() {
  1121. this.params = {operator: 'to be undefined'};
  1122. this.assert(this.obj === void 0);
  1123. });
  1124. Assertion.alias('undefined', 'Undefined');
  1125. /**
  1126. * Assert given object supports es6 iterable protocol (just check
  1127. * that object has property Symbol.iterator, which is a function)
  1128. * @name iterable
  1129. * @memberOf Assertion
  1130. * @category assertion es6
  1131. */
  1132. Assertion.add('iterable', function() {
  1133. this.params = {operator: 'to be iterable'};
  1134. should(this.obj).have.property(Symbol.iterator).which.is.a.Function();
  1135. });
  1136. /**
  1137. * Assert given object supports es6 iterator protocol (just check
  1138. * that object has property next, which is a function)
  1139. * @name iterator
  1140. * @memberOf Assertion
  1141. * @category assertion es6
  1142. */
  1143. Assertion.add('iterator', function() {
  1144. this.params = {operator: 'to be iterator'};
  1145. should(this.obj).have.property('next').which.is.a.Function();
  1146. });
  1147. /**
  1148. * Assert given object is a generator object
  1149. * @name generator
  1150. * @memberOf Assertion
  1151. * @category assertion es6
  1152. */
  1153. Assertion.add('generator', function() {
  1154. this.params = {operator: 'to be generator'};
  1155. should(this.obj).be.iterable
  1156. .and.iterator
  1157. .and.it.is.equal(this.obj[Symbol.iterator]());
  1158. });
  1159. };
  1160. /*
  1161. * should.js - assertion library
  1162. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  1163. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  1164. * MIT Licensed
  1165. */
  1166. function formatEqlResult(r, a, b) {
  1167. return ((r.path.length > 0 ? 'at ' + r.path.map(formatProp).join(' -> ') : '') +
  1168. (r.a === a ? '' : ', A has ' + format(r.a)) +
  1169. (r.b === b ? '' : ' and B has ' + format(r.b)) +
  1170. (r.showReason ? ' because ' + r.reason : '')).trim();
  1171. }
  1172. var equalityAssertions = function(should, Assertion) {
  1173. /**
  1174. * Deep object equality comparison. For full spec see [`should-equal tests`](https://github.com/shouldjs/equal/blob/master/test.js).
  1175. *
  1176. * @name eql
  1177. * @memberOf Assertion
  1178. * @category assertion equality
  1179. * @alias Assertion#deepEqual
  1180. * @param {*} val Expected value
  1181. * @param {string} [description] Optional message
  1182. * @example
  1183. *
  1184. * (10).should.be.eql(10);
  1185. * ('10').should.not.be.eql(10);
  1186. * (-0).should.not.be.eql(+0);
  1187. *
  1188. * NaN.should.be.eql(NaN);
  1189. *
  1190. * ({ a: 10}).should.be.eql({ a: 10 });
  1191. * [ 'a' ].should.not.be.eql({ '0': 'a' });
  1192. */
  1193. Assertion.add('eql', function(val, description) {
  1194. this.params = {operator: 'to equal', expected: val, message: description};
  1195. var obj = this.obj;
  1196. var fails = eql(this.obj, val, should.config);
  1197. this.params.details = fails.map(function(fail) {
  1198. return formatEqlResult(fail, obj, val);
  1199. }).join(', ');
  1200. this.params.showDiff = eql(getType(obj), getType(val)).length === 0;
  1201. this.assert(fails.length === 0);
  1202. });
  1203. /**
  1204. * Exact comparison using ===.
  1205. *
  1206. * @name equal
  1207. * @memberOf Assertion
  1208. * @category assertion equality
  1209. * @alias Assertion#exactly
  1210. * @param {*} val Expected value
  1211. * @param {string} [description] Optional message
  1212. * @example
  1213. *
  1214. * 10.should.be.equal(10);
  1215. * 'a'.should.be.exactly('a');
  1216. *
  1217. * should(null).be.exactly(null);
  1218. */
  1219. Assertion.add('equal', function(val, description) {
  1220. this.params = {operator: 'to be', expected: val, message: description};
  1221. this.params.showDiff = eql(getType(this.obj), getType(val)).length === 0;
  1222. this.assert(val === this.obj);
  1223. });
  1224. Assertion.alias('equal', 'exactly');
  1225. Assertion.alias('eql', 'deepEqual');
  1226. function addOneOf(name, message, method) {
  1227. Assertion.add(name, function(vals) {
  1228. if (arguments.length !== 1) {
  1229. vals = Array.prototype.slice.call(arguments);
  1230. } else {
  1231. should(vals).be.Array();
  1232. }
  1233. this.params = {operator: message, expected: vals};
  1234. var obj = this.obj;
  1235. var found = false;
  1236. shouldTypeAdaptors.forEach(vals, function(val) {
  1237. try {
  1238. should(val)[method](obj);
  1239. found = true;
  1240. return false;
  1241. } catch (e) {
  1242. if (e instanceof should.AssertionError) {
  1243. return;//do nothing
  1244. }
  1245. throw e;
  1246. }
  1247. });
  1248. this.assert(found);
  1249. });
  1250. }
  1251. /**
  1252. * Exact comparison using === to be one of supplied objects.
  1253. *
  1254. * @name equalOneOf
  1255. * @memberOf Assertion
  1256. * @category assertion equality
  1257. * @param {Array|*} vals Expected values
  1258. * @example
  1259. *
  1260. * 'ab'.should.be.equalOneOf('a', 10, 'ab');
  1261. * 'ab'.should.be.equalOneOf(['a', 10, 'ab']);
  1262. */
  1263. addOneOf('equalOneOf', 'to be equals one of', 'equal');
  1264. /**
  1265. * Exact comparison using .eql to be one of supplied objects.
  1266. *
  1267. * @name oneOf
  1268. * @memberOf Assertion
  1269. * @category assertion equality
  1270. * @param {Array|*} vals Expected values
  1271. * @example
  1272. *
  1273. * ({a: 10}).should.be.oneOf('a', 10, 'ab', {a: 10});
  1274. * ({a: 10}).should.be.oneOf(['a', 10, 'ab', {a: 10}]);
  1275. */
  1276. addOneOf('oneOf', 'to be one of', 'eql');
  1277. };
  1278. /*
  1279. * should.js - assertion library
  1280. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  1281. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  1282. * MIT Licensed
  1283. */
  1284. var promiseAssertions = function(should, Assertion$$1) {
  1285. /**
  1286. * Assert given object is a Promise
  1287. *
  1288. * @name Promise
  1289. * @memberOf Assertion
  1290. * @category assertion promises
  1291. * @example
  1292. *
  1293. * promise.should.be.Promise()
  1294. * (new Promise(function(resolve, reject) { resolve(10); })).should.be.a.Promise()
  1295. * (10).should.not.be.a.Promise()
  1296. */
  1297. Assertion$$1.add('Promise', function() {
  1298. this.params = {operator: 'to be promise'};
  1299. var obj = this.obj;
  1300. should(obj).have.property('then')
  1301. .which.is.a.Function();
  1302. });
  1303. /**
  1304. * Assert given promise will be fulfilled. Result of assertion is still .thenable and should be handled accordingly.
  1305. *
  1306. * @name fulfilled
  1307. * @memberOf Assertion
  1308. * @returns {Promise}
  1309. * @category assertion promises
  1310. * @example
  1311. *
  1312. * // don't forget to handle async nature
  1313. * (new Promise(function(resolve, reject) { resolve(10); })).should.be.fulfilled();
  1314. *
  1315. * // test example with mocha it is possible to return promise
  1316. * it('is async', () => {
  1317. * return new Promise(resolve => resolve(10))
  1318. * .should.be.fulfilled();
  1319. * });
  1320. */
  1321. Assertion$$1.prototype.fulfilled = function Assertion$fulfilled() {
  1322. this.params = {operator: 'to be fulfilled'};
  1323. should(this.obj).be.a.Promise();
  1324. var that = this;
  1325. return this.obj.then(function next$onResolve(value) {
  1326. if (that.negate) {
  1327. that.fail();
  1328. }
  1329. return value;
  1330. }, function next$onReject(err) {
  1331. if (!that.negate) {
  1332. that.params.operator += ', but it was rejected with ' + should.format(err);
  1333. that.fail();
  1334. }
  1335. return err;
  1336. });
  1337. };
  1338. /**
  1339. * Assert given promise will be rejected. Result of assertion is still .thenable and should be handled accordingly.
  1340. *
  1341. * @name rejected
  1342. * @memberOf Assertion
  1343. * @category assertion promises
  1344. * @returns {Promise}
  1345. * @example
  1346. *
  1347. * // don't forget to handle async nature
  1348. * (new Promise(function(resolve, reject) { resolve(10); }))
  1349. * .should.not.be.rejected();
  1350. *
  1351. * // test example with mocha it is possible to return promise
  1352. * it('is async', () => {
  1353. * return new Promise((resolve, reject) => reject(new Error('boom')))
  1354. * .should.be.rejected();
  1355. * });
  1356. */
  1357. Assertion$$1.prototype.rejected = function() {
  1358. this.params = {operator: 'to be rejected'};
  1359. should(this.obj).be.a.Promise();
  1360. var that = this;
  1361. return this.obj.then(function(value) {
  1362. if (!that.negate) {
  1363. that.params.operator += ', but it was fulfilled';
  1364. if (arguments.length != 0) {
  1365. that.params.operator += ' with ' + should.format(value);
  1366. }
  1367. that.fail();
  1368. }
  1369. return value;
  1370. }, function next$onError(err) {
  1371. if (that.negate) {
  1372. that.fail();
  1373. }
  1374. return err;
  1375. });
  1376. };
  1377. /**
  1378. * Assert given promise will be fulfilled with some expected value (value compared using .eql).
  1379. * Result of assertion is still .thenable and should be handled accordingly.
  1380. *
  1381. * @name fulfilledWith
  1382. * @memberOf Assertion
  1383. * @category assertion promises
  1384. * @returns {Promise}
  1385. * @example
  1386. *
  1387. * // don't forget to handle async nature
  1388. * (new Promise(function(resolve, reject) { resolve(10); }))
  1389. * .should.be.fulfilledWith(10);
  1390. *
  1391. * // test example with mocha it is possible to return promise
  1392. * it('is async', () => {
  1393. * return new Promise((resolve, reject) => resolve(10))
  1394. * .should.be.fulfilledWith(10);
  1395. * });
  1396. */
  1397. Assertion$$1.prototype.fulfilledWith = function(expectedValue) {
  1398. this.params = {operator: 'to be fulfilled with ' + should.format(expectedValue)};
  1399. should(this.obj).be.a.Promise();
  1400. var that = this;
  1401. return this.obj.then(function(value) {
  1402. if (that.negate) {
  1403. that.fail();
  1404. }
  1405. should(value).eql(expectedValue);
  1406. return value;
  1407. }, function next$onError(err) {
  1408. if (!that.negate) {
  1409. that.params.operator += ', but it was rejected with ' + should.format(err);
  1410. that.fail();
  1411. }
  1412. return err;
  1413. });
  1414. };
  1415. /**
  1416. * Assert given promise will be rejected with some sort of error. Arguments is the same for Assertion#throw.
  1417. * Result of assertion is still .thenable and should be handled accordingly.
  1418. *
  1419. * @name rejectedWith
  1420. * @memberOf Assertion
  1421. * @category assertion promises
  1422. * @returns {Promise}
  1423. * @example
  1424. *
  1425. * function failedPromise() {
  1426. * return new Promise(function(resolve, reject) {
  1427. * reject(new Error('boom'))
  1428. * })
  1429. * }
  1430. * failedPromise().should.be.rejectedWith(Error);
  1431. * failedPromise().should.be.rejectedWith('boom');
  1432. * failedPromise().should.be.rejectedWith(/boom/);
  1433. * failedPromise().should.be.rejectedWith(Error, { message: 'boom' });
  1434. * failedPromise().should.be.rejectedWith({ message: 'boom' });
  1435. *
  1436. * // test example with mocha it is possible to return promise
  1437. * it('is async', () => {
  1438. * return failedPromise().should.be.rejectedWith({ message: 'boom' });
  1439. * });
  1440. */
  1441. Assertion$$1.prototype.rejectedWith = function(message, properties) {
  1442. this.params = {operator: 'to be rejected'};
  1443. should(this.obj).be.a.Promise();
  1444. var that = this;
  1445. return this.obj.then(function(value) {
  1446. if (!that.negate) {
  1447. that.fail();
  1448. }
  1449. return value;
  1450. }, function next$onError(err) {
  1451. if (that.negate) {
  1452. that.fail();
  1453. }
  1454. var errorMatched = true;
  1455. var errorInfo = '';
  1456. if ('string' === typeof message) {
  1457. errorMatched = message === err.message;
  1458. } else if (message instanceof RegExp) {
  1459. errorMatched = message.test(err.message);
  1460. } else if ('function' === typeof message) {
  1461. errorMatched = err instanceof message;
  1462. } else if (message !== null && typeof message === 'object') {
  1463. try {
  1464. should(err).match(message);
  1465. } catch (e) {
  1466. if (e instanceof should.AssertionError) {
  1467. errorInfo = ': ' + e.message;
  1468. errorMatched = false;
  1469. } else {
  1470. throw e;
  1471. }
  1472. }
  1473. }
  1474. if (!errorMatched) {
  1475. if ( typeof message === 'string' || message instanceof RegExp) {
  1476. errorInfo = ' with a message matching ' + should.format(message) + ", but got '" + err.message + "'";
  1477. } else if ('function' === typeof message) {
  1478. errorInfo = ' of type ' + functionName(message) + ', but got ' + functionName(err.constructor);
  1479. }
  1480. } else if ('function' === typeof message && properties) {
  1481. try {
  1482. should(err).match(properties);
  1483. } catch (e) {
  1484. if (e instanceof should.AssertionError) {
  1485. errorInfo = ': ' + e.message;
  1486. errorMatched = false;
  1487. } else {
  1488. throw e;
  1489. }
  1490. }
  1491. }
  1492. that.params.operator += errorInfo;
  1493. that.assert(errorMatched);
  1494. return err;
  1495. });
  1496. };
  1497. /**
  1498. * Assert given object is promise and wrap it in PromisedAssertion, which has all properties of Assertion.
  1499. * That means you can chain as with usual Assertion.
  1500. * Result of assertion is still .thenable and should be handled accordingly.
  1501. *
  1502. * @name finally
  1503. * @memberOf Assertion
  1504. * @alias Assertion#eventually
  1505. * @category assertion promises
  1506. * @returns {PromisedAssertion} Like Assertion, but .then this.obj in Assertion
  1507. * @example
  1508. *
  1509. * (new Promise(function(resolve, reject) { resolve(10); }))
  1510. * .should.be.eventually.equal(10);
  1511. *
  1512. * // test example with mocha it is possible to return promise
  1513. * it('is async', () => {
  1514. * return new Promise(resolve => resolve(10))
  1515. * .should.be.finally.equal(10);
  1516. * });
  1517. */
  1518. Object.defineProperty(Assertion$$1.prototype, 'finally', {
  1519. get: function() {
  1520. should(this.obj).be.a.Promise();
  1521. var that = this;
  1522. return new PromisedAssertion(this.obj.then(function(obj) {
  1523. var a = should(obj);
  1524. a.negate = that.negate;
  1525. a.anyOne = that.anyOne;
  1526. return a;
  1527. }));
  1528. }
  1529. });
  1530. Assertion$$1.alias('finally', 'eventually');
  1531. };
  1532. /*
  1533. * should.js - assertion library
  1534. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  1535. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  1536. * MIT Licensed
  1537. */
  1538. var stringAssertions = function(should, Assertion) {
  1539. /**
  1540. * Assert given string starts with prefix
  1541. * @name startWith
  1542. * @memberOf Assertion
  1543. * @category assertion strings
  1544. * @param {string} str Prefix
  1545. * @param {string} [description] Optional message
  1546. * @example
  1547. *
  1548. * 'abc'.should.startWith('a');
  1549. */
  1550. Assertion.add('startWith', function(str, description) {
  1551. this.params = { operator: 'to start with ' + should.format(str), message: description };
  1552. this.assert(0 === this.obj.indexOf(str));
  1553. });
  1554. /**
  1555. * Assert given string ends with prefix
  1556. * @name endWith
  1557. * @memberOf Assertion
  1558. * @category assertion strings
  1559. * @param {string} str Prefix
  1560. * @param {string} [description] Optional message
  1561. * @example
  1562. *
  1563. * 'abca'.should.endWith('a');
  1564. */
  1565. Assertion.add('endWith', function(str, description) {
  1566. this.params = { operator: 'to end with ' + should.format(str), message: description };
  1567. this.assert(this.obj.indexOf(str, this.obj.length - str.length) >= 0);
  1568. });
  1569. };
  1570. /*
  1571. * should.js - assertion library
  1572. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  1573. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  1574. * MIT Licensed
  1575. */
  1576. var containAssertions = function(should, Assertion) {
  1577. var i = should.format;
  1578. /**
  1579. * Assert that given object contain something that equal to `other`. It uses `should-equal` for equality checks.
  1580. * If given object is array it search that one of elements was equal to `other`.
  1581. * If given object is string it checks if `other` is a substring - expected that `other` is a string.
  1582. * If given object is Object it checks that `other` is a subobject - expected that `other` is a object.
  1583. *
  1584. * @name containEql
  1585. * @memberOf Assertion
  1586. * @category assertion contain
  1587. * @param {*} other Nested object
  1588. * @example
  1589. *
  1590. * [1, 2, 3].should.containEql(1);
  1591. * [{ a: 1 }, 'a', 10].should.containEql({ a: 1 });
  1592. *
  1593. * 'abc'.should.containEql('b');
  1594. * 'ab1c'.should.containEql(1);
  1595. *
  1596. * ({ a: 10, c: { d: 10 }}).should.containEql({ a: 10 });
  1597. * ({ a: 10, c: { d: 10 }}).should.containEql({ c: { d: 10 }});
  1598. * ({ a: 10, c: { d: 10 }}).should.containEql({ b: 10 });
  1599. * // throws AssertionError: expected { a: 10, c: { d: 10 } } to contain { b: 10 }
  1600. * // expected { a: 10, c: { d: 10 } } to have property b
  1601. */
  1602. Assertion.add('containEql', function(other) {
  1603. this.params = { operator: 'to contain ' + i(other) };
  1604. this.is.not.null().and.not.undefined();
  1605. var obj = this.obj;
  1606. if (typeof obj == 'string') {
  1607. this.assert(obj.indexOf(String(other)) >= 0);
  1608. } else if (shouldTypeAdaptors.isIterable(obj)) {
  1609. this.assert(shouldTypeAdaptors.some(obj, function(v) {
  1610. return eql(v, other).length === 0;
  1611. }));
  1612. } else {
  1613. shouldTypeAdaptors.forEach(other, function(value, key) {
  1614. should(obj).have.value(key, value);
  1615. }, this);
  1616. }
  1617. });
  1618. /**
  1619. * Assert that given object is contain equally structured object on the same depth level.
  1620. * If given object is an array and `other` is an array it checks that the eql elements is going in the same sequence in given array (recursive)
  1621. * If given object is an object it checks that the same keys contain deep equal values (recursive)
  1622. * On other cases it try to check with `.eql`
  1623. *
  1624. * @name containDeepOrdered
  1625. * @memberOf Assertion
  1626. * @category assertion contain
  1627. * @param {*} other Nested object
  1628. * @example
  1629. *
  1630. * [ 1, 2, 3].should.containDeepOrdered([1, 2]);
  1631. * [ 1, 2, [ 1, 2, 3 ]].should.containDeepOrdered([ 1, [ 2, 3 ]]);
  1632. *
  1633. * ({ a: 10, b: { c: 10, d: [1, 2, 3] }}).should.containDeepOrdered({a: 10});
  1634. * ({ a: 10, b: { c: 10, d: [1, 2, 3] }}).should.containDeepOrdered({b: {c: 10}});
  1635. * ({ a: 10, b: { c: 10, d: [1, 2, 3] }}).should.containDeepOrdered({b: {d: [1, 3]}});
  1636. */
  1637. Assertion.add('containDeepOrdered', function(other) {
  1638. this.params = {operator: 'to contain ' + i(other)};
  1639. var obj = this.obj;
  1640. if (typeof obj == 'string') {// expect other to be string
  1641. this.is.equal(String(other));
  1642. } else if (shouldTypeAdaptors.isIterable(obj) && shouldTypeAdaptors.isIterable(other)) {
  1643. var objIterator = shouldTypeAdaptors.iterator(obj);
  1644. var otherIterator = shouldTypeAdaptors.iterator(other);
  1645. var nextObj = objIterator.next();
  1646. var nextOther = otherIterator.next();
  1647. while (!nextObj.done && !nextOther.done) {
  1648. try {
  1649. should(nextObj.value[1]).containDeepOrdered(nextOther.value[1]);
  1650. nextOther = otherIterator.next();
  1651. } catch (e) {
  1652. if (!(e instanceof should.AssertionError)) {
  1653. throw e;
  1654. }
  1655. }
  1656. nextObj = objIterator.next();
  1657. }
  1658. this.assert(nextOther.done);
  1659. } else if (obj != null && other != null && typeof obj == 'object' && typeof other == 'object') {//TODO compare types object contains object case
  1660. shouldTypeAdaptors.forEach(other, function(value, key) {
  1661. should(obj[key]).containDeepOrdered(value);
  1662. });
  1663. // if both objects is empty means we finish traversing - and we need to compare for hidden values
  1664. if (shouldTypeAdaptors.isEmpty(other)) {
  1665. this.eql(other);
  1666. }
  1667. } else {
  1668. this.eql(other);
  1669. }
  1670. });
  1671. /**
  1672. * The same like `Assertion#containDeepOrdered` but all checks on arrays without order.
  1673. *
  1674. * @name containDeep
  1675. * @memberOf Assertion
  1676. * @category assertion contain
  1677. * @param {*} other Nested object
  1678. * @example
  1679. *
  1680. * [ 1, 2, 3].should.containDeep([2, 1]);
  1681. * [ 1, 2, [ 1, 2, 3 ]].should.containDeep([ 1, [ 3, 1 ]]);
  1682. */
  1683. Assertion.add('containDeep', function(other) {
  1684. this.params = {operator: 'to contain ' + i(other)};
  1685. var obj = this.obj;
  1686. if (typeof obj == 'string') {// expect other to be string
  1687. this.is.equal(String(other));
  1688. } else if (shouldTypeAdaptors.isIterable(obj) && shouldTypeAdaptors.isIterable(other)) {
  1689. var usedKeys = {};
  1690. shouldTypeAdaptors.forEach(other, function(otherItem) {
  1691. this.assert(shouldTypeAdaptors.some(obj, function(item, index) {
  1692. if (index in usedKeys) {
  1693. return false;
  1694. }
  1695. try {
  1696. should(item).containDeep(otherItem);
  1697. usedKeys[index] = true;
  1698. return true;
  1699. } catch (e) {
  1700. if (e instanceof should.AssertionError) {
  1701. return false;
  1702. }
  1703. throw e;
  1704. }
  1705. }));
  1706. }, this);
  1707. } else if (obj != null && other != null && typeof obj == 'object' && typeof other == 'object') {// object contains object case
  1708. shouldTypeAdaptors.forEach(other, function(value, key) {
  1709. should(obj[key]).containDeep(value);
  1710. });
  1711. // if both objects is empty means we finish traversing - and we need to compare for hidden values
  1712. if (shouldTypeAdaptors.isEmpty(other)) {
  1713. this.eql(other);
  1714. }
  1715. } else {
  1716. this.eql(other);
  1717. }
  1718. });
  1719. };
  1720. /*
  1721. * should.js - assertion library
  1722. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  1723. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  1724. * MIT Licensed
  1725. */
  1726. var aSlice = Array.prototype.slice;
  1727. var propertyAssertions = function(should, Assertion) {
  1728. var i = should.format;
  1729. /**
  1730. * Asserts given object has some descriptor. **On success it change given object to be value of property**.
  1731. *
  1732. * @name propertyWithDescriptor
  1733. * @memberOf Assertion
  1734. * @category assertion property
  1735. * @param {string} name Name of property
  1736. * @param {Object} desc Descriptor like used in Object.defineProperty (not required to add all properties)
  1737. * @example
  1738. *
  1739. * ({ a: 10 }).should.have.propertyWithDescriptor('a', { enumerable: true });
  1740. */
  1741. Assertion.add('propertyWithDescriptor', function(name, desc) {
  1742. this.params = {actual: this.obj, operator: 'to have own property with descriptor ' + i(desc)};
  1743. var obj = this.obj;
  1744. this.have.ownProperty(name);
  1745. should(Object.getOwnPropertyDescriptor(Object(obj), name)).have.properties(desc);
  1746. });
  1747. function processPropsArgs() {
  1748. var args = {};
  1749. if (arguments.length > 1) {
  1750. args.names = aSlice.call(arguments);
  1751. } else {
  1752. var arg = arguments[0];
  1753. if (typeof arg === 'string') {
  1754. args.names = [arg];
  1755. } else if (Array.isArray(arg)) {
  1756. args.names = arg;
  1757. } else {
  1758. args.names = Object.keys(arg);
  1759. args.values = arg;
  1760. }
  1761. }
  1762. return args;
  1763. }
  1764. Assertion.add('enumerable', function(name, val) {
  1765. name = convertPropertyName(name);
  1766. this.params = {
  1767. operator: "to have enumerable property " + formatProp(name) + (arguments.length > 1 ? " equal to " + i(val): "")
  1768. };
  1769. var desc = { enumerable: true };
  1770. if (arguments.length > 1) {
  1771. desc.value = val;
  1772. }
  1773. this.have.propertyWithDescriptor(name, desc);
  1774. });
  1775. Assertion.add('enumerables', function(/*names*/) {
  1776. var args = processPropsArgs.apply(null, arguments);
  1777. this.params = {
  1778. operator: "to have enumerables " + args.names.map(formatProp)
  1779. };
  1780. var obj = this.obj;
  1781. args.names.forEach(function(name) {
  1782. should(obj).have.enumerable(name);
  1783. });
  1784. });
  1785. /**
  1786. * Asserts given object has property with optionally value. **On success it change given object to be value of property**.
  1787. *
  1788. * @name property
  1789. * @memberOf Assertion
  1790. * @category assertion property
  1791. * @param {string} name Name of property
  1792. * @param {*} [val] Optional property value to check
  1793. * @example
  1794. *
  1795. * ({ a: 10 }).should.have.property('a');
  1796. */
  1797. Assertion.add('property', function(name, val) {
  1798. name = convertPropertyName(name);
  1799. if (arguments.length > 1) {
  1800. var p = {};
  1801. p[name] = val;
  1802. this.have.properties(p);
  1803. } else {
  1804. this.have.properties(name);
  1805. }
  1806. this.obj = this.obj[name];
  1807. });
  1808. /**
  1809. * Asserts given object has properties. On this method affect .any modifier, which allow to check not all properties.
  1810. *
  1811. * @name properties
  1812. * @memberOf Assertion
  1813. * @category assertion property
  1814. * @param {Array|...string|Object} names Names of property
  1815. * @example
  1816. *
  1817. * ({ a: 10 }).should.have.properties('a');
  1818. * ({ a: 10, b: 20 }).should.have.properties([ 'a' ]);
  1819. * ({ a: 10, b: 20 }).should.have.properties({ b: 20 });
  1820. */
  1821. Assertion.add('properties', function(names) {
  1822. var values = {};
  1823. if (arguments.length > 1) {
  1824. names = aSlice.call(arguments);
  1825. } else if (!Array.isArray(names)) {
  1826. if (typeof names == 'string' || typeof names == 'symbol') {
  1827. names = [names];
  1828. } else {
  1829. values = names;
  1830. names = Object.keys(names);
  1831. }
  1832. }
  1833. var obj = Object(this.obj), missingProperties = [];
  1834. //just enumerate properties and check if they all present
  1835. names.forEach(function(name) {
  1836. if (!(name in obj)) {
  1837. missingProperties.push(formatProp(name));
  1838. }
  1839. });
  1840. var props = missingProperties;
  1841. if (props.length === 0) {
  1842. props = names.map(formatProp);
  1843. } else if (this.anyOne) {
  1844. props = names.filter(function(name) {
  1845. return missingProperties.indexOf(formatProp(name)) < 0;
  1846. }).map(formatProp);
  1847. }
  1848. var operator = (props.length === 1 ?
  1849. 'to have property ' : 'to have ' + (this.anyOne ? 'any of ' : '') + 'properties ') + props.join(', ');
  1850. this.params = {obj: this.obj, operator: operator};
  1851. //check that all properties presented
  1852. //or if we request one of them that at least one them presented
  1853. this.assert(missingProperties.length === 0 || (this.anyOne && missingProperties.length != names.length));
  1854. // check if values in object matched expected
  1855. var valueCheckNames = Object.keys(values);
  1856. if (valueCheckNames.length) {
  1857. var wrongValues = [];
  1858. props = [];
  1859. // now check values, as there we have all properties
  1860. valueCheckNames.forEach(function(name) {
  1861. var value = values[name];
  1862. if (eql(obj[name], value).length !== 0) {
  1863. wrongValues.push(formatProp(name) + ' of ' + i(value) + ' (got ' + i(obj[name]) + ')');
  1864. } else {
  1865. props.push(formatProp(name) + ' of ' + i(value));
  1866. }
  1867. });
  1868. if ((wrongValues.length !== 0 && !this.anyOne) || (this.anyOne && props.length === 0)) {
  1869. props = wrongValues;
  1870. }
  1871. operator = (props.length === 1 ?
  1872. 'to have property ' : 'to have ' + (this.anyOne ? 'any of ' : '') + 'properties ') + props.join(', ');
  1873. this.params = {obj: this.obj, operator: operator};
  1874. //if there is no not matched values
  1875. //or there is at least one matched
  1876. this.assert(wrongValues.length === 0 || (this.anyOne && wrongValues.length != valueCheckNames.length));
  1877. }
  1878. });
  1879. /**
  1880. * Asserts given object has property `length` with given value `n`
  1881. *
  1882. * @name length
  1883. * @alias Assertion#lengthOf
  1884. * @memberOf Assertion
  1885. * @category assertion property
  1886. * @param {number} n Expected length
  1887. * @param {string} [description] Optional message
  1888. * @example
  1889. *
  1890. * [1, 2].should.have.length(2);
  1891. */
  1892. Assertion.add('length', function(n, description) {
  1893. this.have.property('length', n, description);
  1894. });
  1895. Assertion.alias('length', 'lengthOf');
  1896. /**
  1897. * Asserts given object has own property. **On success it change given object to be value of property**.
  1898. *
  1899. * @name ownProperty
  1900. * @alias Assertion#hasOwnProperty
  1901. * @memberOf Assertion
  1902. * @category assertion property
  1903. * @param {string} name Name of property
  1904. * @param {string} [description] Optional message
  1905. * @example
  1906. *
  1907. * ({ a: 10 }).should.have.ownProperty('a');
  1908. */
  1909. Assertion.add('ownProperty', function(name, description) {
  1910. name = convertPropertyName(name);
  1911. this.params = {
  1912. actual: this.obj,
  1913. operator: 'to have own property ' + formatProp(name),
  1914. message: description
  1915. };
  1916. this.assert(shouldUtil.hasOwnProperty(this.obj, name));
  1917. this.obj = this.obj[name];
  1918. });
  1919. Assertion.alias('ownProperty', 'hasOwnProperty');
  1920. /**
  1921. * Asserts given object is empty. For strings, arrays and arguments it checks .length property, for objects it checks keys.
  1922. *
  1923. * @name empty
  1924. * @memberOf Assertion
  1925. * @category assertion property
  1926. * @example
  1927. *
  1928. * ''.should.be.empty();
  1929. * [].should.be.empty();
  1930. * ({}).should.be.empty();
  1931. */
  1932. Assertion.add('empty', function() {
  1933. this.params = {operator: 'to be empty'};
  1934. this.assert(shouldTypeAdaptors.isEmpty(this.obj));
  1935. }, true);
  1936. /**
  1937. * Asserts given object has such keys. Compared to `properties`, `keys` does not accept Object as a argument.
  1938. * When calling via .key current object in assertion changed to value of this key
  1939. *
  1940. * @name keys
  1941. * @alias Assertion#key
  1942. * @memberOf Assertion
  1943. * @category assertion property
  1944. * @param {...*} keys Keys to check
  1945. * @example
  1946. *
  1947. * ({ a: 10 }).should.have.keys('a');
  1948. * ({ a: 10, b: 20 }).should.have.keys('a', 'b');
  1949. * (new Map([[1, 2]])).should.have.key(1);
  1950. *
  1951. * json.should.have.only.keys('type', 'version')
  1952. */
  1953. Assertion.add('keys', function(keys) {
  1954. keys = aSlice.call(arguments);
  1955. var obj = Object(this.obj);
  1956. // first check if some keys are missing
  1957. var missingKeys = keys.filter(function(key) {
  1958. return !shouldTypeAdaptors.has(obj, key);
  1959. });
  1960. var verb = 'to have ' + (this.onlyThis ? 'only ': '') + (keys.length === 1 ? 'key ' : 'keys ');
  1961. this.params = {operator: verb + keys.join(', ')};
  1962. if (missingKeys.length > 0) {
  1963. this.params.operator += '\n\tmissing keys: ' + missingKeys.join(', ');
  1964. }
  1965. this.assert(missingKeys.length === 0);
  1966. if (this.onlyThis) {
  1967. obj.should.have.size(keys.length);
  1968. }
  1969. });
  1970. Assertion.add('key', function(key) {
  1971. this.have.keys(key);
  1972. this.obj = shouldTypeAdaptors.get(this.obj, key);
  1973. });
  1974. /**
  1975. * Asserts given object has such value for given key
  1976. *
  1977. * @name value
  1978. * @memberOf Assertion
  1979. * @category assertion property
  1980. * @param {*} key Key to check
  1981. * @param {*} value Value to check
  1982. * @example
  1983. *
  1984. * ({ a: 10 }).should.have.value('a', 10);
  1985. * (new Map([[1, 2]])).should.have.value(1, 2);
  1986. */
  1987. Assertion.add('value', function(key, value) {
  1988. this.have.key(key).which.is.eql(value);
  1989. });
  1990. /**
  1991. * Asserts given object has such size.
  1992. *
  1993. * @name size
  1994. * @memberOf Assertion
  1995. * @category assertion property
  1996. * @param {number} s Size to check
  1997. * @example
  1998. *
  1999. * ({ a: 10 }).should.have.size(1);
  2000. * (new Map([[1, 2]])).should.have.size(1);
  2001. */
  2002. Assertion.add('size', function(s) {
  2003. this.params = { operator: 'to have size ' + s };
  2004. shouldTypeAdaptors.size(this.obj).should.be.exactly(s);
  2005. });
  2006. /**
  2007. * Asserts given object has nested property in depth by path. **On success it change given object to be value of final property**.
  2008. *
  2009. * @name propertyByPath
  2010. * @memberOf Assertion
  2011. * @category assertion property
  2012. * @param {Array|...string} properties Properties path to search
  2013. * @example
  2014. *
  2015. * ({ a: {b: 10}}).should.have.propertyByPath('a', 'b').eql(10);
  2016. */
  2017. Assertion.add('propertyByPath', function(properties) {
  2018. properties = aSlice.call(arguments);
  2019. var allProps = properties.map(formatProp);
  2020. properties = properties.map(convertPropertyName);
  2021. var obj = should(Object(this.obj));
  2022. var foundProperties = [];
  2023. var currentProperty;
  2024. while (properties.length) {
  2025. currentProperty = properties.shift();
  2026. this.params = {operator: 'to have property by path ' + allProps.join(', ') + ' - failed on ' + formatProp(currentProperty)};
  2027. obj = obj.have.property(currentProperty);
  2028. foundProperties.push(currentProperty);
  2029. }
  2030. this.params = {obj: this.obj, operator: 'to have property by path ' + allProps.join(', ')};
  2031. this.obj = obj.obj;
  2032. });
  2033. };
  2034. /*
  2035. * should.js - assertion library
  2036. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  2037. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  2038. * MIT Licensed
  2039. */
  2040. var errorAssertions = function(should, Assertion) {
  2041. var i = should.format;
  2042. /**
  2043. * Assert given function throws error with such message.
  2044. *
  2045. * @name throw
  2046. * @memberOf Assertion
  2047. * @category assertion errors
  2048. * @alias Assertion#throwError
  2049. * @param {string|RegExp|Function|Object|GeneratorFunction|GeneratorObject} [message] Message to match or properties
  2050. * @param {Object} [properties] Optional properties that will be matched to thrown error
  2051. * @example
  2052. *
  2053. * (function(){ throw new Error('fail') }).should.throw();
  2054. * (function(){ throw new Error('fail') }).should.throw('fail');
  2055. * (function(){ throw new Error('fail') }).should.throw(/fail/);
  2056. *
  2057. * (function(){ throw new Error('fail') }).should.throw(Error);
  2058. * var error = new Error();
  2059. * error.a = 10;
  2060. * (function(){ throw error; }).should.throw(Error, { a: 10 });
  2061. * (function(){ throw error; }).should.throw({ a: 10 });
  2062. * (function*() {
  2063. * yield throwError();
  2064. * }).should.throw();
  2065. */
  2066. Assertion.add('throw', function(message, properties) {
  2067. var fn = this.obj;
  2068. var err = {};
  2069. var errorInfo = '';
  2070. var thrown = false;
  2071. if (shouldUtil.isGeneratorFunction(fn)) {
  2072. return should(fn()).throw(message, properties);
  2073. } else if (shouldUtil.isIterator(fn)) {
  2074. return should(fn.next.bind(fn)).throw(message, properties);
  2075. }
  2076. this.is.a.Function();
  2077. var errorMatched = true;
  2078. try {
  2079. fn();
  2080. } catch (e) {
  2081. thrown = true;
  2082. err = e;
  2083. }
  2084. if (thrown) {
  2085. if (message) {
  2086. if ('string' == typeof message) {
  2087. errorMatched = message == err.message;
  2088. } else if (message instanceof RegExp) {
  2089. errorMatched = message.test(err.message);
  2090. } else if ('function' == typeof message) {
  2091. errorMatched = err instanceof message;
  2092. } else if (null != message) {
  2093. try {
  2094. should(err).match(message);
  2095. } catch (e) {
  2096. if (e instanceof should.AssertionError) {
  2097. errorInfo = ": " + e.message;
  2098. errorMatched = false;
  2099. } else {
  2100. throw e;
  2101. }
  2102. }
  2103. }
  2104. if (!errorMatched) {
  2105. if ('string' == typeof message || message instanceof RegExp) {
  2106. errorInfo = " with a message matching " + i(message) + ", but got '" + err.message + "'";
  2107. } else if ('function' == typeof message) {
  2108. errorInfo = " of type " + functionName(message) + ", but got " + functionName(err.constructor);
  2109. }
  2110. } else if ('function' == typeof message && properties) {
  2111. try {
  2112. should(err).match(properties);
  2113. } catch (e) {
  2114. if (e instanceof should.AssertionError) {
  2115. errorInfo = ": " + e.message;
  2116. errorMatched = false;
  2117. } else {
  2118. throw e;
  2119. }
  2120. }
  2121. }
  2122. } else {
  2123. errorInfo = " (got " + i(err) + ")";
  2124. }
  2125. }
  2126. this.params = { operator: 'to throw exception' + errorInfo };
  2127. this.assert(thrown);
  2128. this.assert(errorMatched);
  2129. });
  2130. Assertion.alias('throw', 'throwError');
  2131. };
  2132. /*
  2133. * should.js - assertion library
  2134. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  2135. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  2136. * MIT Licensed
  2137. */
  2138. var matchingAssertions = function(should, Assertion) {
  2139. var i = should.format;
  2140. /**
  2141. * Asserts if given object match `other` object, using some assumptions:
  2142. * First object matched if they are equal,
  2143. * If `other` is a regexp and given object is a string check on matching with regexp
  2144. * If `other` is a regexp and given object is an array check if all elements matched regexp
  2145. * If `other` is a regexp and given object is an object check values on matching regexp
  2146. * If `other` is a function check if this function throws AssertionError on given object or return false - it will be assumed as not matched
  2147. * If `other` is an object check if the same keys matched with above rules
  2148. * All other cases failed.
  2149. *
  2150. * Usually it is right idea to add pre type assertions, like `.String()` or `.Object()` to be sure assertions will do what you are expecting.
  2151. * Object iteration happen by keys (properties with enumerable: true), thus some objects can cause small pain. Typical example is js
  2152. * Error - it by default has 2 properties `name` and `message`, but they both non-enumerable. In this case make sure you specify checking props (see examples).
  2153. *
  2154. * @name match
  2155. * @memberOf Assertion
  2156. * @category assertion matching
  2157. * @param {*} other Object to match
  2158. * @param {string} [description] Optional message
  2159. * @example
  2160. * 'foobar'.should.match(/^foo/);
  2161. * 'foobar'.should.not.match(/^bar/);
  2162. *
  2163. * ({ a: 'foo', c: 'barfoo' }).should.match(/foo$/);
  2164. *
  2165. * ['a', 'b', 'c'].should.match(/[a-z]/);
  2166. *
  2167. * (5).should.not.match(function(n) {
  2168. * return n < 0;
  2169. * });
  2170. * (5).should.not.match(function(it) {
  2171. * it.should.be.an.Array();
  2172. * });
  2173. * ({ a: 10, b: 'abc', c: { d: 10 }, d: 0 }).should
  2174. * .match({ a: 10, b: /c$/, c: function(it) {
  2175. * return it.should.have.property('d', 10);
  2176. * }});
  2177. *
  2178. * [10, 'abc', { d: 10 }, 0].should
  2179. * .match({ '0': 10, '1': /c$/, '2': function(it) {
  2180. * return it.should.have.property('d', 10);
  2181. * }});
  2182. *
  2183. * var myString = 'abc';
  2184. *
  2185. * myString.should.be.a.String().and.match(/abc/);
  2186. *
  2187. * myString = {};
  2188. *
  2189. * myString.should.match(/abc/); //yes this will pass
  2190. * //better to do
  2191. * myString.should.be.an.Object().and.not.empty().and.match(/abc/);//fixed
  2192. *
  2193. * (new Error('boom')).should.match(/abc/);//passed because no keys
  2194. * (new Error('boom')).should.not.match({ message: /abc/ });//check specified property
  2195. */
  2196. Assertion.add('match', function(other, description) {
  2197. this.params = {operator: 'to match ' + i(other), message: description};
  2198. if (eql(this.obj, other).length !== 0) {
  2199. if (other instanceof RegExp) { // something - regex
  2200. if (typeof this.obj == 'string') {
  2201. this.assert(other.exec(this.obj));
  2202. } else if (null != this.obj && typeof this.obj == 'object') {
  2203. var notMatchedProps = [], matchedProps = [];
  2204. shouldTypeAdaptors.forEach(this.obj, function(value, name) {
  2205. if (other.exec(value)) {
  2206. matchedProps.push(formatProp(name));
  2207. } else {
  2208. notMatchedProps.push(formatProp(name) + ' (' + i(value) + ')');
  2209. }
  2210. }, this);
  2211. if (notMatchedProps.length) {
  2212. this.params.operator += '\n not matched properties: ' + notMatchedProps.join(', ');
  2213. }
  2214. if (matchedProps.length) {
  2215. this.params.operator += '\n matched properties: ' + matchedProps.join(', ');
  2216. }
  2217. this.assert(notMatchedProps.length === 0);
  2218. } // should we try to convert to String and exec?
  2219. else {
  2220. this.assert(false);
  2221. }
  2222. } else if (typeof other == 'function') {
  2223. var res;
  2224. res = other(this.obj);
  2225. //if we throw exception ok - it is used .should inside
  2226. if (typeof res == 'boolean') {
  2227. this.assert(res); // if it is just boolean function assert on it
  2228. }
  2229. } else if (other != null && this.obj != null && typeof other == 'object' && typeof this.obj == 'object') { // try to match properties (for Object and Array)
  2230. notMatchedProps = [];
  2231. matchedProps = [];
  2232. shouldTypeAdaptors.forEach(other, function(value, key) {
  2233. try {
  2234. should(this.obj).have.property(key).which.match(value);
  2235. matchedProps.push(formatProp(key));
  2236. } catch (e) {
  2237. if (e instanceof should.AssertionError) {
  2238. notMatchedProps.push(formatProp(key) + ' (' + i(this.obj[key]) + ')');
  2239. } else {
  2240. throw e;
  2241. }
  2242. }
  2243. }, this);
  2244. if (notMatchedProps.length) {
  2245. this.params.operator += '\n not matched properties: ' + notMatchedProps.join(', ');
  2246. }
  2247. if (matchedProps.length) {
  2248. this.params.operator += '\n matched properties: ' + matchedProps.join(', ');
  2249. }
  2250. this.assert(notMatchedProps.length === 0);
  2251. } else {
  2252. this.assert(false);
  2253. }
  2254. }
  2255. });
  2256. /**
  2257. * Asserts if given object values or array elements all match `other` object, using some assumptions:
  2258. * First object matched if they are equal,
  2259. * If `other` is a regexp - matching with regexp
  2260. * If `other` is a function check if this function throws AssertionError on given object or return false - it will be assumed as not matched
  2261. * All other cases check if this `other` equal to each element
  2262. *
  2263. * @name matchEach
  2264. * @memberOf Assertion
  2265. * @category assertion matching
  2266. * @alias Assertion#matchEvery
  2267. * @param {*} other Object to match
  2268. * @param {string} [description] Optional message
  2269. * @example
  2270. * [ 'a', 'b', 'c'].should.matchEach(/\w+/);
  2271. * [ 'a', 'a', 'a'].should.matchEach('a');
  2272. *
  2273. * [ 'a', 'a', 'a'].should.matchEach(function(value) { value.should.be.eql('a') });
  2274. *
  2275. * { a: 'a', b: 'a', c: 'a' }.should.matchEach(function(value) { value.should.be.eql('a') });
  2276. */
  2277. Assertion.add('matchEach', function(other, description) {
  2278. this.params = {operator: 'to match each ' + i(other), message: description};
  2279. shouldTypeAdaptors.forEach(this.obj, function(value) {
  2280. should(value).match(other);
  2281. }, this);
  2282. });
  2283. /**
  2284. * Asserts if any of given object values or array elements match `other` object, using some assumptions:
  2285. * First object matched if they are equal,
  2286. * If `other` is a regexp - matching with regexp
  2287. * If `other` is a function check if this function throws AssertionError on given object or return false - it will be assumed as not matched
  2288. * All other cases check if this `other` equal to each element
  2289. *
  2290. * @name matchAny
  2291. * @memberOf Assertion
  2292. * @category assertion matching
  2293. * @param {*} other Object to match
  2294. * @alias Assertion#matchSome
  2295. * @param {string} [description] Optional message
  2296. * @example
  2297. * [ 'a', 'b', 'c'].should.matchAny(/\w+/);
  2298. * [ 'a', 'b', 'c'].should.matchAny('a');
  2299. *
  2300. * [ 'a', 'b', 'c'].should.matchAny(function(value) { value.should.be.eql('a') });
  2301. *
  2302. * { a: 'a', b: 'b', c: 'c' }.should.matchAny(function(value) { value.should.be.eql('a') });
  2303. */
  2304. Assertion.add('matchAny', function(other, description) {
  2305. this.params = {operator: 'to match any ' + i(other), message: description};
  2306. this.assert(shouldTypeAdaptors.some(this.obj, function(value) {
  2307. try {
  2308. should(value).match(other);
  2309. return true;
  2310. } catch (e) {
  2311. if (e instanceof should.AssertionError) {
  2312. // Caught an AssertionError, return false to the iterator
  2313. return false;
  2314. }
  2315. throw e;
  2316. }
  2317. }));
  2318. });
  2319. Assertion.alias('matchAny', 'matchSome');
  2320. Assertion.alias('matchEach', 'matchEvery');
  2321. };
  2322. /*
  2323. * should.js - assertion library
  2324. * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
  2325. * Copyright(c) 2013-2016 Denis Bardadym <bardadymchik@gmail.com>
  2326. * MIT Licensed
  2327. */
  2328. /**
  2329. * Our function should
  2330. *
  2331. * @param {*} obj Object to assert
  2332. * @returns {should.Assertion} Returns new Assertion for beginning assertion chain
  2333. * @example
  2334. *
  2335. * var should = require('should');
  2336. * should('abc').be.a.String();
  2337. */
  2338. function should(obj) {
  2339. return (new Assertion(obj));
  2340. }
  2341. should.AssertionError = AssertionError;
  2342. should.Assertion = Assertion;
  2343. // exposing modules dirty way
  2344. should.modules = {
  2345. format: sformat,
  2346. type: getType,
  2347. equal: eql
  2348. };
  2349. should.format = format;
  2350. /**
  2351. * Object with configuration.
  2352. * It contains such properties:
  2353. * * `checkProtoEql` boolean - Affect if `.eql` will check objects prototypes
  2354. * * `plusZeroAndMinusZeroEqual` boolean - Affect if `.eql` will treat +0 and -0 as equal
  2355. * Also it can contain options for should-format.
  2356. *
  2357. * @type {Object}
  2358. * @memberOf should
  2359. * @static
  2360. * @example
  2361. *
  2362. * var a = { a: 10 }, b = Object.create(null);
  2363. * b.a = 10;
  2364. *
  2365. * a.should.be.eql(b);
  2366. * //not throws
  2367. *
  2368. * should.config.checkProtoEql = true;
  2369. * a.should.be.eql(b);
  2370. * //throws AssertionError: expected { a: 10 } to equal { a: 10 } (because A and B have different prototypes)
  2371. */
  2372. should.config = config;
  2373. /**
  2374. * Allow to extend given prototype with should property using given name. This getter will **unwrap** all standard wrappers like `Number`, `Boolean`, `String`.
  2375. * Using `should(obj)` is the equivalent of using `obj.should` with known issues (like nulls and method calls etc).
  2376. *
  2377. * To add new assertions, need to use Assertion.add method.
  2378. *
  2379. * @param {string} [propertyName] Name of property to add. Default is `'should'`.
  2380. * @param {Object} [proto] Prototype to extend with. Default is `Object.prototype`.
  2381. * @memberOf should
  2382. * @returns {{ name: string, descriptor: Object, proto: Object }} Descriptor enough to return all back
  2383. * @static
  2384. * @example
  2385. *
  2386. * var prev = should.extend('must', Object.prototype);
  2387. *
  2388. * 'abc'.must.startWith('a');
  2389. *
  2390. * var should = should.noConflict(prev);
  2391. * should.not.exist(Object.prototype.must);
  2392. */
  2393. should.extend = function(propertyName, proto) {
  2394. propertyName = propertyName || 'should';
  2395. proto = proto || Object.prototype;
  2396. var prevDescriptor = Object.getOwnPropertyDescriptor(proto, propertyName);
  2397. Object.defineProperty(proto, propertyName, {
  2398. set: function() {
  2399. },
  2400. get: function() {
  2401. return should(isWrapperType(this) ? this.valueOf() : this);
  2402. },
  2403. configurable: true
  2404. });
  2405. return { name: propertyName, descriptor: prevDescriptor, proto: proto };
  2406. };
  2407. /**
  2408. * Delete previous extension. If `desc` missing it will remove default extension.
  2409. *
  2410. * @param {{ name: string, descriptor: Object, proto: Object }} [desc] Returned from `should.extend` object
  2411. * @memberOf should
  2412. * @returns {Function} Returns should function
  2413. * @static
  2414. * @example
  2415. *
  2416. * var should = require('should').noConflict();
  2417. *
  2418. * should(Object.prototype).not.have.property('should');
  2419. *
  2420. * var prev = should.extend('must', Object.prototype);
  2421. * 'abc'.must.startWith('a');
  2422. * should.noConflict(prev);
  2423. *
  2424. * should(Object.prototype).not.have.property('must');
  2425. */
  2426. should.noConflict = function(desc) {
  2427. desc = desc || should._prevShould;
  2428. if (desc) {
  2429. delete desc.proto[desc.name];
  2430. if (desc.descriptor) {
  2431. Object.defineProperty(desc.proto, desc.name, desc.descriptor);
  2432. }
  2433. }
  2434. return should;
  2435. };
  2436. /**
  2437. * Simple utility function for a bit more easier should assertion extension
  2438. * @param {Function} f So called plugin function. It should accept 2 arguments: `should` function and `Assertion` constructor
  2439. * @memberOf should
  2440. * @returns {Function} Returns `should` function
  2441. * @static
  2442. * @example
  2443. *
  2444. * should.use(function(should, Assertion) {
  2445. * Assertion.add('asset', function() {
  2446. * this.params = { operator: 'to be asset' };
  2447. *
  2448. * this.obj.should.have.property('id').which.is.a.Number();
  2449. * this.obj.should.have.property('path');
  2450. * })
  2451. * })
  2452. */
  2453. should.use = function(f) {
  2454. f(should, should.Assertion);
  2455. return this;
  2456. };
  2457. should
  2458. .use(assertExtensions)
  2459. .use(chainAssertions)
  2460. .use(booleanAssertions)
  2461. .use(numberAssertions)
  2462. .use(equalityAssertions)
  2463. .use(typeAssertions)
  2464. .use(stringAssertions)
  2465. .use(propertyAssertions)
  2466. .use(errorAssertions)
  2467. .use(matchingAssertions)
  2468. .use(containAssertions)
  2469. .use(promiseAssertions);
  2470. module.exports = should;