First set of automated tests for Dygraphs.
[dygraphs.git] / auto_tests / lib / Asserts.js
1 /*
2 * Copyright 2009 Google Inc.
3 *
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
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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
14 * the License.
15 */
16
17 function expectAsserts(count) {
18 jstestdriver.expectedAssertCount = count;
19 }
20
21
22 this.fail = function fail(msg) {
23 var err = new Error(msg);
24 err.name = 'AssertError';
25
26 if (!err.message) {
27 err.message = msg;
28 }
29
30 throw err;
31 }
32
33
34 function isBoolean_(bool) {
35 if (typeof(bool) != 'boolean') {
36 this.fail('Not a boolean: ' + this.prettyPrintEntity_(bool));
37 }
38 }
39
40 var isElement_ = (function () {
41 var div = document.createElement('div');
42
43 function isNode(obj) {
44 try {
45 div.appendChild(obj);
46 div.removeChild(obj);
47 } catch (e) {
48 return false;
49 }
50
51 return true;
52 }
53
54 return function isElement(obj) {
55 return obj && obj.nodeType === 1 && isNode(obj);
56 };
57 }());
58
59 function formatElement_(el) {
60 var tagName;
61
62 try {
63 tagName = el.tagName.toLowerCase();
64 var str = "<" + tagName;
65 var attrs = el.attributes, attribute;
66
67 for (var i = 0, l = attrs.length; i < l; i++) {
68 attribute = attrs.item(i);
69
70 if (!!attribute.nodeValue) {
71 str += " " + attribute.nodeName + "=\"" + attribute.nodeValue + "\"";
72 }
73 }
74
75 return str + ">...</" + tagName + ">";
76 } catch (e) {
77 return "[Element]" + (!!tagName ? " " + tagName : "");
78 }
79 }
80
81 function prettyPrintEntity_(entity) {
82 if (isElement_(entity)) {
83 return formatElement_(entity);
84 }
85
86 var str;
87
88 if (typeof entity == "function") {
89 try {
90 str = entity.toString().match(/(function [^\(]+\(\))/)[1];
91 } catch (e) {}
92
93 return str || "[function]";
94 }
95
96 try {
97 str = this.JSON.stringify(entity);
98 } catch (e) {}
99
100 return str || "[" + typeof entity + "]";
101 }
102
103
104 function argsWithOptionalMsg_(args, length) {
105 var copyOfArgs = [];
106 // make copy because it's bad practice to change a passed in mutable
107 // And to ensure we aren't working with an arguments array. IE gets bitchy.
108 for(var i = 0; i < args.length; i++) {
109 copyOfArgs.push(args[i]);
110 }
111 var min = length - 1;
112
113 if (args.length < min) {
114 this.fail("expected at least " +
115 min + " arguments, got " + args.length);
116 } else if (args.length == length) {
117 copyOfArgs[0] += " ";
118 } else {
119 copyOfArgs.unshift("");
120 }
121 return copyOfArgs;
122 }
123
124
125 function assertTrue(msg, actual) {
126 var args = this.argsWithOptionalMsg_(arguments, 2);
127 jstestdriver.assertCount++;
128
129 isBoolean_(args[1]);
130 if (args[1] != true) {
131 this.fail(args[0] + 'expected true but was ' +
132 this.prettyPrintEntity_(args[1]));
133 }
134 return true;
135 };
136
137
138 function assertFalse(msg, actual) {
139 var args = this.argsWithOptionalMsg_(arguments, 2);
140 jstestdriver.assertCount++;
141
142 isBoolean_(args[1]);
143 if (args[1] != false) {
144 this.fail(args[0] + 'expected false but was ' +
145 this.prettyPrintEntity_(args[1]));
146 }
147 return true;
148 };
149
150
151 function assertEquals(msg, expected, actual) {
152 var args = this.argsWithOptionalMsg_(arguments, 3);
153 jstestdriver.assertCount++;
154 msg = args[0];
155 expected = args[1];
156 actual = args[2];
157
158 if (!compare_(expected, actual)) {
159 this.fail(msg + 'expected ' + this.prettyPrintEntity_(expected) +
160 ' but was ' + this.prettyPrintEntity_(actual) + '');
161 }
162 return true;
163 };
164
165
166 function compare_(expected, actual) {
167 if (expected === actual) {
168 return true;
169 }
170
171 if (typeof expected != "object" ||
172 typeof actual != "object" ||
173 !expected || !actual) {
174 return expected == actual;
175 }
176
177 if (isElement_(expected) || isElement_(actual)) {
178 return false;
179 }
180
181 var key = null;
182 var actualLength = 0;
183 var expectedLength = 0;
184
185 try {
186 // If an array is expected the length of actual should be simple to
187 // determine. If it is not it is undefined.
188 if (jstestdriver.jQuery.isArray(actual)) {
189 actualLength = actual.length;
190 } else {
191 // In case it is an object it is a little bit more complicated to
192 // get the length.
193 for (key in actual) {
194 if (actual.hasOwnProperty(key)) {
195 ++actualLength;
196 }
197 }
198 }
199
200 // Arguments object
201 if (actualLength == 0 && typeof actual.length == "number") {
202 actualLength = actual.length;
203
204 for (var i = 0, l = actualLength; i < l; i++) {
205 if (!(i in actual)) {
206 actualLength = 0;
207 break;
208 }
209 }
210 }
211
212 for (key in expected) {
213 if (expected.hasOwnProperty(key)) {
214 if (!compare_(expected[key], actual[key])) {
215 return false;
216 }
217
218 ++expectedLength;
219 }
220 }
221
222 if (expectedLength != actualLength) {
223 return false;
224 }
225
226 return expectedLength == 0 ? expected.toString() == actual.toString() : true;
227 } catch (e) {
228 return false;
229 }
230 };
231
232
233 function assertNotEquals(msg, expected, actual) {
234 try {
235 assertEquals.apply(this, arguments);
236 } catch (e) {
237 if (e.name == "AssertError") {
238 return true;
239 }
240
241 throw e;
242 }
243
244 var args = this.argsWithOptionalMsg_(arguments, 3);
245
246 this.fail(args[0] + "expected " + this.prettyPrintEntity_(args[1]) +
247 " not to be equal to " + this.prettyPrintEntity_(args[2]));
248 }
249
250
251 function assertSame(msg, expected, actual) {
252 var args = this.argsWithOptionalMsg_(arguments, 3);
253 jstestdriver.assertCount++;
254
255 if (!isSame_(args[2], args[1])) {
256 this.fail(args[0] + 'expected ' + this.prettyPrintEntity_(args[1]) +
257 ' but was ' + this.prettyPrintEntity_(args[2]));
258 }
259 return true;
260 };
261
262
263 function assertNotSame(msg, expected, actual) {
264 var args = this.argsWithOptionalMsg_(arguments, 3);
265 jstestdriver.assertCount++;
266
267 if (isSame_(args[2], args[1])) {
268 this.fail(args[0] + 'expected not same as ' +
269 this.prettyPrintEntity_(args[1]) + ' but was ' +
270 this.prettyPrintEntity_(args[2]));
271 }
272 return true;
273 };
274
275
276 function isSame_(expected, actual) {
277 return actual === expected;
278 };
279
280
281 function assertNull(msg, actual) {
282 var args = this.argsWithOptionalMsg_(arguments, 2);
283 jstestdriver.assertCount++;
284
285 if (args[1] !== null) {
286 this.fail(args[0] + 'expected null but was ' +
287 this.prettyPrintEntity_(args[1]));
288 }
289 return true;
290 };
291
292
293 function assertNotNull(msg, actual) {
294 var args = this.argsWithOptionalMsg_(arguments, 2);
295 jstestdriver.assertCount++;
296
297 if (args[1] === null) {
298 this.fail(args[0] + "expected not null but was null");
299 }
300
301 return true;
302 };
303
304
305 function assertUndefined(msg, actual) {
306 var args = this.argsWithOptionalMsg_(arguments, 2);
307 jstestdriver.assertCount++;
308
309 if (typeof args[1] != "undefined") {
310 this.fail(args[2] + "expected undefined but was " +
311 this.prettyPrintEntity_(args[1]));
312 }
313 return true;
314 };
315
316
317 function assertNotUndefined(msg, actual) {
318 var args = this.argsWithOptionalMsg_(arguments, 2);
319 jstestdriver.assertCount++;
320
321 if (typeof args[1] == "undefined") {
322 this.fail(args[0] + 'expected not undefined but was undefined');
323 }
324 return true;
325 };
326
327
328 function assertNaN(msg, actual) {
329 var args = this.argsWithOptionalMsg_(arguments, 2);
330 jstestdriver.assertCount++;
331
332 if (!isNaN(args[1])) {
333 this.fail(args[0] + "expected to be NaN but was " + args[1]);
334 }
335
336 return true;
337 }
338
339
340 function assertNotNaN(msg, actual) {
341 var args = this.argsWithOptionalMsg_(arguments, 2);
342 jstestdriver.assertCount++;
343
344 if (isNaN(args[1])) {
345 this.fail(args[0] + "expected not to be NaN");
346 }
347
348 return true;
349 }
350
351
352 function assertException(msg, callback, error) {
353 if (arguments.length == 1) {
354 // assertThrows(callback)
355 callback = msg;
356 msg = "";
357 } else if (arguments.length == 2) {
358 if (typeof callback != "function") {
359 // assertThrows(callback, type)
360 error = callback;
361 callback = msg;
362 msg = "";
363 } else {
364 // assertThrows(msg, callback)
365 msg += " ";
366 }
367 } else {
368 // assertThrows(msg, callback, type)
369 msg += " ";
370 }
371
372 jstestdriver.assertCount++;
373
374 try {
375 callback();
376 } catch(e) {
377 if (e.name == "AssertError") {
378 throw e;
379 }
380
381 if (error && e.name != error) {
382 this.fail(msg + "expected to throw " +
383 error + " but threw " + e.name);
384 }
385
386 return true;
387 }
388
389 this.fail(msg + "expected to throw exception");
390 }
391
392
393 function assertNoException(msg, callback) {
394 var args = this.argsWithOptionalMsg_(arguments, 2);
395 jstestdriver.assertCount++;
396
397 try {
398 args[1]();
399 } catch(e) {
400 fail(args[0] + "expected not to throw exception, but threw " +
401 e.name + " (" + e.message + ")");
402 }
403 }
404
405
406 function assertArray(msg, actual) {
407 var args = this.argsWithOptionalMsg_(arguments, 2);
408 jstestdriver.assertCount++;
409
410 if (!jstestdriver.jQuery.isArray(args[1])) {
411 fail(args[0] + "expected to be array, but was " +
412 this.prettyPrintEntity_(args[1]));
413 }
414 }
415
416
417 function assertTypeOf(msg, expected, value) {
418 var args = this.argsWithOptionalMsg_(arguments, 3);
419 jstestdriver.assertCount++;
420 var actual = typeof args[2];
421
422 if (actual != args[1]) {
423 this.fail(args[0] + "expected to be " + args[1] + " but was " + actual);
424 }
425
426 return true;
427 }
428
429
430 function assertBoolean(msg, actual) {
431 var args = this.argsWithOptionalMsg_(arguments, 2);
432 return assertTypeOf(args[0], "boolean", args[1]);
433 }
434
435
436 function assertFunction(msg, actual) {
437 var args = this.argsWithOptionalMsg_(arguments, 2);
438 return assertTypeOf(args[0], "function", args[1]);
439 }
440
441
442 function assertObject(msg, actual) {
443 var args = this.argsWithOptionalMsg_(arguments, 2);
444 return assertTypeOf(args[0], "object", args[1]);
445 }
446
447
448 function assertNumber(msg, actual) {
449 var args = this.argsWithOptionalMsg_(arguments, 2);
450 return assertTypeOf(args[0], "number", args[1]);
451 }
452
453
454 function assertString(msg, actual) {
455 var args = this.argsWithOptionalMsg_(arguments, 2);
456 return assertTypeOf(args[0], "string", args[1]);
457 }
458
459
460 function assertMatch(msg, regexp, actual) {
461 var args = this.argsWithOptionalMsg_(arguments, 3);
462 var isUndef = typeof args[2] == "undefined";
463 jstestdriver.assertCount++;
464 var _undef;
465
466 if (isUndef || !args[1].test(args[2])) {
467 actual = (isUndef ? _undef : this.prettyPrintEntity_(args[2]));
468 this.fail(args[0] + "expected " + actual + " to match " + args[1]);
469 }
470
471 return true;
472 }
473
474
475 function assertNoMatch(msg, regexp, actual) {
476 var args = this.argsWithOptionalMsg_(arguments, 3);
477 jstestdriver.assertCount++;
478
479 if (args[1].test(args[2])) {
480 this.fail(args[0] + "expected " + this.prettyPrintEntity_(args[2]) +
481 " not to match " + args[1]);
482 }
483
484 return true;
485 }
486
487
488 function assertTagName(msg, tagName, element) {
489 var args = this.argsWithOptionalMsg_(arguments, 3);
490 var actual = args[2] && args[2].tagName;
491
492 if (String(actual).toUpperCase() != args[1].toUpperCase()) {
493 this.fail(args[0] + "expected tagName to be " + args[1] + " but was " +
494 actual);
495 }
496 return true;
497 }
498
499
500 function assertClassName(msg, className, element) {
501 var args = this.argsWithOptionalMsg_(arguments, 3);
502 var actual = args[2] && args[2].className;
503 var regexp = new RegExp("(^|\\s)" + args[1] + "(\\s|$)");
504
505 try {
506 this.assertMatch(args[0], regexp, actual);
507 } catch (e) {
508 actual = this.prettyPrintEntity_(actual);
509 this.fail(args[0] + "expected class name to include " +
510 this.prettyPrintEntity_(args[1]) + " but was " + actual);
511 }
512
513 return true;
514 }
515
516
517 function assertElementId(msg, id, element) {
518 var args = this.argsWithOptionalMsg_(arguments, 3);
519 var actual = args[2] && args[2].id;
520 jstestdriver.assertCount++;
521
522 if (actual !== args[1]) {
523 this.fail(args[0] + "expected id to be " + args[1] + " but was " +
524 actual);
525 }
526
527 return true;
528 }
529
530
531 function assertInstanceOf(msg, constructor, actual) {
532 jstestdriver.assertCount++;
533 var args = this.argsWithOptionalMsg_(arguments, 3);
534 var pretty = this.prettyPrintEntity_(args[2]);
535 var expected = args[1] && args[1].name || args[1];
536
537 if (args[2] == null) {
538 this.fail(args[0] + "expected " + pretty + " to be instance of " +
539 expected);
540 }
541
542 if (!(Object(args[2]) instanceof args[1])) {
543 this.fail(args[0] + "expected " + pretty + " to be instance of " +
544 expected);
545 }
546
547 return true;
548 }
549
550
551 function assertNotInstanceOf(msg, constructor, actual) {
552 var args = this.argsWithOptionalMsg_(arguments, 3);
553 jstestdriver.assertCount++;
554
555 if (Object(args[2]) instanceof args[1]) {
556 var expected = args[1] && args[1].name || args[1];
557 var pretty = this.prettyPrintEntity_(args[2]);
558 this.fail(args[0] + "expected " + pretty + " not to be instance of " +
559 expected);
560 }
561
562 return true;
563 }
564
565 var assert = assertTrue;