oojspec 0.2.0 → 0.3.0
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.
- checksums.yaml +4 -4
- data/lib/assets/javascripts/oojspec/runner.js.coffee +14 -7
- data/lib/oojspec/version.rb +1 -1
- data/vendor/assets/javascripts/buster/all.js.coffee +2 -0
- data/vendor/assets/javascripts/buster/bane.js +174 -0
- data/vendor/assets/javascripts/buster/buster-core.js +6 -5
- data/vendor/assets/javascripts/buster/expect.js +39 -35
- data/vendor/assets/javascripts/buster/formatio.js +215 -0
- data/vendor/assets/javascripts/buster/lodash.js +5163 -0
- data/vendor/assets/javascripts/buster/referee.js +692 -0
- data/vendor/assets/javascripts/buster/samsam.js +399 -0
- metadata +8 -5
- data/vendor/assets/javascripts/buster/buster-assertions.js +0 -782
- data/vendor/assets/javascripts/buster/buster-format.js +0 -199
@@ -0,0 +1,692 @@
|
|
1
|
+
((typeof define === "function" && define.amd && function (m) {
|
2
|
+
define("referee", ["expect", "lodash", "samsam", "bane"], m);
|
3
|
+
}) || (typeof module === "object" && function (m) {
|
4
|
+
module.exports = m(
|
5
|
+
require("./expect"),
|
6
|
+
require("lodash"),
|
7
|
+
require("samsam"),
|
8
|
+
require("bane")
|
9
|
+
);
|
10
|
+
}) || function (m) {
|
11
|
+
this.referee = m(
|
12
|
+
this.expect,
|
13
|
+
this._,
|
14
|
+
this.samsam,
|
15
|
+
this.bane
|
16
|
+
);
|
17
|
+
})(function (expect, _, samsam, bane) {
|
18
|
+
"use strict";
|
19
|
+
|
20
|
+
var toString = Object.prototype.toString;
|
21
|
+
var slice = Array.prototype.slice;
|
22
|
+
var assert, refute, referee = bane.createEventEmitter();
|
23
|
+
|
24
|
+
referee.countAssertion = function countAssertion() {
|
25
|
+
if (typeof referee.count !== "number") { referee.count = 0; }
|
26
|
+
referee.count += 1;
|
27
|
+
};
|
28
|
+
|
29
|
+
function interpolate(string, prop, value) {
|
30
|
+
return string.replace(new RegExp("\\$\\{" + prop + "\\}", "g"), value);
|
31
|
+
}
|
32
|
+
|
33
|
+
// Interpolate positional arguments. Replaces occurences of ${<index>} in
|
34
|
+
// the string with the corresponding entry in values[<index>]
|
35
|
+
function interpolatePosArg(message, values) {
|
36
|
+
return _.reduce(values, function (msg, value, index) {
|
37
|
+
return interpolate(msg, index, referee.format(value));
|
38
|
+
}, message);
|
39
|
+
}
|
40
|
+
|
41
|
+
function interpolateProperties(message, properties) {
|
42
|
+
return _.reduce(_.keys(properties), function (str, name) {
|
43
|
+
var formattedValue = name == "customMessage" ? referee.prepareMessage(properties[name]) : referee.format(properties[name]);
|
44
|
+
return interpolate(str, name, formattedValue);
|
45
|
+
}, message || "");
|
46
|
+
}
|
47
|
+
|
48
|
+
// Internal helper. Used throughout to fail assertions if they receive
|
49
|
+
// too few arguments. The name is provided for a helpful error message.
|
50
|
+
function assertArgNum(name, args, num) {
|
51
|
+
if (args.length < num) {
|
52
|
+
referee.fail("[" + name + "] Expected to receive at least " +
|
53
|
+
num + " argument" + (num > 1 ? "s" : ""));
|
54
|
+
return false;
|
55
|
+
}
|
56
|
+
return true;
|
57
|
+
}
|
58
|
+
|
59
|
+
// Internal helper. Not the most elegant of functions, but it takes
|
60
|
+
// care of all the nitty-gritty of assertion functions: counting,
|
61
|
+
// verifying parameter count, interpolating messages with actual
|
62
|
+
// values and so on.
|
63
|
+
function defineAssertion(type, name, func, minArgs, messageValues) {
|
64
|
+
referee[type][name] = function () {
|
65
|
+
referee.countAssertion();
|
66
|
+
var fullName = type + "." + name, failed = false;
|
67
|
+
|
68
|
+
if (!assertArgNum(fullName, arguments, minArgs || func.length)) {
|
69
|
+
return;
|
70
|
+
}
|
71
|
+
|
72
|
+
var args = slice.call(arguments, 0),
|
73
|
+
namedValues = {};
|
74
|
+
|
75
|
+
if (typeof messageValues === "function") {
|
76
|
+
var replacedValues = messageValues.apply(this, args);
|
77
|
+
if (typeof(replacedValues) === "object") {
|
78
|
+
namedValues = replacedValues;
|
79
|
+
} else {
|
80
|
+
args = replacedValues
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
var ctx = {
|
85
|
+
fail: function (msg) {
|
86
|
+
failed = true;
|
87
|
+
delete this.fail;
|
88
|
+
var message = referee[type][name][msg] || msg;
|
89
|
+
message = interpolatePosArg(message, args);
|
90
|
+
message = interpolateProperties(message, this);
|
91
|
+
message = interpolateProperties(message, namedValues);
|
92
|
+
referee.fail("[" + type + "." + name + "] " + message);
|
93
|
+
return false;
|
94
|
+
}
|
95
|
+
};
|
96
|
+
|
97
|
+
if (!func.apply(ctx, arguments) && !failed) {
|
98
|
+
// when a function returns false and hasn't already failed with a custom message,
|
99
|
+
// fail with default message
|
100
|
+
ctx.fail("message");
|
101
|
+
}
|
102
|
+
|
103
|
+
if (!failed) {
|
104
|
+
referee.emit.apply(referee, ["pass", fullName].concat(args));
|
105
|
+
}
|
106
|
+
};
|
107
|
+
}
|
108
|
+
|
109
|
+
referee.add = function (name, opt) {
|
110
|
+
var refuteArgs;
|
111
|
+
|
112
|
+
if (opt.refute) {
|
113
|
+
refuteArgs = opt.refute.length;
|
114
|
+
} else {
|
115
|
+
refuteArgs = opt.assert.length;
|
116
|
+
opt.refute = function () {
|
117
|
+
return !opt.assert.apply(this, arguments);
|
118
|
+
};
|
119
|
+
}
|
120
|
+
|
121
|
+
var values = opt.values;
|
122
|
+
defineAssertion("assert", name, opt.assert, opt.assert.length, values);
|
123
|
+
defineAssertion("refute", name, opt.refute, refuteArgs, values);
|
124
|
+
|
125
|
+
assert[name].message = opt.assertMessage;
|
126
|
+
refute[name].message = opt.refuteMessage;
|
127
|
+
|
128
|
+
if (opt.expectation) {
|
129
|
+
if (referee.expect && referee.expect.wrapAssertion) {
|
130
|
+
referee.expect.wrapAssertion(name, opt.expectation, referee);
|
131
|
+
} else {
|
132
|
+
assert[name].expectationName = opt.expectation;
|
133
|
+
refute[name].expectationName = opt.expectation;
|
134
|
+
}
|
135
|
+
}
|
136
|
+
};
|
137
|
+
|
138
|
+
assert = referee.assert = function assert(actual, message) {
|
139
|
+
referee.countAssertion();
|
140
|
+
if (!assertArgNum("assert", arguments, 1)) { return; }
|
141
|
+
|
142
|
+
if (!actual) {
|
143
|
+
var v = referee.format(actual);
|
144
|
+
referee.fail(message || "[assert] Expected " + v + " to be truthy");
|
145
|
+
} else {
|
146
|
+
referee.emit("pass", "assert", message || "", actual);
|
147
|
+
}
|
148
|
+
};
|
149
|
+
|
150
|
+
assert.toString = function () {
|
151
|
+
return "referee.assert()";
|
152
|
+
};
|
153
|
+
|
154
|
+
refute = referee.refute = function (actual, message) {
|
155
|
+
referee.countAssertion();
|
156
|
+
if (!assertArgNum("refute", arguments, 1)) { return; }
|
157
|
+
|
158
|
+
if (actual) {
|
159
|
+
var v = referee.format(actual);
|
160
|
+
referee.fail(message || "[refute] Expected " + v + " to be falsy");
|
161
|
+
} else {
|
162
|
+
referee.emit("pass", "refute", message || "", actual);
|
163
|
+
}
|
164
|
+
};
|
165
|
+
|
166
|
+
referee.count = 0;
|
167
|
+
|
168
|
+
referee.fail = function (message) {
|
169
|
+
var exception = new Error(message);
|
170
|
+
exception.name = "AssertionError";
|
171
|
+
|
172
|
+
try {
|
173
|
+
throw exception;
|
174
|
+
} catch (e) {
|
175
|
+
referee.emit("failure", e);
|
176
|
+
}
|
177
|
+
|
178
|
+
if (typeof referee.throwOnFailure !== "boolean" ||
|
179
|
+
referee.throwOnFailure) {
|
180
|
+
throw exception;
|
181
|
+
}
|
182
|
+
};
|
183
|
+
|
184
|
+
referee.format = function (object) { return String(object); };
|
185
|
+
|
186
|
+
referee.prepareMessage = function msg(message) {
|
187
|
+
if (!message) {
|
188
|
+
return "";
|
189
|
+
}
|
190
|
+
return message + (/[.:!?]$/.test(message) ? " " : ": ");
|
191
|
+
};
|
192
|
+
|
193
|
+
function actualAndExpectedMessageValues(actual, expected, message) {
|
194
|
+
return {
|
195
|
+
actual: actual,
|
196
|
+
expected: expected,
|
197
|
+
customMessage: message
|
198
|
+
};
|
199
|
+
}
|
200
|
+
|
201
|
+
function actualMessageValues(actual, message) {
|
202
|
+
return {
|
203
|
+
actual: actual,
|
204
|
+
customMessage: message
|
205
|
+
};
|
206
|
+
}
|
207
|
+
|
208
|
+
function actualAndTypeOfMessageValues(actual, message) {
|
209
|
+
return {
|
210
|
+
actual: actual,
|
211
|
+
actualType: typeof actual,
|
212
|
+
customMessage: message
|
213
|
+
};
|
214
|
+
}
|
215
|
+
|
216
|
+
referee.add("same", {
|
217
|
+
assert: function (actual, expected) {
|
218
|
+
return samsam.identical(actual, expected);
|
219
|
+
},
|
220
|
+
refute: function (actual, expected) {
|
221
|
+
return !samsam.identical(actual, expected);
|
222
|
+
},
|
223
|
+
assertMessage: "${customMessage}${actual} expected to be the same object as ${expected}",
|
224
|
+
refuteMessage: "${customMessage}${actual} expected not to be the same object as ${expected}",
|
225
|
+
expectation: "toBe",
|
226
|
+
values: actualAndExpectedMessageValues
|
227
|
+
});
|
228
|
+
|
229
|
+
// Extract/replace with separate module that does a more detailed
|
230
|
+
// visualization of multi-line strings
|
231
|
+
function multiLineStringDiff(actual, expected, message) {
|
232
|
+
if (actual === expected) { return true; }
|
233
|
+
|
234
|
+
var heading = assert.equals.multiLineStringHeading;
|
235
|
+
var failureText = interpolateProperties(heading, { customMessage: message });
|
236
|
+
var actualLines = actual.split("\n");
|
237
|
+
var expectedLines = expected.split("\n");
|
238
|
+
var lineCount = Math.max(expectedLines.length, actualLines.length);
|
239
|
+
var i, lines = [];
|
240
|
+
|
241
|
+
for (i = 0; i < lineCount; ++i) {
|
242
|
+
if (expectedLines[i] !== actualLines[i]) {
|
243
|
+
lines.push("line " + (i + 1) + ": " + (expectedLines[i] || "") +
|
244
|
+
"\nwas: " + (actualLines[i] || ""));
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
referee.fail("[assert.equals] " + failureText + lines.join("\n\n"));
|
249
|
+
return false;
|
250
|
+
}
|
251
|
+
|
252
|
+
referee.add("equals", {
|
253
|
+
// Uses arguments[2] because the function's .length is used to determine
|
254
|
+
// the minimum required number of arguments.
|
255
|
+
assert: function (actual, expected) {
|
256
|
+
if (typeof actual === "string" && typeof expected === "string" &&
|
257
|
+
(actual.indexOf("\n") >= 0 ||
|
258
|
+
expected.indexOf("\n") >= 0)) {
|
259
|
+
return multiLineStringDiff(actual, expected, arguments[2]);
|
260
|
+
}
|
261
|
+
|
262
|
+
return samsam.deepEqual(actual, expected);
|
263
|
+
},
|
264
|
+
|
265
|
+
refute: function (actual, expected) {
|
266
|
+
return !samsam.deepEqual(actual, expected);
|
267
|
+
},
|
268
|
+
|
269
|
+
assertMessage: "${customMessage}${actual} expected to be equal to ${expected}",
|
270
|
+
refuteMessage: "${customMessage}${actual} expected not to be equal to ${expected}",
|
271
|
+
expectation: "toEqual",
|
272
|
+
values: actualAndExpectedMessageValues
|
273
|
+
});
|
274
|
+
|
275
|
+
assert.equals.multiLineStringHeading = "${customMessage}Expected multi-line strings " +
|
276
|
+
"to be equal:\n";
|
277
|
+
|
278
|
+
referee.add("greater", {
|
279
|
+
assert: function (actual, expected) {
|
280
|
+
return actual > expected;
|
281
|
+
},
|
282
|
+
|
283
|
+
assertMessage: "${customMessage}Expected ${actual} to be greater than ${expected}",
|
284
|
+
refuteMessage: "${customMessage}Expected ${actual} to be less than or equal to ${expected}",
|
285
|
+
expectation: "toBeGreaterThan",
|
286
|
+
values: actualAndExpectedMessageValues
|
287
|
+
});
|
288
|
+
|
289
|
+
referee.add("less", {
|
290
|
+
assert: function (actual, expected) {
|
291
|
+
return actual < expected;
|
292
|
+
},
|
293
|
+
|
294
|
+
assertMessage: "${customMessage}Expected ${actual} to be less than ${expected}",
|
295
|
+
refuteMessage: "${customMessage}Expected ${actual} to be greater than or equal to ${expected}",
|
296
|
+
expectation: "toBeLessThan",
|
297
|
+
values: actualAndExpectedMessageValues
|
298
|
+
});
|
299
|
+
|
300
|
+
referee.add("defined", {
|
301
|
+
assert: function (actual) {
|
302
|
+
return typeof actual !== "undefined";
|
303
|
+
},
|
304
|
+
assertMessage: "${customMessage}Expected to be defined",
|
305
|
+
refuteMessage: "${customMessage}Expected ${actual} (${actualType}) not to be defined",
|
306
|
+
expectation: "toBeDefined",
|
307
|
+
values: actualAndTypeOfMessageValues
|
308
|
+
});
|
309
|
+
|
310
|
+
referee.add("isNull", {
|
311
|
+
assert: function (actual) {
|
312
|
+
return actual === null;
|
313
|
+
},
|
314
|
+
assertMessage: "${customMessage}Expected ${actual} to be null",
|
315
|
+
refuteMessage: "${customMessage}Expected not to be null",
|
316
|
+
expectation: "toBeNull",
|
317
|
+
values: actualMessageValues
|
318
|
+
});
|
319
|
+
|
320
|
+
|
321
|
+
referee.match = function (actual, matcher) {
|
322
|
+
try {
|
323
|
+
return samsam.match(actual, matcher);
|
324
|
+
} catch (e) {
|
325
|
+
throw new Error("Matcher (" + referee.format(matcher) +
|
326
|
+
") was not a string, a number, a function, " +
|
327
|
+
"a boolean or an object");
|
328
|
+
}
|
329
|
+
};
|
330
|
+
|
331
|
+
referee.add("match", {
|
332
|
+
assert: function (actual, matcher) {
|
333
|
+
var passed;
|
334
|
+
|
335
|
+
try {
|
336
|
+
passed = referee.match(actual, matcher);
|
337
|
+
} catch (e) {
|
338
|
+
this.exceptionMessage = e.message;
|
339
|
+
return this.fail("exceptionMessage");
|
340
|
+
}
|
341
|
+
|
342
|
+
return passed;
|
343
|
+
},
|
344
|
+
|
345
|
+
refute: function (actual, matcher) {
|
346
|
+
var passed;
|
347
|
+
|
348
|
+
try {
|
349
|
+
passed = referee.match(actual, matcher);
|
350
|
+
} catch (e) {
|
351
|
+
this.exceptionMessage = e.message;
|
352
|
+
return this.fail("exceptionMessage");
|
353
|
+
}
|
354
|
+
|
355
|
+
return !passed;
|
356
|
+
},
|
357
|
+
|
358
|
+
assertMessage: "${customMessage}${actual} expected to match ${expected}",
|
359
|
+
refuteMessage: "${customMessage}${actual} expected not to match ${expected}",
|
360
|
+
expectation: "toMatch",
|
361
|
+
values: actualAndExpectedMessageValues
|
362
|
+
});
|
363
|
+
|
364
|
+
assert.match.exceptionMessage = refute.match.exceptionMessage = "${customMessage}${exceptionMessage}";
|
365
|
+
|
366
|
+
referee.add("isObject", {
|
367
|
+
assert: function (actual) {
|
368
|
+
return typeof actual === "object" && !!actual;
|
369
|
+
},
|
370
|
+
assertMessage: "${customMessage}${actual} (${actualType}) expected to be object and not null",
|
371
|
+
refuteMessage: "${customMessage}${actual} expected to be null or not an object",
|
372
|
+
expectation: "toBeObject",
|
373
|
+
values: actualAndTypeOfMessageValues
|
374
|
+
});
|
375
|
+
|
376
|
+
referee.add("isFunction", {
|
377
|
+
assert: function (actual) {
|
378
|
+
return typeof actual === "function";
|
379
|
+
},
|
380
|
+
assertMessage: "${customMessage}${actual} (${actualType}) expected to be function",
|
381
|
+
refuteMessage: "${customMessage}${actual} expected not to be function",
|
382
|
+
expectation: "toBeFunction",
|
383
|
+
values: function (actual, message) {
|
384
|
+
return {
|
385
|
+
actual: String(actual).replace("\n", ""),
|
386
|
+
actualType: typeof actual,
|
387
|
+
customMessage: message
|
388
|
+
};
|
389
|
+
}
|
390
|
+
});
|
391
|
+
|
392
|
+
referee.add("isTrue", {
|
393
|
+
assert: function (actual) {
|
394
|
+
return actual === true;
|
395
|
+
},
|
396
|
+
assertMessage: "${customMessage}Expected ${actual} to be true",
|
397
|
+
refuteMessage: "${customMessage}Expected ${actual} to not be true",
|
398
|
+
expectation: "toBeTrue",
|
399
|
+
values: actualMessageValues
|
400
|
+
});
|
401
|
+
|
402
|
+
referee.add("isFalse", {
|
403
|
+
assert: function (actual) {
|
404
|
+
return actual === false;
|
405
|
+
},
|
406
|
+
assertMessage: "${customMessage}Expected ${actual} to be false",
|
407
|
+
refuteMessage: "${customMessage}Expected ${actual} to not be false",
|
408
|
+
expectation: "toBeFalse",
|
409
|
+
values: actualMessageValues
|
410
|
+
});
|
411
|
+
|
412
|
+
referee.add("isString", {
|
413
|
+
assert: function (actual) {
|
414
|
+
return typeof actual === "string";
|
415
|
+
},
|
416
|
+
assertMessage: "${customMessage}Expected ${actual} (${actualType}) to be string",
|
417
|
+
refuteMessage: "${customMessage}Expected ${actual} not to be string",
|
418
|
+
expectation: "toBeString",
|
419
|
+
values: actualAndTypeOfMessageValues
|
420
|
+
});
|
421
|
+
|
422
|
+
referee.add("isBoolean", {
|
423
|
+
assert: function (actual) {
|
424
|
+
return typeof actual === "boolean";
|
425
|
+
},
|
426
|
+
assertMessage: "${customMessage}Expected ${actual} (${actualType}) to be boolean",
|
427
|
+
refuteMessage: "${customMessage}Expected ${actual} not to be boolean",
|
428
|
+
expectation: "toBeBoolean",
|
429
|
+
values: actualAndTypeOfMessageValues
|
430
|
+
});
|
431
|
+
|
432
|
+
referee.add("isNumber", {
|
433
|
+
assert: function (actual) {
|
434
|
+
return typeof actual === "number" && !isNaN(actual);
|
435
|
+
},
|
436
|
+
assertMessage: "${customMessage}Expected ${actual} (${actualType}) to be a non-NaN number",
|
437
|
+
refuteMessage: "${customMessage}Expected ${actual} to be NaN or a non-number value",
|
438
|
+
expectation: "toBeNumber",
|
439
|
+
values: actualAndTypeOfMessageValues
|
440
|
+
});
|
441
|
+
|
442
|
+
referee.add("isNaN", {
|
443
|
+
assert: function (actual) {
|
444
|
+
return typeof actual === "number" && isNaN(actual);
|
445
|
+
},
|
446
|
+
assertMessage: "${customMessage}Expected ${actual} to be NaN",
|
447
|
+
refuteMessage: "${customMessage}Expected not to be NaN",
|
448
|
+
expectation: "toBeNaN",
|
449
|
+
values: actualAndTypeOfMessageValues
|
450
|
+
});
|
451
|
+
|
452
|
+
referee.add("isArray", {
|
453
|
+
assert: function (actual) {
|
454
|
+
return toString.call(actual) === "[object Array]";
|
455
|
+
},
|
456
|
+
assertMessage: "${customMessage}Expected ${actual} to be array",
|
457
|
+
refuteMessage: "${customMessage}Expected ${actual} not to be array",
|
458
|
+
expectation: "toBeArray",
|
459
|
+
values: actualAndTypeOfMessageValues
|
460
|
+
});
|
461
|
+
|
462
|
+
function isArrayLike(object) {
|
463
|
+
return _.isArray(object) ||
|
464
|
+
(!!object && typeof object.length === "number" &&
|
465
|
+
typeof object.splice === "function") ||
|
466
|
+
_.isArguments(object);
|
467
|
+
}
|
468
|
+
|
469
|
+
referee.isArrayLike = isArrayLike;
|
470
|
+
|
471
|
+
referee.add("isArrayLike", {
|
472
|
+
assert: function (actual) {
|
473
|
+
return isArrayLike(actual);
|
474
|
+
},
|
475
|
+
assertMessage: "${customMessage}Expected ${actual} to be array like",
|
476
|
+
refuteMessage: "${customMessage}Expected ${actual} not to be array like",
|
477
|
+
expectation: "toBeArrayLike",
|
478
|
+
values: actualAndTypeOfMessageValues
|
479
|
+
});
|
480
|
+
|
481
|
+
function exactKeys(object, keys) {
|
482
|
+
var keyMap = {};
|
483
|
+
var keyCnt = 0;
|
484
|
+
for (var i = 0; i < keys.length; i++) {
|
485
|
+
keyMap[keys[i]] = true;
|
486
|
+
keyCnt += 1;
|
487
|
+
}
|
488
|
+
for (var key in object) {
|
489
|
+
if (object.hasOwnProperty(key)) {
|
490
|
+
if (! keyMap[key]) {
|
491
|
+
return false;
|
492
|
+
}
|
493
|
+
keyCnt -= 1;
|
494
|
+
}
|
495
|
+
}
|
496
|
+
return keyCnt === 0;
|
497
|
+
}
|
498
|
+
|
499
|
+
referee.add("keys", {
|
500
|
+
assert: function (actual, keys) {
|
501
|
+
return exactKeys(actual, keys);
|
502
|
+
},
|
503
|
+
assertMessage: "${customMessage}Expected ${actualObject} to have exact keys ${keys}",
|
504
|
+
refuteMessage: "${customMessage}Expected not to have exact keys ${keys}",
|
505
|
+
expectation: "toHaveKeys",
|
506
|
+
values: function (actual, keys, message) {
|
507
|
+
return {
|
508
|
+
actualObject: actual,
|
509
|
+
keys: keys,
|
510
|
+
customMessage: message
|
511
|
+
}
|
512
|
+
}
|
513
|
+
});
|
514
|
+
|
515
|
+
function captureException(callback) {
|
516
|
+
try { callback(); } catch (e) { return e; }
|
517
|
+
return null;
|
518
|
+
}
|
519
|
+
|
520
|
+
referee.captureException = captureException;
|
521
|
+
|
522
|
+
referee.add("exception", {
|
523
|
+
assert: function (callback) {
|
524
|
+
var matcher = arguments[1];
|
525
|
+
var customMessage = arguments[2];
|
526
|
+
|
527
|
+
if (typeof matcher === "string") {
|
528
|
+
customMessage = matcher;
|
529
|
+
matcher = undefined;
|
530
|
+
}
|
531
|
+
|
532
|
+
this.expected = matcher;
|
533
|
+
this.customMessage = customMessage;
|
534
|
+
|
535
|
+
var err = captureException(callback);
|
536
|
+
|
537
|
+
if (err) {
|
538
|
+
this.actualExceptionType = err.name;
|
539
|
+
this.actualExceptionMessage = err.message;
|
540
|
+
this.actualExceptionStack = err.stack;
|
541
|
+
}
|
542
|
+
|
543
|
+
if (!err) {
|
544
|
+
if (typeof matcher === "object") {
|
545
|
+
return this.fail("typeNoExceptionMessage");
|
546
|
+
} else {
|
547
|
+
return this.fail("message");
|
548
|
+
}
|
549
|
+
}
|
550
|
+
|
551
|
+
if (typeof matcher === "object" && !referee.match(err, matcher)) {
|
552
|
+
return this.fail("typeFailMessage");
|
553
|
+
}
|
554
|
+
|
555
|
+
if (typeof matcher === "function" && matcher(err) !== true) {
|
556
|
+
return this.fail("matchFailMessage");
|
557
|
+
}
|
558
|
+
|
559
|
+
return true;
|
560
|
+
},
|
561
|
+
|
562
|
+
refute: function (callback) {
|
563
|
+
var err = captureException(callback);
|
564
|
+
|
565
|
+
if (err) {
|
566
|
+
this.customMessage = arguments[1];
|
567
|
+
this.actualExceptionType = err.name;
|
568
|
+
this.actualExceptionMessage = err.message;
|
569
|
+
return false;
|
570
|
+
}
|
571
|
+
|
572
|
+
return true;
|
573
|
+
},
|
574
|
+
|
575
|
+
expectation: "toThrow",
|
576
|
+
assertMessage: "${customMessage}Expected exception",
|
577
|
+
refuteMessage: "${customMessage}Expected not to throw but threw ${actualExceptionType} (${actualExceptionMessage})"
|
578
|
+
});
|
579
|
+
|
580
|
+
assert.exception.typeNoExceptionMessage = "${customMessage}Expected ${expected} but no exception was thrown";
|
581
|
+
assert.exception.typeFailMessage = "${customMessage}Expected ${expected} but threw ${actualExceptionType} (${actualExceptionMessage})\n${actualExceptionStack}";
|
582
|
+
assert.exception.matchFailMessage = "${customMessage}Expected thrown ${actualExceptionType} (${actualExceptionMessage}) to pass matcher function";
|
583
|
+
|
584
|
+
|
585
|
+
referee.add("near", {
|
586
|
+
assert: function (actual, expected, delta) {
|
587
|
+
return Math.abs(actual - expected) <= delta;
|
588
|
+
},
|
589
|
+
assertMessage: "${customMessage}Expected ${actual} to be equal to ${expected} +/- ${delta}",
|
590
|
+
refuteMessage: "${customMessage}Expected ${actual} not to be equal to ${expected} +/- ${delta}",
|
591
|
+
expectation: "toBeNear",
|
592
|
+
values: function (actual, expected, delta, message) {
|
593
|
+
return {
|
594
|
+
actual: actual,
|
595
|
+
expected: expected,
|
596
|
+
delta: delta,
|
597
|
+
customMessage: message
|
598
|
+
};
|
599
|
+
}
|
600
|
+
});
|
601
|
+
|
602
|
+
referee.add("hasPrototype", {
|
603
|
+
assert: function (actual, protoObj) {
|
604
|
+
return protoObj.isPrototypeOf(actual);
|
605
|
+
},
|
606
|
+
assertMessage: "${customMessage}Expected ${actual} to have ${expected} on its prototype chain",
|
607
|
+
refuteMessage: "${customMessage}Expected ${actual} not to have ${expected} on its " +
|
608
|
+
"prototype chain",
|
609
|
+
expectation: "toHavePrototype",
|
610
|
+
values: actualAndExpectedMessageValues
|
611
|
+
});
|
612
|
+
|
613
|
+
referee.add("contains", {
|
614
|
+
assert: function (haystack, needle) {
|
615
|
+
return _.include(haystack, needle);
|
616
|
+
},
|
617
|
+
assertMessage: "${customMessage}Expected [${actual}] to contain ${expected}",
|
618
|
+
refuteMessage: "${customMessage}Expected [${actual}] not to contain ${expected}",
|
619
|
+
expectation: "toContain",
|
620
|
+
values: actualAndExpectedMessageValues
|
621
|
+
});
|
622
|
+
|
623
|
+
referee.add("tagName", {
|
624
|
+
assert: function (element, tagName) {
|
625
|
+
// Uses arguments[2] because the function's .length is used to
|
626
|
+
// determine the minimum required number of arguments.
|
627
|
+
if (!element.tagName) {
|
628
|
+
return this.fail("noTagNameMessage");
|
629
|
+
}
|
630
|
+
|
631
|
+
return tagName.toLowerCase &&
|
632
|
+
tagName.toLowerCase() === element.tagName.toLowerCase();
|
633
|
+
},
|
634
|
+
assertMessage: "${customMessage}Expected tagName to be ${expected} but was ${actual}",
|
635
|
+
refuteMessage: "${customMessage}Expected tagName not to be ${actual}",
|
636
|
+
expectation: "toHaveTagName",
|
637
|
+
values: function (element, tagName, message) {
|
638
|
+
return {
|
639
|
+
actualElement: element,
|
640
|
+
actual: element.tagName,
|
641
|
+
expected: tagName,
|
642
|
+
customMessage: message
|
643
|
+
};
|
644
|
+
}
|
645
|
+
});
|
646
|
+
|
647
|
+
assert.tagName.noTagNameMessage = "${customMessage}Expected ${actualElement} to have tagName " +
|
648
|
+
"property";
|
649
|
+
refute.tagName.noTagNameMessage = "${customMessage}Expected ${actualElement} to have tagName " +
|
650
|
+
"property";
|
651
|
+
|
652
|
+
referee.add("className", {
|
653
|
+
assert: function (element, name) {
|
654
|
+
if (typeof element.className === "undefined") {
|
655
|
+
return this.fail("noClassNameMessage");
|
656
|
+
}
|
657
|
+
|
658
|
+
var expected = typeof name === "string" ? name.split(" ") : name;
|
659
|
+
var actual = element.className.split(" ");
|
660
|
+
var i, l;
|
661
|
+
for (i = 0, l = expected.length; i < l; i++) {
|
662
|
+
if (!_.include(actual, expected[i])) { return false; }
|
663
|
+
}
|
664
|
+
|
665
|
+
return true;
|
666
|
+
},
|
667
|
+
assertMessage: "${customMessage}Expected object's className to include ${expected} " +
|
668
|
+
"but was ${actual}",
|
669
|
+
refuteMessage: "${customMessage}Expected object's className not to include ${expected}",
|
670
|
+
expectation: "toHaveClassName",
|
671
|
+
values: function (element, className, message) {
|
672
|
+
return {
|
673
|
+
actualElement: element,
|
674
|
+
actual: element.className,
|
675
|
+
expected: className,
|
676
|
+
customMessage: message
|
677
|
+
};
|
678
|
+
}
|
679
|
+
});
|
680
|
+
|
681
|
+
assert.className.noClassNameMessage = "${customMessage}Expected object to have " +
|
682
|
+
"className property";
|
683
|
+
refute.className.noClassNameMessage = "${customMessage}Expected object to have " +
|
684
|
+
"className property";
|
685
|
+
|
686
|
+
referee.expect = function () {
|
687
|
+
expect.init(referee);
|
688
|
+
return expect.apply(referee, arguments);
|
689
|
+
};
|
690
|
+
|
691
|
+
return referee;
|
692
|
+
});
|