# lib/goog/testing/asserts.js

1 | // Copyright 2010 The Closure Library Authors. All Rights Reserved.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS-IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | goog.provide('goog.testing.JsUnitException');
15 | goog.provide('goog.testing.asserts');
16 | goog.provide('goog.testing.asserts.ArrayLike');
17 |
18 | goog.require('goog.testing.stacktrace');
19 |
20 | // TODO(user): Copied from JsUnit with some small modifications, we should
21 | // reimplement the asserters.
22 |
23 |
24 | /**
25 | * @typedef {Array|NodeList|Arguments|{length: number}}
26 | */
27 | goog.testing.asserts.ArrayLike;
28 |
29 | var DOUBLE_EQUALITY_PREDICATE = function(var1, var2) {
30 | return var1 == var2;
31 | };
32 | var JSUNIT_UNDEFINED_VALUE;
33 | var TO_STRING_EQUALITY_PREDICATE = function(var1, var2) {
34 | return var1.toString() === var2.toString();
35 | };
36 |
37 | var PRIMITIVE_EQUALITY_PREDICATES = {
38 | 'String': DOUBLE_EQUALITY_PREDICATE,
39 | 'Number': DOUBLE_EQUALITY_PREDICATE,
40 | 'Boolean': DOUBLE_EQUALITY_PREDICATE,
41 | 'Date': function(date1, date2) {
42 | return date1.getTime() == date2.getTime();
43 | },
44 | 'RegExp': TO_STRING_EQUALITY_PREDICATE,
45 | 'Function': TO_STRING_EQUALITY_PREDICATE
46 | };
47 |
48 |
49 | /**
50 | * Compares equality of two numbers, allowing them to differ up to a given
51 | * tolerance.
52 | * @param {number} var1 A number.
53 | * @param {number} var2 A number.
54 | * @param {number} tolerance the maximum allowed difference.
55 | * @return {boolean} Whether the two variables are sufficiently close.
56 | * @private
57 | */
58 | goog.testing.asserts.numberRoughEqualityPredicate_ = function(
59 | var1, var2, tolerance) {
60 | return Math.abs(var1 - var2) <= tolerance;
61 | };
62 |
63 |
64 | /**
65 | * @type {Object<string, function(*, *, number): boolean>}
66 | * @private
67 | */
68 | goog.testing.asserts.primitiveRoughEqualityPredicates_ = {
69 | 'Number': goog.testing.asserts.numberRoughEqualityPredicate_
70 | };
71 |
72 |
73 | var _trueTypeOf = function(something) {
74 | var result = typeof something;
75 | try {
76 | switch (result) {
77 | case 'string':
78 | break;
79 | case 'boolean':
80 | break;
81 | case 'number':
82 | break;
83 | case 'object':
84 | if (something == null) {
85 | result = 'null';
86 | break;
87 | }
88 | case 'function':
89 | switch (something.constructor) {
90 | case new String('').constructor:
91 | result = 'String';
92 | break;
93 | case new Boolean(true).constructor:
94 | result = 'Boolean';
95 | break;
96 | case new Number(0).constructor:
97 | result = 'Number';
98 | break;
99 | case new Array().constructor:
100 | result = 'Array';
101 | break;
102 | case new RegExp().constructor:
103 | result = 'RegExp';
104 | break;
105 | case new Date().constructor:
106 | result = 'Date';
107 | break;
108 | case Function:
109 | result = 'Function';
110 | break;
111 | default:
112 | var m = something.constructor.toString().match(
113 | /function\s*([^( ]+)\(/);
114 | if (m) {
115 | result = m[1];
116 | } else {
117 | break;
118 | }
119 | }
120 | break;
121 | }
122 | } catch (e) {
123 |
124 | } finally {
125 | result = result.substr(0, 1).toUpperCase() + result.substr(1);
126 | }
127 | return result;
128 | };
129 |
130 | var _displayStringForValue = function(aVar) {
131 | var result;
132 | try {
133 | result = '<' + String(aVar) + '>';
134 | } catch (ex) {
135 | result = '<toString failed: ' + ex.message + '>';
136 | // toString does not work on this object :-(
137 | }
138 | if (!(aVar === null || aVar === JSUNIT_UNDEFINED_VALUE)) {
139 | result += ' (' + _trueTypeOf(aVar) + ')';
140 | }
141 | return result;
142 | };
143 |
144 | var fail = function(failureMessage) {
145 | goog.testing.asserts.raiseException('Call to fail()', failureMessage);
146 | };
147 |
148 | var argumentsIncludeComments = function(expectedNumberOfNonCommentArgs, args) {
149 | return args.length == expectedNumberOfNonCommentArgs + 1;
150 | };
151 |
152 | var commentArg = function(expectedNumberOfNonCommentArgs, args) {
153 | if (argumentsIncludeComments(expectedNumberOfNonCommentArgs, args)) {
154 | return args[0];
155 | }
156 |
157 | return null;
158 | };
159 |
160 | var nonCommentArg = function(desiredNonCommentArgIndex,
161 | expectedNumberOfNonCommentArgs, args) {
162 | return argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) ?
163 | args[desiredNonCommentArgIndex] :
164 | args[desiredNonCommentArgIndex - 1];
165 | };
166 |
167 | var _validateArguments = function(expectedNumberOfNonCommentArgs, args) {
168 | var valid = args.length == expectedNumberOfNonCommentArgs ||
169 | args.length == expectedNumberOfNonCommentArgs + 1 &&
170 | goog.isString(args[0]);
171 | _assert(null, valid, 'Incorrect arguments passed to assert function');
172 | };
173 |
174 | var _assert = function(comment, booleanValue, failureMessage) {
175 | if (!booleanValue) {
176 | goog.testing.asserts.raiseException(comment, failureMessage);
177 | }
178 | };
179 |
180 |
181 | /**
182 | * @param {*} expected The expected value.
183 | * @param {*} actual The actual value.
184 | * @return {string} A failure message of the values don't match.
185 | * @private
186 | */
187 | goog.testing.asserts.getDefaultErrorMsg_ = function(expected, actual) {
188 | var msg = 'Expected ' + _displayStringForValue(expected) + ' but was ' +
189 | _displayStringForValue(actual);
190 | if ((typeof expected == 'string') && (typeof actual == 'string')) {
191 | // Try to find a human-readable difference.
192 | var limit = Math.min(expected.length, actual.length);
193 | var commonPrefix = 0;
194 | while (commonPrefix < limit &&
195 | expected.charAt(commonPrefix) == actual.charAt(commonPrefix)) {
196 | commonPrefix++;
197 | }
198 |
199 | var commonSuffix = 0;
200 | while (commonSuffix < limit &&
201 | expected.charAt(expected.length - commonSuffix - 1) ==
202 | actual.charAt(actual.length - commonSuffix - 1)) {
203 | commonSuffix++;
204 | }
205 |
206 | if (commonPrefix + commonSuffix > limit) {
207 | commonSuffix = 0;
208 | }
209 |
210 | if (commonPrefix > 2 || commonSuffix > 2) {
211 | var printString = function(str) {
212 | var startIndex = Math.max(0, commonPrefix - 2);
213 | var endIndex = Math.min(str.length, str.length - (commonSuffix - 2));
214 | return (startIndex > 0 ? '...' : '') +
215 | str.substring(startIndex, endIndex) +
216 | (endIndex < str.length ? '...' : '');
217 | };
218 |
219 | msg += '\nDifference was at position ' + commonPrefix +
220 | '. Expected [' + printString(expected) +
221 | '] vs. actual [' + printString(actual) + ']';
222 | }
223 | }
224 | return msg;
225 | };
226 |
227 |
228 | /**
229 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
230 | * @param {*=} opt_b The value to assert (2 args only).
231 | */
232 | var assert = function(a, opt_b) {
233 | _validateArguments(1, arguments);
234 | var comment = commentArg(1, arguments);
235 | var booleanValue = nonCommentArg(1, 1, arguments);
236 |
237 | _assert(comment, goog.isBoolean(booleanValue),
238 | 'Bad argument to assert(boolean)');
239 | _assert(comment, booleanValue, 'Call to assert(boolean) with false');
240 | };
241 |
242 |
243 | /**
244 | * Asserts that the function throws an error.
245 | *
246 | * @param {!(string|Function)} a The assertion comment or the function to call.
247 | * @param {!Function=} opt_b The function to call (if the first argument of
248 | * {@code assertThrows} was the comment).
249 | * @return {*} The error thrown by the function.
250 | * @throws {goog.testing.JsUnitException} If the assertion failed.
251 | */
252 | var assertThrows = function(a, opt_b) {
253 | _validateArguments(1, arguments);
254 | var func = nonCommentArg(1, 1, arguments);
255 | var comment = commentArg(1, arguments);
256 | _assert(comment, typeof func == 'function',
257 | 'Argument passed to assertThrows is not a function');
258 |
259 | try {
260 | func();
261 | } catch (e) {
262 | if (e && goog.isString(e['stacktrace']) && goog.isString(e['message'])) {
263 | // Remove the stack trace appended to the error message by Opera 10.0
264 | var startIndex = e['message'].length - e['stacktrace'].length;
265 | if (e['message'].indexOf(e['stacktrace'], startIndex) == startIndex) {
266 | e['message'] = e['message'].substr(0, startIndex - 14);
267 | }
268 | }
269 | return e;
270 | }
271 | goog.testing.asserts.raiseException(comment,
272 | 'No exception thrown from function passed to assertThrows');
273 | };
274 |
275 |
276 | /**
277 | * Asserts that the function does not throw an error.
278 | *
279 | * @param {!(string|Function)} a The assertion comment or the function to call.
280 | * @param {!Function=} opt_b The function to call (if the first argument of
281 | * {@code assertNotThrows} was the comment).
282 | * @return {*} The return value of the function.
283 | * @throws {goog.testing.JsUnitException} If the assertion failed.
284 | */
285 | var assertNotThrows = function(a, opt_b) {
286 | _validateArguments(1, arguments);
287 | var comment = commentArg(1, arguments);
288 | var func = nonCommentArg(1, 1, arguments);
289 | _assert(comment, typeof func == 'function',
290 | 'Argument passed to assertNotThrows is not a function');
291 |
292 | try {
293 | return func();
294 | } catch (e) {
295 | comment = comment ? (comment + '\n') : '';
296 | comment += 'A non expected exception was thrown from function passed to ' +
297 | 'assertNotThrows';
298 | // Some browsers don't have a stack trace so at least have the error
299 | // description.
300 | var stackTrace = e['stack'] || e['stacktrace'] || e.toString();
301 | goog.testing.asserts.raiseException(comment, stackTrace);
302 | }
303 | };
304 |
305 |
306 | /**
307 | * Asserts that the given callback function results in a JsUnitException when
308 | * called, and that the resulting failure message matches the given expected
309 | * message.
310 | * @param {function() : void} callback Function to be run expected to result
311 | * in a JsUnitException (usually contains a call to an assert).
312 | * @param {string=} opt_expectedMessage Failure message expected to be given
313 | * with the exception.
314 | */
315 | var assertThrowsJsUnitException = function(callback, opt_expectedMessage) {
316 | var failed = false;
317 | try {
318 | goog.testing.asserts.callWithoutLogging(callback);
319 | } catch (ex) {
320 | if (!ex.isJsUnitException) {
321 | fail('Expected a JsUnitException');
322 | }
323 | if (typeof opt_expectedMessage != 'undefined' &&
324 | ex.message != opt_expectedMessage) {
325 | fail('Expected message [' + opt_expectedMessage + '] but got [' +
326 | ex.message + ']');
327 | }
328 | failed = true;
329 | }
330 | if (!failed) {
331 | fail('Expected a failure: ' + opt_expectedMessage);
332 | }
333 | };
334 |
335 |
336 | /**
337 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
338 | * @param {*=} opt_b The value to assert (2 args only).
339 | */
340 | var assertTrue = function(a, opt_b) {
341 | _validateArguments(1, arguments);
342 | var comment = commentArg(1, arguments);
343 | var booleanValue = nonCommentArg(1, 1, arguments);
344 |
345 | _assert(comment, goog.isBoolean(booleanValue),
346 | 'Bad argument to assertTrue(boolean)');
347 | _assert(comment, booleanValue, 'Call to assertTrue(boolean) with false');
348 | };
349 |
350 |
351 | /**
352 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
353 | * @param {*=} opt_b The value to assert (2 args only).
354 | */
355 | var assertFalse = function(a, opt_b) {
356 | _validateArguments(1, arguments);
357 | var comment = commentArg(1, arguments);
358 | var booleanValue = nonCommentArg(1, 1, arguments);
359 |
360 | _assert(comment, goog.isBoolean(booleanValue),
361 | 'Bad argument to assertFalse(boolean)');
362 | _assert(comment, !booleanValue, 'Call to assertFalse(boolean) with true');
363 | };
364 |
365 |
366 | /**
367 | * @param {*} a The expected value (2 args) or the debug message (3 args).
368 | * @param {*} b The actual value (2 args) or the expected value (3 args).
369 | * @param {*=} opt_c The actual value (3 args only).
370 | */
371 | var assertEquals = function(a, b, opt_c) {
372 | _validateArguments(2, arguments);
373 | var var1 = nonCommentArg(1, 2, arguments);
374 | var var2 = nonCommentArg(2, 2, arguments);
375 | _assert(commentArg(2, arguments), var1 === var2,
376 | goog.testing.asserts.getDefaultErrorMsg_(var1, var2));
377 | };
378 |
379 |
380 | /**
381 | * @param {*} a The expected value (2 args) or the debug message (3 args).
382 | * @param {*} b The actual value (2 args) or the expected value (3 args).
383 | * @param {*=} opt_c The actual value (3 args only).
384 | */
385 | var assertNotEquals = function(a, b, opt_c) {
386 | _validateArguments(2, arguments);
387 | var var1 = nonCommentArg(1, 2, arguments);
388 | var var2 = nonCommentArg(2, 2, arguments);
389 | _assert(commentArg(2, arguments), var1 !== var2,
390 | 'Expected not to be ' + _displayStringForValue(var2));
391 | };
392 |
393 |
394 | /**
395 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
396 | * @param {*=} opt_b The value to assert (2 args only).
397 | */
398 | var assertNull = function(a, opt_b) {
399 | _validateArguments(1, arguments);
400 | var aVar = nonCommentArg(1, 1, arguments);
401 | _assert(commentArg(1, arguments), aVar === null,
402 | goog.testing.asserts.getDefaultErrorMsg_(null, aVar));
403 | };
404 |
405 |
406 | /**
407 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
408 | * @param {*=} opt_b The value to assert (2 args only).
409 | */
410 | var assertNotNull = function(a, opt_b) {
411 | _validateArguments(1, arguments);
412 | var aVar = nonCommentArg(1, 1, arguments);
413 | _assert(commentArg(1, arguments), aVar !== null,
414 | 'Expected not to be ' + _displayStringForValue(null));
415 | };
416 |
417 |
418 | /**
419 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
420 | * @param {*=} opt_b The value to assert (2 args only).
421 | */
422 | var assertUndefined = function(a, opt_b) {
423 | _validateArguments(1, arguments);
424 | var aVar = nonCommentArg(1, 1, arguments);
425 | _assert(commentArg(1, arguments), aVar === JSUNIT_UNDEFINED_VALUE,
426 | goog.testing.asserts.getDefaultErrorMsg_(JSUNIT_UNDEFINED_VALUE, aVar));
427 | };
428 |
429 |
430 | /**
431 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
432 | * @param {*=} opt_b The value to assert (2 args only).
433 | */
434 | var assertNotUndefined = function(a, opt_b) {
435 | _validateArguments(1, arguments);
436 | var aVar = nonCommentArg(1, 1, arguments);
437 | _assert(commentArg(1, arguments), aVar !== JSUNIT_UNDEFINED_VALUE,
438 | 'Expected not to be ' + _displayStringForValue(JSUNIT_UNDEFINED_VALUE));
439 | };
440 |
441 |
442 | /**
443 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
444 | * @param {*=} opt_b The value to assert (2 args only).
445 | */
446 | var assertNotNullNorUndefined = function(a, opt_b) {
447 | _validateArguments(1, arguments);
448 | assertNotNull.apply(null, arguments);
449 | assertNotUndefined.apply(null, arguments);
450 | };
451 |
452 |
453 | /**
454 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
455 | * @param {*=} opt_b The value to assert (2 args only).
456 | */
457 | var assertNonEmptyString = function(a, opt_b) {
458 | _validateArguments(1, arguments);
459 | var aVar = nonCommentArg(1, 1, arguments);
460 | _assert(commentArg(1, arguments),
461 | aVar !== JSUNIT_UNDEFINED_VALUE && aVar !== null &&
462 | typeof aVar == 'string' && aVar !== '',
463 | 'Expected non-empty string but was ' + _displayStringForValue(aVar));
464 | };
465 |
466 |
467 | /**
468 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
469 | * @param {*=} opt_b The value to assert (2 args only).
470 | */
471 | var assertNaN = function(a, opt_b) {
472 | _validateArguments(1, arguments);
473 | var aVar = nonCommentArg(1, 1, arguments);
474 | _assert(commentArg(1, arguments), isNaN(aVar), 'Expected NaN');
475 | };
476 |
477 |
478 | /**
479 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
480 | * @param {*=} opt_b The value to assert (2 args only).
481 | */
482 | var assertNotNaN = function(a, opt_b) {
483 | _validateArguments(1, arguments);
484 | var aVar = nonCommentArg(1, 1, arguments);
485 | _assert(commentArg(1, arguments), !isNaN(aVar), 'Expected not NaN');
486 | };
487 |
488 |
489 | /**
490 | * Runs a function in an environment where test failures are not logged. This is
491 | * useful for testing test code, where failures can be a normal part of a test.
492 | * @param {function() : void} fn Function to run without logging failures.
493 | */
494 | goog.testing.asserts.callWithoutLogging = function(fn) {
495 | var testRunner = goog.global['G_testRunner'];
496 | var oldLogTestFailure = testRunner['logTestFailure'];
497 | try {
498 | // Any failures in the callback shouldn't be recorded.
499 | testRunner['logTestFailure'] = undefined;
500 | fn();
501 | } finally {
502 | testRunner['logTestFailure'] = oldLogTestFailure;
503 | }
504 | };
505 |
506 |
507 | /**
508 | * The return value of the equality predicate passed to findDifferences below,
509 | * in cases where the predicate can't test the input variables for equality.
510 | * @type {?string}
511 | */
512 | goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS = null;
513 |
514 |
515 | /**
516 | * The return value of the equality predicate passed to findDifferences below,
517 | * in cases where the input vriables are equal.
518 | * @type {?string}
519 | */
520 | goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL = '';
521 |
522 |
523 | /**
524 | * Determines if two items of any type match, and formulates an error message
525 | * if not.
526 | * @param {*} expected Expected argument to match.
527 | * @param {*} actual Argument as a result of performing the test.
528 | * @param {(function(string, *, *): ?string)=} opt_equalityPredicate An optional
529 | * function that can be used to check equality of variables. It accepts 3
530 | * arguments: type-of-variables, var1, var2 (in that order) and returns an
531 | * error message if the variables are not equal,
532 | * goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL if the variables
533 | * are equal, or
534 | * goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS if the predicate
535 | * couldn't check the input variables. The function will be called only if
536 | * the types of var1 and var2 are identical.
537 | * @return {?string} Null on success, error message on failure.
538 | */
539 | goog.testing.asserts.findDifferences = function(expected, actual,
540 | opt_equalityPredicate) {
541 | var failures = [];
542 | var seen1 = [];
543 | var seen2 = [];
544 |
545 | // To avoid infinite recursion when the two parameters are self-referential
546 | // along the same path of properties, keep track of the object pairs already
547 | // seen in this call subtree, and abort when a cycle is detected.
548 | function innerAssertWithCycleCheck(var1, var2, path) {
549 | // This is used for testing, so we can afford to be slow (but more
550 | // accurate). So we just check whether var1 is in seen1. If we
551 | // found var1 in index i, we simply need to check whether var2 is
552 | // in seen2[i]. If it is, we do not recurse to check var1/var2. If
553 | // it isn't, we know that the structures of the two objects must be
554 | // different.
555 | //
556 | // This is based on the fact that values at index i in seen1 and
557 | // seen2 will be checked for equality eventually (when
558 | // innerAssertImplementation(seen1[i], seen2[i], path) finishes).
559 | for (var i = 0; i < seen1.length; ++i) {
560 | var match1 = seen1[i] === var1;
561 | var match2 = seen2[i] === var2;
562 | if (match1 || match2) {
563 | if (!match1 || !match2) {
564 | // Asymmetric cycles, so the objects have different structure.
565 | failures.push('Asymmetric cycle detected at ' + path);
566 | }
567 | return;
568 | }
569 | }
570 |
571 | seen1.push(var1);
572 | seen2.push(var2);
573 | innerAssertImplementation(var1, var2, path);
574 | seen1.pop();
575 | seen2.pop();
576 | }
577 |
578 | var equalityPredicate = opt_equalityPredicate || function(type, var1, var2) {
579 | var typedPredicate = PRIMITIVE_EQUALITY_PREDICATES[type];
580 | if (!typedPredicate) {
581 | return goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS;
582 | }
583 | var equal = typedPredicate(var1, var2);
584 | return equal ? goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL :
585 | goog.testing.asserts.getDefaultErrorMsg_(var1, var2);
586 | };
587 |
588 | /**
589 | * @param {*} var1 An item in the expected object.
590 | * @param {*} var2 The corresponding item in the actual object.
591 | * @param {string} path Their path in the objects.
592 | * @suppress {missingProperties} The map_ property is unknown to the compiler
593 | * unless goog.structs.Map is loaded.
594 | */
595 | function innerAssertImplementation(var1, var2, path) {
596 | if (var1 === var2) {
597 | return;
598 | }
599 |
600 | var typeOfVar1 = _trueTypeOf(var1);
601 | var typeOfVar2 = _trueTypeOf(var2);
602 |
603 | if (typeOfVar1 == typeOfVar2) {
604 | var isArray = typeOfVar1 == 'Array';
605 | var errorMessage = equalityPredicate(typeOfVar1, var1, var2);
606 | if (errorMessage !=
607 | goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS) {
608 | if (errorMessage !=
609 | goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL) {
610 | failures.push(path + ': ' + errorMessage);
611 | }
612 | } else if (isArray && var1.length != var2.length) {
613 | failures.push(path + ': Expected ' + var1.length + '-element array ' +
614 | 'but got a ' + var2.length + '-element array');
615 | } else {
616 | var childPath = path + (isArray ? '[%s]' : (path ? '.%s' : '%s'));
617 |
618 | // if an object has an __iterator__ property, we have no way of
619 | // actually inspecting its raw properties, and JS 1.7 doesn't
620 | // overload [] to make it possible for someone to generically
621 | // use what the iterator returns to compare the object-managed
622 | // properties. This gets us into deep poo with things like
623 | // goog.structs.Map, at least on systems that support iteration.
624 | if (!var1['__iterator__']) {
625 | for (var prop in var1) {
626 | if (isArray && goog.testing.asserts.isArrayIndexProp_(prop)) {
627 | // Skip array indices for now. We'll handle them later.
628 | continue;
629 | }
630 |
631 | if (prop in var2) {
632 | innerAssertWithCycleCheck(var1[prop], var2[prop],
633 | childPath.replace('%s', prop));
634 | } else {
635 | failures.push('property ' + prop +
636 | ' not present in actual ' + (path || typeOfVar2));
637 | }
638 | }
639 | // make sure there aren't properties in var2 that are missing
640 | // from var1. if there are, then by definition they don't
641 | // match.
642 | for (var prop in var2) {
643 | if (isArray && goog.testing.asserts.isArrayIndexProp_(prop)) {
644 | // Skip array indices for now. We'll handle them later.
645 | continue;
646 | }
647 |
648 | if (!(prop in var1)) {
649 | failures.push('property ' + prop +
650 | ' not present in expected ' +
651 | (path || typeOfVar1));
652 | }
653 | }
654 |
655 | // Handle array indices by iterating from 0 to arr.length.
656 | //
657 | // Although all browsers allow holes in arrays, browsers
658 | // are inconsistent in what they consider a hole. For example,
659 | // "[0,undefined,2]" has a hole on IE but not on Firefox.
660 | //
661 | // Because our style guide bans for...in iteration over arrays,
662 | // we assume that most users don't care about holes in arrays,
663 | // and that it is ok to say that a hole is equivalent to a slot
664 | // populated with 'undefined'.
665 | if (isArray) {
666 | for (prop = 0; prop < var1.length; prop++) {
667 | innerAssertWithCycleCheck(var1[prop], var2[prop],
668 | childPath.replace('%s', String(prop)));
669 | }
670 | }
671 | } else {
672 | // special-case for closure objects that have iterators
673 | if (goog.isFunction(var1.equals)) {
674 | // use the object's own equals function, assuming it accepts an
675 | // object and returns a boolean
676 | if (!var1.equals(var2)) {
677 | failures.push('equals() returned false for ' +
678 | (path || typeOfVar1));
679 | }
680 | } else if (var1.map_) {
681 | // assume goog.structs.Map or goog.structs.Set, where comparing
682 | // their private map_ field is sufficient
683 | innerAssertWithCycleCheck(var1.map_, var2.map_,
684 | childPath.replace('%s', 'map_'));
685 | } else {
686 | // else die, so user knows we can't do anything
687 | failures.push('unable to check ' + (path || typeOfVar1) +
688 | ' for equality: it has an iterator we do not ' +
689 | 'know how to handle. please add an equals method');
690 | }
691 | }
692 | }
693 | } else {
694 | failures.push(path + ' ' +
695 | goog.testing.asserts.getDefaultErrorMsg_(var1, var2));
696 | }
697 | }
698 |
699 | innerAssertWithCycleCheck(expected, actual, '');
700 | return failures.length == 0 ? null :
701 | goog.testing.asserts.getDefaultErrorMsg_(expected, actual) +
702 | '\n ' + failures.join('\n ');
703 | };
704 |
705 |
706 | /**
707 | * Notes:
708 | * Object equality has some nasty browser quirks, and this implementation is
709 | * not 100% correct. For example,
710 | *
711 | * <code>
712 | * var a = [0, 1, 2];
713 | * var b = [0, 1, 2];
714 | * delete a[1];
715 | * b[1] = undefined;
716 | * assertObjectEquals(a, b); // should fail, but currently passes
717 | * </code>
718 | *
719 | * See asserts_test.html for more interesting edge cases.
720 | *
721 | * The first comparison object provided is the expected value, the second is
722 | * the actual.
723 | *
724 | * @param {*} a Assertion message or comparison object.
725 | * @param {*} b Comparison object.
726 | * @param {*=} opt_c Comparison object, if an assertion message was provided.
727 | */
728 | var assertObjectEquals = function(a, b, opt_c) {
729 | _validateArguments(2, arguments);
730 | var v1 = nonCommentArg(1, 2, arguments);
731 | var v2 = nonCommentArg(2, 2, arguments);
732 | var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : '';
733 | var differences = goog.testing.asserts.findDifferences(v1, v2);
734 |
735 | _assert(failureMessage, !differences, differences);
736 | };
737 |
738 |
739 | /**
740 | * Similar to assertObjectEquals above, but accepts a tolerance margin.
741 | *
742 | * @param {*} a Assertion message or comparison object.
743 | * @param {*} b Comparison object.
744 | * @param {*} c Comparison object or tolerance.
745 | * @param {*=} opt_d Tolerance, if an assertion message was provided.
746 | */
747 | var assertObjectRoughlyEquals = function(a, b, c, opt_d) {
748 | _validateArguments(3, arguments);
749 | var v1 = nonCommentArg(1, 3, arguments);
750 | var v2 = nonCommentArg(2, 3, arguments);
751 | var tolerance = nonCommentArg(3, 3, arguments);
752 | var failureMessage = commentArg(3, arguments) ? commentArg(3, arguments) : '';
753 | var equalityPredicate = function(type, var1, var2) {
754 | var typedPredicate =
755 | goog.testing.asserts.primitiveRoughEqualityPredicates_[type];
756 | if (!typedPredicate) {
757 | return goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS;
758 | }
759 | var equal = typedPredicate(var1, var2, tolerance);
760 | return equal ? goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL :
761 | goog.testing.asserts.getDefaultErrorMsg_(var1, var2) +
762 | ' which was more than ' + tolerance + ' away';
763 | };
764 | var differences = goog.testing.asserts.findDifferences(
765 | v1, v2, equalityPredicate);
766 |
767 | _assert(failureMessage, !differences, differences);
768 | };
769 |
770 |
771 | /**
772 | * Compares two arbitrary objects for non-equalness.
773 | *
774 | * All the same caveats as for assertObjectEquals apply here:
775 | * Undefined values may be confused for missing values, or vice versa.
776 | *
777 | * @param {*} a Assertion message or comparison object.
778 | * @param {*} b Comparison object.
779 | * @param {*=} opt_c Comparison object, if an assertion message was provided.
780 | */
781 | var assertObjectNotEquals = function(a, b, opt_c) {
782 | _validateArguments(2, arguments);
783 | var v1 = nonCommentArg(1, 2, arguments);
784 | var v2 = nonCommentArg(2, 2, arguments);
785 | var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : '';
786 | var differences = goog.testing.asserts.findDifferences(v1, v2);
787 |
788 | _assert(failureMessage, differences, 'Objects should not be equal');
789 | };
790 |
791 |
792 | /**
793 | * Compares two arrays ignoring negative indexes and extra properties on the
794 | * array objects. Use case: Internet Explorer adds the index, lastIndex and
795 | * input enumerable fields to the result of string.match(/regexp/g), which makes
796 | * assertObjectEquals fail.
797 | * @param {*} a The expected array (2 args) or the debug message (3 args).
798 | * @param {*} b The actual array (2 args) or the expected array (3 args).
799 | * @param {*=} opt_c The actual array (3 args only).
800 | */
801 | var assertArrayEquals = function(a, b, opt_c) {
802 | _validateArguments(2, arguments);
803 | var v1 = nonCommentArg(1, 2, arguments);
804 | var v2 = nonCommentArg(2, 2, arguments);
805 | var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : '';
806 |
807 | var typeOfVar1 = _trueTypeOf(v1);
808 | _assert(failureMessage,
809 | typeOfVar1 == 'Array',
810 | 'Expected an array for assertArrayEquals but found a ' + typeOfVar1);
811 |
812 | var typeOfVar2 = _trueTypeOf(v2);
813 | _assert(failureMessage,
814 | typeOfVar2 == 'Array',
815 | 'Expected an array for assertArrayEquals but found a ' + typeOfVar2);
816 |
817 | assertObjectEquals(failureMessage,
818 | Array.prototype.concat.call(v1), Array.prototype.concat.call(v2));
819 | };
820 |
821 |
822 | /**
823 | * Compares two objects that can be accessed like an array and assert that
824 | * each element is equal.
825 | * @param {string|Object} a Failure message (3 arguments)
826 | * or object #1 (2 arguments).
827 | * @param {Object} b Object #1 (2 arguments) or object #2 (3 arguments).
828 | * @param {Object=} opt_c Object #2 (3 arguments).
829 | */
830 | var assertElementsEquals = function(a, b, opt_c) {
831 | _validateArguments(2, arguments);
832 |
833 | var v1 = nonCommentArg(1, 2, arguments);
834 | var v2 = nonCommentArg(2, 2, arguments);
835 | var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : '';
836 |
837 | if (!v1) {
838 | assert(failureMessage, !v2);
839 | } else {
840 | assertEquals('length mismatch: ' + failureMessage, v1.length, v2.length);
841 | for (var i = 0; i < v1.length; ++i) {
842 | assertEquals(
843 | 'mismatch at index ' + i + ': ' + failureMessage, v1[i], v2[i]);
844 | }
845 | }
846 | };
847 |
848 |
849 | /**
850 | * Compares two objects that can be accessed like an array and assert that
851 | * each element is roughly equal.
852 | * @param {string|Object} a Failure message (4 arguments)
853 | * or object #1 (3 arguments).
854 | * @param {Object} b Object #1 (4 arguments) or object #2 (3 arguments).
855 | * @param {Object|number} c Object #2 (4 arguments) or tolerance (3 arguments).
856 | * @param {number=} opt_d tolerance (4 arguments).
857 | */
858 | var assertElementsRoughlyEqual = function(a, b, c, opt_d) {
859 | _validateArguments(3, arguments);
860 |
861 | var v1 = nonCommentArg(1, 3, arguments);
862 | var v2 = nonCommentArg(2, 3, arguments);
863 | var tolerance = nonCommentArg(3, 3, arguments);
864 | var failureMessage = commentArg(3, arguments) ? commentArg(3, arguments) : '';
865 |
866 | if (!v1) {
867 | assert(failureMessage, !v2);
868 | } else {
869 | assertEquals('length mismatch: ' + failureMessage, v1.length, v2.length);
870 | for (var i = 0; i < v1.length; ++i) {
871 | assertRoughlyEquals(failureMessage, v1[i], v2[i], tolerance);
872 | }
873 | }
874 | };
875 |
876 |
877 | /**
878 | * Compares two array-like objects without taking their order into account.
879 | * @param {string|goog.testing.asserts.ArrayLike} a Assertion message or the
880 | * expected elements.
881 | * @param {goog.testing.asserts.ArrayLike} b Expected elements or the actual
882 | * elements.
883 | * @param {goog.testing.asserts.ArrayLike=} opt_c Actual elements.
884 | */
885 | var assertSameElements = function(a, b, opt_c) {
886 | _validateArguments(2, arguments);
887 | var expected = nonCommentArg(1, 2, arguments);
888 | var actual = nonCommentArg(2, 2, arguments);
889 | var message = commentArg(2, arguments);
890 |
891 | assertTrue('Bad arguments to assertSameElements(opt_message, expected: ' +
892 | 'ArrayLike, actual: ArrayLike)',
893 | goog.isArrayLike(expected) && goog.isArrayLike(actual));
894 |
895 | // Clones expected and actual and converts them to real arrays.
896 | expected = goog.testing.asserts.toArray_(expected);
897 | actual = goog.testing.asserts.toArray_(actual);
898 | // TODO(user): It would be great to show only the difference
899 | // between the expected and actual elements.
900 | _assert(message, expected.length == actual.length,
901 | 'Expected ' + expected.length + ' elements: [' + expected + '], ' +
902 | 'got ' + actual.length + ' elements: [' + actual + ']');
903 |
904 | var toFind = goog.testing.asserts.toArray_(expected);
905 | for (var i = 0; i < actual.length; i++) {
906 | var index = goog.testing.asserts.indexOf_(toFind, actual[i]);
907 | _assert(message, index != -1, 'Expected [' + expected + '], got [' +
908 | actual + ']');
909 | toFind.splice(index, 1);
910 | }
911 | };
912 |
913 |
914 | /**
915 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
916 | * @param {*=} opt_b The value to assert (2 args only).
917 | */
918 | var assertEvaluatesToTrue = function(a, opt_b) {
919 | _validateArguments(1, arguments);
920 | var value = nonCommentArg(1, 1, arguments);
921 | if (!value) {
922 | _assert(commentArg(1, arguments), false, 'Expected to evaluate to true');
923 | }
924 | };
925 |
926 |
927 | /**
928 | * @param {*} a The value to assert (1 arg) or debug message (2 args).
929 | * @param {*=} opt_b The value to assert (2 args only).
930 | */
931 | var assertEvaluatesToFalse = function(a, opt_b) {
932 | _validateArguments(1, arguments);
933 | var value = nonCommentArg(1, 1, arguments);
934 | if (value) {
935 | _assert(commentArg(1, arguments), false, 'Expected to evaluate to false');
936 | }
937 | };
938 |
939 |
940 | /**
941 | * Compares two HTML snippets.
942 | *
943 | * Take extra care if attributes are involved. {@code assertHTMLEquals}'s
944 | * implementation isn't prepared for complex cases. For example, the following
945 | * comparisons erroneously fail:
946 | * <pre>
947 | * assertHTMLEquals('<a href="x" target="y">', '<a target="y" href="x">');
948 | * assertHTMLEquals('<div classname="a b">', '<div classname="b a">');
949 | * assertHTMLEquals('<input disabled>', '<input disabled="disabled">');
950 | * </pre>
951 | *
952 | * When in doubt, use {@code goog.testing.dom.assertHtmlMatches}.
953 | *
954 | * @param {*} a The expected value (2 args) or the debug message (3 args).
955 | * @param {*} b The actual value (2 args) or the expected value (3 args).
956 | * @param {*=} opt_c The actual value (3 args only).
957 | */
958 | var assertHTMLEquals = function(a, b, opt_c) {
959 | _validateArguments(2, arguments);
960 | var var1 = nonCommentArg(1, 2, arguments);
961 | var var2 = nonCommentArg(2, 2, arguments);
962 | var var1Standardized = standardizeHTML(var1);
963 | var var2Standardized = standardizeHTML(var2);
964 |
965 | _assert(commentArg(2, arguments), var1Standardized === var2Standardized,
966 | goog.testing.asserts.getDefaultErrorMsg_(
967 | var1Standardized, var2Standardized));
968 | };
969 |
970 |
971 | /**
972 | * Compares two CSS property values to make sure that they represent the same
973 | * things. This will normalize values in the browser. For example, in Firefox,
974 | * this assertion will consider "rgb(0, 0, 255)" and "#0000ff" to be identical
975 | * values for the "color" property. This function won't normalize everything --
976 | * for example, in most browsers, "blue" will not match "#0000ff". It is
977 | * intended only to compensate for unexpected normalizations performed by
978 | * the browser that should also affect your expected value.
979 | * @param {string} a Assertion message, or the CSS property name.
980 | * @param {string} b CSS property name, or the expected value.
981 | * @param {string} c The expected value, or the actual value.
982 | * @param {string=} opt_d The actual value.
983 | */
984 | var assertCSSValueEquals = function(a, b, c, opt_d) {
985 | _validateArguments(3, arguments);
986 | var propertyName = nonCommentArg(1, 3, arguments);
987 | var expectedValue = nonCommentArg(2, 3, arguments);
988 | var actualValue = nonCommentArg(3, 3, arguments);
989 | var expectedValueStandardized =
990 | standardizeCSSValue(propertyName, expectedValue);
991 | var actualValueStandardized =
992 | standardizeCSSValue(propertyName, actualValue);
993 |
994 | _assert(commentArg(3, arguments),
995 | expectedValueStandardized == actualValueStandardized,
996 | goog.testing.asserts.getDefaultErrorMsg_(
997 | expectedValueStandardized, actualValueStandardized));
998 | };
999 |
1000 |
1001 | /**
1002 | * @param {*} a The expected value (2 args) or the debug message (3 args).
1003 | * @param {*} b The actual value (2 args) or the expected value (3 args).
1004 | * @param {*=} opt_c The actual value (3 args only).
1005 | */
1006 | var assertHashEquals = function(a, b, opt_c) {
1007 | _validateArguments(2, arguments);
1008 | var var1 = nonCommentArg(1, 2, arguments);
1009 | var var2 = nonCommentArg(2, 2, arguments);
1010 | var message = commentArg(2, arguments);
1011 | for (var key in var1) {
1012 | _assert(message,
1013 | key in var2, 'Expected hash had key ' + key + ' that was not found');
1014 | _assert(message, var1[key] == var2[key], 'Value for key ' + key +
1015 | ' mismatch - expected = ' + var1[key] + ', actual = ' + var2[key]);
1016 | }
1017 |
1018 | for (var key in var2) {
1019 | _assert(message, key in var1, 'Actual hash had key ' + key +
1020 | ' that was not expected');
1021 | }
1022 | };
1023 |
1024 |
1025 | /**
1026 | * @param {*} a The expected value (3 args) or the debug message (4 args).
1027 | * @param {*} b The actual value (3 args) or the expected value (4 args).
1028 | * @param {*} c The tolerance (3 args) or the actual value (4 args).
1029 | * @param {*=} opt_d The tolerance (4 args only).
1030 | */
1031 | var assertRoughlyEquals = function(a, b, c, opt_d) {
1032 | _validateArguments(3, arguments);
1033 | var expected = nonCommentArg(1, 3, arguments);
1034 | var actual = nonCommentArg(2, 3, arguments);
1035 | var tolerance = nonCommentArg(3, 3, arguments);
1036 | _assert(commentArg(3, arguments),
1037 | goog.testing.asserts.numberRoughEqualityPredicate_(
1038 | expected, actual, tolerance),
1039 | 'Expected ' + expected + ', but got ' + actual +
1040 | ' which was more than ' + tolerance + ' away');
1041 | };
1042 |
1043 |
1044 | /**
1045 | * Checks if the given element is the member of the given container.
1046 | * @param {*} a Failure message (3 arguments) or the contained element
1047 | * (2 arguments).
1048 | * @param {*} b The contained element (3 arguments) or the container
1049 | * (2 arguments).
1050 | * @param {*=} opt_c The container.
1051 | */
1052 | var assertContains = function(a, b, opt_c) {
1053 | _validateArguments(2, arguments);
1054 | var contained = nonCommentArg(1, 2, arguments);
1055 | var container = nonCommentArg(2, 2, arguments);
1056 | _assert(commentArg(2, arguments),
1057 | goog.testing.asserts.contains_(container, contained),
1058 | 'Expected \'' + container + '\' to contain \'' + contained + '\'');
1059 | };
1060 |
1061 |
1062 | /**
1063 | * Checks if the given element is not the member of the given container.
1064 | * @param {*} a Failure message (3 arguments) or the contained element
1065 | * (2 arguments).
1066 | * @param {*} b The contained element (3 arguments) or the container
1067 | * (2 arguments).
1068 | * @param {*=} opt_c The container.
1069 | */
1070 | var assertNotContains = function(a, b, opt_c) {
1071 | _validateArguments(2, arguments);
1072 | var contained = nonCommentArg(1, 2, arguments);
1073 | var container = nonCommentArg(2, 2, arguments);
1074 | _assert(commentArg(2, arguments),
1075 | !goog.testing.asserts.contains_(container, contained),
1076 | 'Expected \'' + container + '\' not to contain \'' + contained + '\'');
1077 | };
1078 |
1079 |
1080 | /**
1081 | * Checks if the given string matches the given regular expression.
1082 | * @param {*} a Failure message (3 arguments) or the expected regular
1083 | * expression as a string or RegExp (2 arguments).
1084 | * @param {*} b The regular expression (3 arguments) or the string to test
1085 | * (2 arguments).
1086 | * @param {*=} opt_c The string to test.
1087 | */
1088 | var assertRegExp = function(a, b, opt_c) {
1089 | _validateArguments(2, arguments);
1090 | var regexp = nonCommentArg(1, 2, arguments);
1091 | var string = nonCommentArg(2, 2, arguments);
1092 | if (typeof(regexp) == 'string') {
1093 | regexp = new RegExp(regexp);
1094 | }
1095 | _assert(commentArg(2, arguments),
1096 | regexp.test(string),
1097 | 'Expected \'' + string + '\' to match RegExp ' + regexp.toString());
1098 | };
1099 |
1100 |
1101 | /**
1102 | * Converts an array like object to array or clones it if it's already array.
1103 | * @param {goog.testing.asserts.ArrayLike} arrayLike The collection.
1104 | * @return {!Array<?>} Copy of the collection as array.
1105 | * @private
1106 | */
1107 | goog.testing.asserts.toArray_ = function(arrayLike) {
1108 | var ret = [];
1109 | for (var i = 0; i < arrayLike.length; i++) {
1110 | ret[i] = arrayLike[i];
1111 | }
1112 | return ret;
1113 | };
1114 |
1115 |
1116 | /**
1117 | * Finds the position of the first occurrence of an element in a container.
1118 | * @param {goog.testing.asserts.ArrayLike} container
1119 | * The array to find the element in.
1120 | * @param {*} contained Element to find.
1121 | * @return {number} Index of the first occurrence or -1 if not found.
1122 | * @private
1123 | */
1124 | goog.testing.asserts.indexOf_ = function(container, contained) {
1125 | if (container.indexOf) {
1126 | return container.indexOf(contained);
1127 | } else {
1128 | // IE6/7 do not have indexOf so do a search.
1129 | for (var i = 0; i < container.length; i++) {
1130 | if (container[i] === contained) {
1131 | return i;
1132 | }
1133 | }
1134 | return -1;
1135 | }
1136 | };
1137 |
1138 |
1139 | /**
1140 | * Tells whether the array contains the given element.
1141 | * @param {goog.testing.asserts.ArrayLike} container The array to
1142 | * find the element in.
1143 | * @param {*} contained Element to find.
1144 | * @return {boolean} Whether the element is in the array.
1145 | * @private
1146 | */
1147 | goog.testing.asserts.contains_ = function(container, contained) {
1148 | // TODO(user): Can we check for container.contains as well?
1149 | // That would give us support for most goog.structs (though weird results
1150 | // with anything else with a contains method, like goog.math.Range). Falling
1151 | // back with container.some would catch all iterables, too.
1152 | return goog.testing.asserts.indexOf_(container, contained) != -1;
1153 | };
1154 |
1155 | var standardizeHTML = function(html) {
1156 | var translator = document.createElement('DIV');
1157 | translator.innerHTML = html;
1158 |
1159 | // Trim whitespace from result (without relying on goog.string)
1160 | return translator.innerHTML.replace(/^\s+|\s+$/g, '');
1161 | };
1162 |
1163 |
1164 | /**
1165 | * Standardizes a CSS value for a given property by applying it to an element
1166 | * and then reading it back.
1167 | * @param {string} propertyName CSS property name.
1168 | * @param {string} value CSS value.
1169 | * @return {string} Normalized CSS value.
1170 | */
1171 | var standardizeCSSValue = function(propertyName, value) {
1172 | var styleDeclaration = document.createElement('DIV').style;
1173 | styleDeclaration[propertyName] = value;
1174 | return styleDeclaration[propertyName];
1175 | };
1176 |
1177 |
1178 | /**
1179 | * Raises a JsUnit exception with the given comment.
1180 | * @param {string} comment A summary for the exception.
1181 | * @param {string=} opt_message A description of the exception.
1182 | */
1183 | goog.testing.asserts.raiseException = function(comment, opt_message) {
1184 | throw new goog.testing.JsUnitException(comment, opt_message);
1185 | };
1186 |
1187 |
1188 | /**
1189 | * Helper function for assertObjectEquals.
1190 | * @param {string} prop A property name.
1191 | * @return {boolean} If the property name is an array index.
1192 | * @private
1193 | */
1194 | goog.testing.asserts.isArrayIndexProp_ = function(prop) {
1195 | return (prop | 0) == prop;
1196 | };
1197 |
1198 |
1199 |
1200 | /**
1201 | * @param {string} comment A summary for the exception.
1202 | * @param {?string=} opt_message A description of the exception.
1203 | * @constructor
1204 | * @extends {Error}
1205 | * @final
1206 | */
1207 | goog.testing.JsUnitException = function(comment, opt_message) {
1208 | this.isJsUnitException = true;
1209 | this.message = (comment ? comment : '') +
1210 | (comment && opt_message ? '\n' : '') +
1211 | (opt_message ? opt_message : '');
1212 | this.stackTrace = goog.testing.stacktrace.get();
1213 | // These fields are for compatibility with jsUnitTestManager.
1214 | this.comment = comment || null;
1215 | this.jsUnitMessage = opt_message || '';
1216 |
1217 | // Ensure there is a stack trace.
1218 | if (Error.captureStackTrace) {
1219 | Error.captureStackTrace(this, goog.testing.JsUnitException);
1220 | } else {
1221 | this.stack = new Error().stack || '';
1222 | }
1223 | };
1224 | goog.inherits(goog.testing.JsUnitException, Error);
1225 |
1226 |
1227 | /** @override */
1228 | goog.testing.JsUnitException.prototype.toString = function() {
1229 | return this.message;
1230 | };
1231 |
1232 |
1233 | goog.exportSymbol('fail', fail);
1234 | goog.exportSymbol('assert', assert);
1235 | goog.exportSymbol('assertThrows', assertThrows);
1236 | goog.exportSymbol('assertNotThrows', assertNotThrows);
1237 | goog.exportSymbol('assertTrue', assertTrue);
1238 | goog.exportSymbol('assertFalse', assertFalse);
1239 | goog.exportSymbol('assertEquals', assertEquals);
1240 | goog.exportSymbol('assertNotEquals', assertNotEquals);
1241 | goog.exportSymbol('assertNull', assertNull);
1242 | goog.exportSymbol('assertNotNull', assertNotNull);
1243 | goog.exportSymbol('assertUndefined', assertUndefined);
1244 | goog.exportSymbol('assertNotUndefined', assertNotUndefined);
1245 | goog.exportSymbol('assertNotNullNorUndefined', assertNotNullNorUndefined);
1246 | goog.exportSymbol('assertNonEmptyString', assertNonEmptyString);
1247 | goog.exportSymbol('assertNaN', assertNaN);
1248 | goog.exportSymbol('assertNotNaN', assertNotNaN);
1249 | goog.exportSymbol('assertObjectEquals', assertObjectEquals);
1250 | goog.exportSymbol('assertObjectRoughlyEquals', assertObjectRoughlyEquals);
1251 | goog.exportSymbol('assertObjectNotEquals', assertObjectNotEquals);
1252 | goog.exportSymbol('assertArrayEquals', assertArrayEquals);
1253 | goog.exportSymbol('assertElementsEquals', assertElementsEquals);
1254 | goog.exportSymbol('assertElementsRoughlyEqual', assertElementsRoughlyEqual);
1255 | goog.exportSymbol('assertSameElements', assertSameElements);
1256 | goog.exportSymbol('assertEvaluatesToTrue', assertEvaluatesToTrue);
1257 | goog.exportSymbol('assertEvaluatesToFalse', assertEvaluatesToFalse);
1258 | goog.exportSymbol('assertHTMLEquals', assertHTMLEquals);
1259 | goog.exportSymbol('assertHashEquals', assertHashEquals);
1260 | goog.exportSymbol('assertRoughlyEquals', assertRoughlyEquals);
1261 | goog.exportSymbol('assertContains', assertContains);
1262 | goog.exportSymbol('assertNotContains', assertNotContains);
1263 | goog.exportSymbol('assertRegExp', assertRegExp);