rack-cors 2.0.0 → 2.0.2

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