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.
- data/MIT-LICENSE +20 -0
- data/README.md +174 -0
- data/Rakefile +27 -0
- data/app/views/oojspec/runner.html.erb +25 -0
- data/lib/assets/javascripts/oojspec.js.coffee +256 -0
- data/lib/assets/stylesheets/oojspec.css.erb +5 -0
- data/lib/oojspec/engine.rb +15 -0
- data/lib/oojspec/version.rb +3 -0
- data/lib/oojspec.rb +5 -0
- data/lib/tasks/oojspec_tasks.rake +4 -0
- data/vendor/assets/images/buster/logo.png +0 -0
- data/vendor/assets/javascripts/buster/all.js.coffee +3 -0
- data/vendor/assets/javascripts/buster/buster-assertions.js +782 -0
- data/vendor/assets/javascripts/buster/buster-core.js +222 -0
- data/vendor/assets/javascripts/buster/buster-event-emitter.js +152 -0
- data/vendor/assets/javascripts/buster/buster-format.js +199 -0
- data/vendor/assets/javascripts/buster/expect.js +63 -0
- data/vendor/assets/javascripts/buster/html.js +324 -0
- data/vendor/assets/javascripts/buster/stack-filter.js +63 -0
- data/vendor/assets/stylesheets/buster/buster-test.css +201 -0
- metadata +104 -0
@@ -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
|
+
}());
|