oojspec 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }());