should.js 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238
  1. /**
  2. * should.js by TJ Holowaychuk (MIT), adapted to run in browser and node.
  3. */
  4. (function (should) {
  5. if ('undefined' != typeof exports) {
  6. module.exports = exports = should = require('assert');
  7. }
  8. /**
  9. * Expose constructor.
  10. */
  11. should.Assertion = Assertion;
  12. /**
  13. * Possible assertion flags.
  14. */
  15. var flags = {
  16. not: ['be', 'have', 'include']
  17. , an: ['instance']
  18. , and: ['be', 'have', 'include', 'an']
  19. , be: ['an']
  20. , have: ['an', 'own']
  21. , include: ['an']
  22. , not: ['include', 'have', 'be']
  23. , own: []
  24. , instance: []
  25. };
  26. /**
  27. * Extend Object.prototype.
  28. */
  29. if ('object' == typeof process) {
  30. Object.defineProperty(
  31. Object.prototype
  32. , 'should'
  33. , {
  34. get: function () {
  35. var self = this.valueOf()
  36. , fn = function () {
  37. return new Assertion(self);
  38. };
  39. if ('undefined' != typeof exports) {
  40. fn.__proto__ = exports;
  41. fn.exports = exports;
  42. }
  43. return fn;
  44. }
  45. , enumerable: false
  46. }
  47. );
  48. } else {
  49. Object.prototype.should = function () {
  50. return new Assertion(this.valueOf());
  51. };
  52. }
  53. /**
  54. * Constructor
  55. *
  56. * @api private
  57. */
  58. function Assertion (obj) {
  59. if (obj !== undefined) {
  60. this.obj = obj;
  61. this.flags = {};
  62. var $flags = keys(flags);
  63. for (var i = 0, l = $flags.length; i < l; i++) {
  64. this[$flags[i]] = new FlaggedAssertion(this, $flags[i]);
  65. }
  66. }
  67. };
  68. /**
  69. * Performs an assertion
  70. *
  71. * @api private
  72. */
  73. Assertion.prototype.assert = function (truth, msg, error) {
  74. var msg = this.flags.not ? error : msg
  75. , ok = this.flags.not ? !truth : truth;
  76. if (!ok) {
  77. throw new Error(msg);
  78. }
  79. this.flags = {};
  80. };
  81. /**
  82. * Checks if the value is true
  83. *
  84. * @api public
  85. */
  86. Assertion.prototype.be_true = function () {
  87. this.assert(
  88. this.obj === true
  89. , 'expected ' + i(this.obj) + ' to be true'
  90. , 'expected ' + i(this.obj) + ' to not be true');
  91. return this;
  92. };
  93. /**
  94. * Checks if the value is true
  95. *
  96. * @api public
  97. */
  98. Assertion.prototype.be_false = function () {
  99. this.assert(
  100. this.obj === false
  101. , 'expected ' + i(this.obj) + ' to be false'
  102. , 'expected ' + i(this.obj) + ' to not be false'
  103. );
  104. return this;
  105. };
  106. /**
  107. * Check if the value is truthy
  108. *
  109. * @api public
  110. */
  111. Assertion.prototype.ok = function () {
  112. this.assert(
  113. this.obj == true
  114. , 'expected ' + i(this.obj) + ' to be true'
  115. , 'expected ' + i(this.obj) + ' to not be true');
  116. };
  117. /**
  118. * Checks if the array is empty.
  119. *
  120. * @api public
  121. */
  122. Assertion.prototype.empty = function () {
  123. this.obj.should().have.property('length');
  124. this.assert(
  125. 0 === this.obj.length
  126. , 'expected ' + i(this.obj) + ' to be empty'
  127. , 'expected ' + i(this.obj) + ' to not be empty');
  128. return this;
  129. };
  130. /**
  131. * Checks if the obj is arguments.
  132. *
  133. * @api public
  134. */
  135. Assertion.prototype.arguments = function () {
  136. this.assert(
  137. '[object Arguments]' == Object.prototype.toString.call(this.obj)
  138. , 'expected ' + i(this.obj) + ' to be arguments'
  139. , 'expected ' + i(this.obj) + ' to not be arguments');
  140. return this;
  141. };
  142. /**
  143. * Checks if the obj exactly equals another.
  144. *
  145. * @api public
  146. */
  147. Assertion.prototype.equal = function (obj) {
  148. this.assert(
  149. obj === this.obj
  150. , 'expected ' + i(this.obj) + ' to equal ' + i(obj)
  151. , 'expected ' + i(this.obj) + ' to not equal ' + i(obj));
  152. return this;
  153. };
  154. /**
  155. * Checks if the obj sortof equals another.
  156. *
  157. * @api public
  158. */
  159. Assertion.prototype.eql = function (obj) {
  160. this.assert(
  161. should.eql(obj, this.obj)
  162. , 'expected ' + i(this.obj) + ' to sort of equal ' + i(obj)
  163. , 'expected ' + i(this.obj) + ' to sort of not equal ' + i(obj));
  164. return this;
  165. };
  166. /**
  167. * Assert within start to finish (inclusive).
  168. *
  169. * @param {Number} start
  170. * @param {Number} finish
  171. * @api public
  172. */
  173. Assertion.prototype.within = function (start, finish) {
  174. var range = start + '..' + finish;
  175. this.assert(
  176. this.obj >= start && this.obj <= finish
  177. , 'expected ' + i(this.obj) + ' to be within ' + range
  178. , 'expected ' + i(this.obj) + ' to not be within ' + range);
  179. return this;
  180. };
  181. /**
  182. * Assert typeof.
  183. *
  184. * @api public
  185. */
  186. Assertion.prototype.a = function (type) {
  187. this.assert(
  188. type == typeof this.obj
  189. , 'expected ' + i(this.obj) + ' to be a ' + type
  190. , 'expected ' + i(this.obj) + ' not to be a ' + type);
  191. return this;
  192. };
  193. /**
  194. * Assert instanceof.
  195. *
  196. * @api public
  197. */
  198. Assertion.prototype.of = function (constructor) {
  199. var name = constructor.name;
  200. this.assert(
  201. this.obj instanceof constructor
  202. , 'expected ' + i(this.obj) + ' to be an instance of ' + name
  203. , 'expected ' + i(this.obj) + ' not to be an instance of ' + name);
  204. return this;
  205. };
  206. /**
  207. * Assert numeric value above _n_.
  208. *
  209. * @param {Number} n
  210. * @api public
  211. */
  212. Assertion.prototype.greaterThan =
  213. Assertion.prototype.above = function (n) {
  214. this.assert(
  215. this.obj > n
  216. , 'expected ' + i(this.obj) + ' to be above ' + n
  217. , 'expected ' + i(this.obj) + ' to be below ' + n);
  218. return this;
  219. };
  220. /**
  221. * Assert numeric value below _n_.
  222. *
  223. * @param {Number} n
  224. * @api public
  225. */
  226. Assertion.prototype.lessThan =
  227. Assertion.prototype.below = function (n) {
  228. this.assert(
  229. this.obj < n
  230. , 'expected ' + i(this.obj) + ' to be below ' + n
  231. , 'expected ' + i(this.obj) + ' to be above ' + n);
  232. return this;
  233. };
  234. /**
  235. * Assert string value matches _regexp_.
  236. *
  237. * @param {RegExp} regexp
  238. * @api public
  239. */
  240. Assertion.prototype.match = function (regexp) {
  241. this.assert(
  242. regexp.exec(this.obj)
  243. , 'expected ' + i(this.obj) + ' to match ' + regexp
  244. , 'expected ' + i(this.obj) + ' not to match ' + regexp);
  245. return this;
  246. };
  247. /**
  248. * Assert property "length" exists and has value of _n_.
  249. *
  250. * @param {Number} n
  251. * @api public
  252. */
  253. Assertion.prototype.length = function (n) {
  254. this.obj.should().have.property('length');
  255. var len = this.obj.length;
  256. this.assert(
  257. n == len
  258. , 'expected ' + i(this.obj) + ' to have a length of ' + n + ' but got ' + len
  259. , 'expected ' + i(this.obj) + ' to not have a length of ' + len);
  260. return this;
  261. };
  262. /**
  263. * Assert substring.
  264. *
  265. * @param {String} str
  266. * @api public
  267. */
  268. Assertion.prototype.string = function(str){
  269. this.obj.should().be.a('string');
  270. this.assert(
  271. ~this.obj.indexOf(str)
  272. , 'expected ' + i(this.obj) + ' to include ' + i(str)
  273. , 'expected ' + i(this.obj) + ' to not include ' + i(str));
  274. return this;
  275. };
  276. /**
  277. * Assert inclusion of object.
  278. *
  279. * @param {Object} obj
  280. * @api public
  281. */
  282. Assertion.prototype.object = function(obj){
  283. this.obj.should().be.a('object');
  284. var included = true;
  285. for (var key in obj) {
  286. if (obj.hasOwnProperty(key) && !should.eql(obj[key], this.obj[key])) {
  287. included = false;
  288. break;
  289. }
  290. }
  291. this.assert(
  292. included
  293. , 'expected ' + i(this.obj) + ' to include ' + i(obj)
  294. , 'expected ' + i(this.obj) + ' to not include ' + i(obj));
  295. return this;
  296. };
  297. /**
  298. * Assert property _name_ exists, with optional _val_.
  299. *
  300. * @param {String} name
  301. * @param {Mixed} val
  302. * @api public
  303. */
  304. Assertion.prototype.property = function (name, val) {
  305. if (this.flags.own) {
  306. this.assert(
  307. this.obj.hasOwnProperty(name)
  308. , 'expected ' + i(this.obj) + ' to have own property ' + i(name)
  309. , 'expected ' + i(this.obj) + ' to not have own property ' + i(name));
  310. return this;
  311. }
  312. if (this.flags.not && undefined !== val) {
  313. if (undefined === this.obj[name]) {
  314. throw new Error(i(this.obj) + ' has no property ' + i(name));
  315. }
  316. } else {
  317. this.assert(
  318. undefined !== this.obj[name]
  319. , 'expected ' + i(this.obj) + ' to have a property ' + i(name)
  320. , 'expected ' + i(this.obj) + ' to not have a property ' + i(name));
  321. }
  322. if (undefined !== val) {
  323. this.assert(
  324. val === this.obj[name]
  325. , 'expected ' + i(this.obj) + ' to have a property ' + i(name)
  326. + ' of ' + i(val) + ', but got ' + i(this.obj[name])
  327. , 'expected ' + i(this.obj) + ' to not have a property ' + i(name)
  328. + ' of ' + i(val));
  329. }
  330. this.obj = this.obj[name];
  331. return this;
  332. };
  333. /**
  334. * Assert that the array contains _obj_.
  335. *
  336. * @param {Mixed} obj
  337. * @api public
  338. */
  339. Assertion.prototype.contain = function (obj) {
  340. this.obj.should().be.an.instance.of(Array);
  341. this.assert(
  342. ~indexOf(this.obj, obj)
  343. , 'expected ' + i(this.obj) + ' to contain ' + i(obj)
  344. , 'expected ' + i(this.obj) + ' to not contain ' + i(obj));
  345. return this;
  346. };
  347. /**
  348. * Assert exact keys or inclusion of keys by using
  349. * the `.include` modifier.
  350. *
  351. * @param {Array|String ...} keys
  352. * @api public
  353. */
  354. Assertion.prototype.key =
  355. Assertion.prototype.keys = function (keys) {
  356. var str
  357. , ok = true;
  358. keys = keys instanceof Array
  359. ? keys
  360. : Array.prototype.slice.call(arguments);
  361. if (!keys.length) throw new Error('keys required');
  362. var actual = keys(this.obj)
  363. , len = keys.length;
  364. // Inclusion
  365. ok = every(keys, function(key){
  366. return ~indexOf(actual, key);
  367. });
  368. // Strict
  369. if (!this.flags.not && !this.flags.include) {
  370. ok = ok && keys.length == actual.length;
  371. }
  372. // Key string
  373. if (len > 1) {
  374. keys = map(keys, function(key){
  375. return i(key);
  376. });
  377. var last = keys.pop();
  378. str = keys.join(', ') + ', and ' + last;
  379. } else {
  380. str = i(keys[0]);
  381. }
  382. // Form
  383. str = (len > 1 ? 'keys ' : 'key ') + str;
  384. // Have / include
  385. str = (this.flag.include ? 'include ' : 'have ') + str;
  386. // Assertion
  387. this.assert(
  388. ok
  389. , 'expected ' + i(this.obj) + ' to ' + str
  390. , 'expected ' + i(this.obj) + ' to not ' + str);
  391. return this;
  392. };
  393. /**
  394. * Assertion with a flag.
  395. *
  396. * @api private
  397. */
  398. function FlaggedAssertion (parent, flag) {
  399. this.parent = parent;
  400. this.obj = parent.obj;
  401. this.flag = flag;
  402. this.flags = {};
  403. this.flags[flag] = true;
  404. for (var i in parent.flags) {
  405. if (parent.flags.hasOwnProperty(i)) {
  406. this.flags[i] = true;
  407. }
  408. }
  409. var $flags = flags[flag];
  410. for (var i = 0, l = $flags.length; i < l; i++) {
  411. this[$flags[i]] = new FlaggedAssertion(this, $flags[i]);
  412. }
  413. };
  414. /**
  415. * Inherits from assertion
  416. */
  417. FlaggedAssertion.prototype = new Assertion;
  418. /**
  419. * Array every compatibility
  420. *
  421. * @see bit.ly/5Fq1N2
  422. * @api public
  423. */
  424. function every (arr, fn, thisObj) {
  425. var scope = thisObj || window;
  426. for (var i = 0, j = arr.length; i < j; ++i) {
  427. if (!fn.call(scope, arr[i], i, arr)) {
  428. return false;
  429. }
  430. }
  431. return true;
  432. };
  433. /**
  434. * Array indexOf compatibility.
  435. *
  436. * @see bit.ly/a5Dxa2
  437. * @api public
  438. */
  439. function indexOf (arr, o, i) {
  440. if (Array.prototype.indexOf) {
  441. return Array.prototype.indexOf.call(arr, o, i);
  442. }
  443. for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0
  444. ; i < j && arr[i] !== o; i++);
  445. return j <= i ? -1 : i;
  446. };
  447. /**
  448. * Inspects an object.
  449. *
  450. * @see taken from node.js `util` module (copyright Joyent, MIT license)
  451. * @api private
  452. */
  453. function i (obj, showHidden, depth) {
  454. var seen = [];
  455. function stylize (str) {
  456. return str;
  457. };
  458. function format (value, recurseTimes) {
  459. // Provide a hook for user-specified inspect functions.
  460. // Check that value is an object with an inspect function on it
  461. if (value && typeof value.inspect === 'function' &&
  462. // Filter out the util module, it's inspect function is special
  463. value !== exports &&
  464. // Also filter out any prototype objects using the circular check.
  465. !(value.constructor && value.constructor.prototype === value)) {
  466. return value.inspect(recurseTimes);
  467. }
  468. // Primitive types cannot have properties
  469. switch (typeof value) {
  470. case 'undefined':
  471. return stylize('undefined', 'undefined');
  472. case 'string':
  473. var simple = '\'' + json.stringify(value).replace(/^"|"$/g, '')
  474. .replace(/'/g, "\\'")
  475. .replace(/\\"/g, '"') + '\'';
  476. return stylize(simple, 'string');
  477. case 'number':
  478. return stylize('' + value, 'number');
  479. case 'boolean':
  480. return stylize('' + value, 'boolean');
  481. }
  482. // For some reason typeof null is "object", so special case here.
  483. if (value === null) {
  484. return stylize('null', 'null');
  485. }
  486. // Look up the keys of the object.
  487. var visible_keys = keys(value);
  488. var $keys = showHidden ? Object.getOwnPropertyNames(value) : visible_keys;
  489. // Functions without properties can be shortcutted.
  490. if (typeof value === 'function' && $keys.length === 0) {
  491. if (isRegExp(value)) {
  492. return stylize('' + value, 'regexp');
  493. } else {
  494. var name = value.name ? ': ' + value.name : '';
  495. return stylize('[Function' + name + ']', 'special');
  496. }
  497. }
  498. // Dates without properties can be shortcutted
  499. if (isDate(value) && $keys.length === 0) {
  500. return stylize(value.toUTCString(), 'date');
  501. }
  502. var base, type, braces;
  503. // Determine the object type
  504. if (isArray(value)) {
  505. type = 'Array';
  506. braces = ['[', ']'];
  507. } else {
  508. type = 'Object';
  509. braces = ['{', '}'];
  510. }
  511. // Make functions say that they are functions
  512. if (typeof value === 'function') {
  513. var n = value.name ? ': ' + value.name : '';
  514. base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']';
  515. } else {
  516. base = '';
  517. }
  518. // Make dates with properties first say the date
  519. if (isDate(value)) {
  520. base = ' ' + value.toUTCString();
  521. }
  522. if ($keys.length === 0) {
  523. return braces[0] + base + braces[1];
  524. }
  525. if (recurseTimes < 0) {
  526. if (isRegExp(value)) {
  527. return stylize('' + value, 'regexp');
  528. } else {
  529. return stylize('[Object]', 'special');
  530. }
  531. }
  532. seen.push(value);
  533. var output = map($keys, function(key) {
  534. var name, str;
  535. if (value.__lookupGetter__) {
  536. if (value.__lookupGetter__(key)) {
  537. if (value.__lookupSetter__(key)) {
  538. str = stylize('[Getter/Setter]', 'special');
  539. } else {
  540. str = stylize('[Getter]', 'special');
  541. }
  542. } else {
  543. if (value.__lookupSetter__(key)) {
  544. str = stylize('[Setter]', 'special');
  545. }
  546. }
  547. }
  548. if (indexOf(visible_keys, key) < 0) {
  549. name = '[' + key + ']';
  550. }
  551. if (!str) {
  552. if (indexOf(seen, value[key]) < 0) {
  553. if (recurseTimes === null) {
  554. str = format(value[key]);
  555. } else {
  556. str = format(value[key], recurseTimes - 1);
  557. }
  558. if (str.indexOf('\n') > -1) {
  559. if (isArray(value)) {
  560. str = map(str.split('\n'), function(line) {
  561. return ' ' + line;
  562. }).join('\n').substr(2);
  563. } else {
  564. str = '\n' + map(str.split('\n'), function(line) {
  565. return ' ' + line;
  566. }).join('\n');
  567. }
  568. }
  569. } else {
  570. str = stylize('[Circular]', 'special');
  571. }
  572. }
  573. if (typeof name === 'undefined') {
  574. if (type === 'Array' && key.match(/^\d+$/)) {
  575. return str;
  576. }
  577. name = json.stringify('' + key);
  578. if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
  579. name = name.substr(1, name.length - 2);
  580. name = stylize(name, 'name');
  581. } else {
  582. name = name.replace(/'/g, "\\'")
  583. .replace(/\\"/g, '"')
  584. .replace(/(^"|"$)/g, "'");
  585. name = stylize(name, 'string');
  586. }
  587. }
  588. return name + ': ' + str;
  589. });
  590. seen.pop();
  591. var numLinesEst = 0;
  592. var length = reduce(output, function(prev, cur) {
  593. numLinesEst++;
  594. if (indexOf(cur, '\n') >= 0) numLinesEst++;
  595. return prev + cur.length + 1;
  596. }, 0);
  597. if (length > 50) {
  598. output = braces[0] +
  599. (base === '' ? '' : base + '\n ') +
  600. ' ' +
  601. output.join(',\n ') +
  602. ' ' +
  603. braces[1];
  604. } else {
  605. output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
  606. }
  607. return output;
  608. }
  609. return format(obj, (typeof depth === 'undefined' ? 2 : depth));
  610. };
  611. function isArray (ar) {
  612. return ar instanceof Array ||
  613. Object.prototype.toString.call(ar) == '[object Array]';
  614. };
  615. function isRegExp(re) {
  616. var s = '' + re;
  617. return re instanceof RegExp || // easy case
  618. // duck-type for context-switching evalcx case
  619. typeof(re) === 'function' &&
  620. re.constructor.name === 'RegExp' &&
  621. re.compile &&
  622. re.test &&
  623. re.exec &&
  624. s.match(/^\/.*\/[gim]{0,3}$/);
  625. };
  626. function isDate(d) {
  627. if (d instanceof Date) return true;
  628. return false;
  629. };
  630. function keys (obj) {
  631. if (Object.keys) {
  632. return Object.keys(obj);
  633. }
  634. var keys = [];
  635. for (var i in obj) {
  636. if (obj.hasOwnProperty(i)) {
  637. keys.push(i);
  638. }
  639. }
  640. return keys;
  641. }
  642. function map (arr, mapper, that) {
  643. if (Array.prototype.map) {
  644. return Array.prototype.map.call(arr, mapper, that);
  645. }
  646. var other= new Array(arr.length);
  647. for (var i= 0, n = arr.length; i<n; i++)
  648. if (i in arr)
  649. other[i] = mapper.call(that, arr[i], i, arr);
  650. return other;
  651. };
  652. function reduce (arr, fun) {
  653. if (Array.prototype.reduce) {
  654. return Array.prototype.reduce.apply(
  655. arr
  656. , Array.prototype.slice.call(arguments, 1)
  657. );
  658. }
  659. var len = +this.length;
  660. if (typeof fun !== "function")
  661. throw new TypeError();
  662. // no value to return if no initial value and an empty array
  663. if (len === 0 && arguments.length === 1)
  664. throw new TypeError();
  665. var i = 0;
  666. if (arguments.length >= 2) {
  667. var rv = arguments[1];
  668. } else {
  669. do {
  670. if (i in this) {
  671. rv = this[i++];
  672. break;
  673. }
  674. // if array contains no values, no initial value to return
  675. if (++i >= len)
  676. throw new TypeError();
  677. } while (true);
  678. }
  679. for (; i < len; i++) {
  680. if (i in this)
  681. rv = fun.call(null, rv, this[i], i, this);
  682. }
  683. return rv;
  684. };
  685. /**
  686. * Strict equality
  687. *
  688. * @api public
  689. */
  690. should.equal = function (a, b) {
  691. if (a !== b) {
  692. should.fail('expected ' + i(a) + ' to equal ' + i(b));
  693. }
  694. };
  695. /**
  696. * Fails with msg
  697. *
  698. * @param {String} msg
  699. * @api public
  700. */
  701. should.fail = function (msg) {
  702. throw new Error(msg);
  703. };
  704. /**
  705. * Asserts deep equality
  706. *
  707. * @see taken from node.js `assert` module (copyright Joyent, MIT license)
  708. * @api private
  709. */
  710. should.eql = function eql (actual, expected) {
  711. // 7.1. All identical values are equivalent, as determined by ===.
  712. if (actual === expected) {
  713. return true;
  714. } else if ('undefined' != typeof Buffer
  715. && Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
  716. if (actual.length != expected.length) return false;
  717. for (var i = 0; i < actual.length; i++) {
  718. if (actual[i] !== expected[i]) return false;
  719. }
  720. return true;
  721. // 7.2. If the expected value is a Date object, the actual value is
  722. // equivalent if it is also a Date object that refers to the same time.
  723. } else if (actual instanceof Date && expected instanceof Date) {
  724. return actual.getTime() === expected.getTime();
  725. // 7.3. Other pairs that do not both pass typeof value == "object",
  726. // equivalence is determined by ==.
  727. } else if (typeof actual != 'object' && typeof expected != 'object') {
  728. return actual == expected;
  729. // 7.4. For all other Object pairs, including Array objects, equivalence is
  730. // determined by having the same number of owned properties (as verified
  731. // with Object.prototype.hasOwnProperty.call), the same set of keys
  732. // (although not necessarily the same order), equivalent values for every
  733. // corresponding key, and an identical "prototype" property. Note: this
  734. // accounts for both named and indexed properties on Arrays.
  735. } else {
  736. return objEquiv(actual, expected);
  737. }
  738. }
  739. function isUndefinedOrNull (value) {
  740. return value === null || value === undefined;
  741. }
  742. function isArguments (object) {
  743. return Object.prototype.toString.call(object) == '[object Arguments]';
  744. }
  745. function objEquiv (a, b) {
  746. if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
  747. return false;
  748. // an identical "prototype" property.
  749. if (a.prototype !== b.prototype) return false;
  750. //~~~I've managed to break Object.keys through screwy arguments passing.
  751. // Converting to array solves the problem.
  752. if (isArguments(a)) {
  753. if (!isArguments(b)) {
  754. return false;
  755. }
  756. a = pSlice.call(a);
  757. b = pSlice.call(b);
  758. return should.eql(a, b);
  759. }
  760. try{
  761. var ka = keys(a),
  762. kb = keys(b),
  763. key, i;
  764. } catch (e) {//happens when one is a string literal and the other isn't
  765. return false;
  766. }
  767. // having the same number of owned properties (keys incorporates hasOwnProperty)
  768. if (ka.length != kb.length)
  769. return false;
  770. //the same set of keys (although not necessarily the same order),
  771. ka.sort();
  772. kb.sort();
  773. //~~~cheap key test
  774. for (i = ka.length - 1; i >= 0; i--) {
  775. if (ka[i] != kb[i])
  776. return false;
  777. }
  778. //equivalent values for every corresponding key, and
  779. //~~~possibly expensive deep test
  780. for (i = ka.length - 1; i >= 0; i--) {
  781. key = ka[i];
  782. if (!should.eql(a[key], b[key]))
  783. return false;
  784. }
  785. return true;
  786. }
  787. var json = (function () {
  788. "use strict";
  789. if ('object' == typeof JSON && JSON.parse && JSON.stringify) {
  790. return {
  791. parse: nativeJSON.parse
  792. , stringify: nativeJSON.stringify
  793. }
  794. }
  795. var JSON = {};
  796. function f(n) {
  797. // Format integers to have at least two digits.
  798. return n < 10 ? '0' + n : n;
  799. }
  800. function date(d, key) {
  801. return isFinite(d.valueOf()) ?
  802. d.getUTCFullYear() + '-' +
  803. f(d.getUTCMonth() + 1) + '-' +
  804. f(d.getUTCDate()) + 'T' +
  805. f(d.getUTCHours()) + ':' +
  806. f(d.getUTCMinutes()) + ':' +
  807. f(d.getUTCSeconds()) + 'Z' : null;
  808. };
  809. var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  810. escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  811. gap,
  812. indent,
  813. meta = { // table of character substitutions
  814. '\b': '\\b',
  815. '\t': '\\t',
  816. '\n': '\\n',
  817. '\f': '\\f',
  818. '\r': '\\r',
  819. '"' : '\\"',
  820. '\\': '\\\\'
  821. },
  822. rep;
  823. function quote(string) {
  824. // If the string contains no control characters, no quote characters, and no
  825. // backslash characters, then we can safely slap some quotes around it.
  826. // Otherwise we must also replace the offending characters with safe escape
  827. // sequences.
  828. escapable.lastIndex = 0;
  829. return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
  830. var c = meta[a];
  831. return typeof c === 'string' ? c :
  832. '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  833. }) + '"' : '"' + string + '"';
  834. }
  835. function str(key, holder) {
  836. // Produce a string from holder[key].
  837. var i, // The loop counter.
  838. k, // The member key.
  839. v, // The member value.
  840. length,
  841. mind = gap,
  842. partial,
  843. value = holder[key];
  844. // If the value has a toJSON method, call it to obtain a replacement value.
  845. if (value instanceof Date) {
  846. value = date(key);
  847. }
  848. // If we were called with a replacer function, then call the replacer to
  849. // obtain a replacement value.
  850. if (typeof rep === 'function') {
  851. value = rep.call(holder, key, value);
  852. }
  853. // What happens next depends on the value's type.
  854. switch (typeof value) {
  855. case 'string':
  856. return quote(value);
  857. case 'number':
  858. // JSON numbers must be finite. Encode non-finite numbers as null.
  859. return isFinite(value) ? String(value) : 'null';
  860. case 'boolean':
  861. case 'null':
  862. // If the value is a boolean or null, convert it to a string. Note:
  863. // typeof null does not produce 'null'. The case is included here in
  864. // the remote chance that this gets fixed someday.
  865. return String(value);
  866. // If the type is 'object', we might be dealing with an object or an array or
  867. // null.
  868. case 'object':
  869. // Due to a specification blunder in ECMAScript, typeof null is 'object',
  870. // so watch out for that case.
  871. if (!value) {
  872. return 'null';
  873. }
  874. // Make an array to hold the partial results of stringifying this object value.
  875. gap += indent;
  876. partial = [];
  877. // Is the value an array?
  878. if (Object.prototype.toString.apply(value) === '[object Array]') {
  879. // The value is an array. Stringify every element. Use null as a placeholder
  880. // for non-JSON values.
  881. length = value.length;
  882. for (i = 0; i < length; i += 1) {
  883. partial[i] = str(i, value) || 'null';
  884. }
  885. // Join all of the elements together, separated with commas, and wrap them in
  886. // brackets.
  887. v = partial.length === 0 ? '[]' : gap ?
  888. '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
  889. '[' + partial.join(',') + ']';
  890. gap = mind;
  891. return v;
  892. }
  893. // If the replacer is an array, use it to select the members to be stringified.
  894. if (rep && typeof rep === 'object') {
  895. length = rep.length;
  896. for (i = 0; i < length; i += 1) {
  897. if (typeof rep[i] === 'string') {
  898. k = rep[i];
  899. v = str(k, value);
  900. if (v) {
  901. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  902. }
  903. }
  904. }
  905. } else {
  906. // Otherwise, iterate through all of the keys in the object.
  907. for (k in value) {
  908. if (Object.prototype.hasOwnProperty.call(value, k)) {
  909. v = str(k, value);
  910. if (v) {
  911. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  912. }
  913. }
  914. }
  915. }
  916. // Join all of the member texts together, separated with commas,
  917. // and wrap them in braces.
  918. v = partial.length === 0 ? '{}' : gap ?
  919. '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
  920. '{' + partial.join(',') + '}';
  921. gap = mind;
  922. return v;
  923. }
  924. }
  925. // If the JSON object does not yet have a stringify method, give it one.
  926. JSON.stringify = function (value, replacer, space) {
  927. // The stringify method takes a value and an optional replacer, and an optional
  928. // space parameter, and returns a JSON text. The replacer can be a function
  929. // that can replace values, or an array of strings that will select the keys.
  930. // A default replacer method can be provided. Use of the space parameter can
  931. // produce text that is more easily readable.
  932. var i;
  933. gap = '';
  934. indent = '';
  935. // If the space parameter is a number, make an indent string containing that
  936. // many spaces.
  937. if (typeof space === 'number') {
  938. for (i = 0; i < space; i += 1) {
  939. indent += ' ';
  940. }
  941. // If the space parameter is a string, it will be used as the indent string.
  942. } else if (typeof space === 'string') {
  943. indent = space;
  944. }
  945. // If there is a replacer, it must be a function or an array.
  946. // Otherwise, throw an error.
  947. rep = replacer;
  948. if (replacer && typeof replacer !== 'function' &&
  949. (typeof replacer !== 'object' ||
  950. typeof replacer.length !== 'number')) {
  951. throw new Error('JSON.stringify');
  952. }
  953. // Make a fake root object containing our value under the key of ''.
  954. // Return the result of stringifying the value.
  955. return str('', {'': value});
  956. };
  957. // If the JSON object does not yet have a parse method, give it one.
  958. JSON.parse = function (text, reviver) {
  959. // The parse method takes a text and an optional reviver function, and returns
  960. // a JavaScript value if the text is a valid JSON text.
  961. var j;
  962. function walk(holder, key) {
  963. // The walk method is used to recursively walk the resulting structure so
  964. // that modifications can be made.
  965. var k, v, value = holder[key];
  966. if (value && typeof value === 'object') {
  967. for (k in value) {
  968. if (Object.prototype.hasOwnProperty.call(value, k)) {
  969. v = walk(value, k);
  970. if (v !== undefined) {
  971. value[k] = v;
  972. } else {
  973. delete value[k];
  974. }
  975. }
  976. }
  977. }
  978. return reviver.call(holder, key, value);
  979. }
  980. // Parsing happens in four stages. In the first stage, we replace certain
  981. // Unicode characters with escape sequences. JavaScript handles many characters
  982. // incorrectly, either silently deleting them, or treating them as line endings.
  983. text = String(text);
  984. cx.lastIndex = 0;
  985. if (cx.test(text)) {
  986. text = text.replace(cx, function (a) {
  987. return '\\u' +
  988. ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  989. });
  990. }
  991. // In the second stage, we run the text against regular expressions that look
  992. // for non-JSON patterns. We are especially concerned with '()' and 'new'
  993. // because they can cause invocation, and '=' because it can cause mutation.
  994. // But just to be safe, we want to reject all unexpected forms.
  995. // We split the second stage into 4 regexp operations in order to work around
  996. // crippling inefficiencies in IE's and Safari's regexp engines. First we
  997. // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
  998. // replace all simple value tokens with ']' characters. Third, we delete all
  999. // open brackets that follow a colon or comma or that begin the text. Finally,
  1000. // we look to see that the remaining characters are only whitespace or ']' or
  1001. // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
  1002. if (/^[\],:{}\s]*$/
  1003. .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
  1004. .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
  1005. .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
  1006. // In the third stage we use the eval function to compile the text into a
  1007. // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
  1008. // in JavaScript: it can begin a block or an object literal. We wrap the text
  1009. // in parens to eliminate the ambiguity.
  1010. j = eval('(' + text + ')');
  1011. // In the optional fourth stage, we recursively walk the new structure, passing
  1012. // each name/value pair to a reviver function for possible transformation.
  1013. return typeof reviver === 'function' ?
  1014. walk({'': j}, '') : j;
  1015. }
  1016. // If the text is not JSON parseable, then a SyntaxError is thrown.
  1017. throw new SyntaxError('JSON.parse');
  1018. };
  1019. return JSON;
  1020. })();
  1021. })('undefined' != typeof exports ? exports : (should = {}));