should.js 99 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532
  1. /*!
  2. * should - test framework agnostic BDD-style assertions
  3. * @version v7.1.1
  4. * @author TJ Holowaychuk <tj@vision-media.ca> and contributors
  5. * @link https://github.com/shouldjs/should.js
  6. * @license MIT
  7. */
  8. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Should = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  9. var should = require('./lib/should');
  10. var defaultProto = Object.prototype;
  11. var defaultProperty = 'should';
  12. //Expose api via `Object#should`.
  13. try {
  14. var prevShould = should.extend(defaultProperty, defaultProto);
  15. should._prevShould = prevShould;
  16. } catch(e) {
  17. //ignore errors
  18. }
  19. module.exports = should;
  20. },{"./lib/should":17}],2:[function(require,module,exports){
  21. var util = require('./util');
  22. /**
  23. * should AssertionError
  24. * @param {Object} options
  25. * @constructor
  26. * @memberOf should
  27. * @static
  28. */
  29. var AssertionError = function AssertionError(options) {
  30. util.merge(this, options);
  31. if(!options.message) {
  32. Object.defineProperty(this, 'message', {
  33. get: function() {
  34. if(!this._message) {
  35. this._message = this.generateMessage();
  36. this.generatedMessage = true;
  37. }
  38. return this._message;
  39. },
  40. configurable: true,
  41. enumerable: false
  42. }
  43. );
  44. }
  45. if(Error.captureStackTrace) {
  46. Error.captureStackTrace(this, this.stackStartFunction);
  47. } else {
  48. // non v8 browsers so we can have a stacktrace
  49. var err = new Error();
  50. if(err.stack) {
  51. var out = err.stack;
  52. if(this.stackStartFunction) {
  53. // try to strip useless frames
  54. var fn_name = util.functionName(this.stackStartFunction);
  55. var idx = out.indexOf('\n' + fn_name);
  56. if(idx >= 0) {
  57. // once we have located the function frame
  58. // we need to strip out everything before it (and its line)
  59. var next_line = out.indexOf('\n', idx + 1);
  60. out = out.substring(next_line + 1);
  61. }
  62. }
  63. this.stack = out;
  64. }
  65. }
  66. };
  67. var indent = ' ';
  68. function prependIndent(line) {
  69. return indent + line;
  70. }
  71. function indentLines(text) {
  72. return text.split('\n').map(prependIndent).join('\n');
  73. }
  74. // assert.AssertionError instanceof Error
  75. AssertionError.prototype = Object.create(Error.prototype, {
  76. name: {
  77. value: 'AssertionError'
  78. },
  79. generateMessage: {
  80. value: function() {
  81. if(!this.operator && this.previous) {
  82. return this.previous.message;
  83. }
  84. var actual = util.format(this.actual);
  85. var expected = 'expected' in this ? ' ' + util.format(this.expected) : '';
  86. var details = 'details' in this && this.details ? ' (' + this.details + ')' : '';
  87. var previous = this.previous ? '\n' + indentLines(this.previous.message) : '';
  88. return 'expected ' + actual + (this.negate ? ' not ' : ' ') + this.operator + expected + details + previous;
  89. }
  90. }
  91. });
  92. module.exports = AssertionError;
  93. },{"./util":18}],3:[function(require,module,exports){
  94. var AssertionError = require('./assertion-error');
  95. var util = require('./util');
  96. /**
  97. * should Assertion
  98. * @param {*} obj Given object for assertion
  99. * @constructor
  100. * @memberOf should
  101. * @static
  102. */
  103. function Assertion(obj) {
  104. this.obj = obj;
  105. this.anyOne = false;
  106. this.negate = false;
  107. this.params = {actual: obj};
  108. }
  109. /**
  110. * Way to extend Assertion function. It uses some logic
  111. * to define only positive assertions and itself rule with negative assertion.
  112. *
  113. * All actions happen in subcontext and this method take care about negation.
  114. * Potentially we can add some more modifiers that does not depends from state of assertion.
  115. * @memberOf Assertion
  116. * @category assertion
  117. * @static
  118. * @param {String} name Name of assertion. It will be used for defining method or getter on Assertion.prototype
  119. * @param {Function} func Function that will be called on executing assertion
  120. * @example
  121. *
  122. * Assertion.add('asset', function() {
  123. * this.params = { operator: 'to be asset' };
  124. *
  125. * this.obj.should.have.property('id').which.is.a.Number();
  126. * this.obj.should.have.property('path');
  127. * });
  128. */
  129. Assertion.add = function(name, func) {
  130. var prop = {enumerable: true, configurable: true};
  131. prop.value = function() {
  132. var context = new Assertion(this.obj, this, name);
  133. context.anyOne = this.anyOne;
  134. try {
  135. func.apply(context, arguments);
  136. } catch(e) {
  137. //check for fail
  138. if(e instanceof AssertionError) {
  139. //negative fail
  140. if(this.negate) {
  141. this.obj = context.obj;
  142. this.negate = false;
  143. return this;
  144. }
  145. if(context !== e.assertion) {
  146. context.params.previous = e;
  147. }
  148. //positive fail
  149. context.negate = false;
  150. context.fail();
  151. }
  152. // throw if it is another exception
  153. throw e;
  154. }
  155. //negative pass
  156. if(this.negate) {
  157. context.negate = true;//because .fail will set negate
  158. context.params.details = 'false negative fail';
  159. context.fail();
  160. }
  161. //positive pass
  162. if(!this.params.operator) this.params = context.params;//shortcut
  163. this.obj = context.obj;
  164. this.negate = false;
  165. return this;
  166. };
  167. Object.defineProperty(Assertion.prototype, name, prop);
  168. };
  169. Assertion.addChain = function(name, onCall) {
  170. onCall = onCall || function() {
  171. };
  172. Object.defineProperty(Assertion.prototype, name, {
  173. get: function() {
  174. onCall();
  175. return this;
  176. },
  177. enumerable: true
  178. });
  179. };
  180. /**
  181. * Create alias for some `Assertion` property
  182. *
  183. * @memberOf Assertion
  184. * @category assertion
  185. * @static
  186. * @param {String} from Name of to map
  187. * @param {String} to Name of alias
  188. * @example
  189. *
  190. * Assertion.alias('true', 'True');
  191. */
  192. Assertion.alias = function(from, to) {
  193. var desc = Object.getOwnPropertyDescriptor(Assertion.prototype, from);
  194. if(!desc) throw new Error('Alias ' + from + ' -> ' + to + ' could not be created as ' + from + ' not defined');
  195. Object.defineProperty(Assertion.prototype, to, desc);
  196. };
  197. Assertion.prototype = {
  198. constructor: Assertion,
  199. /**
  200. * Base method for assertions. Before calling this method need to fill Assertion#params object. This method usually called from other assertion methods.
  201. * `Assertion#params` can contain such properties:
  202. * * `operator` - required string containing description of this assertion
  203. * * `obj` - optional replacement for this.obj, it usefull if you prepare more clear object then given
  204. * * `message` - if this property filled with string any others will be ignored and this one used as assertion message
  205. * * `expected` - any object used when you need to assert relation between given object and expected. Like given == expected (== is a relation)
  206. * * `details` - additional string with details to generated message
  207. *
  208. * @memberOf Assertion
  209. * @category assertion
  210. * @param {*} expr Any expression that will be used as a condition for asserting.
  211. * @example
  212. *
  213. * var a = new should.Assertion(42);
  214. *
  215. * a.params = {
  216. * operator: 'to be magic number',
  217. * }
  218. *
  219. * a.assert(false);
  220. * //throws AssertionError: expected 42 to be magic number
  221. */
  222. assert: function(expr) {
  223. if(expr) return this;
  224. var params = this.params;
  225. if('obj' in params && !('actual' in params)) {
  226. params.actual = params.obj;
  227. } else if(!('obj' in params) && !('actual' in params)) {
  228. params.actual = this.obj;
  229. }
  230. params.stackStartFunction = params.stackStartFunction || this.assert;
  231. params.negate = this.negate;
  232. params.assertion = this;
  233. throw new AssertionError(params);
  234. },
  235. /**
  236. * Shortcut for `Assertion#assert(false)`.
  237. *
  238. * @memberOf Assertion
  239. * @category assertion
  240. * @example
  241. *
  242. * var a = new should.Assertion(42);
  243. *
  244. * a.params = {
  245. * operator: 'to be magic number',
  246. * }
  247. *
  248. * a.fail();
  249. * //throws AssertionError: expected 42 to be magic number
  250. */
  251. fail: function() {
  252. return this.assert(false);
  253. },
  254. /**
  255. * Negation modifier. Current assertion chain become negated. Each call invert negation on current assertion.
  256. *
  257. * @memberOf Assertion
  258. * @category assertion
  259. */
  260. get not() {
  261. this.negate = !this.negate;
  262. return this;
  263. },
  264. /**
  265. * Any modifier - it affect on execution of sequenced assertion to do not `check all`, but `check any of`.
  266. *
  267. * @memberOf Assertion
  268. * @category assertion
  269. */
  270. get any() {
  271. this.anyOne = true;
  272. return this;
  273. }
  274. };
  275. module.exports = Assertion;
  276. },{"./assertion-error":2,"./util":18}],4:[function(require,module,exports){
  277. var Formatter = require('should-format').Formatter;
  278. var config = {
  279. checkProtoEql: false,
  280. getFormatter: function(opts) {
  281. return new Formatter(opts || config);
  282. }
  283. };
  284. module.exports = config;
  285. },{"should-format":21}],5:[function(require,module,exports){
  286. // implement assert interface using already written peaces of should.js
  287. // http://wiki.commonjs.org/wiki/Unit_Testing/1.0
  288. //
  289. // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
  290. //
  291. // Originally from narwhal.js (http://narwhaljs.org)
  292. // Copyright (c) 2009 Thomas Robinson <280north.com>
  293. //
  294. // Permission is hereby granted, free of charge, to any person obtaining a copy
  295. // of this software and associated documentation files (the 'Software'), to
  296. // deal in the Software without restriction, including without limitation the
  297. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  298. // sell copies of the Software, and to permit persons to whom the Software is
  299. // furnished to do so, subject to the following conditions:
  300. //
  301. // The above copyright notice and this permission notice shall be included in
  302. // all copies or substantial portions of the Software.
  303. //
  304. // THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  305. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  306. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  307. // AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  308. // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  309. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  310. // when used in node, this will actually load the util module we depend on
  311. // versus loading the builtin util module as happens otherwise
  312. // this is a bug in node module loading as far as I am concerned
  313. var Assertion = require('./../assertion');
  314. var _deepEqual = require('should-equal');
  315. var pSlice = Array.prototype.slice;
  316. // 1. The assert module provides functions that throw
  317. // AssertionError's when particular conditions are not met. The
  318. // assert module must conform to the following interface.
  319. var assert = module.exports = ok;
  320. // 3. All of the following functions must throw an AssertionError
  321. // when a corresponding condition is not met, with a message that
  322. // may be undefined if not provided. All assertion methods provide
  323. // both the actual and expected values to the assertion error for
  324. // display purposes.
  325. /**
  326. * Node.js standard [`assert.fail`](http://nodejs.org/api/assert.html#assert_assert_fail_actual_expected_message_operator).
  327. * @static
  328. * @memberOf should
  329. * @category assertion assert
  330. * @param {*} actual Actual object
  331. * @param {*} expected Expected object
  332. * @param {string} message Message for assertion
  333. * @param {string} operator Operator text
  334. */
  335. function fail(actual, expected, message, operator, stackStartFunction) {
  336. var a = new Assertion(actual);
  337. a.params = {
  338. operator: operator,
  339. expected: expected,
  340. message: message,
  341. stackStartFunction: stackStartFunction || fail
  342. };
  343. a.fail();
  344. }
  345. // EXTENSION! allows for well behaved errors defined elsewhere.
  346. assert.fail = fail;
  347. // 4. Pure assertion tests whether a value is truthy, as determined
  348. // by !!guard.
  349. // assert.ok(guard, message_opt);
  350. // This statement is equivalent to assert.equal(true, !!guard,
  351. // message_opt);. To test strictly for the value true, use
  352. // assert.strictEqual(true, guard, message_opt);.
  353. /**
  354. * Node.js standard [`assert.ok`](http://nodejs.org/api/assert.html#assert_assert_value_message_assert_ok_value_message).
  355. * @static
  356. * @memberOf should
  357. * @category assertion assert
  358. * @param {*} value
  359. * @param {string} [message]
  360. */
  361. function ok(value, message) {
  362. if(!value) fail(value, true, message, '==', assert.ok);
  363. }
  364. assert.ok = ok;
  365. // 5. The equality assertion tests shallow, coercive equality with
  366. // ==.
  367. // assert.equal(actual, expected, message_opt);
  368. /**
  369. * Node.js standard [`assert.equal`](http://nodejs.org/api/assert.html#assert_assert_equal_actual_expected_message).
  370. * @static
  371. * @memberOf should
  372. * @category assertion assert
  373. * @param {*} actual
  374. * @param {*} expected
  375. * @param {string} [message]
  376. */
  377. assert.equal = function equal(actual, expected, message) {
  378. if(actual != expected) fail(actual, expected, message, '==', assert.equal);
  379. };
  380. // 6. The non-equality assertion tests for whether two objects are not equal
  381. // with != assert.notEqual(actual, expected, message_opt);
  382. /**
  383. * Node.js standard [`assert.notEqual`](http://nodejs.org/api/assert.html#assert_assert_notequal_actual_expected_message).
  384. * @static
  385. * @memberOf should
  386. * @category assertion assert
  387. * @param {*} actual
  388. * @param {*} expected
  389. * @param {string} [message]
  390. */
  391. assert.notEqual = function notEqual(actual, expected, message) {
  392. if(actual == expected) {
  393. fail(actual, expected, message, '!=', assert.notEqual);
  394. }
  395. };
  396. // 7. The equivalence assertion tests a deep equality relation.
  397. // assert.deepEqual(actual, expected, message_opt);
  398. /**
  399. * Node.js standard [`assert.deepEqual`](http://nodejs.org/api/assert.html#assert_assert_deepequal_actual_expected_message).
  400. * @static
  401. * @memberOf should
  402. * @category assertion assert
  403. * @param {*} actual
  404. * @param {*} expected
  405. * @param {string} [message]
  406. */
  407. assert.deepEqual = function deepEqual(actual, expected, message) {
  408. if(!_deepEqual(actual, expected).result) {
  409. fail(actual, expected, message, 'deepEqual', assert.deepEqual);
  410. }
  411. };
  412. // 8. The non-equivalence assertion tests for any deep inequality.
  413. // assert.notDeepEqual(actual, expected, message_opt);
  414. /**
  415. * Node.js standard [`assert.notDeepEqual`](http://nodejs.org/api/assert.html#assert_assert_notdeepequal_actual_expected_message).
  416. * @static
  417. * @memberOf should
  418. * @category assertion assert
  419. * @param {*} actual
  420. * @param {*} expected
  421. * @param {string} [message]
  422. */
  423. assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
  424. if(_deepEqual(actual, expected).result) {
  425. fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
  426. }
  427. };
  428. // 9. The strict equality assertion tests strict equality, as determined by ===.
  429. // assert.strictEqual(actual, expected, message_opt);
  430. /**
  431. * Node.js standard [`assert.strictEqual`](http://nodejs.org/api/assert.html#assert_assert_strictequal_actual_expected_message).
  432. * @static
  433. * @memberOf should
  434. * @category assertion assert
  435. * @param {*} actual
  436. * @param {*} expected
  437. * @param {string} [message]
  438. */
  439. assert.strictEqual = function strictEqual(actual, expected, message) {
  440. if(actual !== expected) {
  441. fail(actual, expected, message, '===', assert.strictEqual);
  442. }
  443. };
  444. // 10. The strict non-equality assertion tests for strict inequality, as
  445. // determined by !==. assert.notStrictEqual(actual, expected, message_opt);
  446. /**
  447. * Node.js standard [`assert.notStrictEqual`](http://nodejs.org/api/assert.html#assert_assert_notstrictequal_actual_expected_message).
  448. * @static
  449. * @memberOf should
  450. * @category assertion assert
  451. * @param {*} actual
  452. * @param {*} expected
  453. * @param {string} [message]
  454. */
  455. assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
  456. if(actual === expected) {
  457. fail(actual, expected, message, '!==', assert.notStrictEqual);
  458. }
  459. };
  460. function expectedException(actual, expected) {
  461. if(!actual || !expected) {
  462. return false;
  463. }
  464. if(Object.prototype.toString.call(expected) == '[object RegExp]') {
  465. return expected.test(actual);
  466. } else if(actual instanceof expected) {
  467. return true;
  468. } else if(expected.call({}, actual) === true) {
  469. return true;
  470. }
  471. return false;
  472. }
  473. function _throws(shouldThrow, block, expected, message) {
  474. var actual;
  475. if(typeof expected == 'string') {
  476. message = expected;
  477. expected = null;
  478. }
  479. try {
  480. block();
  481. } catch(e) {
  482. actual = e;
  483. }
  484. message = (expected && expected.name ? ' (' + expected.name + ')' : '.') +
  485. (message ? ' ' + message : '.');
  486. if(shouldThrow && !actual) {
  487. fail(actual, expected, 'Missing expected exception' + message);
  488. }
  489. if(!shouldThrow && expectedException(actual, expected)) {
  490. fail(actual, expected, 'Got unwanted exception' + message);
  491. }
  492. if((shouldThrow && actual && expected && !expectedException(actual, expected)) || (!shouldThrow && actual)) {
  493. throw actual;
  494. }
  495. }
  496. // 11. Expected to throw an error:
  497. // assert.throws(block, Error_opt, message_opt);
  498. /**
  499. * Node.js standard [`assert.throws`](http://nodejs.org/api/assert.html#assert_assert_throws_block_error_message).
  500. * @static
  501. * @memberOf should
  502. * @category assertion assert
  503. * @param {Function} block
  504. * @param {Function} [error]
  505. * @param {String} [message]
  506. */
  507. assert.throws = function(block, /*optional*/error, /*optional*/message) {
  508. _throws.apply(this, [true].concat(pSlice.call(arguments)));
  509. };
  510. // EXTENSION! This is annoying to write outside this module.
  511. /**
  512. * Node.js standard [`assert.doesNotThrow`](http://nodejs.org/api/assert.html#assert_assert_doesnotthrow_block_message).
  513. * @static
  514. * @memberOf should
  515. * @category assertion assert
  516. * @param {Function} block
  517. * @param {String} [message]
  518. */
  519. assert.doesNotThrow = function(block, /*optional*/message) {
  520. _throws.apply(this, [false].concat(pSlice.call(arguments)));
  521. };
  522. /**
  523. * Node.js standard [`assert.ifError`](http://nodejs.org/api/assert.html#assert_assert_iferror_value).
  524. * @static
  525. * @memberOf should
  526. * @category assertion assert
  527. * @param {Error} err
  528. */
  529. assert.ifError = function(err) {
  530. if(err) {
  531. throw err;
  532. }
  533. };
  534. },{"./../assertion":3,"should-equal":20}],6:[function(require,module,exports){
  535. /*
  536. * Should
  537. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  538. * MIT Licensed
  539. */
  540. var util = require('../util')
  541. , assert = require('./_assert')
  542. , AssertionError = require('../assertion-error');
  543. module.exports = function(should) {
  544. var i = should.format;
  545. /*
  546. * Expose assert to should
  547. *
  548. * This allows you to do things like below
  549. * without require()ing the assert module.
  550. *
  551. * should.equal(foo.bar, undefined);
  552. *
  553. */
  554. util.merge(should, assert);
  555. /**
  556. * Assert _obj_ exists, with optional message.
  557. *
  558. * @static
  559. * @memberOf should
  560. * @category assertion assert
  561. * @alias should.exists
  562. * @param {*} obj
  563. * @param {String} [msg]
  564. * @example
  565. *
  566. * should.exist(1);
  567. * should.exist(new Date());
  568. */
  569. should.exist = should.exists = function(obj, msg) {
  570. if(null == obj) {
  571. throw new AssertionError({
  572. message: msg || ('expected ' + i(obj) + ' to exist'), stackStartFunction: should.exist
  573. });
  574. }
  575. };
  576. should.not = {};
  577. /**
  578. * Asserts _obj_ does not exist, with optional message.
  579. *
  580. * @name not.exist
  581. * @static
  582. * @memberOf should
  583. * @category assertion assert
  584. * @alias should.not.exists
  585. * @param {*} obj
  586. * @param {String} [msg]
  587. * @example
  588. *
  589. * should.not.exist(null);
  590. * should.not.exist(void 0);
  591. */
  592. should.not.exist = should.not.exists = function(obj, msg) {
  593. if(null != obj) {
  594. throw new AssertionError({
  595. message: msg || ('expected ' + i(obj) + ' to not exist'), stackStartFunction: should.not.exist
  596. });
  597. }
  598. };
  599. };
  600. },{"../assertion-error":2,"../util":18,"./_assert":5}],7:[function(require,module,exports){
  601. /*
  602. * Should
  603. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  604. * MIT Licensed
  605. */
  606. module.exports = function(should, Assertion) {
  607. /**
  608. * Assert given object is exactly `true`.
  609. *
  610. * @name true
  611. * @memberOf Assertion
  612. * @category assertion bool
  613. * @alias Assertion#True
  614. * @example
  615. *
  616. * (true).should.be.true();
  617. * false.should.not.be.true();
  618. *
  619. * ({ a: 10}).should.not.be.true();
  620. */
  621. Assertion.add('true', function() {
  622. this.is.exactly(true);
  623. });
  624. Assertion.alias('true', 'True');
  625. /**
  626. * Assert given object is exactly `false`.
  627. *
  628. * @name false
  629. * @memberOf Assertion
  630. * @category assertion bool
  631. * @alias Assertion#False
  632. * @example
  633. *
  634. * (true).should.not.be.false();
  635. * false.should.be.false();
  636. */
  637. Assertion.add('false', function() {
  638. this.is.exactly(false);
  639. });
  640. Assertion.alias('false', 'False');
  641. /**
  642. * Assert given object is thuthy according javascript type conversions.
  643. *
  644. * @name ok
  645. * @memberOf Assertion
  646. * @category assertion bool
  647. * @example
  648. *
  649. * (true).should.be.ok();
  650. * ''.should.not.be.ok();
  651. * should(null).not.be.ok();
  652. * should(void 0).not.be.ok();
  653. *
  654. * (10).should.be.ok();
  655. * (0).should.not.be.ok();
  656. */
  657. Assertion.add('ok', function() {
  658. this.params = { operator: 'to be truthy' };
  659. this.assert(this.obj);
  660. });
  661. };
  662. },{}],8:[function(require,module,exports){
  663. module.exports = function(should, Assertion) {
  664. /**
  665. * Simple chaining. It actually do nothing.
  666. *
  667. * @memberOf Assertion
  668. * @name be
  669. * @property {should.Assertion} be
  670. * @alias Assertion#an
  671. * @alias Assertion#of
  672. * @alias Assertion#a
  673. * @alias Assertion#and
  674. * @alias Assertion#have
  675. * @alias Assertion#has
  676. * @alias Assertion#with
  677. * @alias Assertion#is
  678. * @alias Assertion#which
  679. * @alias Assertion#the
  680. * @alias Assertion#it
  681. * @category assertion chaining
  682. */
  683. ['an', 'of', 'a', 'and', 'be', 'has', 'have', 'with', 'is', 'which', 'the', 'it'].forEach(function(name) {
  684. Assertion.addChain(name);
  685. });
  686. };
  687. },{}],9:[function(require,module,exports){
  688. /*
  689. * Should
  690. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  691. * MIT Licensed
  692. */
  693. var util = require('../util');
  694. var eql = require('should-equal');
  695. module.exports = function(should, Assertion) {
  696. var i = should.format;
  697. /**
  698. * Assert that given object contain something that equal to `other`. It uses `should-equal` for equality checks.
  699. * If given object is array it search that one of elements was equal to `other`.
  700. * If given object is string it checks if `other` is a substring - expected that `other` is a string.
  701. * If given object is Object it checks that `other` is a subobject - expected that `other` is a object.
  702. *
  703. * @name containEql
  704. * @memberOf Assertion
  705. * @category assertion contain
  706. * @param {*} other Nested object
  707. * @example
  708. *
  709. * [1, 2, 3].should.containEql(1);
  710. * [{ a: 1 }, 'a', 10].should.containEql({ a: 1 });
  711. *
  712. * 'abc'.should.containEql('b');
  713. * 'ab1c'.should.containEql(1);
  714. *
  715. * ({ a: 10, c: { d: 10 }}).should.containEql({ a: 10 });
  716. * ({ a: 10, c: { d: 10 }}).should.containEql({ c: { d: 10 }});
  717. * ({ a: 10, c: { d: 10 }}).should.containEql({ b: 10 });
  718. * // throws AssertionError: expected { a: 10, c: { d: 10 } } to contain { b: 10 }
  719. * // expected { a: 10, c: { d: 10 } } to have property b
  720. */
  721. Assertion.add('containEql', function(other) {
  722. this.params = {operator: 'to contain ' + i(other)};
  723. this.is.not.null().and.not.undefined();
  724. var obj = this.obj;
  725. if(typeof obj == 'string') {
  726. this.assert(obj.indexOf(String(other)) >= 0);
  727. } else if(util.isIndexable(obj)) {
  728. this.assert(util.some(obj, function(v) {
  729. return eql(v, other).result;
  730. }));
  731. } else {
  732. this.have.properties(other);
  733. }
  734. });
  735. /**
  736. * Assert that given object is contain equally structured object on the same depth level.
  737. * 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)
  738. * If given object is an object it checks that the same keys contain deep equal values (recursive)
  739. * On other cases it try to check with `.eql`
  740. *
  741. * @name containDeepOrdered
  742. * @memberOf Assertion
  743. * @category assertion contain
  744. * @param {*} other Nested object
  745. * @example
  746. *
  747. * [ 1, 2, 3].should.containDeepOrdered([1, 2]);
  748. * [ 1, 2, [ 1, 2, 3 ]].should.containDeepOrdered([ 1, [ 2, 3 ]]);
  749. *
  750. * ({ a: 10, b: { c: 10, d: [1, 2, 3] }}).should.containDeepOrdered({a: 10});
  751. * ({ a: 10, b: { c: 10, d: [1, 2, 3] }}).should.containDeepOrdered({b: {c: 10}});
  752. * ({ a: 10, b: { c: 10, d: [1, 2, 3] }}).should.containDeepOrdered({b: {d: [1, 3]}});
  753. */
  754. Assertion.add('containDeepOrdered', function(other) {
  755. this.params = {operator: 'to contain ' + i(other)};
  756. var obj = this.obj;
  757. if(typeof obj == 'string') {// expect other to be string
  758. this.is.equal(String(other));
  759. } else if(util.isIndexable(obj) && util.isIndexable(other)) {
  760. for(var objIdx = 0, otherIdx = 0, objLength = util.length(obj), otherLength = util.length(other); objIdx < objLength && otherIdx < otherLength; objIdx++) {
  761. try {
  762. should(obj[objIdx]).containDeepOrdered(other[otherIdx]);
  763. otherIdx++;
  764. } catch(e) {
  765. if(e instanceof should.AssertionError) {
  766. continue;
  767. }
  768. throw e;
  769. }
  770. }
  771. this.assert(otherIdx === otherLength);
  772. } else if(obj != null && other != null && typeof obj == 'object' && typeof other == 'object') {// object contains object case
  773. util.forEach(other, function(value, key) {
  774. should(obj[key]).containDeepOrdered(value);
  775. });
  776. // if both objects is empty means we finish traversing - and we need to compare for hidden values
  777. if(util.isEmptyObject(other)) {
  778. this.eql(other);
  779. }
  780. } else {
  781. this.eql(other);
  782. }
  783. });
  784. /**
  785. * The same like `Assertion#containDeepOrdered` but all checks on arrays without order.
  786. *
  787. * @name containDeep
  788. * @memberOf Assertion
  789. * @category assertion contain
  790. * @param {*} other Nested object
  791. * @example
  792. *
  793. * [ 1, 2, 3].should.containDeep([2, 1]);
  794. * [ 1, 2, [ 1, 2, 3 ]].should.containDeep([ 1, [ 3, 1 ]]);
  795. */
  796. Assertion.add('containDeep', function(other) {
  797. this.params = {operator: 'to contain ' + i(other)};
  798. var obj = this.obj;
  799. if(typeof obj == 'string') {// expect other to be string
  800. this.is.equal(String(other));
  801. } else if(util.isIndexable(obj) && util.isIndexable(other)) {
  802. var usedKeys = {};
  803. util.forEach(other, function(otherItem) {
  804. this.assert(util.some(obj, function(item, index) {
  805. if(index in usedKeys) return false;
  806. try {
  807. should(item).containDeep(otherItem);
  808. usedKeys[index] = true;
  809. return true;
  810. } catch(e) {
  811. if(e instanceof should.AssertionError) {
  812. return false;
  813. }
  814. throw e;
  815. }
  816. }));
  817. }, this);
  818. } else if(obj != null && other != null && typeof obj == 'object' && typeof other == 'object') {// object contains object case
  819. util.forEach(other, function(value, key) {
  820. should(obj[key]).containDeep(value);
  821. });
  822. // if both objects is empty means we finish traversing - and we need to compare for hidden values
  823. if(util.isEmptyObject(other)) {
  824. this.eql(other);
  825. }
  826. } else {
  827. this.eql(other);
  828. }
  829. });
  830. };
  831. },{"../util":18,"should-equal":20}],10:[function(require,module,exports){
  832. /*
  833. * Should
  834. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  835. * MIT Licensed
  836. */
  837. var eql = require('should-equal');
  838. var type = require('should-type');
  839. var util = require('../util');
  840. function formatEqlResult(r, a, b) {
  841. return ((r.path.length > 0 ? 'at ' + r.path.map(util.formatProp).join(' -> ') : '') +
  842. (r.a === a ? '' : ', A has ' + util.format(r.a)) +
  843. (r.b === b ? '' : ' and B has ' + util.format(r.b)) +
  844. (r.showReason ? ' because ' + r.reason : '')).trim();
  845. }
  846. module.exports = function(should, Assertion) {
  847. /**
  848. * Deep object equality comparison. For full spec see [`should-equal tests`](https://github.com/shouldjs/equal/blob/master/test.js).
  849. *
  850. * @name eql
  851. * @memberOf Assertion
  852. * @category assertion equality
  853. * @alias Assertion#deepEqual
  854. * @param {*} val Expected value
  855. * @param {string} [description] Optional message
  856. * @example
  857. *
  858. * (10).should.be.eql(10);
  859. * ('10').should.not.be.eql(10);
  860. * (-0).should.not.be.eql(+0);
  861. *
  862. * NaN.should.be.eql(NaN);
  863. *
  864. * ({ a: 10}).should.be.eql({ a: 10 });
  865. * [ 'a' ].should.not.be.eql({ '0': 'a' });
  866. */
  867. Assertion.add('eql', function(val, description) {
  868. this.params = {operator: 'to equal', expected: val, message: description};
  869. var result = eql(this.obj, val, should.config);
  870. this.params.details = result.result ? '' : formatEqlResult(result, this.obj, val);
  871. this.params.showDiff = eql(type(this.obj), type(val)).result;
  872. this.assert(result.result);
  873. });
  874. /**
  875. * Exact comparison using ===.
  876. *
  877. * @name equal
  878. * @memberOf Assertion
  879. * @category assertion equality
  880. * @alias Assertion#exactly
  881. * @param {*} val Expected value
  882. * @param {string} [description] Optional message
  883. * @example
  884. *
  885. * 10.should.be.equal(10);
  886. * 'a'.should.be.exactly('a');
  887. *
  888. * should(null).be.exactly(null);
  889. */
  890. Assertion.add('equal', function(val, description) {
  891. this.params = {operator: 'to be', expected: val, message: description};
  892. this.params.showDiff = eql(type(this.obj), type(val)).result;
  893. this.assert(val === this.obj);
  894. });
  895. Assertion.alias('equal', 'exactly');
  896. Assertion.alias('eql', 'deepEqual');
  897. function addOneOf(name, message, method) {
  898. Assertion.add(name, function(vals) {
  899. if(arguments.length !== 1) {
  900. vals = Array.prototype.slice.call(arguments);
  901. } else {
  902. should(vals).be.Array();
  903. }
  904. this.params = {operator: message, expected: vals};
  905. var obj = this.obj;
  906. var found = false;
  907. util.forEach(vals, function(val) {
  908. try {
  909. should(val)[method](obj);
  910. found = true;
  911. return false;
  912. } catch(e) {
  913. if(e instanceof should.AssertionError) {
  914. return;//do nothing
  915. }
  916. throw e;
  917. }
  918. });
  919. this.assert(found);
  920. });
  921. }
  922. /**
  923. * Exact comparison using === to be one of supplied objects.
  924. *
  925. * @name equalOneOf
  926. * @memberOf Assertion
  927. * @category assertion equality
  928. * @param {Array|*} vals Expected values
  929. * @example
  930. *
  931. * 'ab'.should.be.equalOneOf('a', 10, 'ab');
  932. * 'ab'.should.be.equalOneOf(['a', 10, 'ab']);
  933. */
  934. addOneOf('equalOneOf', 'to be equals one of', 'equal');
  935. /**
  936. * Exact comparison using .eql to be one of supplied objects.
  937. *
  938. * @name oneOf
  939. * @memberOf Assertion
  940. * @category assertion equality
  941. * @param {Array|*} vals Expected values
  942. * @example
  943. *
  944. * ({a: 10}).should.be.oneOf('a', 10, 'ab', {a: 10});
  945. * ({a: 10}).should.be.oneOf(['a', 10, 'ab', {a: 10}]);
  946. */
  947. addOneOf('oneOf', 'to be one of', 'eql');
  948. };
  949. },{"../util":18,"should-equal":20,"should-type":23}],11:[function(require,module,exports){
  950. /*
  951. * Should
  952. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  953. * MIT Licensed
  954. */
  955. var util = require('../util');
  956. module.exports = function(should, Assertion) {
  957. var i = should.format;
  958. /**
  959. * Assert given function throws error with such message.
  960. *
  961. * @name throw
  962. * @memberOf Assertion
  963. * @category assertion errors
  964. * @alias Assertion#throwError
  965. * @param {string|RegExp|Function|Object|GeneratorFunction|GeneratorObject} [message] Message to match or properties
  966. * @param {Object} [properties] Optional properties that will be matched to thrown error
  967. * @example
  968. *
  969. * (function(){ throw new Error('fail') }).should.throw();
  970. * (function(){ throw new Error('fail') }).should.throw('fail');
  971. * (function(){ throw new Error('fail') }).should.throw(/fail/);
  972. *
  973. * (function(){ throw new Error('fail') }).should.throw(Error);
  974. * var error = new Error();
  975. * error.a = 10;
  976. * (function(){ throw error; }).should.throw(Error, { a: 10 });
  977. * (function(){ throw error; }).should.throw({ a: 10 });
  978. * (function*() {
  979. * yield throwError();
  980. * }).should.throw();
  981. */
  982. Assertion.add('throw', function(message, properties) {
  983. var fn = this.obj
  984. , err = {}
  985. , errorInfo = ''
  986. , thrown = false;
  987. if(util.isGeneratorFunction(fn)) {
  988. return should(fn()).throw(message, properties);
  989. } else if(util.isGeneratorObject(fn)) {
  990. return should(fn.next.bind(fn)).throw(message, properties);
  991. }
  992. this.is.a.Function();
  993. var errorMatched = true;
  994. try {
  995. fn();
  996. } catch(e) {
  997. thrown = true;
  998. err = e;
  999. }
  1000. if(thrown) {
  1001. if(message) {
  1002. if('string' == typeof message) {
  1003. errorMatched = message == err.message;
  1004. } else if(message instanceof RegExp) {
  1005. errorMatched = message.test(err.message);
  1006. } else if('function' == typeof message) {
  1007. errorMatched = err instanceof message;
  1008. } else if(null != message) {
  1009. try {
  1010. should(err).match(message);
  1011. } catch(e) {
  1012. if(e instanceof should.AssertionError) {
  1013. errorInfo = ": " + e.message;
  1014. errorMatched = false;
  1015. } else {
  1016. throw e;
  1017. }
  1018. }
  1019. }
  1020. if(!errorMatched) {
  1021. if('string' == typeof message || message instanceof RegExp) {
  1022. errorInfo = " with a message matching " + i(message) + ", but got '" + err.message + "'";
  1023. } else if('function' == typeof message) {
  1024. errorInfo = " of type " + util.functionName(message) + ", but got " + util.functionName(err.constructor);
  1025. }
  1026. } else if('function' == typeof message && properties) {
  1027. try {
  1028. should(err).match(properties);
  1029. } catch(e) {
  1030. if(e instanceof should.AssertionError) {
  1031. errorInfo = ": " + e.message;
  1032. errorMatched = false;
  1033. } else {
  1034. throw e;
  1035. }
  1036. }
  1037. }
  1038. } else {
  1039. errorInfo = " (got " + i(err) + ")";
  1040. }
  1041. }
  1042. this.params = { operator: 'to throw exception' + errorInfo };
  1043. this.assert(thrown);
  1044. this.assert(errorMatched);
  1045. });
  1046. Assertion.alias('throw', 'throwError');
  1047. };
  1048. },{"../util":18}],12:[function(require,module,exports){
  1049. /*
  1050. * Should
  1051. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  1052. * MIT Licensed
  1053. */
  1054. var util = require('../util');
  1055. var eql = require('should-equal');
  1056. module.exports = function(should, Assertion) {
  1057. var i = should.format;
  1058. /**
  1059. * Asserts if given object match `other` object, using some assumptions:
  1060. * First object matched if they are equal,
  1061. * If `other` is a regexp and given object is a string check on matching with regexp
  1062. * If `other` is a regexp and given object is an array check if all elements matched regexp
  1063. * If `other` is a regexp and given object is an object check values on matching regexp
  1064. * If `other` is a function check if this function throws AssertionError on given object or return false - it will be assumed as not matched
  1065. * If `other` is an object check if the same keys matched with above rules
  1066. * All other cases failed
  1067. *
  1068. * @name match
  1069. * @memberOf Assertion
  1070. * @category assertion matching
  1071. * @param {*} other Object to match
  1072. * @param {string} [description] Optional message
  1073. * @example
  1074. * 'foobar'.should.match(/^foo/);
  1075. * 'foobar'.should.not.match(/^bar/);
  1076. *
  1077. * ({ a: 'foo', c: 'barfoo' }).should.match(/foo$/);
  1078. *
  1079. * ['a', 'b', 'c'].should.match(/[a-z]/);
  1080. *
  1081. * (5).should.not.match(function(n) {
  1082. * return n < 0;
  1083. * });
  1084. * (5).should.not.match(function(it) {
  1085. * it.should.be.an.Array();
  1086. * });
  1087. * ({ a: 10, b: 'abc', c: { d: 10 }, d: 0 }).should
  1088. * .match({ a: 10, b: /c$/, c: function(it) {
  1089. * return it.should.have.property('d', 10);
  1090. * }});
  1091. *
  1092. * [10, 'abc', { d: 10 }, 0].should
  1093. * .match({ '0': 10, '1': /c$/, '2': function(it) {
  1094. * return it.should.have.property('d', 10);
  1095. * }});
  1096. */
  1097. Assertion.add('match', function(other, description) {
  1098. this.params = {operator: 'to match ' + i(other), message: description};
  1099. if(!eql(this.obj, other).result) {
  1100. if(other instanceof RegExp) { // something - regex
  1101. if(typeof this.obj == 'string') {
  1102. this.assert(other.exec(this.obj));
  1103. } else if(util.isIndexable(this.obj)) {
  1104. util.forEach(this.obj, function(item) {
  1105. this.assert(other.exec(item));// should we try to convert to String and exec?
  1106. }, this);
  1107. } else if(null != this.obj && typeof this.obj == 'object') {
  1108. var notMatchedProps = [], matchedProps = [];
  1109. util.forEach(this.obj, function(value, name) {
  1110. if(other.exec(value)) matchedProps.push(util.formatProp(name));
  1111. else notMatchedProps.push(util.formatProp(name) + ' (' + i(value) + ')');
  1112. }, this);
  1113. if(notMatchedProps.length)
  1114. this.params.operator += '\n not matched properties: ' + notMatchedProps.join(', ');
  1115. if(matchedProps.length)
  1116. this.params.operator += '\n matched properties: ' + matchedProps.join(', ');
  1117. this.assert(notMatchedProps.length === 0);
  1118. } // should we try to convert to String and exec?
  1119. } else if(typeof other == 'function') {
  1120. var res;
  1121. res = other(this.obj);
  1122. //if(res instanceof Assertion) {
  1123. // this.params.operator += '\n ' + res.getMessage();
  1124. //}
  1125. //if we throw exception ok - it is used .should inside
  1126. if(typeof res == 'boolean') {
  1127. this.assert(res); // if it is just boolean function assert on it
  1128. }
  1129. } else if(other != null && typeof other == 'object') { // try to match properties (for Object and Array)
  1130. notMatchedProps = [];
  1131. matchedProps = [];
  1132. util.forEach(other, function(value, key) {
  1133. try {
  1134. should(this.obj).have.property(key).which.match(value);
  1135. matchedProps.push(util.formatProp(key));
  1136. } catch(e) {
  1137. if(e instanceof should.AssertionError) {
  1138. notMatchedProps.push(util.formatProp(key) + ' (' + i(this.obj[key]) + ')');
  1139. } else {
  1140. throw e;
  1141. }
  1142. }
  1143. }, this);
  1144. if(notMatchedProps.length)
  1145. this.params.operator += '\n not matched properties: ' + notMatchedProps.join(', ');
  1146. if(matchedProps.length)
  1147. this.params.operator += '\n matched properties: ' + matchedProps.join(', ');
  1148. this.assert(notMatchedProps.length === 0);
  1149. } else {
  1150. this.assert(false);
  1151. }
  1152. }
  1153. });
  1154. /**
  1155. * Asserts if given object values or array elements all match `other` object, using some assumptions:
  1156. * First object matched if they are equal,
  1157. * If `other` is a regexp - matching with regexp
  1158. * If `other` is a function check if this function throws AssertionError on given object or return false - it will be assumed as not matched
  1159. * All other cases check if this `other` equal to each element
  1160. *
  1161. * @name matchEach
  1162. * @memberOf Assertion
  1163. * @category assertion matching
  1164. * @alias Assertion#matchSome
  1165. * @param {*} other Object to match
  1166. * @param {string} [description] Optional message
  1167. * @example
  1168. * [ 'a', 'b', 'c'].should.matchEach(/\w+/);
  1169. * [ 'a', 'a', 'a'].should.matchEach('a');
  1170. *
  1171. * [ 'a', 'a', 'a'].should.matchEach(function(value) { value.should.be.eql('a') });
  1172. *
  1173. * { a: 'a', b: 'a', c: 'a' }.should.matchEach(function(value) { value.should.be.eql('a') });
  1174. */
  1175. Assertion.add('matchEach', function(other, description) {
  1176. this.params = {operator: 'to match each ' + i(other), message: description};
  1177. util.forEach(this.obj, function(value) {
  1178. should(value).match(other);
  1179. }, this);
  1180. });
  1181. /**
  1182. * Asserts if any of given object values or array elements match `other` object, using some assumptions:
  1183. * First object matched if they are equal,
  1184. * If `other` is a regexp - matching with regexp
  1185. * If `other` is a function check if this function throws AssertionError on given object or return false - it will be assumed as not matched
  1186. * All other cases check if this `other` equal to each element
  1187. *
  1188. * @name matchAny
  1189. * @memberOf Assertion
  1190. * @category assertion matching
  1191. * @param {*} other Object to match
  1192. * @alias Assertion#matchEvery
  1193. * @param {string} [description] Optional message
  1194. * @example
  1195. * [ 'a', 'b', 'c'].should.matchAny(/\w+/);
  1196. * [ 'a', 'b', 'c'].should.matchAny('a');
  1197. *
  1198. * [ 'a', 'b', 'c'].should.matchAny(function(value) { value.should.be.eql('a') });
  1199. *
  1200. * { a: 'a', b: 'b', c: 'c' }.should.matchAny(function(value) { value.should.be.eql('a') });
  1201. */
  1202. Assertion.add('matchAny', function(other, description) {
  1203. this.params = {operator: 'to match any ' + i(other), message: description};
  1204. this.assert(util.some(this.obj, function(value) {
  1205. try {
  1206. should(value).match(other);
  1207. return true;
  1208. } catch(e) {
  1209. if(e instanceof should.AssertionError) {
  1210. // Caught an AssertionError, return false to the iterator
  1211. return false;
  1212. }
  1213. throw e;
  1214. }
  1215. }));
  1216. });
  1217. Assertion.alias('matchAny', 'matchSome');
  1218. Assertion.alias('matchEach', 'matchEvery');
  1219. };
  1220. },{"../util":18,"should-equal":20}],13:[function(require,module,exports){
  1221. /*
  1222. * Should
  1223. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  1224. * MIT Licensed
  1225. */
  1226. module.exports = function(should, Assertion) {
  1227. /**
  1228. * Assert given object is NaN
  1229. * @name NaN
  1230. * @memberOf Assertion
  1231. * @category assertion numbers
  1232. * @example
  1233. *
  1234. * (10).should.not.be.NaN();
  1235. * NaN.should.be.NaN();
  1236. */
  1237. Assertion.add('NaN', function() {
  1238. this.params = { operator: 'to be NaN' };
  1239. this.assert(this.obj !== this.obj);
  1240. });
  1241. /**
  1242. * Assert given object is not finite (positive or negative)
  1243. *
  1244. * @name Infinity
  1245. * @memberOf Assertion
  1246. * @category assertion numbers
  1247. * @example
  1248. *
  1249. * (10).should.not.be.Infinity();
  1250. * NaN.should.not.be.Infinity();
  1251. */
  1252. Assertion.add('Infinity', function() {
  1253. this.params = { operator: 'to be Infinity' };
  1254. this.is.a.Number()
  1255. .and.not.a.NaN()
  1256. .and.assert(!isFinite(this.obj));
  1257. });
  1258. /**
  1259. * Assert given number between `start` and `finish` or equal one of them.
  1260. *
  1261. * @name within
  1262. * @memberOf Assertion
  1263. * @category assertion numbers
  1264. * @param {number} start Start number
  1265. * @param {number} finish Finish number
  1266. * @param {string} [description] Optional message
  1267. * @example
  1268. *
  1269. * (10).should.be.within(0, 20);
  1270. */
  1271. Assertion.add('within', function(start, finish, description) {
  1272. this.params = { operator: 'to be within ' + start + '..' + finish, message: description };
  1273. this.assert(this.obj >= start && this.obj <= finish);
  1274. });
  1275. /**
  1276. * Assert given number near some other `value` within `delta`
  1277. *
  1278. * @name approximately
  1279. * @memberOf Assertion
  1280. * @category assertion numbers
  1281. * @param {number} value Center number
  1282. * @param {number} delta Radius
  1283. * @param {string} [description] Optional message
  1284. * @example
  1285. *
  1286. * (9.99).should.be.approximately(10, 0.1);
  1287. */
  1288. Assertion.add('approximately', function(value, delta, description) {
  1289. this.params = { operator: 'to be approximately ' + value + ' ±' + delta, message: description };
  1290. this.assert(Math.abs(this.obj - value) <= delta);
  1291. });
  1292. /**
  1293. * Assert given number above `n`.
  1294. *
  1295. * @name above
  1296. * @alias Assertion#greaterThan
  1297. * @memberOf Assertion
  1298. * @category assertion numbers
  1299. * @param {number} n Margin number
  1300. * @param {string} [description] Optional message
  1301. * @example
  1302. *
  1303. * (10).should.be.above(0);
  1304. */
  1305. Assertion.add('above', function(n, description) {
  1306. this.params = { operator: 'to be above ' + n, message: description };
  1307. this.assert(this.obj > n);
  1308. });
  1309. /**
  1310. * Assert given number below `n`.
  1311. *
  1312. * @name below
  1313. * @alias Assertion#lessThan
  1314. * @memberOf Assertion
  1315. * @category assertion numbers
  1316. * @param {number} n Margin number
  1317. * @param {string} [description] Optional message
  1318. * @example
  1319. *
  1320. * (0).should.be.below(10);
  1321. */
  1322. Assertion.add('below', function(n, description) {
  1323. this.params = { operator: 'to be below ' + n, message: description };
  1324. this.assert(this.obj < n);
  1325. });
  1326. Assertion.alias('above', 'greaterThan');
  1327. Assertion.alias('below', 'lessThan');
  1328. /**
  1329. * Assert given number above `n`.
  1330. *
  1331. * @name aboveOrEqual
  1332. * @alias Assertion#greaterThanOrEqual
  1333. * @memberOf Assertion
  1334. * @category assertion numbers
  1335. * @param {number} n Margin number
  1336. * @param {string} [description] Optional message
  1337. * @example
  1338. *
  1339. * (10).should.be.aboveOrEqual(0);
  1340. * (10).should.be.aboveOrEqual(10);
  1341. */
  1342. Assertion.add('aboveOrEqual', function(n, description) {
  1343. this.params = { operator: 'to be above or equal' + n, message: description };
  1344. this.assert(this.obj >= n);
  1345. });
  1346. /**
  1347. * Assert given number below `n`.
  1348. *
  1349. * @name belowOrEqual
  1350. * @alias Assertion#lessThanOrEqual
  1351. * @memberOf Assertion
  1352. * @category assertion numbers
  1353. * @param {number} n Margin number
  1354. * @param {string} [description] Optional message
  1355. * @example
  1356. *
  1357. * (0).should.be.belowOrEqual(10);
  1358. * (0).should.be.belowOrEqual(0);
  1359. */
  1360. Assertion.add('belowOrEqual', function(n, description) {
  1361. this.params = { operator: 'to be below or equal' + n, message: description };
  1362. this.assert(this.obj <= n);
  1363. });
  1364. Assertion.alias('aboveOrEqual', 'greaterThanOrEqual');
  1365. Assertion.alias('belowOrEqual', 'lessThanOrEqual');
  1366. };
  1367. },{}],14:[function(require,module,exports){
  1368. /*
  1369. * Should
  1370. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  1371. * MIT Licensed
  1372. */
  1373. var util = require('../util');
  1374. var eql = require('should-equal');
  1375. var aSlice = Array.prototype.slice;
  1376. module.exports = function(should, Assertion) {
  1377. var i = should.format;
  1378. /**
  1379. * Asserts given object has some descriptor. **On success it change given object to be value of property**.
  1380. *
  1381. * @name propertyWithDescriptor
  1382. * @memberOf Assertion
  1383. * @category assertion property
  1384. * @param {string} name Name of property
  1385. * @param {Object} desc Descriptor like used in Object.defineProperty (not required to add all properties)
  1386. * @example
  1387. *
  1388. * ({ a: 10 }).should.have.propertyWithDescriptor('a', { enumerable: true });
  1389. */
  1390. Assertion.add('propertyWithDescriptor', function(name, desc) {
  1391. this.params = {actual: this.obj, operator: 'to have own property with descriptor ' + i(desc)};
  1392. var obj = this.obj;
  1393. this.have.ownProperty(name);
  1394. should(Object.getOwnPropertyDescriptor(Object(obj), name)).have.properties(desc);
  1395. });
  1396. function processPropsArgs() {
  1397. var args = {};
  1398. if(arguments.length > 1) {
  1399. args.names = aSlice.call(arguments);
  1400. } else {
  1401. var arg = arguments[0];
  1402. if(typeof arg === 'string') {
  1403. args.names = [arg];
  1404. } else if(util.isIndexable(arg)) {
  1405. args.names = arg;
  1406. } else {
  1407. args.names = Object.keys(arg);
  1408. args.values = arg;
  1409. }
  1410. }
  1411. return args;
  1412. }
  1413. /**
  1414. * Asserts given object has enumerable property with optionally value. **On success it change given object to be value of property**.
  1415. *
  1416. * @name enumerable
  1417. * @memberOf Assertion
  1418. * @category assertion property
  1419. * @param {string} name Name of property
  1420. * @param {*} [val] Optional property value to check
  1421. * @example
  1422. *
  1423. * ({ a: 10 }).should.have.enumerable('a');
  1424. */
  1425. Assertion.add('enumerable', function(name, val) {
  1426. name = util.convertPropertyName(name);
  1427. this.params = {
  1428. operator: "to have enumerable property " + util.formatProp(name) + (arguments.length > 1 ? " equal to " + i(val): "")
  1429. };
  1430. var desc = { enumerable: true };
  1431. if(arguments.length > 1) desc.value = val;
  1432. this.have.propertyWithDescriptor(name, desc);
  1433. });
  1434. /**
  1435. * Asserts given object has enumerable properties
  1436. *
  1437. * @name enumerables
  1438. * @memberOf Assertion
  1439. * @category assertion property
  1440. * @param {Array|...string|Object} names Names of property
  1441. * @example
  1442. *
  1443. * ({ a: 10, b: 10 }).should.have.enumerables('a');
  1444. */
  1445. Assertion.add('enumerables', function(names) {
  1446. var args = processPropsArgs.apply(null, arguments);
  1447. this.params = {
  1448. operator: "to have enumerables " + args.names.map(util.formatProp)
  1449. };
  1450. var obj = this.obj;
  1451. args.names.forEach(function(name) {
  1452. should(obj).have.enumerable(name);
  1453. });
  1454. });
  1455. /**
  1456. * Asserts given object has property with optionally value. **On success it change given object to be value of property**.
  1457. *
  1458. * @name property
  1459. * @memberOf Assertion
  1460. * @category assertion property
  1461. * @param {string} name Name of property
  1462. * @param {*} [val] Optional property value to check
  1463. * @example
  1464. *
  1465. * ({ a: 10 }).should.have.property('a');
  1466. */
  1467. Assertion.add('property', function(name, val) {
  1468. name = util.convertPropertyName(name);
  1469. if(arguments.length > 1) {
  1470. var p = {};
  1471. p[name] = val;
  1472. this.have.properties(p);
  1473. } else {
  1474. this.have.properties(name);
  1475. }
  1476. this.obj = this.obj[name];
  1477. });
  1478. /**
  1479. * Asserts given object has properties. On this method affect .any modifier, which allow to check not all properties.
  1480. *
  1481. * @name properties
  1482. * @memberOf Assertion
  1483. * @category assertion property
  1484. * @param {Array|...string|Object} names Names of property
  1485. * @example
  1486. *
  1487. * ({ a: 10 }).should.have.properties('a');
  1488. * ({ a: 10, b: 20 }).should.have.properties([ 'a' ]);
  1489. * ({ a: 10, b: 20 }).should.have.properties({ b: 20 });
  1490. */
  1491. Assertion.add('properties', function(names) {
  1492. var values = {};
  1493. if(arguments.length > 1) {
  1494. names = aSlice.call(arguments);
  1495. } else if(!Array.isArray(names)) {
  1496. if(typeof names == 'string' || typeof names == 'symbol') {
  1497. names = [names];
  1498. } else {
  1499. values = names;
  1500. names = Object.keys(names);
  1501. }
  1502. }
  1503. var obj = Object(this.obj), missingProperties = [];
  1504. //just enumerate properties and check if they all present
  1505. names.forEach(function(name) {
  1506. if(!(name in obj)) missingProperties.push(util.formatProp(name));
  1507. });
  1508. var props = missingProperties;
  1509. if(props.length === 0) {
  1510. props = names.map(util.formatProp);
  1511. } else if(this.anyOne) {
  1512. props = names.filter(function(name) {
  1513. return missingProperties.indexOf(util.formatProp(name)) < 0;
  1514. }).map(util.formatProp);
  1515. }
  1516. var operator = (props.length === 1 ?
  1517. 'to have property ' : 'to have ' + (this.anyOne ? 'any of ' : '') + 'properties ') + props.join(', ');
  1518. this.params = {obj: this.obj, operator: operator};
  1519. //check that all properties presented
  1520. //or if we request one of them that at least one them presented
  1521. this.assert(missingProperties.length === 0 || (this.anyOne && missingProperties.length != names.length));
  1522. // check if values in object matched expected
  1523. var valueCheckNames = Object.keys(values);
  1524. if(valueCheckNames.length) {
  1525. var wrongValues = [];
  1526. props = [];
  1527. // now check values, as there we have all properties
  1528. valueCheckNames.forEach(function(name) {
  1529. var value = values[name];
  1530. if(!eql(obj[name], value).result) {
  1531. wrongValues.push(util.formatProp(name) + ' of ' + i(value) + ' (got ' + i(obj[name]) + ')');
  1532. } else {
  1533. props.push(util.formatProp(name) + ' of ' + i(value));
  1534. }
  1535. });
  1536. if((wrongValues.length !== 0 && !this.anyOne) || (this.anyOne && props.length === 0)) {
  1537. props = wrongValues;
  1538. }
  1539. operator = (props.length === 1 ?
  1540. 'to have property ' : 'to have ' + (this.anyOne ? 'any of ' : '') + 'properties ') + props.join(', ');
  1541. this.params = {obj: this.obj, operator: operator};
  1542. //if there is no not matched values
  1543. //or there is at least one matched
  1544. this.assert(wrongValues.length === 0 || (this.anyOne && wrongValues.length != valueCheckNames.length));
  1545. }
  1546. });
  1547. /**
  1548. * Asserts given object has property `length` with given value `n`
  1549. *
  1550. * @name length
  1551. * @alias Assertion#lengthOf
  1552. * @memberOf Assertion
  1553. * @category assertion property
  1554. * @param {number} n Expected length
  1555. * @param {string} [description] Optional message
  1556. * @example
  1557. *
  1558. * [1, 2].should.have.length(2);
  1559. */
  1560. Assertion.add('length', function(n, description) {
  1561. this.have.property('length', n, description);
  1562. });
  1563. Assertion.alias('length', 'lengthOf');
  1564. var hasOwnProperty = Object.prototype.hasOwnProperty;
  1565. /**
  1566. * Asserts given object has own property. **On success it change given object to be value of property**.
  1567. *
  1568. * @name ownProperty
  1569. * @alias Assertion#hasOwnProperty
  1570. * @memberOf Assertion
  1571. * @category assertion property
  1572. * @param {string} name Name of property
  1573. * @param {string} [description] Optional message
  1574. * @example
  1575. *
  1576. * ({ a: 10 }).should.have.ownProperty('a');
  1577. */
  1578. Assertion.add('ownProperty', function(name, description) {
  1579. name = util.convertPropertyName(name);
  1580. this.params = {
  1581. actual: this.obj,
  1582. operator: 'to have own property ' + util.formatProp(name),
  1583. message: description
  1584. };
  1585. this.assert(hasOwnProperty.call(this.obj, name));
  1586. this.obj = this.obj[name];
  1587. });
  1588. Assertion.alias('ownProperty', 'hasOwnProperty');
  1589. /**
  1590. * Asserts given object is empty. For strings, arrays and arguments it checks .length property, for objects it checks keys.
  1591. *
  1592. * @name empty
  1593. * @memberOf Assertion
  1594. * @category assertion property
  1595. * @example
  1596. *
  1597. * ''.should.be.empty();
  1598. * [].should.be.empty();
  1599. * ({}).should.be.empty();
  1600. */
  1601. Assertion.add('empty', function() {
  1602. this.params = {operator: 'to be empty'};
  1603. if(util.length(this.obj) !== void 0) {
  1604. should(this.obj).have.property('length', 0);
  1605. } else {
  1606. var obj = Object(this.obj); // wrap to reference for booleans and numbers
  1607. for(var prop in obj) {
  1608. should(this.obj).not.have.ownProperty(prop);
  1609. }
  1610. }
  1611. }, true);
  1612. /**
  1613. * Asserts given object has exact keys. Compared to `properties`, `keys` does not accept Object as a argument.
  1614. *
  1615. * @name keys
  1616. * @alias Assertion#key
  1617. * @memberOf Assertion
  1618. * @category assertion property
  1619. * @param {Array|...string} [keys] Keys to check
  1620. * @example
  1621. *
  1622. * ({ a: 10 }).should.have.keys('a');
  1623. * ({ a: 10, b: 20 }).should.have.keys('a', 'b');
  1624. * ({ a: 10, b: 20 }).should.have.keys([ 'a', 'b' ]);
  1625. * ({}).should.have.keys();
  1626. */
  1627. Assertion.add('keys', function(keys) {
  1628. if(arguments.length > 1) keys = aSlice.call(arguments);
  1629. else if(arguments.length === 1 && typeof keys === 'string') keys = [keys];
  1630. else if(arguments.length === 0) keys = [];
  1631. keys = keys.map(String);
  1632. var obj = Object(this.obj);
  1633. // first check if some keys are missing
  1634. var missingKeys = [];
  1635. keys.forEach(function(key) {
  1636. if(!hasOwnProperty.call(this.obj, key))
  1637. missingKeys.push(util.formatProp(key));
  1638. }, this);
  1639. // second check for extra keys
  1640. var extraKeys = [];
  1641. Object.keys(obj).forEach(function(key) {
  1642. if(keys.indexOf(key) < 0) {
  1643. extraKeys.push(util.formatProp(key));
  1644. }
  1645. });
  1646. var verb = keys.length === 0 ? 'to be empty' :
  1647. 'to have ' + (keys.length === 1 ? 'key ' : 'keys ');
  1648. this.params = {operator: verb + keys.map(util.formatProp).join(', ')};
  1649. if(missingKeys.length > 0)
  1650. this.params.operator += '\n\tmissing keys: ' + missingKeys.join(', ');
  1651. if(extraKeys.length > 0)
  1652. this.params.operator += '\n\textra keys: ' + extraKeys.join(', ');
  1653. this.assert(missingKeys.length === 0 && extraKeys.length === 0);
  1654. });
  1655. Assertion.alias("keys", "key");
  1656. /**
  1657. * Asserts given object has nested property in depth by path. **On success it change given object to be value of final property**.
  1658. *
  1659. * @name propertyByPath
  1660. * @memberOf Assertion
  1661. * @category assertion property
  1662. * @param {Array|...string} properties Properties path to search
  1663. * @example
  1664. *
  1665. * ({ a: {b: 10}}).should.have.propertyByPath('a', 'b').eql(10);
  1666. */
  1667. Assertion.add('propertyByPath', function(properties) {
  1668. if(arguments.length > 1) properties = aSlice.call(arguments);
  1669. else if(arguments.length === 1 && typeof properties == 'string') properties = [properties];
  1670. else if(arguments.length === 0) properties = [];
  1671. var allProps = properties.map(util.formatProp);
  1672. properties = properties.map(String);
  1673. var obj = should(Object(this.obj));
  1674. var foundProperties = [];
  1675. var currentProperty;
  1676. while(currentProperty = properties.shift()) {
  1677. this.params = {operator: 'to have property by path ' + allProps.join(', ') + ' - failed on ' + util.formatProp(currentProperty)};
  1678. obj = obj.have.property(currentProperty);
  1679. foundProperties.push(currentProperty);
  1680. }
  1681. this.params = {obj: this.obj, operator: 'to have property by path ' + allProps.join(', ')};
  1682. this.obj = obj.obj;
  1683. });
  1684. };
  1685. },{"../util":18,"should-equal":20}],15:[function(require,module,exports){
  1686. /*
  1687. * Should
  1688. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  1689. * MIT Licensed
  1690. */
  1691. module.exports = function(should, Assertion) {
  1692. /**
  1693. * Assert given string starts with prefix
  1694. * @name startWith
  1695. * @memberOf Assertion
  1696. * @category assertion strings
  1697. * @param {string} str Prefix
  1698. * @param {string} [description] Optional message
  1699. * @example
  1700. *
  1701. * 'abc'.should.startWith('a');
  1702. */
  1703. Assertion.add('startWith', function(str, description) {
  1704. this.params = { operator: 'to start with ' + should.format(str), message: description };
  1705. this.assert(0 === this.obj.indexOf(str));
  1706. });
  1707. /**
  1708. * Assert given string starts with prefix
  1709. * @name endWith
  1710. * @memberOf Assertion
  1711. * @category assertion strings
  1712. * @param {string} str Prefix
  1713. * @param {string} [description] Optional message
  1714. * @example
  1715. *
  1716. * 'abca'.should.endWith('a');
  1717. */
  1718. Assertion.add('endWith', function(str, description) {
  1719. this.params = { operator: 'to end with ' + should.format(str), message: description };
  1720. this.assert(this.obj.indexOf(str, this.obj.length - str.length) >= 0);
  1721. });
  1722. };
  1723. },{}],16:[function(require,module,exports){
  1724. /*
  1725. * Should
  1726. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  1727. * MIT Licensed
  1728. */
  1729. var util = require('../util');
  1730. module.exports = function(should, Assertion) {
  1731. /**
  1732. * Assert given object is number
  1733. * @name Number
  1734. * @memberOf Assertion
  1735. * @category assertion types
  1736. */
  1737. Assertion.add('Number', function() {
  1738. this.params = {operator: 'to be a number'};
  1739. this.have.type('number');
  1740. });
  1741. /**
  1742. * Assert given object is arguments
  1743. * @name arguments
  1744. * @alias Assertion#Arguments
  1745. * @memberOf Assertion
  1746. * @category assertion types
  1747. */
  1748. Assertion.add('arguments', function() {
  1749. this.params = {operator: 'to be arguments'};
  1750. this.have.class('Arguments');
  1751. });
  1752. Assertion.alias('arguments', 'Arguments');
  1753. /**
  1754. * Assert given object has some type using `typeof`
  1755. * @name type
  1756. * @memberOf Assertion
  1757. * @param {string} type Type name
  1758. * @param {string} [description] Optional message
  1759. * @category assertion types
  1760. */
  1761. Assertion.add('type', function(type, description) {
  1762. this.params = {operator: 'to have type ' + type, message: description};
  1763. should(typeof this.obj).be.exactly(type);
  1764. });
  1765. /**
  1766. * Assert given object is instance of `constructor`
  1767. * @name instanceof
  1768. * @alias Assertion#instanceOf
  1769. * @memberOf Assertion
  1770. * @param {Function} constructor Constructor function
  1771. * @param {string} [description] Optional message
  1772. * @category assertion types
  1773. */
  1774. Assertion.add('instanceof', function(constructor, description) {
  1775. this.params = {operator: 'to be an instance of ' + util.functionName(constructor), message: description};
  1776. this.assert(Object(this.obj) instanceof constructor);
  1777. });
  1778. Assertion.alias('instanceof', 'instanceOf');
  1779. /**
  1780. * Assert given object is function
  1781. * @name Function
  1782. * @memberOf Assertion
  1783. * @category assertion types
  1784. */
  1785. Assertion.add('Function', function() {
  1786. this.params = {operator: 'to be a function'};
  1787. this.have.type('function');
  1788. });
  1789. /**
  1790. * Assert given object is object
  1791. * @name Object
  1792. * @memberOf Assertion
  1793. * @category assertion types
  1794. */
  1795. Assertion.add('Object', function() {
  1796. this.params = {operator: 'to be an object'};
  1797. this.is.not.null().and.have.type('object');
  1798. });
  1799. /**
  1800. * Assert given object is string
  1801. * @name String
  1802. * @memberOf Assertion
  1803. * @category assertion types
  1804. */
  1805. Assertion.add('String', function() {
  1806. this.params = {operator: 'to be a string'};
  1807. this.have.type('string');
  1808. });
  1809. /**
  1810. * Assert given object is array
  1811. * @name Array
  1812. * @memberOf Assertion
  1813. * @category assertion types
  1814. */
  1815. Assertion.add('Array', function() {
  1816. this.params = {operator: 'to be an array'};
  1817. this.have.class('Array');
  1818. });
  1819. /**
  1820. * Assert given object is boolean
  1821. * @name Boolean
  1822. * @memberOf Assertion
  1823. * @category assertion types
  1824. */
  1825. Assertion.add('Boolean', function() {
  1826. this.params = {operator: 'to be a boolean'};
  1827. this.have.type('boolean');
  1828. });
  1829. /**
  1830. * Assert given object is error
  1831. * @name Error
  1832. * @memberOf Assertion
  1833. * @category assertion types
  1834. */
  1835. Assertion.add('Error', function() {
  1836. this.params = {operator: 'to be an error'};
  1837. this.have.instanceOf(Error);
  1838. });
  1839. /**
  1840. * Assert given object is null
  1841. * @name null
  1842. * @alias Assertion#Null
  1843. * @memberOf Assertion
  1844. * @category assertion types
  1845. */
  1846. Assertion.add('null', function() {
  1847. this.params = {operator: 'to be null'};
  1848. this.assert(this.obj === null);
  1849. });
  1850. Assertion.alias('null', 'Null');
  1851. /**
  1852. * Assert given object has some internal [[Class]], via Object.prototype.toString call
  1853. * @name class
  1854. * @alias Assertion#Class
  1855. * @memberOf Assertion
  1856. * @category assertion types
  1857. */
  1858. Assertion.add('class', function(cls) {
  1859. this.params = {operator: 'to have [[Class]] ' + cls};
  1860. this.assert(Object.prototype.toString.call(this.obj) === '[object ' + cls + ']');
  1861. });
  1862. Assertion.alias('class', 'Class');
  1863. /**
  1864. * Assert given object is undefined
  1865. * @name undefined
  1866. * @alias Assertion#Undefined
  1867. * @memberOf Assertion
  1868. * @category assertion types
  1869. */
  1870. Assertion.add('undefined', function() {
  1871. this.params = {operator: 'to be undefined'};
  1872. this.assert(this.obj === void 0);
  1873. });
  1874. Assertion.alias('undefined', 'Undefined');
  1875. /**
  1876. * Assert given object supports es6 iterable protocol (just check
  1877. * that object has property Symbol.iterator, which is a function)
  1878. * @name iterable
  1879. * @memberOf Assertion
  1880. * @category assertion es6
  1881. */
  1882. Assertion.add('iterable', function() {
  1883. this.params = {operator: 'to be iterable'};
  1884. should(this.obj).have.property(Symbol.iterator).which.is.a.Function();
  1885. });
  1886. /**
  1887. * Assert given object supports es6 iterator protocol (just check
  1888. * that object has property next, which is a function)
  1889. * @name iterator
  1890. * @memberOf Assertion
  1891. * @category assertion es6
  1892. */
  1893. Assertion.add('iterator', function() {
  1894. this.params = {operator: 'to be iterator'};
  1895. should(this.obj).have.property('next').which.is.a.Function();
  1896. });
  1897. /**
  1898. * Assert given object is a generator object
  1899. * @name generator
  1900. * @memberOf Assertion
  1901. * @category assertion es6
  1902. */
  1903. Assertion.add('generator', function() {
  1904. this.params = {operator: 'to be generator'};
  1905. should(this.obj).be.iterable
  1906. .and.iterator
  1907. .and.it.is.equal(this.obj[Symbol.iterator]());
  1908. });
  1909. };
  1910. },{"../util":18}],17:[function(require,module,exports){
  1911. /*
  1912. * Should
  1913. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  1914. * MIT Licensed
  1915. */
  1916. var util = require('./util');
  1917. /**
  1918. * Our function should
  1919. *
  1920. * @param {*} obj Object to assert
  1921. * @returns {should.Assertion} Returns new Assertion for beginning assertion chain
  1922. * @example
  1923. *
  1924. * var should = require('should');
  1925. * should('abc').be.a.String();
  1926. */
  1927. var should = function should(obj) {
  1928. return (new should.Assertion(obj));
  1929. };
  1930. should.AssertionError = require('./assertion-error');
  1931. should.Assertion = require('./assertion');
  1932. should.format = util.format;
  1933. should.type = require('should-type');
  1934. should.util = util;
  1935. /**
  1936. * Object with configuration.
  1937. * It contains such properties:
  1938. * * `checkProtoEql` boolean - Affect if `.eql` will check objects prototypes
  1939. * Also it can contain options for should-format.
  1940. *
  1941. * @type {Object}
  1942. * @memberOf should
  1943. * @static
  1944. * @example
  1945. *
  1946. * var a = { a: 10 }, b = Object.create(null);
  1947. * b.a = 10;
  1948. *
  1949. * a.should.be.eql(b);
  1950. * //not throws
  1951. *
  1952. * should.config.checkProtoEql = true;
  1953. * a.should.be.eql(b);
  1954. * //throws AssertionError: expected { a: 10 } to equal { a: 10 } (because A and B have different prototypes)
  1955. */
  1956. should.config = require('./config');
  1957. //Expose should to external world.
  1958. exports = module.exports = should;
  1959. /**
  1960. * Allow to extend given prototype with should property using given name. This getter will **unwrap** all standard wrappers like `Number`, `Boolean`, `String`.
  1961. * Using `should(obj)` is the equivalent of using `obj.should` with known issues (like nulls and method calls etc).
  1962. *
  1963. * @param {string} [propertyName] Name of property to add. Default is `'should'`.
  1964. * @param {Object} [proto] Prototype to extend with. Default is `Object.prototype`.
  1965. * @memberOf should
  1966. * @returns {{ name: string, descriptor: Object, proto: Object }} Descriptor enough to return all back
  1967. * @static
  1968. * @example
  1969. *
  1970. * var prev = should.extend('must', Object.prototype);
  1971. *
  1972. * 'abc'.must.startWith('a');
  1973. *
  1974. * var should = should.noConflict(prev);
  1975. * should.not.exist(Object.prototype.must);
  1976. */
  1977. should.extend = function(propertyName, proto) {
  1978. propertyName = propertyName || 'should';
  1979. proto = proto || Object.prototype;
  1980. var prevDescriptor = Object.getOwnPropertyDescriptor(proto, propertyName);
  1981. Object.defineProperty(proto, propertyName, {
  1982. set: function() {
  1983. },
  1984. get: function() {
  1985. return should(util.isWrapperType(this) ? this.valueOf() : this);
  1986. },
  1987. configurable: true
  1988. });
  1989. return { name: propertyName, descriptor: prevDescriptor, proto: proto };
  1990. };
  1991. /**
  1992. * Delete previous extension. If `desc` missing it will remove default extension.
  1993. *
  1994. * @param {{ name: string, descriptor: Object, proto: Object }} [desc] Returned from `should.extend` object
  1995. * @memberOf should
  1996. * @returns {Function} Returns should function
  1997. * @static
  1998. * @example
  1999. *
  2000. * var should = require('should').noConflict();
  2001. *
  2002. * should(Object.prototype).not.have.property('should');
  2003. *
  2004. * var prev = should.extend('must', Object.prototype);
  2005. * 'abc'.must.startWith('a');
  2006. * should.noConflict(prev);
  2007. *
  2008. * should(Object.prototype).not.have.property('must');
  2009. */
  2010. should.noConflict = function(desc) {
  2011. desc = desc || should._prevShould;
  2012. if(desc) {
  2013. delete desc.proto[desc.name];
  2014. if(desc.descriptor) {
  2015. Object.defineProperty(desc.proto, desc.name, desc.descriptor);
  2016. }
  2017. }
  2018. return should;
  2019. };
  2020. /**
  2021. * Simple utility function for a bit more easier should assertion extension
  2022. * @param {Function} f So called plugin function. It should accept 2 arguments: `should` function and `Assertion` constructor
  2023. * @memberOf should
  2024. * @returns {Function} Returns `should` function
  2025. * @static
  2026. * @example
  2027. *
  2028. * should.use(function(should, Assertion) {
  2029. * Assertion.add('asset', function() {
  2030. * this.params = { operator: 'to be asset' };
  2031. *
  2032. * this.obj.should.have.property('id').which.is.a.Number();
  2033. * this.obj.should.have.property('path');
  2034. * })
  2035. * })
  2036. */
  2037. should.use = function(f) {
  2038. f(should, should.Assertion);
  2039. return this;
  2040. };
  2041. should
  2042. .use(require('./ext/assert'))
  2043. .use(require('./ext/chain'))
  2044. .use(require('./ext/bool'))
  2045. .use(require('./ext/number'))
  2046. .use(require('./ext/eql'))
  2047. .use(require('./ext/type'))
  2048. .use(require('./ext/string'))
  2049. .use(require('./ext/property'))
  2050. .use(require('./ext/error'))
  2051. .use(require('./ext/match'))
  2052. .use(require('./ext/contain'));
  2053. },{"./assertion":3,"./assertion-error":2,"./config":4,"./ext/assert":6,"./ext/bool":7,"./ext/chain":8,"./ext/contain":9,"./ext/eql":10,"./ext/error":11,"./ext/match":12,"./ext/number":13,"./ext/property":14,"./ext/string":15,"./ext/type":16,"./util":18,"should-type":23}],18:[function(require,module,exports){
  2054. /*
  2055. * Should
  2056. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  2057. * MIT Licensed
  2058. */
  2059. var type = require('should-type');
  2060. var config = require('./config');
  2061. /**
  2062. * Check if given obj just a primitive type wrapper
  2063. * @param {Object} obj
  2064. * @returns {boolean}
  2065. * @private
  2066. */
  2067. exports.isWrapperType = function(obj) {
  2068. return obj instanceof Number || obj instanceof String || obj instanceof Boolean;
  2069. };
  2070. exports.merge = function(a, b) {
  2071. if(a && b) {
  2072. for(var key in b) {
  2073. a[key] = b[key];
  2074. }
  2075. }
  2076. return a;
  2077. };
  2078. var hasOwnProperty = Object.prototype.hasOwnProperty;
  2079. exports.forEach = function forEach(obj, f, context) {
  2080. if(exports.isGeneratorFunction(obj)) {
  2081. return forEach(obj(), f, context);
  2082. } else if (exports.isGeneratorObject(obj)) {
  2083. var value = obj.next();
  2084. while(!value.done) {
  2085. if(f.call(context, value.value, 'value', obj) === false)
  2086. return;
  2087. value = obj.next();
  2088. }
  2089. } else {
  2090. for(var prop in obj) {
  2091. if(hasOwnProperty.call(obj, prop)) {
  2092. if(f.call(context, obj[prop], prop, obj) === false)
  2093. return;
  2094. }
  2095. }
  2096. }
  2097. };
  2098. exports.some = function(obj, f, context) {
  2099. var res = false;
  2100. exports.forEach(obj, function(value, key) {
  2101. if(f.call(context, value, key, obj)) {
  2102. res = true;
  2103. return false;
  2104. }
  2105. }, context);
  2106. return res;
  2107. };
  2108. exports.isEmptyObject = function(obj) {
  2109. for(var prop in obj) {
  2110. if(hasOwnProperty.call(obj, prop)) {
  2111. return false;
  2112. }
  2113. }
  2114. return true;
  2115. };
  2116. exports.isIndexable = function(obj) {
  2117. var t = type(obj);
  2118. return (t.type === type.OBJECT && t.cls === type.ARRAY) ||
  2119. (t.type === type.OBJECT && t.cls === type.BUFFER) ||
  2120. (t.type === type.OBJECT && t.cls === type.ARGUMENTS) ||
  2121. (t.type === type.OBJECT && t.cls === type.ARRAY_BUFFER) ||
  2122. (t.type === type.OBJECT && t.cls === type.TYPED_ARRAY) ||
  2123. (t.type === type.OBJECT && t.cls === type.DATA_VIEW) ||
  2124. (t.type === type.OBJECT && t.cls === type.STRING) ||
  2125. (t.type === type.STRING);
  2126. };
  2127. exports.length = function(obj) {
  2128. var t = type(obj);
  2129. switch(t.type) {
  2130. case type.STRING:
  2131. return obj.length;
  2132. case type.OBJECT:
  2133. switch(t.cls) {
  2134. case type.ARRAY_BUFFER:
  2135. case type.TYPED_ARRAY:
  2136. case type.DATA_VIEW:
  2137. return obj.byteLength;
  2138. case type.ARRAY:
  2139. case type.BUFFER:
  2140. case type.ARGUMENTS:
  2141. case type.FUNCTION:
  2142. return obj.length;
  2143. }
  2144. }
  2145. };
  2146. exports.convertPropertyName = function(name) {
  2147. if(typeof name == 'symbol') {
  2148. return name;
  2149. } else {
  2150. return String(name);
  2151. }
  2152. };
  2153. exports.isGeneratorObject = function(obj) {
  2154. if(!obj) return false;
  2155. return typeof obj.next == 'function' &&
  2156. typeof obj[Symbol.iterator] == 'function' &&
  2157. obj[Symbol.iterator]() === obj;
  2158. };
  2159. //TODO find better way
  2160. exports.isGeneratorFunction = function(f) {
  2161. if(typeof f != 'function') return false;
  2162. return /^function\s*\*\s*/.test(f.toString());
  2163. };
  2164. exports.format = function(value, opts) {
  2165. return config.getFormatter(opts).format(value);
  2166. };
  2167. exports.functionName = require('should-format').Formatter.functionName;
  2168. exports.formatProp = function(value) {
  2169. return config.getFormatter().formatPropertyName(String(value));
  2170. };
  2171. },{"./config":4,"should-format":21,"should-type":23}],19:[function(require,module,exports){
  2172. module.exports = function format(msg) {
  2173. var args = arguments;
  2174. for(var i = 1, l = args.length; i < l; i++) {
  2175. msg = msg.replace(/%s/, args[i]);
  2176. }
  2177. return msg;
  2178. }
  2179. },{}],20:[function(require,module,exports){
  2180. var getType = require('should-type');
  2181. var format = require('./format');
  2182. var hasOwnProperty = Object.prototype.hasOwnProperty;
  2183. function makeResult(r, path, reason, a, b) {
  2184. var o = {result: r};
  2185. if(!r) {
  2186. o.path = path;
  2187. o.reason = reason;
  2188. o.a = a;
  2189. o.b = b;
  2190. }
  2191. return o;
  2192. }
  2193. var EQUALS = makeResult(true);
  2194. function typeToString(t) {
  2195. return t.type + (t.cls ? '(' + t.cls + (t.sub ? ' ' + t.sub : '') + ')' : '');
  2196. }
  2197. var REASON = {
  2198. PLUS_0_AND_MINUS_0: '+0 is not equal to -0',
  2199. DIFFERENT_TYPES: 'A has type %s and B has type %s',
  2200. NAN_NUMBER: 'NaN is not equal to any number',
  2201. EQUALITY: 'A is not equal to B',
  2202. EQUALITY_PROTOTYPE: 'A and B have different prototypes',
  2203. WRAPPED_VALUE: 'A wrapped value is not equal to B wrapped value',
  2204. FUNCTION_SOURCES: 'function A is not equal to B by source code value (via .toString call)',
  2205. MISSING_KEY: '%s has no key %s',
  2206. CIRCULAR_VALUES: 'A has circular reference that was visited not in the same time as B',
  2207. SET_MAP_MISSING_KEY: 'Set/Map missing key',
  2208. MAP_VALUE_EQUALITY: 'Values of the same key in A and B is not equal'
  2209. };
  2210. function eqInternal(a, b, opts, stackA, stackB, path) {
  2211. var r = EQUALS;
  2212. function result(comparison, reason) {
  2213. return makeResult(comparison, path, reason, a, b);
  2214. }
  2215. function checkPropertyEquality(property) {
  2216. return eqInternal(a[property], b[property], opts, stackA, stackB, path.concat([property]));
  2217. }
  2218. // equal a and b exit early
  2219. if(a === b) {
  2220. // check for +0 !== -0;
  2221. return result(a !== 0 || (1 / a == 1 / b), REASON.PLUS_0_AND_MINUS_0);
  2222. }
  2223. var l, p;
  2224. var typeA = getType(a),
  2225. typeB = getType(b);
  2226. // if objects has different types they are not equals
  2227. var typeDifferents = typeA.type !== typeB.type || typeA.cls !== typeB.cls;
  2228. if(typeDifferents || ((opts.checkSubType && typeA.sub !== typeB.sub) || !opts.checkSubType)) {
  2229. return result(false, format(REASON.DIFFERENT_TYPES, typeToString(typeA), typeToString(typeB)));
  2230. }
  2231. //early checks for types
  2232. switch(typeA.type) {
  2233. case 'number':
  2234. // NaN !== NaN
  2235. return (a !== a) ? result(b !== b, REASON.NAN_NUMBER)
  2236. // but treat `+0` vs. `-0` as not equal
  2237. : (a === 0 ? result(1 / a === 1 / b, REASON.PLUS_0_AND_MINUS_0) : result(a === b, REASON.EQUALITY));
  2238. case 'boolean':
  2239. case 'string':
  2240. return result(a === b, REASON.EQUALITY);
  2241. case 'function':
  2242. var fA = a.toString(), fB = b.toString();
  2243. r = eqInternal(fA, fB, opts, stackA, stackB, path);
  2244. if(!r.result) {
  2245. r.reason = REASON.FUNCTION_SOURCES;
  2246. return r;
  2247. }
  2248. break;//check user properties
  2249. case 'object':
  2250. // additional checks for object instances
  2251. switch(typeA.cls) {
  2252. // check regexp flags
  2253. // TODO add es6 flags
  2254. case 'regexp':
  2255. p = ['source', 'global', 'multiline', 'lastIndex', 'ignoreCase'];
  2256. while(p.length) {
  2257. r = checkPropertyEquality(p.shift());
  2258. if(!r.result) return r;
  2259. }
  2260. break;//check user properties
  2261. //check by timestamp only
  2262. case 'date':
  2263. if(+a !== +b) {
  2264. return result(false, REASON.EQUALITY);
  2265. }
  2266. break;//check user properties
  2267. //primitive type wrappers
  2268. case 'number':
  2269. case 'boolean':
  2270. case 'string':
  2271. r = eqInternal(a.valueOf(), b.valueOf(), opts, stackA, stackB, path);
  2272. if(!r.result) {
  2273. r.reason = REASON.WRAPPED_VALUE;
  2274. return r;
  2275. }
  2276. break;//check user properties
  2277. //node buffer
  2278. case 'buffer':
  2279. //if length different it is obviously different
  2280. r = checkPropertyEquality('length');
  2281. if(!r.result) return r;
  2282. l = a.length;
  2283. while(l--) {
  2284. r = checkPropertyEquality(l);
  2285. if(!r.result) return r;
  2286. }
  2287. //we do not check for user properties because
  2288. //node Buffer have some strange hidden properties
  2289. return EQUALS;
  2290. case 'error':
  2291. //check defined properties
  2292. p = ['name', 'message'];
  2293. while(p.length) {
  2294. r = checkPropertyEquality(p.shift());
  2295. if(!r.result) return r;
  2296. }
  2297. break;//check user properties
  2298. case 'array':
  2299. case 'arguments':
  2300. case 'typed-array':
  2301. r = checkPropertyEquality('length');
  2302. if(!r.result) return r;
  2303. break;//check user properties
  2304. case 'array-buffer':
  2305. r = checkPropertyEquality('byteLength');
  2306. if(!r.result) return r;
  2307. break;//check user properties
  2308. case 'map':
  2309. case 'set':
  2310. r = checkPropertyEquality('size');
  2311. if(!r.result) return r;
  2312. stackA.push(a);
  2313. stackB.push(b);
  2314. var itA = a.entries();
  2315. var nextA = itA.next();
  2316. while(!nextA.done) {
  2317. var key = nextA.value[0];
  2318. //first check for primitive key if we can do light check
  2319. //using .has and .get
  2320. if(getType(key).type != 'object') {
  2321. if(b.has(key)) {
  2322. if(typeA.cls == 'map') {
  2323. //for map we also check its value to be equal
  2324. var value = b.get(key);
  2325. r = eqInternal(nextA.value[1], value, opts, stackA, stackB, path);
  2326. if(!r.result) {
  2327. r.a = nextA.value;
  2328. r.b = value;
  2329. r.reason = REASON.MAP_VALUE_EQUALITY;
  2330. break;
  2331. }
  2332. }
  2333. } else {
  2334. r = result(false, REASON.SET_MAP_MISSING_KEY);
  2335. r.a = key;
  2336. r.b = key;
  2337. break;
  2338. }
  2339. } else {
  2340. //heavy check
  2341. //we search by iterator for key equality using equal
  2342. var itB = b.entries();
  2343. var nextB = itB.next();
  2344. while(!nextB.done) {
  2345. //first check for keys
  2346. r = eqInternal(nextA.value[0], nextB.value[0], opts, stackA, stackB, path);
  2347. if(!r.result) {
  2348. r.reason = REASON.SET_MAP_MISSING_KEY;
  2349. r.a = key;
  2350. r.b = key;
  2351. } else {
  2352. if(typeA.cls == 'map') {
  2353. r = eqInternal(nextA.value[1], nextB.value[1], opts, stackA, stackB, path);
  2354. if(!r.result) {
  2355. r.a = nextA.value;
  2356. r.b = nextB.value;
  2357. r.reason = REASON.MAP_VALUE_EQUALITY;
  2358. }
  2359. }
  2360. break;
  2361. }
  2362. nextB = itB.next();
  2363. }
  2364. }
  2365. if(!r.result) {
  2366. break;
  2367. }
  2368. nextA = itA.next();
  2369. }
  2370. stackA.pop();
  2371. stackB.pop();
  2372. if(!r.result) {
  2373. r.reason = REASON.SET_MAP_MISSING_ENTRY;
  2374. return r;
  2375. }
  2376. break; //check user properties
  2377. }
  2378. }
  2379. // compare deep objects and arrays
  2380. // stacks contain references only
  2381. //
  2382. l = stackA.length;
  2383. while(l--) {
  2384. if(stackA[l] == a) {
  2385. return result(stackB[l] == b, REASON.CIRCULAR_VALUES);
  2386. }
  2387. }
  2388. // add `a` and `b` to the stack of traversed objects
  2389. stackA.push(a);
  2390. stackB.push(b);
  2391. var key;
  2392. for(key in b) {
  2393. if(hasOwnProperty.call(b, key)) {
  2394. r = result(hasOwnProperty.call(a, key), format(REASON.MISSING_KEY, 'A', key));
  2395. if(!r.result) {
  2396. break;
  2397. }
  2398. if(r.result) {
  2399. r = checkPropertyEquality(key);
  2400. if(!r.result) {
  2401. break;
  2402. }
  2403. }
  2404. }
  2405. }
  2406. if(r.result) {
  2407. // ensure both objects have the same number of properties
  2408. for(key in a) {
  2409. if(hasOwnProperty.call(a, key)) {
  2410. r = result(hasOwnProperty.call(b, key), format(REASON.MISSING_KEY, 'B', key));
  2411. if(!r.result) {
  2412. return r;
  2413. }
  2414. }
  2415. }
  2416. }
  2417. stackA.pop();
  2418. stackB.pop();
  2419. if(!r.result) return r;
  2420. var prototypesEquals = false, canComparePrototypes = false;
  2421. if(opts.checkProtoEql) {
  2422. if(Object.getPrototypeOf) {//TODO should i check prototypes for === or use eq?
  2423. prototypesEquals = Object.getPrototypeOf(a) === Object.getPrototypeOf(b);
  2424. canComparePrototypes = true;
  2425. } else if(a.__proto__ && b.__proto__) {
  2426. prototypesEquals = a.__proto__ === b.__proto__;
  2427. canComparePrototypes = true;
  2428. }
  2429. if(canComparePrototypes && !prototypesEquals) {
  2430. r = result(prototypesEquals, REASON.EQUALITY_PROTOTYPE);
  2431. r.showReason = true;
  2432. if(!r.result) {
  2433. return r;
  2434. }
  2435. }
  2436. }
  2437. return EQUALS;
  2438. }
  2439. var defaultOptions = {
  2440. checkProtoEql: true,
  2441. checkSubType: true
  2442. };
  2443. function eq(a, b, opts) {
  2444. opts = opts || {};
  2445. if(typeof opts.checkProtoEql !== 'boolean')
  2446. opts.checkProtoEql = defaultOptions.checkProtoEql;
  2447. if(typeof opts.checkSubType !== 'boolean')
  2448. opts.checkSubType = defaultOptions.checkSubType;
  2449. var r = eqInternal(a, b, opts, [], [], []);
  2450. return r;
  2451. }
  2452. module.exports = eq;
  2453. eq.r = REASON;
  2454. },{"./format":19,"should-type":23}],21:[function(require,module,exports){
  2455. var getType = require('should-type');
  2456. var util = require('./util');
  2457. function genKeysFunc(f) {
  2458. return function(value) {
  2459. var k = f(value);
  2460. k.sort();
  2461. return k;
  2462. };
  2463. }
  2464. function Formatter(opts) {
  2465. opts = opts || {};
  2466. this.seen = [];
  2467. this.keys = genKeysFunc(opts.keys === false ? Object.getOwnPropertyNames : Object.keys);
  2468. this.maxLineLength = typeof opts.maxLineLength === 'number' ? opts.maxLineLength : 60;
  2469. this.propSep = opts.propSep || ',';
  2470. this.isUTCdate = !!opts.isUTCdate;
  2471. }
  2472. Formatter.prototype = {
  2473. constructor: Formatter,
  2474. format: function(value) {
  2475. var t = getType(value);
  2476. var name1 = t.type, name2 = t.type;
  2477. if(t.cls) {
  2478. name1 += '_' + t.cls;
  2479. name2 += '_' + t.cls;
  2480. }
  2481. if(t.sub) {
  2482. name2 += '_' + t.sub;
  2483. }
  2484. var f = this['_format_' + name2] || this['_format_' + name1] || this['_format_' + t.type] || this.defaultFormat;
  2485. return f.call(this, value).trim();
  2486. },
  2487. _formatObject: function(value, opts) {
  2488. opts = opts || {};
  2489. var mainKeys = opts.keys || this.keys(value);
  2490. var len = 0;
  2491. var formatPropertyValue = opts.formatPropertyValue || this.formatPropertyValue;
  2492. var formatPropertyName = opts.formatPropertyName || this.formatPropertyName;
  2493. var keyValueSep = opts.keyValueSep || ': ';
  2494. var keyFilter = opts.keyFilter || function() { return true; };
  2495. this.seen.push(value);
  2496. var keys = [];
  2497. mainKeys.forEach(function(key) {
  2498. if(!keyFilter(key)) return;
  2499. var fName = formatPropertyName.call(this, key);
  2500. var f = (fName ? fName + keyValueSep : '') + formatPropertyValue.call(this, value, key);
  2501. len += f.length;
  2502. keys.push(f);
  2503. }, this);
  2504. this.seen.pop();
  2505. (opts.additionalProperties || []).forEach(function(keyValue) {
  2506. var f = keyValue[0] + keyValueSep + this.format(keyValue[1]);
  2507. len += f.length;
  2508. keys.push(f);
  2509. }, this);
  2510. var prefix = opts.prefix || Formatter.constructorName(value) || '';
  2511. if(prefix.length > 0) prefix += ' ';
  2512. var lbracket, rbracket;
  2513. if(Array.isArray(opts.brackets)) {
  2514. lbracket = opts.brackets && opts.brackets[0];
  2515. rbracket = opts.brackets && opts.brackets[1];
  2516. } else {
  2517. lbracket = '{';
  2518. rbracket = '}';
  2519. }
  2520. var rootValue = opts.value || '';
  2521. if(keys.length === 0)
  2522. return rootValue || (prefix + lbracket + rbracket);
  2523. if(len <= this.maxLineLength) {
  2524. return prefix + lbracket + ' ' + (rootValue ? rootValue + ' ' : '') + keys.join(this.propSep + ' ') + ' ' + rbracket;
  2525. } else {
  2526. return prefix + lbracket + '\n' + (rootValue ? ' ' + rootValue + '\n' : '') + keys.map(util.addSpaces).join(this.propSep + '\n') + '\n' + rbracket;
  2527. }
  2528. },
  2529. formatObject: function(value, prefix, props) {
  2530. props = props || this.keys(value);
  2531. var len = 0;
  2532. this.seen.push(value);
  2533. props = props.map(function(prop) {
  2534. var f = this.formatProperty(value, prop);
  2535. len += f.length;
  2536. return f;
  2537. }, this);
  2538. this.seen.pop();
  2539. if(props.length === 0) return '{}';
  2540. if(len <= this.maxLineLength) {
  2541. return '{ ' + (prefix ? prefix + ' ' : '') + props.join(this.propSep + ' ') + ' }';
  2542. } else {
  2543. return '{' + '\n' + (prefix ? ' ' + prefix + '\n' : '') + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
  2544. }
  2545. },
  2546. formatPropertyName: function(name) {
  2547. return name.match(/^[a-zA-Z_$][a-zA-Z_$0-9]*$/) ? name : this.format(name);
  2548. },
  2549. formatProperty: function(value, prop) {
  2550. var desc = Formatter.getPropertyDescriptor(value, prop);
  2551. var propName = this.formatPropertyName(prop);
  2552. var propValue = desc.get && desc.set ?
  2553. '[Getter/Setter]' : desc.get ?
  2554. '[Getter]' : desc.set ?
  2555. '[Setter]' : this.seen.indexOf(desc.value) >= 0 ?
  2556. '[Circular]' :
  2557. this.format(desc.value);
  2558. return propName + ': ' + propValue;
  2559. },
  2560. formatPropertyValue: function(value, prop) {
  2561. var desc = Formatter.getPropertyDescriptor(value, prop);
  2562. var propValue = desc.get && desc.set ?
  2563. '[Getter/Setter]' : desc.get ?
  2564. '[Getter]' : desc.set ?
  2565. '[Setter]' : this.seen.indexOf(desc.value) >= 0 ?
  2566. '[Circular]' :
  2567. this.format(desc.value);
  2568. return propValue;
  2569. }
  2570. };
  2571. Formatter.add = function add(type, cls, sub, f) {
  2572. var args = Array.prototype.slice.call(arguments);
  2573. f = args.pop();
  2574. Formatter.prototype['_format_' + args.join('_')] = f;
  2575. };
  2576. Formatter.formatObjectWithPrefix = function formatObjectWithPrefix(f) {
  2577. return function(value) {
  2578. var prefix = f.call(this, value);
  2579. var props = this.keys(value);
  2580. if(props.length == 0) return prefix;
  2581. else return this.formatObject(value, prefix, props);
  2582. };
  2583. };
  2584. var functionNameRE = /^\s*function\s*(\S*)\s*\(/;
  2585. Formatter.functionName = function functionName(f) {
  2586. if(f.name) {
  2587. return f.name;
  2588. }
  2589. var name = f.toString().match(functionNameRE)[1];
  2590. return name;
  2591. };
  2592. Formatter.constructorName = function(obj) {
  2593. while (obj) {
  2594. var descriptor = Object.getOwnPropertyDescriptor(obj, 'constructor');
  2595. if (descriptor !== undefined &&
  2596. typeof descriptor.value === 'function') {
  2597. var name = Formatter.functionName(descriptor.value);
  2598. if(name !== '') {
  2599. return name;
  2600. }
  2601. }
  2602. obj = Object.getPrototypeOf(obj);
  2603. }
  2604. };
  2605. Formatter.getPropertyDescriptor = function(obj, value) {
  2606. var desc;
  2607. try {
  2608. desc = Object.getOwnPropertyDescriptor(obj, value) || {value: obj[value]};
  2609. } catch(e) {
  2610. desc = {value: e};
  2611. }
  2612. return desc;
  2613. };
  2614. Formatter.generateFunctionForIndexedArray = function generateFunctionForIndexedArray(lengthProp, name, padding) {
  2615. return function(value) {
  2616. var max = this.byteArrayMaxLength || 50;
  2617. var length = value[lengthProp];
  2618. var formattedValues = [];
  2619. var len = 0;
  2620. for(var i = 0; i < max && i < length; i++) {
  2621. var b = value[i] || 0;
  2622. var v = util.pad0(b.toString(16), padding);
  2623. len += v.length;
  2624. formattedValues.push(v);
  2625. }
  2626. var prefix = value.constructor.name || name || '';
  2627. if(prefix) prefix += ' ';
  2628. if(formattedValues.length === 0)
  2629. return prefix + '[]';
  2630. if(len <= this.maxLineLength) {
  2631. return prefix + '[ ' + formattedValues.join(this.propSep + ' ') + ' ' + ']';
  2632. } else {
  2633. return prefix + '[\n' + formattedValues.map(util.addSpaces).join(this.propSep + '\n') + '\n' + ']';
  2634. }
  2635. };
  2636. };
  2637. Formatter.add('undefined', function() { return 'undefined' });
  2638. Formatter.add('null', function() { return 'null' });
  2639. Formatter.add('boolean', function(value) { return value ? 'true': 'false' });
  2640. Formatter.add('symbol', function(value) { return value.toString() });
  2641. ['number', 'boolean'].forEach(function(name) {
  2642. Formatter.add('object', name, function(value) {
  2643. return this._formatObject(value, {
  2644. additionalProperties: [['[[PrimitiveValue]]', value.valueOf()]]
  2645. });
  2646. });
  2647. });
  2648. Formatter.add('object', 'string', function(value) {
  2649. var realValue = value.valueOf();
  2650. return this._formatObject(value, {
  2651. keyFilter: function(key) {
  2652. //skip useless indexed properties
  2653. return !(key.match(/\d+/) && parseInt(key, 10) < realValue.length);
  2654. },
  2655. additionalProperties: [['[[PrimitiveValue]]', realValue]]
  2656. });
  2657. });
  2658. Formatter.add('object', 'regexp', function(value) {
  2659. return this._formatObject(value, {
  2660. value: String(value)
  2661. });
  2662. });
  2663. Formatter.add('number', function(value) {
  2664. if(value === 0 && 1 / value < 0) return '-0';
  2665. return String(value);
  2666. });
  2667. Formatter.add('string', function(value) {
  2668. return '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
  2669. .replace(/'/g, "\\'")
  2670. .replace(/\\"/g, '"') + '\'';
  2671. });
  2672. Formatter.add('object', function(value) {
  2673. return this._formatObject(value);
  2674. });
  2675. Formatter.add('object', 'arguments', function(value) {
  2676. return this._formatObject(value, {
  2677. prefix: 'Arguments',
  2678. formatPropertyName: function(key) {
  2679. if(!key.match(/\d+/)) {
  2680. return this.formatPropertyName(key);
  2681. }
  2682. },
  2683. brackets: ['[', ']']
  2684. });
  2685. });
  2686. Formatter.add('object', 'array', function(value) {
  2687. return this._formatObject(value, {
  2688. formatPropertyName: function(key) {
  2689. if(!key.match(/\d+/)) {
  2690. return this.formatPropertyName(key);
  2691. }
  2692. },
  2693. brackets: ['[', ']']
  2694. });
  2695. });
  2696. function formatDate(value, isUTC) {
  2697. var prefix = isUTC ? 'UTC' : '';
  2698. var date = value['get' + prefix + 'FullYear']() +
  2699. '-' +
  2700. util.pad0(value['get' + prefix + 'Month']() + 1, 2) +
  2701. '-' +
  2702. util.pad0(value['get' + prefix + 'Date'](), 2);
  2703. var time = util.pad0(value['get' + prefix + 'Hours'](), 2) +
  2704. ':' +
  2705. util.pad0(value['get' + prefix + 'Minutes'](), 2) +
  2706. ':' +
  2707. util.pad0(value['get' + prefix + 'Seconds'](), 2) +
  2708. '.' +
  2709. util.pad0(value['get' + prefix + 'Milliseconds'](), 3);
  2710. var to = value.getTimezoneOffset();
  2711. var absTo = Math.abs(to);
  2712. var hours = Math.floor(absTo / 60);
  2713. var minutes = absTo - hours * 60;
  2714. var tzFormat = (to < 0 ? '+' : '-') + util.pad0(hours, 2) + util.pad0(minutes, 2);
  2715. return date + ' ' + time + (isUTC ? '' : ' ' + tzFormat);
  2716. }
  2717. Formatter.add('object', 'date', function(value) {
  2718. return this._formatObject(value, { value: formatDate(value, this.isUTCdate) });
  2719. });
  2720. Formatter.add('function', function(value) {
  2721. return this._formatObject(value, {
  2722. additionalProperties: [['name', Formatter.functionName(value)]]
  2723. });
  2724. });
  2725. Formatter.add('object', 'error', function(value) {
  2726. return this._formatObject(value, {
  2727. prefix: value.name,
  2728. additionalProperties: [['message', value.message]]
  2729. });
  2730. });
  2731. Formatter.add('object', 'buffer', Formatter.generateFunctionForIndexedArray('length', 'Buffer', 2));
  2732. Formatter.add('object', 'array-buffer', Formatter.generateFunctionForIndexedArray('byteLength', 'ArrayBuffer', 2));
  2733. Formatter.add('object', 'typed-array', 'int8', Formatter.generateFunctionForIndexedArray('length', 'Int8Array', 2));
  2734. Formatter.add('object', 'typed-array', 'uint8', Formatter.generateFunctionForIndexedArray('length', 'Uint8Array', 2));
  2735. Formatter.add('object', 'typed-array', 'uint8clamped', Formatter.generateFunctionForIndexedArray('length', 'Uint8ClampedArray', 2));
  2736. Formatter.add('object', 'typed-array', 'int16', Formatter.generateFunctionForIndexedArray('length', 'Int16Array', 4));
  2737. Formatter.add('object', 'typed-array', 'uint16', Formatter.generateFunctionForIndexedArray('length', 'Uint16Array', 4));
  2738. Formatter.add('object', 'typed-array', 'int32', Formatter.generateFunctionForIndexedArray('length', 'Int32Array', 8));
  2739. Formatter.add('object', 'typed-array', 'uint32', Formatter.generateFunctionForIndexedArray('length', 'Uint32Array', 8));
  2740. //TODO add float32 and float64
  2741. Formatter.add('object', 'promise', function() {
  2742. return '[Promise]';//TODO it could be nice to inspect its state and value
  2743. });
  2744. Formatter.add('object', 'xhr', function() {
  2745. return '[XMLHttpRequest]';//TODO it could be nice to inspect its state
  2746. });
  2747. Formatter.add('object', 'html-element', function(value) {
  2748. return value.outerHTML;
  2749. });
  2750. Formatter.add('object', 'html-element', '#text', function(value) {
  2751. return value.nodeValue;
  2752. });
  2753. Formatter.add('object', 'html-element', '#document', function(value) {
  2754. return value.documentElement.outerHTML;
  2755. });
  2756. Formatter.add('object', 'host', function() {
  2757. return '[Host]';
  2758. });
  2759. Formatter.add('object', 'set', function(value) {
  2760. var iter = value.values();
  2761. var len = 0;
  2762. this.seen.push(value);
  2763. var props = [];
  2764. var next = iter.next();
  2765. while(!next.done) {
  2766. var val = next.value;
  2767. var f = this.format(val);
  2768. len += f.length;
  2769. props.push(f);
  2770. next = iter.next();
  2771. }
  2772. this.seen.pop();
  2773. if(props.length === 0) return 'Set {}';
  2774. if(len <= this.maxLineLength) {
  2775. return 'Set { ' + props.join(this.propSep + ' ') + ' }';
  2776. } else {
  2777. return 'Set {\n' + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
  2778. }
  2779. });
  2780. Formatter.add('object', 'map', function(value) {
  2781. var iter = value.entries();
  2782. var len = 0;
  2783. this.seen.push(value);
  2784. var props = [];
  2785. var next = iter.next();
  2786. while(!next.done) {
  2787. var val = next.value;
  2788. var fK = this.format(val[0]);
  2789. var fV = this.format(val[1]);
  2790. var f;
  2791. if((fK.length + fV.length + 4) <= this.maxLineLength) {
  2792. f = fK + ' => ' + fV;
  2793. } else {
  2794. f = fK + ' =>\n' + fV;
  2795. }
  2796. len += fK.length + fV.length + 4;
  2797. props.push(f);
  2798. next = iter.next();
  2799. }
  2800. this.seen.pop();
  2801. if(props.length === 0) return 'Map {}';
  2802. if(len <= this.maxLineLength) {
  2803. return 'Map { ' + props.join(this.propSep + ' ') + ' }';
  2804. } else {
  2805. return 'Map {\n' + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
  2806. }
  2807. });
  2808. Formatter.prototype.defaultFormat = Formatter.prototype._format_object;
  2809. function defaultFormat(value, opts) {
  2810. return new Formatter(opts).format(value);
  2811. }
  2812. defaultFormat.Formatter = Formatter;
  2813. module.exports = defaultFormat;
  2814. },{"./util":22,"should-type":23}],22:[function(require,module,exports){
  2815. function addSpaces(v) {
  2816. return v.split('\n').map(function(vv) { return ' ' + vv; }).join('\n');
  2817. }
  2818. function pad(str, value, filler) {
  2819. str = String(str)
  2820. var isRight = false;
  2821. if(value < 0) {
  2822. isRight = true;
  2823. value = -value;
  2824. }
  2825. if(str.length < value) {
  2826. var padding = new Array(value - str.length + 1).join(filler);
  2827. return isRight ? str + padding : padding + str;
  2828. } else{
  2829. return str;
  2830. }
  2831. }
  2832. module.exports = {
  2833. addSpaces: addSpaces,
  2834. pad: pad,
  2835. pad0: function(str, value) {
  2836. return pad(str, value, '0');
  2837. }
  2838. };
  2839. },{}],23:[function(require,module,exports){
  2840. var toString = Object.prototype.toString;
  2841. var types = require('./types');
  2842. /**
  2843. * Simple data function to store type information
  2844. * @param {string} type Usually what is returned from typeof
  2845. * @param {string} cls Sanitized @Class via Object.prototype.toString
  2846. * @param {string} sub If type and cls the same, and need to specify somehow
  2847. * @private
  2848. * @example
  2849. *
  2850. * //for null
  2851. * new Type('null');
  2852. *
  2853. * //for Date
  2854. * new Type('object', 'date');
  2855. *
  2856. * //for Uint8Array
  2857. *
  2858. * new Type('object', 'typed-array', 'uint8');
  2859. */
  2860. function Type(type, cls, sub) {
  2861. this.type = type;
  2862. this.cls = cls;
  2863. this.sub = sub;
  2864. }
  2865. /**
  2866. * Function to store type checks
  2867. * @private
  2868. */
  2869. function TypeChecker() {
  2870. this.checks = [];
  2871. }
  2872. TypeChecker.prototype = {
  2873. add: function(func) {
  2874. this.checks.push(func);
  2875. return this;
  2876. },
  2877. addTypeOf: function(type, res) {
  2878. return this.add(function(obj, tpeOf) {
  2879. if(tpeOf === type) {
  2880. return new Type(res);
  2881. }
  2882. });
  2883. },
  2884. addClass: function(cls, res, sub) {
  2885. return this.add(function(obj, tpeOf, objCls) {
  2886. if(objCls === cls) {
  2887. return new Type(types.OBJECT, res, sub);
  2888. }
  2889. });
  2890. },
  2891. getType: function(obj) {
  2892. var typeOf = typeof obj;
  2893. var cls = toString.call(obj);
  2894. for(var i = 0, l = this.checks.length; i < l; i++) {
  2895. var res = this.checks[i].call(this, obj, typeOf, cls);
  2896. if(typeof res !== 'undefined') return res;
  2897. }
  2898. }
  2899. };
  2900. var main = new TypeChecker();
  2901. //TODO add iterators
  2902. main
  2903. .addTypeOf(types.NUMBER, types.NUMBER)
  2904. .addTypeOf(types.UNDEFINED, types.UNDEFINED)
  2905. .addTypeOf(types.STRING, types.STRING)
  2906. .addTypeOf(types.BOOLEAN, types.BOOLEAN)
  2907. .addTypeOf(types.FUNCTION, types.FUNCTION)
  2908. .addTypeOf(types.SYMBOL, types.SYMBOL)
  2909. .add(function(obj, tpeOf) {
  2910. if(obj === null) return new Type(types.NULL);
  2911. })
  2912. .addClass('[object String]', types.STRING)
  2913. .addClass('[object Boolean]', types.BOOLEAN)
  2914. .addClass('[object Number]', types.NUMBER)
  2915. .addClass('[object Array]', types.ARRAY)
  2916. .addClass('[object RegExp]', types.REGEXP)
  2917. .addClass('[object Error]', types.ERROR)
  2918. .addClass('[object Date]', types.DATE)
  2919. .addClass('[object Arguments]', types.ARGUMENTS)
  2920. .addClass('[object Math]')
  2921. .addClass('[object JSON]')
  2922. .addClass('[object ArrayBuffer]', types.ARRAY_BUFFER)
  2923. .addClass('[object Int8Array]', types.TYPED_ARRAY, 'int8')
  2924. .addClass('[object Uint8Array]', types.TYPED_ARRAY, 'uint8')
  2925. .addClass('[object Uint8ClampedArray]', types.TYPED_ARRAY, 'uint8clamped')
  2926. .addClass('[object Int16Array]', types.TYPED_ARRAY, 'int16')
  2927. .addClass('[object Uint16Array]', types.TYPED_ARRAY, 'uint16')
  2928. .addClass('[object Int32Array]', types.TYPED_ARRAY, 'int32')
  2929. .addClass('[object Uint32Array]', types.TYPED_ARRAY, 'uint32')
  2930. .addClass('[object Float32Array]', types.TYPED_ARRAY, 'float32')
  2931. .addClass('[object Float64Array]', types.TYPED_ARRAY, 'float64')
  2932. .addClass('[object DataView]', types.DATA_VIEW)
  2933. .addClass('[object Map]', types.MAP)
  2934. .addClass('[object WeakMap]', types.WEAK_MAP)
  2935. .addClass('[object Set]', types.SET)
  2936. .addClass('[object WeakSet]', types.WEAK_SET)
  2937. .addClass('[object Promise]', types.PROMISE)
  2938. .addClass('[object Blob]', types.BLOB)
  2939. .addClass('[object File]', types.FILE)
  2940. .addClass('[object FileList]', types.FILE_LIST)
  2941. .addClass('[object XMLHttpRequest]', types.XHR)
  2942. .add(function(obj) {
  2943. if((typeof Promise === types.FUNCTION && obj instanceof Promise) ||
  2944. (typeof obj.then === types.FUNCTION)) {
  2945. return new Type(types.OBJECT, types.PROMISE);
  2946. }
  2947. })
  2948. .add(function(obj) {
  2949. if(typeof Buffer !== 'undefined' && obj instanceof Buffer) {
  2950. return new Type(types.OBJECT, types.BUFFER);
  2951. }
  2952. })
  2953. .add(function(obj) {
  2954. if(typeof Node !== 'undefined' && obj instanceof Node) {
  2955. return new Type(types.OBJECT, types.HTML_ELEMENT, obj.nodeName);
  2956. }
  2957. })
  2958. .add(function(obj) {
  2959. // probably at the begginging should be enough these checks
  2960. if(obj.Boolean === Boolean && obj.Number === Number && obj.String === String && obj.Date === Date) {
  2961. return new Type(types.OBJECT, types.HOST);
  2962. }
  2963. })
  2964. .add(function() {
  2965. return new Type(types.OBJECT);
  2966. });
  2967. /**
  2968. * Get type information of anything
  2969. *
  2970. * @param {any} obj Anything that could require type information
  2971. * @return {Type} type info
  2972. */
  2973. function getGlobalType(obj) {
  2974. return main.getType(obj);
  2975. }
  2976. getGlobalType.checker = main;
  2977. getGlobalType.TypeChecker = TypeChecker;
  2978. getGlobalType.Type = Type;
  2979. Object.keys(types).forEach(function(typeName) {
  2980. getGlobalType[typeName] = types[typeName];
  2981. });
  2982. module.exports = getGlobalType;
  2983. },{"./types":24}],24:[function(require,module,exports){
  2984. var types = {
  2985. NUMBER: 'number',
  2986. UNDEFINED: 'undefined',
  2987. STRING: 'string',
  2988. BOOLEAN: 'boolean',
  2989. OBJECT: 'object',
  2990. FUNCTION: 'function',
  2991. NULL: 'null',
  2992. ARRAY: 'array',
  2993. REGEXP: 'regexp',
  2994. DATE: 'date',
  2995. ERROR: 'error',
  2996. ARGUMENTS: 'arguments',
  2997. SYMBOL: 'symbol',
  2998. ARRAY_BUFFER: 'array-buffer',
  2999. TYPED_ARRAY: 'typed-array',
  3000. DATA_VIEW: 'data-view',
  3001. MAP: 'map',
  3002. SET: 'set',
  3003. WEAK_SET: 'weak-set',
  3004. WEAK_MAP: 'weak-map',
  3005. PROMISE: 'promise',
  3006. // node buffer
  3007. BUFFER: 'buffer',
  3008. // dom html element
  3009. HTML_ELEMENT: 'html-element',
  3010. HTML_ELEMENT_TEXT: 'html-element-text',
  3011. DOCUMENT: 'document',
  3012. WINDOW: 'window',
  3013. FILE: 'file',
  3014. FILE_LIST: 'file-list',
  3015. BLOB: 'blob',
  3016. HOST: 'host',
  3017. XHR: 'xhr'
  3018. };
  3019. module.exports = types;
  3020. },{}]},{},[1])(1)
  3021. });