oojspec 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,782 @@
1
+ /*jslint eqeqeq: false, onevar: false, plusplus: false*/
2
+ /*global buster, require, module*/
3
+ (function () {
4
+ var isCommonJS = typeof require == "function" && typeof module == "object";
5
+ if (isCommonJS) buster = require("buster-core");
6
+ var toString = Object.prototype.toString;
7
+ var slice = Array.prototype.slice;
8
+ var assert, refute, ba = buster.assertions = buster.eventEmitter.create();
9
+
10
+ if (isCommonJS) {
11
+ module.exports = buster.assertions;
12
+ }
13
+
14
+ function countAssertion() {
15
+ if (typeof ba.count != "number") {
16
+ ba.count = 0;
17
+ }
18
+
19
+ ba.count += 1;
20
+ }
21
+
22
+ ba.count = countAssertion;
23
+
24
+ function assertEnoughArguments(name, args, num) {
25
+ if (args.length < num) {
26
+ ba.fail("[" + name + "] Expected to receive at least " +
27
+ num + " argument" + (num > 1 ? "s" : ""));
28
+ return false;
29
+ }
30
+
31
+ return true;
32
+ }
33
+
34
+ function defineAssertion(type, name, func, fl, messageValues) {
35
+ ba[type][name] = function () {
36
+ var fullName = type + "." + name;
37
+ countAssertion();
38
+ if (!assertEnoughArguments(fullName, arguments, fl || func.length)) return;
39
+
40
+ var failed = false;
41
+
42
+ var ctx = {
43
+ fail: function () {
44
+ failed = true;
45
+ var failArgs = [type, name].concat(slice.call(arguments));
46
+ fail.apply(this, failArgs);
47
+ return true;
48
+ }
49
+ };
50
+
51
+ var args = slice.call(arguments, 0);
52
+
53
+ if (typeof messageValues == "function") {
54
+ args = messageValues.apply(this, args);
55
+ }
56
+
57
+ if (!func.apply(ctx, arguments)) {
58
+ return fail.apply(ctx, [type, name, "message"].concat(args));
59
+ }
60
+
61
+ if (!failed) {
62
+ ba.emit.apply(ba, ["pass", fullName].concat(args));
63
+ }
64
+ };
65
+ }
66
+
67
+ ba.add = function (name, options) {
68
+ var refuteArgs;
69
+
70
+ if (options.refute) {
71
+ refuteArgs = options.refute.length;
72
+ } else {
73
+ refuteArgs = options.assert.length;
74
+ options.refute = function () {
75
+ return !options.assert.apply(this, arguments);
76
+ };
77
+ }
78
+
79
+ var values = options && options.values; // TODO: Remove
80
+ defineAssertion("assert", name, options.assert, options.assert.length, values);
81
+ defineAssertion("refute", name, options.refute, refuteArgs, values);
82
+
83
+ assert[name].message = options.assertMessage;
84
+ refute[name].message = options.refuteMessage;
85
+
86
+ if (options.expectation) {
87
+ if (ba.expect && ba.expect.wrapAssertion) {
88
+ ba.expect.wrapAssertion(name, options.expectation);
89
+ } else {
90
+ assert[name].expectationName = options.expectation;
91
+ refute[name].expectationName = options.expectation;
92
+ }
93
+ }
94
+ };
95
+
96
+ function interpolate(string, property, value) {
97
+ return string.replace(new RegExp("\\$\\{" + property + "\\}", "g"), value);
98
+ }
99
+
100
+ function interpolatePosArg(message, values) {
101
+ var value;
102
+ values = values || [];
103
+
104
+ for (var i = 0, l = values.length; i < l; i++) {
105
+ message = interpolate(message, i, ba.format(values[i]));
106
+ }
107
+
108
+ return message;
109
+ }
110
+
111
+ function interpolateProperties(msg, properties) {
112
+ for (var prop in properties) {
113
+ msg = interpolate(msg, prop, ba.format(properties[prop]));
114
+ }
115
+
116
+ return msg || "";
117
+ }
118
+
119
+ function fail(type, assertion, msg) {
120
+ delete this.fail;
121
+ var message = interpolateProperties(
122
+ interpolatePosArg(ba[type][assertion][msg] || msg,
123
+ [].slice.call(arguments, 3)), this);
124
+ ba.fail("[" + type + "." + assertion + "] " + message);
125
+ }
126
+
127
+ function isDate(value) {
128
+ // Duck typed dates, allows objects to take on the role of dates
129
+ // without actually being dates
130
+ return typeof value.getTime == "function" &&
131
+ value.getTime() == value.valueOf();
132
+ }
133
+
134
+ ba.isDate = isDate;
135
+
136
+ // Fixes NaN === NaN (should be true) and
137
+ // -0 === +0 (should be false)
138
+ // http://wiki.ecmascript.org/doku.php?id=harmony:egal
139
+ function egal(x, y) {
140
+ if (x === y) {
141
+ // 0 === -0, but they are not identical
142
+ return x !== 0 || 1 / x === 1 / y;
143
+ }
144
+
145
+ // NaN !== NaN, but they are identical.
146
+ // NaNs are the only non-reflexive value, i.e., if x !== x,
147
+ // then x is a NaN.
148
+ // isNaN is broken: it converts its argument to number, so
149
+ // isNaN("foo") => true
150
+ return x !== x && y !== y;
151
+ }
152
+
153
+ function areEqual(expected, actual) {
154
+ if (egal(expected, actual)) {
155
+ return true;
156
+ }
157
+
158
+ // Elements are only equal if expected === actual
159
+ if (buster.isElement(expected) || buster.isElement(actual)) {
160
+ return false;
161
+ }
162
+
163
+ // null and undefined only pass for null === null and
164
+ // undefined === undefined
165
+ /*jsl: ignore*/
166
+ if (expected == null || actual == null) {
167
+ return actual === expected;
168
+ }
169
+ /*jsl: end*/
170
+
171
+ if (isDate(expected) || isDate(actual)) {
172
+ return isDate(expected) && isDate(actual) &&
173
+ expected.getTime() == actual.getTime();
174
+ }
175
+
176
+ var useCoercingEquality = typeof expected != "object" || typeof actual != "object";
177
+
178
+ if (expected instanceof RegExp && actual instanceof RegExp) {
179
+ if (expected.toString() != actual.toString()) {
180
+ return false;
181
+ }
182
+
183
+ useCoercingEquality = false;
184
+ }
185
+
186
+ // Arrays can only be equal to arrays
187
+ var expectedStr = toString.call(expected);
188
+ var actualStr = toString.call(actual);
189
+
190
+ // Coerce and compare when primitives are involved
191
+ if (useCoercingEquality) {
192
+ return expectedStr != "[object Array]" && actualStr != "[object Array]" &&
193
+ expected == actual;
194
+ }
195
+
196
+ var expectedKeys = ba.keys(expected);
197
+ var actualKeys = ba.keys(actual);
198
+
199
+ if (isArguments(expected) || isArguments(actual)) {
200
+ if (expected.length != actual.length) {
201
+ return false;
202
+ }
203
+ } else {
204
+ if (typeof expected != typeof actual || expectedStr != actualStr ||
205
+ expectedKeys.length != actualKeys.length) {
206
+ return false;
207
+ }
208
+ }
209
+
210
+ var key;
211
+
212
+ for (var i = 0, l = expectedKeys.length; i < l; i++) {
213
+ key = expectedKeys[i];
214
+
215
+ if (!Object.prototype.hasOwnProperty.call(actual, key) ||
216
+ !areEqual(expected[key], actual[key])) {
217
+ return false;
218
+ }
219
+ }
220
+
221
+ return true;
222
+ }
223
+
224
+ ba.deepEqual = areEqual;
225
+
226
+ assert = ba.assert = function assert(actual, message) {
227
+ countAssertion();
228
+ if (!assertEnoughArguments("assert", arguments, 1)) return;
229
+
230
+ if (!actual) {
231
+ var val = ba.format(actual);
232
+ ba.fail(message || "[assert] Expected " + val + " to be truthy");
233
+ } else {
234
+ ba.emit("pass", "assert", message || "", actual);
235
+ }
236
+ };
237
+
238
+ assert.toString = function () {
239
+ return "buster.assert";
240
+ };
241
+
242
+ refute = ba.refute = function (actual, message) {
243
+ countAssertion();
244
+ if (!assertEnoughArguments("refute", arguments, 1)) return;
245
+
246
+ if (actual) {
247
+ var val = ba.format(actual);
248
+ ba.fail(message || "[refute] Expected " + val + " to be falsy");
249
+ } else {
250
+ ba.emit("pass", "refute", message || "", actual);
251
+ }
252
+ };
253
+
254
+ assert.message = "[assert] Expected ${0} to be truthy";
255
+ ba.count = 0;
256
+
257
+ ba.fail = function (message) {
258
+ var exception = new Error(message);
259
+ exception.name = "AssertionError";
260
+
261
+ try {
262
+ throw exception;
263
+ } catch (e) {
264
+ ba.emit("failure", e);
265
+ }
266
+
267
+ if (typeof ba.throwOnFailure != "boolean" || ba.throwOnFailure) {
268
+ throw exception;
269
+ }
270
+ };
271
+
272
+ ba.format = function (object) {
273
+ return "" + object;
274
+ };
275
+
276
+ function msg(message) {
277
+ if (!message) { return ""; }
278
+ return message + (/[.:!?]$/.test(message) ? " " : ": ");
279
+ }
280
+
281
+ function actualAndExpectedMessageValues(actual, expected, message) {
282
+ return [actual, expected, msg(message)]
283
+ }
284
+
285
+ function actualMessageValues(actual) {
286
+ return [actual, msg(arguments[1])];
287
+ }
288
+
289
+ function actualAndTypeOfMessageValues(actual) {
290
+ return [actual, typeof actual, msg(arguments[1])];
291
+ }
292
+
293
+ ba.add("same", {
294
+ assert: function (actual, expected) {
295
+ return egal(actual, expected);
296
+ },
297
+ refute: function (actual, expected) {
298
+ return !egal(actual, expected);
299
+ },
300
+ assertMessage: "${2}${0} expected to be the same object as ${1}",
301
+ refuteMessage: "${2}${0} expected not to be the same object as ${1}",
302
+ expectation: "toBe",
303
+ values: actualAndExpectedMessageValues
304
+ });
305
+
306
+ function multiLineStringDiff(actual, expected, message) {
307
+ if (actual == expected) return true;
308
+
309
+ var message = interpolatePosArg(assert.equals.multiLineStringHeading, [message]),
310
+ actualLines = actual.split("\n"),
311
+ expectedLines = expected.split("\n"),
312
+ lineCount = Math.max(expectedLines.length, actualLines.length),
313
+ lines = [];
314
+
315
+ for (var i = 0; i < lineCount; ++i) {
316
+ if (expectedLines[i] != actualLines[i]) {
317
+ lines.push("line " + (i + 1) + ": " + (expectedLines[i] || "") +
318
+ "\nwas: " + (actualLines[i] || ""));
319
+ }
320
+ }
321
+
322
+ ba.fail("[assert.equals] " + message + lines.join("\n\n"));
323
+ return false;
324
+ }
325
+
326
+ ba.add("equals", {
327
+ assert: function (actual, expected) {
328
+ if (typeof actual == "string" && typeof expected == "string" &&
329
+ (actual.indexOf("\n") >= 0 || expected.indexOf("\n") >= 0)) {
330
+ var message = msg(arguments[2]);
331
+ return multiLineStringDiff.call(this, actual, expected, message);
332
+ }
333
+
334
+ return areEqual(actual, expected);
335
+ },
336
+
337
+ refute: function (actual, expected) {
338
+ return !areEqual(actual, expected);
339
+ },
340
+
341
+ assertMessage: "${2}${0} expected to be equal to ${1}",
342
+ refuteMessage: "${2}${0} expected not to be equal to ${1}",
343
+ expectation: "toEqual",
344
+ values: actualAndExpectedMessageValues
345
+ });
346
+
347
+ assert.equals.multiLineStringHeading = "${0}Expected multi-line strings to be equal:\n";
348
+
349
+ ba.add("greater", {
350
+ assert: function (actual, expected) {
351
+ return actual > expected;
352
+ },
353
+
354
+ assertMessage: "${2}Expected ${0} to be greater than ${1}",
355
+ refuteMessage: "${2}Expected ${0} to be less than or equal to ${1}",
356
+ expectation: "toBeGreaterThan",
357
+ values: actualAndExpectedMessageValues
358
+ });
359
+
360
+ ba.add("less", {
361
+ assert: function (actual, expected) {
362
+ return actual < expected;
363
+ },
364
+
365
+ assertMessage: "${2}Expected ${0} to be less than ${1}",
366
+ refuteMessage: "${2}Expected ${0} to be greater than or equal to ${1}",
367
+ expectation: "toBeLessThan",
368
+ values: actualAndExpectedMessageValues
369
+ });
370
+
371
+ ba.add("defined", {
372
+ assert: function (actual) {
373
+ return typeof actual != "undefined";
374
+ },
375
+ assertMessage: "${2}Expected to be defined",
376
+ refuteMessage: "${2}Expected ${0} (${1}) not to be defined",
377
+ expectation: "toBeDefined",
378
+ values: actualAndTypeOfMessageValues
379
+ });
380
+
381
+ ba.add("isNull", {
382
+ assert: function (actual) {
383
+ return actual === null;
384
+ },
385
+ assertMessage: "${1}Expected ${0} to be null",
386
+ refuteMessage: "${1}Expected not to be null",
387
+ expectation: "toBeNull",
388
+ values: actualMessageValues
389
+ });
390
+
391
+ function match(object, matcher) {
392
+ if (matcher && typeof matcher.test == "function") {
393
+ return matcher.test(object);
394
+ }
395
+
396
+ if (typeof matcher == "function") {
397
+ return matcher(object) === true;
398
+ }
399
+
400
+ if (typeof matcher == "string") {
401
+ matcher = matcher.toLowerCase();
402
+ return !!object && ("" + object).toLowerCase().indexOf(matcher) >= 0;
403
+ }
404
+
405
+ if (typeof matcher == "number") {
406
+ return matcher == object;
407
+ }
408
+
409
+ if (typeof matcher == "boolean") {
410
+ return matcher === object;
411
+ }
412
+
413
+ if (matcher && typeof matcher == "object") {
414
+ for (var prop in matcher) {
415
+ if (!match(object[prop], matcher[prop])) {
416
+ return false;
417
+ }
418
+ }
419
+
420
+ return true;
421
+ }
422
+
423
+ throw new Error("Matcher (" + ba.format(matcher) + ") was not a " +
424
+ "string, a number, a function, a boolean or an object");
425
+ }
426
+
427
+ ba.match = match;
428
+
429
+ ba.add("match", {
430
+ assert: function (actual, matcher) {
431
+ var passed;
432
+
433
+ try {
434
+ passed = match(actual, matcher);
435
+ } catch (e) {
436
+ return this.fail("exceptionMessage", e.message, msg(arguments[2]));
437
+ }
438
+
439
+ return passed;
440
+ },
441
+
442
+ refute: function (actual, matcher) {
443
+ var passed;
444
+
445
+ try {
446
+ passed = match(actual, matcher);
447
+ } catch (e) {
448
+ return this.fail("exceptionMessage", e.message);
449
+ }
450
+
451
+ return !passed;
452
+ },
453
+
454
+ assertMessage: "${2}${0} expected to match ${1}",
455
+ refuteMessage: "${2}${0} expected not to match ${1}",
456
+ expectation: "toMatch",
457
+ values: actualAndExpectedMessageValues
458
+ });
459
+
460
+ assert.match.exceptionMessage = "${1}${0}";
461
+ refute.match.exceptionMessage = "${1}${0}";
462
+
463
+ ba.add("isObject", {
464
+ assert: function (actual) {
465
+ return typeof actual == "object" && !!actual;
466
+ },
467
+ assertMessage: "${2}${0} (${1}) expected to be object and not null",
468
+ refuteMessage: "${2}${0} expected to be null or not an object",
469
+ expectation: "toBeObject",
470
+ values: actualAndTypeOfMessageValues
471
+ });
472
+
473
+ ba.add("isFunction", {
474
+ assert: function (actual) {
475
+ return typeof actual == "function";
476
+ },
477
+ assertMessage: "${2}${0} (${1}) expected to be function",
478
+ refuteMessage: "${2}${0} expected not to be function",
479
+ expectation: "toBeFunction",
480
+ values: function (actual) {
481
+ return [("" + actual).replace("\n", ""), typeof actual, msg(arguments[1])];
482
+ }
483
+ });
484
+
485
+ ba.add("isTrue", {
486
+ assert: function (actual) {
487
+ return actual === true;
488
+ },
489
+ assertMessage: "${1}Expected ${0} to be true",
490
+ refuteMessage: "${1}Expected ${0} to not be true",
491
+ expectation: "toBeTrue",
492
+ values: actualMessageValues
493
+ });
494
+
495
+ ba.add("isFalse", {
496
+ assert: function (actual) {
497
+ return actual === false;
498
+ },
499
+ assertMessage: "${1}Expected ${0} to be false",
500
+ refuteMessage: "${1}Expected ${0} to not be false",
501
+ expectation: "toBeFalse",
502
+ values: actualMessageValues
503
+ });
504
+
505
+ ba.add("isString", {
506
+ assert: function (actual) {
507
+ return typeof actual == "string";
508
+ },
509
+ assertMessage: "${2}Expected ${0} (${1}) to be string",
510
+ refuteMessage: "${2}Expected ${0} not to be string",
511
+ expectation: "toBeString",
512
+ values: actualAndTypeOfMessageValues
513
+ });
514
+
515
+ ba.add("isBoolean", {
516
+ assert: function (actual) {
517
+ return typeof actual == "boolean";
518
+ },
519
+ assertMessage: "${2}Expected ${0} (${1}) to be boolean",
520
+ refuteMessage: "${2}Expected ${0} not to be boolean",
521
+ expectation: "toBeBoolean",
522
+ values: actualAndTypeOfMessageValues
523
+ });
524
+
525
+ ba.add("isNumber", {
526
+ assert: function (actual) {
527
+ return typeof actual == "number" && !isNaN(actual);
528
+ },
529
+ assertMessage: "${2}Expected ${0} (${1}) to be a non-NaN number",
530
+ refuteMessage: "${2}Expected ${0} to be NaN or another non-number value",
531
+ expectation: "toBeNumber",
532
+ values: actualAndTypeOfMessageValues
533
+ });
534
+
535
+ ba.add("isNaN", {
536
+ assert: function (actual) {
537
+ return typeof actual == "number" && isNaN(actual);
538
+ },
539
+ assertMessage: "${2}Expected ${0} to be NaN",
540
+ refuteMessage: "${2}Expected not to be NaN",
541
+ expectation: "toBeNaN",
542
+ values: actualAndTypeOfMessageValues
543
+ });
544
+
545
+ ba.add("isArray", {
546
+ assert: function (actual) {
547
+ return toString.call(actual) == "[object Array]";
548
+ },
549
+ assertMessage: "${2}Expected ${0} to be array",
550
+ refuteMessage: "${2}Expected ${0} not to be array",
551
+ expectation: "toBeArray",
552
+ values: actualAndTypeOfMessageValues
553
+ });
554
+
555
+ function isArrayLike(object) {
556
+ return toString.call(object) == "[object Array]" ||
557
+ (!!object && typeof object.length == "number" &&
558
+ typeof object.splice == "function") ||
559
+ ba.isArguments(object);
560
+ }
561
+
562
+ ba.isArrayLike = isArrayLike;
563
+
564
+ ba.add("isArrayLike", {
565
+ assert: function (actual) {
566
+ return isArrayLike(actual);
567
+ },
568
+ assertMessage: "${2}Expected ${0} to be array like",
569
+ refuteMessage: "${2}Expected ${0} not to be array like",
570
+ expectation: "toBeArrayLike",
571
+ values: actualAndTypeOfMessageValues
572
+ });
573
+
574
+ function captureException(callback) {
575
+ try {
576
+ callback();
577
+ } catch (e) {
578
+ return e;
579
+ }
580
+
581
+ return null;
582
+ }
583
+
584
+ ba.captureException = captureException;
585
+
586
+ assert.exception = function (callback, exception, message) {
587
+ countAssertion();
588
+ if (!assertEnoughArguments("assert.exception", arguments, 1)) return
589
+
590
+ if (!callback) {
591
+ return;
592
+ }
593
+
594
+ var err = captureException(callback);
595
+ message = msg(message);
596
+
597
+ if (!err) {
598
+ if (exception) {
599
+ return fail.call({}, "assert", "exception", "typeNoExceptionMessage",
600
+ message, exception);
601
+ } else {
602
+ return fail.call({}, "assert", "exception", "message",
603
+ message, exception);
604
+ }
605
+ }
606
+
607
+ if (exception && err.name != exception) {
608
+ if (typeof window != "undefined" && typeof console != "undefined") {
609
+ console.log(err);
610
+ }
611
+
612
+ return fail.call({}, "assert", "exception", "typeFailMessage",
613
+ message, exception, err.name, err.message);
614
+ }
615
+
616
+ ba.emit("pass", "assert.exception", message, callback, exception);
617
+ };
618
+
619
+ assert.exception.typeNoExceptionMessage = "${0}Expected ${1} but no exception was thrown";
620
+ assert.exception.message = "${0}Expected exception";
621
+ assert.exception.typeFailMessage = "${0}Expected ${1} but threw ${2} (${3})";
622
+ assert.exception.expectationName = "toThrow";
623
+
624
+ refute.exception = function (callback) {
625
+ countAssertion();
626
+ if (!assertEnoughArguments("refute.exception", arguments, 1)) return;
627
+
628
+ var err = captureException(callback);
629
+
630
+ if (err) {
631
+ fail.call({}, "refute", "exception", "message",
632
+ msg(arguments[1]), err.name, err.message, callback);
633
+ } else {
634
+ ba.emit("pass", "refute.exception", callback);
635
+ }
636
+ };
637
+
638
+ refute.exception.message = "${0}Expected not to throw but threw ${1} (${2})";
639
+ refute.exception.expectationName = "toThrow";
640
+
641
+ ba.add("near", {
642
+ assert: function (actual, expected, delta) {
643
+ return Math.abs(actual - expected) <= delta;
644
+ },
645
+ assertMessage: "${3}Expected ${0} to be equal to ${1} +/- ${2}",
646
+ refuteMessage: "${3}Expected ${0} not to be equal to ${1} +/- ${2}",
647
+ expectation: "toBeNear",
648
+ values: function (actual, expected, delta, message) {
649
+ return [actual, expected, delta, msg(message)];
650
+ }
651
+ });
652
+
653
+ ba.add("hasPrototype", {
654
+ assert: function (actual, protoObj) {
655
+ return protoObj.isPrototypeOf(actual);
656
+ },
657
+ assertMessage: "${2}Expected ${0} to have ${1} on its prototype chain",
658
+ refuteMessage: "${2}Expected ${0} not to have ${1} on its prototype chain",
659
+ expectation: "toHavePrototype",
660
+ values: actualAndExpectedMessageValues
661
+ });
662
+
663
+ ba.add("contains", {
664
+ assert: function (haystack, needle) {
665
+ for (var i = 0; i < haystack.length; i++) {
666
+ if (haystack[i] === needle) {
667
+ return true;
668
+ }
669
+ }
670
+ return false;
671
+ },
672
+ assertMessage: "${2}Expected [${0}] to contain ${1}",
673
+ refuteMessage: "${2}Expected [${0}] not to contain ${1}",
674
+ expectation: "toContain",
675
+ values: actualAndExpectedMessageValues
676
+ });
677
+
678
+ ba.add("tagName", {
679
+ assert: function (element, tagName) {
680
+ if (!element.tagName) {
681
+ return this.fail("noTagNameMessage", tagName, element, msg(arguments[2]));
682
+ }
683
+
684
+ return tagName.toLowerCase &&
685
+ tagName.toLowerCase() == element.tagName.toLowerCase();
686
+ },
687
+ assertMessage: "${2}Expected tagName to be ${0} but was ${1}",
688
+ refuteMessage: "${2}Expected tagName not to be ${0}",
689
+ expectation: "toHaveTagName",
690
+ values: function (element, tagName, message) {
691
+ return [tagName, element.tagName, msg(message)];
692
+ }
693
+ });
694
+
695
+ assert.tagName.noTagNameMessage = "${2}Expected ${1} to have tagName property";
696
+ refute.tagName.noTagNameMessage = "${2}Expected ${1} to have tagName property";
697
+
698
+ function indexOf(arr, item) {
699
+ for (var i = 0, l = arr.length; i < l; i++) {
700
+ if (arr[i] == item) {
701
+ return i;
702
+ }
703
+ }
704
+
705
+ return -1;
706
+ }
707
+
708
+ ba.add("className", {
709
+ assert: function (element, className) {
710
+ if (typeof element.className == "undefined") {
711
+ return this.fail("noClassNameMessage", className, element, msg(arguments[2]));
712
+ }
713
+
714
+ var expected = typeof className == "string" ? className.split(" ") : className;
715
+ var actual = element.className.split(" ");
716
+
717
+ for (var i = 0, l = expected.length; i < l; i++) {
718
+ if (indexOf(actual, expected[i]) < 0) {
719
+ return false;
720
+ }
721
+ }
722
+
723
+ return true;
724
+ },
725
+ assertMessage: "${2}Expected object's className to include ${0} but was ${1}",
726
+ refuteMessage: "${2}Expected object's className not to include ${0}",
727
+ expectation: "toHaveClassName",
728
+ values: function (element, className, message) {
729
+ return [className, element.className, msg(message)];
730
+ }
731
+ });
732
+
733
+ assert.className.noClassNameMessage = "${2}Expected object to have className property";
734
+ refute.className.noClassNameMessage = "${2}Expected object to have className property";
735
+
736
+ if (typeof module != "undefined") {
737
+ ba.expect = function () {
738
+ ba.expect = require("./buster-assertions/expect");
739
+ return ba.expect.apply(exports, arguments);
740
+ };
741
+ }
742
+
743
+ function isArguments(obj) {
744
+ if (typeof obj != "object" || typeof obj.length != "number" ||
745
+ toString.call(obj) == "[object Array]") {
746
+ return false;
747
+ }
748
+
749
+ if (typeof obj.callee == "function") {
750
+ return true;
751
+ }
752
+
753
+ try {
754
+ obj[obj.length] = 6;
755
+ delete obj[obj.length];
756
+ } catch (e) {
757
+ return true;
758
+ }
759
+
760
+ return false;
761
+ }
762
+
763
+ ba.isArguments = isArguments;
764
+
765
+ if (Object.keys) {
766
+ ba.keys = function (obj) {
767
+ return Object.keys(obj)
768
+ };
769
+ } else {
770
+ ba.keys = function (object) {
771
+ var keys = [];
772
+
773
+ for (var prop in object) {
774
+ if (Object.prototype.hasOwnProperty.call(object, prop)) {
775
+ keys.push(prop);
776
+ }
777
+ }
778
+
779
+ return keys;
780
+ }
781
+ }
782
+ }());