2 * Copyright 2009 Google Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
16 function expectAsserts(count
) {
17 jstestdriver
.expectedAssertCount
= count
;
21 var fail
= function fail(msg
) {
22 var err
= new Error(msg
);
23 err
.name
= 'AssertError';
33 function isBoolean_(bool
) {
34 if (typeof(bool
) != 'boolean') {
35 fail('Not a boolean: ' + prettyPrintEntity_(bool
));
40 var isElement_
= (function () {
41 var div
= document
.createElement('div');
43 function isNode(obj
) {
54 return function isElement(obj
) {
55 return obj
&& obj
.nodeType
=== 1 && isNode(obj
);
60 function formatElement_(el
) {
64 tagName
= el
.tagName
.toLowerCase();
65 var str
= '<' + tagName
;
66 var attrs
= el
.attributes
, attribute
;
68 for (var i
= 0, l
= attrs
.length
; i
< l
; i
++) {
69 attribute
= attrs
.item(i
);
71 if (!!attribute
.nodeValue
) {
72 str
+= ' ' + attribute
.nodeName
+ '=\"' + attribute
.nodeValue
+ '\"';
76 return str
+ '>...</' + tagName
+ '>';
78 return '[Element]' + (!!tagName
? ' ' + tagName
: '');
83 function prettyPrintEntity_(entity
) {
84 if (isElement_(entity
)) {
85 return formatElement_(entity
);
90 if (typeof entity
== 'function') {
92 str
= entity
.toString().match(/(function [^\(]+\(\))/)[1];
95 return str
|| '[function]';
99 str
= JSON
.stringify(entity
);
102 return str
|| '[' + typeof entity
+ ']';
106 function argsWithOptionalMsg_(args
, length
) {
108 // make copy because it's bad practice to change a passed in mutable
109 // And to ensure we aren't working with an arguments array. IE gets bitchy.
110 for(var i
= 0; i
< args
.length
; i
++) {
111 copyOfArgs
.push(args
[i
]);
113 var min
= length
- 1;
115 if (args
.length
< min
) {
116 fail('expected at least ' + min
+ ' arguments, got ' + args
.length
);
117 } else if (args
.length
== length
) {
118 copyOfArgs
[0] += ' ';
120 copyOfArgs
.unshift('');
126 function assertTrue(msg
, actual
) {
127 var args
= argsWithOptionalMsg_(arguments
, 2);
128 jstestdriver
.assertCount
++;
131 if (args
[1] != true) {
132 fail(args
[0] + 'expected true but was ' + prettyPrintEntity_(args
[1]));
138 function assertFalse(msg
, actual
) {
139 var args
= argsWithOptionalMsg_(arguments
, 2);
140 jstestdriver
.assertCount
++;
143 if (args
[1] != false) {
144 fail(args
[0] + 'expected false but was ' + prettyPrintEntity_(args
[1]));
150 function assertEquals(msg
, expected
, actual
) {
151 var args
= argsWithOptionalMsg_(arguments
, 3);
152 jstestdriver
.assertCount
++;
157 if (!compare_(expected
, actual
)) {
158 fail(msg
+ 'expected ' + prettyPrintEntity_(expected
) + ' but was ' +
159 prettyPrintEntity_(actual
) + '');
165 function compare_(expected
, actual
) {
166 if (expected
=== actual
) {
170 if (typeof expected
!= 'object' ||
171 typeof actual
!= 'object' ||
172 !expected
|| !actual
) {
173 return expected
== actual
;
176 if (isElement_(expected
) || isElement_(actual
)) {
181 var actualLength
= 0;
182 var expectedLength
= 0;
185 // If an array is expected the length of actual should be simple to
186 // determine. If it is not it is undefined.
187 if (jstestdriver
.jQuery
.isArray(actual
)) {
188 actualLength
= actual
.length
;
190 // In case it is an object it is a little bit more complicated to
192 for (key
in actual
) {
193 if (actual
.hasOwnProperty(key
)) {
200 if (actualLength
== 0 && typeof actual
.length
== 'number') {
201 actualLength
= actual
.length
;
203 for (var i
= 0, l
= actualLength
; i
< l
; i
++) {
204 if (!(i
in actual
)) {
211 for (key
in expected
) {
212 if (expected
.hasOwnProperty(key
)) {
213 if (!compare_(expected
[key
], actual
[key
])) {
221 if (expectedLength
!= actualLength
) {
225 return expectedLength
== 0 ? expected
.toString() == actual
.toString() : true;
232 function assertNotEquals(msg
, expected
, actual
) {
234 assertEquals
.apply(this, arguments
);
236 if (e
.name
== 'AssertError') {
243 var args
= argsWithOptionalMsg_(arguments
, 3);
245 fail(args
[0] + 'expected ' + prettyPrintEntity_(args
[1]) +
246 ' not to be equal to ' + prettyPrintEntity_(args
[2]));
250 function assertSame(msg
, expected
, actual
) {
251 var args
= argsWithOptionalMsg_(arguments
, 3);
252 jstestdriver
.assertCount
++;
254 if (!isSame_(args
[2], args
[1])) {
255 fail(args
[0] + 'expected ' + prettyPrintEntity_(args
[1]) + ' but was ' +
256 prettyPrintEntity_(args
[2]));
262 function assertNotSame(msg
, expected
, actual
) {
263 var args
= argsWithOptionalMsg_(arguments
, 3);
264 jstestdriver
.assertCount
++;
266 if (isSame_(args
[2], args
[1])) {
267 fail(args
[0] + 'expected not same as ' + prettyPrintEntity_(args
[1]) +
268 ' but was ' + prettyPrintEntity_(args
[2]));
274 function isSame_(expected
, actual
) {
275 return actual
=== expected
;
279 function assertNull(msg
, actual
) {
280 var args
= argsWithOptionalMsg_(arguments
, 2);
281 jstestdriver
.assertCount
++;
283 if (args
[1] !== null) {
284 fail(args
[0] + 'expected null but was ' + prettyPrintEntity_(args
[1]));
290 function assertNotNull(msg
, actual
) {
291 var args
= argsWithOptionalMsg_(arguments
, 2);
292 jstestdriver
.assertCount
++;
294 if (args
[1] === null) {
295 fail(args
[0] + 'expected not null but was null');
302 function assertUndefined(msg
, actual
) {
303 var args
= argsWithOptionalMsg_(arguments
, 2);
304 jstestdriver
.assertCount
++;
306 if (typeof args
[1] != 'undefined') {
307 fail(args
[2] + 'expected undefined but was ' + prettyPrintEntity_(args
[1]));
313 function assertNotUndefined(msg
, actual
) {
314 var args
= argsWithOptionalMsg_(arguments
, 2);
315 jstestdriver
.assertCount
++;
317 if (typeof args
[1] == 'undefined') {
318 fail(args
[0] + 'expected not undefined but was undefined');
324 function assertNaN(msg
, actual
) {
325 var args
= argsWithOptionalMsg_(arguments
, 2);
326 jstestdriver
.assertCount
++;
328 if (!isNaN(args
[1])) {
329 fail(args
[0] + 'expected to be NaN but was ' + args
[1]);
336 function assertNotNaN(msg
, actual
) {
337 var args
= argsWithOptionalMsg_(arguments
, 2);
338 jstestdriver
.assertCount
++;
340 if (isNaN(args
[1])) {
341 fail(args
[0] + 'expected not to be NaN');
348 function assertException(msg
, callback
, error
) {
349 if (arguments
.length
== 1) {
350 // assertThrows(callback)
353 } else if (arguments
.length
== 2) {
354 if (typeof callback
!= 'function') {
355 // assertThrows(callback, type)
360 // assertThrows(msg, callback)
364 // assertThrows(msg, callback, type)
368 jstestdriver
.assertCount
++;
373 if (e
.name
== 'AssertError') {
377 if (error
&& e
.name
!= error
) {
378 fail(msg
+ 'expected to throw ' + error
+ ' but threw ' + e
.name
);
384 fail(msg
+ 'expected to throw exception');
388 function assertNoException(msg
, callback
) {
389 var args
= argsWithOptionalMsg_(arguments
, 2);
390 jstestdriver
.assertCount
++;
395 fail(args
[0] + 'expected not to throw exception, but threw ' + e
.name
+
396 ' (' + e
.message
+ ')');
401 function assertArray(msg
, actual
) {
402 var args
= argsWithOptionalMsg_(arguments
, 2);
403 jstestdriver
.assertCount
++;
405 if (!jstestdriver
.jQuery
.isArray(args
[1])) {
406 fail(args
[0] + 'expected to be array, but was ' +
407 prettyPrintEntity_(args
[1]));
412 function assertTypeOf(msg
, expected
, value
) {
413 var args
= argsWithOptionalMsg_(arguments
, 3);
414 jstestdriver
.assertCount
++;
415 var actual
= typeof args
[2];
417 if (actual
!= args
[1]) {
418 fail(args
[0] + 'expected to be ' + args
[1] + ' but was ' + actual
);
425 function assertBoolean(msg
, actual
) {
426 var args
= argsWithOptionalMsg_(arguments
, 2);
427 return assertTypeOf(args
[0], 'boolean', args
[1]);
431 function assertFunction(msg
, actual
) {
432 var args
= argsWithOptionalMsg_(arguments
, 2);
433 return assertTypeOf(args
[0], 'function', args
[1]);
437 function assertObject(msg
, actual
) {
438 var args
= argsWithOptionalMsg_(arguments
, 2);
439 return assertTypeOf(args
[0], 'object', args
[1]);
443 function assertNumber(msg
, actual
) {
444 var args
= argsWithOptionalMsg_(arguments
, 2);
445 return assertTypeOf(args
[0], 'number', args
[1]);
449 function assertString(msg
, actual
) {
450 var args
= argsWithOptionalMsg_(arguments
, 2);
451 return assertTypeOf(args
[0], 'string', args
[1]);
455 function assertMatch(msg
, regexp
, actual
) {
456 var args
= argsWithOptionalMsg_(arguments
, 3);
457 var isUndef
= typeof args
[2] == 'undefined';
458 jstestdriver
.assertCount
++;
461 if (isUndef
|| !args
[1].test(args
[2])) {
462 actual
= (isUndef
? _undef
: prettyPrintEntity_(args
[2]));
463 fail(args
[0] + 'expected ' + actual
+ ' to match ' + args
[1]);
470 function assertNoMatch(msg
, regexp
, actual
) {
471 var args
= argsWithOptionalMsg_(arguments
, 3);
472 jstestdriver
.assertCount
++;
474 if (args
[1].test(args
[2])) {
475 fail(args
[0] + 'expected ' + prettyPrintEntity_(args
[2]) +
476 ' not to match ' + args
[1]);
483 function assertTagName(msg
, tagName
, element
) {
484 var args
= argsWithOptionalMsg_(arguments
, 3);
485 var actual
= args
[2] && args
[2].tagName
;
487 if (String(actual
).toUpperCase() != args
[1].toUpperCase()) {
488 fail(args
[0] + 'expected tagName to be ' + args
[1] + ' but was ' + actual
);
494 function assertClassName(msg
, className
, element
) {
495 var args
= argsWithOptionalMsg_(arguments
, 3);
496 var actual
= args
[2] && args
[2].className
;
497 var regexp
= new RegExp('(^|\\s)' + args
[1] + '(\\s|$)');
500 assertMatch(args
[0], regexp
, actual
);
502 actual
= prettyPrintEntity_(actual
);
503 fail(args
[0] + 'expected class name to include ' +
504 prettyPrintEntity_(args
[1]) + ' but was ' + actual
);
511 function assertElementId(msg
, id
, element
) {
512 var args
= argsWithOptionalMsg_(arguments
, 3);
513 var actual
= args
[2] && args
[2].id
;
514 jstestdriver
.assertCount
++;
516 if (actual
!== args
[1]) {
517 fail(args
[0] + 'expected id to be ' + args
[1] + ' but was ' + actual
);
524 function assertInstanceOf(msg
, constructor
, actual
) {
525 jstestdriver
.assertCount
++;
526 var args
= argsWithOptionalMsg_(arguments
, 3);
527 var pretty
= prettyPrintEntity_(args
[2]);
528 var expected
= args
[1] && args
[1].name
|| args
[1];
530 if (args
[2] == null) {
531 fail(args
[0] + 'expected ' + pretty
+ ' to be instance of ' + expected
);
534 if (!(Object(args
[2]) instanceof args
[1])) {
535 fail(args
[0] + 'expected ' + pretty
+ ' to be instance of ' + expected
);
542 function assertNotInstanceOf(msg
, constructor
, actual
) {
543 var args
= argsWithOptionalMsg_(arguments
, 3);
544 jstestdriver
.assertCount
++;
546 if (Object(args
[2]) instanceof args
[1]) {
547 var expected
= args
[1] && args
[1].name
|| args
[1];
548 var pretty
= prettyPrintEntity_(args
[2]);
549 fail(args
[0] + 'expected ' + pretty
+ ' not to be instance of ' + expected
);
556 * Asserts that two doubles, or the elements of two arrays of doubles,
557 * are equal to within a positive delta.
559 function assertEqualsDelta(msg
, expected
, actual
, epsilon
) {
560 var args
= this.argsWithOptionalMsg_(arguments
, 4);
561 jstestdriver
.assertCount
++;
567 if (!compareDelta_(expected
, actual
, epsilon
)) {
568 this.fail(msg
+ 'expected ' + epsilon
+ ' within ' +
569 this.prettyPrintEntity_(expected
) +
570 ' but was ' + this.prettyPrintEntity_(actual
) + '');
575 function compareDelta_(expected
, actual
, epsilon
) {
576 var compareDouble
= function(e
,a
,d
) {
577 return Math
.abs(e
- a
) <= d
;
579 if (expected
=== actual
) {
583 if (typeof expected
== "number" ||
584 typeof actual
== "number" ||
585 !expected
|| !actual
) {
586 return compareDouble(expected
, actual
, epsilon
);
589 if (isElement_(expected
) || isElement_(actual
)) {
594 var actualLength
= 0;
595 var expectedLength
= 0;
598 // If an array is expected the length of actual should be simple to
599 // determine. If it is not it is undefined.
600 if (jstestdriver
.jQuery
.isArray(actual
)) {
601 actualLength
= actual
.length
;
603 // In case it is an object it is a little bit more complicated to
605 for (key
in actual
) {
606 if (actual
.hasOwnProperty(key
)) {
613 if (actualLength
== 0 && typeof actual
.length
== "number") {
614 actualLength
= actual
.length
;
616 for (var i
= 0, l
= actualLength
; i
< l
; i
++) {
617 if (!(i
in actual
)) {
624 for (key
in expected
) {
625 if (expected
.hasOwnProperty(key
)) {
626 if (!compareDelta_(expected
[key
], actual
[key
], epsilon
)) {
634 if (expectedLength
!= actualLength
) {
638 return expectedLength
== 0 ? expected
.toString() == actual
.toString() : true;
644 var assert
= assertTrue
;