|
1 /* |
|
2 Copyright (c) 2001-2005 World Wide Web Consortium, |
|
3 (Massachusetts Institute of Technology, Institut National de |
|
4 Recherche en Informatique et en Automatique, Keio University). All |
|
5 Rights Reserved. This program is distributed under the W3C's Software |
|
6 Intellectual Property License. This program is distributed in the |
|
7 hope that it will be useful, but WITHOUT ANY WARRANTY; without even |
|
8 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
|
9 PURPOSE. |
|
10 See W3C License http://www.w3.org/Consortium/Legal/ for more details. |
|
11 */ |
|
12 |
|
13 function assertNull(descr, actual) { |
|
14 return ok(actual === null, descr); |
|
15 } |
|
16 |
|
17 |
|
18 function assertNotNull(descr, actual) { |
|
19 return ok(actual !== null, descr); |
|
20 } |
|
21 |
|
22 function assertTrue(descr, actual) { |
|
23 return ok(actual === true, descr); |
|
24 } |
|
25 |
|
26 function assertFalse(descr, actual) { |
|
27 return ok(actual === false, descr); |
|
28 } |
|
29 |
|
30 function assertEquals(descr, expected, actual) { |
|
31 return is(expected, actual, descr); |
|
32 } |
|
33 |
|
34 function assertSize(descr, expected, actual) { |
|
35 ok(actual !== null, descr); |
|
36 // Work around too strict checks. |
|
37 if (!actual) { |
|
38 ok(actual, "[assertSize()] 'actual' has a value"); |
|
39 return; |
|
40 } |
|
41 |
|
42 is(actual.length, expected, descr); |
|
43 } |
|
44 |
|
45 function assertEqualsAutoCase(context, descr, expected, actual) { |
|
46 if (builder.contentType == "text/html") { |
|
47 if(context == "attribute") { |
|
48 is(actual.toLowerCase(), expected.toLowerCase(), descr); |
|
49 } else { |
|
50 is(actual, expected.toUpperCase(), descr); |
|
51 } |
|
52 } else { |
|
53 is(expected, actual, descr); |
|
54 } |
|
55 } |
|
56 |
|
57 |
|
58 function assertEqualsCollectionAutoCase(context, descr, expected, actual) { |
|
59 // |
|
60 // if they aren't the same size, they aren't equal |
|
61 is(actual.length, expected.length, descr); |
|
62 |
|
63 // |
|
64 // if there length is the same, then every entry in the expected list |
|
65 // must appear once and only once in the actual list |
|
66 var expectedLen = expected.length; |
|
67 var expectedValue; |
|
68 var actualLen = actual.length; |
|
69 var i; |
|
70 var j; |
|
71 var matches; |
|
72 for(i = 0; i < expectedLen; i++) { |
|
73 matches = 0; |
|
74 expectedValue = expected[i]; |
|
75 for(j = 0; j < actualLen; j++) { |
|
76 if (builder.contentType == "text/html") { |
|
77 if (context == "attribute") { |
|
78 if (expectedValue.toLowerCase() == actual[j].toLowerCase()) { |
|
79 matches++; |
|
80 } |
|
81 } else { |
|
82 if (expectedValue.toUpperCase() == actual[j]) { |
|
83 matches++; |
|
84 } |
|
85 } |
|
86 } else { |
|
87 if(expectedValue == actual[j]) { |
|
88 matches++; |
|
89 } |
|
90 } |
|
91 } |
|
92 if(matches == 0) { |
|
93 ok(false, descr + ": No match found for " + expectedValue); |
|
94 } |
|
95 if(matches > 1) { |
|
96 ok(false, descr + ": Multiple matches found for " + expectedValue); |
|
97 } |
|
98 } |
|
99 } |
|
100 |
|
101 function assertEqualsCollection(descr, expected, actual) { |
|
102 // |
|
103 // if they aren't the same size, they aren't equal |
|
104 is(actual.length, expected.length, descr); |
|
105 // |
|
106 // if there length is the same, then every entry in the expected list |
|
107 // must appear once and only once in the actual list |
|
108 var expectedLen = expected.length; |
|
109 var expectedValue; |
|
110 var actualLen = actual.length; |
|
111 var i; |
|
112 var j; |
|
113 var matches; |
|
114 for(i = 0; i < expectedLen; i++) { |
|
115 matches = 0; |
|
116 expectedValue = expected[i]; |
|
117 for(j = 0; j < actualLen; j++) { |
|
118 if(expectedValue == actual[j]) { |
|
119 matches++; |
|
120 } |
|
121 } |
|
122 if(matches == 0) { |
|
123 ok(false, descr + ": No match found for " + expectedValue); |
|
124 } |
|
125 if(matches > 1) { |
|
126 ok(false, descr + ": Multiple matches found for " + expectedValue); |
|
127 } |
|
128 } |
|
129 } |
|
130 |
|
131 |
|
132 function assertEqualsListAutoCase(context, descr, expected, actual) { |
|
133 var minLength = expected.length; |
|
134 if (actual.length < minLength) { |
|
135 minLength = actual.length; |
|
136 } |
|
137 // |
|
138 for(var i = 0; i < minLength; i++) { |
|
139 assertEqualsAutoCase(context, descr, expected[i], actual[i]); |
|
140 } |
|
141 // |
|
142 // if they aren't the same size, they aren't equal |
|
143 is(actual.length, expected.length, descr); |
|
144 } |
|
145 |
|
146 |
|
147 function assertEqualsList(descr, expected, actual) { |
|
148 var minLength = expected.length; |
|
149 if (actual.length < minLength) { |
|
150 minLength = actual.length; |
|
151 } |
|
152 // |
|
153 for(var i = 0; i < minLength; i++) { |
|
154 if(expected[i] != actual[i]) { |
|
155 is(actual[i], expected[i], descr); |
|
156 } |
|
157 } |
|
158 // |
|
159 // if they aren't the same size, they aren't equal |
|
160 is(actual.length, expected.length, descr); |
|
161 } |
|
162 |
|
163 function assertInstanceOf(descr, type, obj) { |
|
164 if(type == "Attr") { |
|
165 is(2, obj.nodeType, descr); |
|
166 var specd = obj.specified; |
|
167 } |
|
168 /* |
|
169 else { |
|
170 // Ensure at least one SimpleTest check is reported. (Bug 483992) |
|
171 todo_is(type, "Attr", "[DOMTestCase.assertInstanceOf()] Fake default check."); |
|
172 } |
|
173 */ |
|
174 } |
|
175 |
|
176 function assertSame(descr, expected, actual) { |
|
177 if(expected != actual) { |
|
178 is(expected.nodeType, actual.nodeType, descr); |
|
179 is(expected.nodeValue, actual.nodeValue, descr); |
|
180 } |
|
181 else { |
|
182 // Ensure at least one SimpleTest check is reported. (Bug 483992) |
|
183 todo_isnot(expected, actual, "[DOMTestCase.assertSame()] Fake default check." + |
|
184 " (Type=" + actual.nodeType + ", Value=" + actual.nodeValue + ")"); |
|
185 } |
|
186 } |
|
187 |
|
188 function assertURIEquals(assertID, scheme, path, host, file, name, query, fragment, isAbsolute, actual) { |
|
189 // |
|
190 // URI must be non-null |
|
191 ok(assertID, "[assertURIEquals()] 'assertID' has a value"); |
|
192 ok(actual, "[assertURIEquals()] 'actual' has a value"); |
|
193 /* |
|
194 // Add missing early return. |
|
195 if (!actual) |
|
196 return; |
|
197 */ |
|
198 |
|
199 var uri = actual; |
|
200 |
|
201 var lastPound = actual.lastIndexOf("#"); |
|
202 var actualFragment = ""; |
|
203 if(lastPound != -1) { |
|
204 // |
|
205 // substring before pound |
|
206 // |
|
207 uri = actual.substring(0,lastPound); |
|
208 actualFragment = actual.substring(lastPound+1); |
|
209 } |
|
210 if(fragment != null) is(actualFragment, fragment, assertID); |
|
211 |
|
212 var lastQuestion = uri.lastIndexOf("?"); |
|
213 var actualQuery = ""; |
|
214 if(lastQuestion != -1) { |
|
215 // |
|
216 // substring before pound |
|
217 // |
|
218 uri = actual.substring(0,lastQuestion); |
|
219 actualQuery = actual.substring(lastQuestion+1); |
|
220 } |
|
221 if(query != null) is(actualQuery, query, assertID); |
|
222 |
|
223 var firstColon = uri.indexOf(":"); |
|
224 var firstSlash = uri.indexOf("/"); |
|
225 var actualPath = uri; |
|
226 var actualScheme = ""; |
|
227 if(firstColon != -1 && firstColon < firstSlash) { |
|
228 actualScheme = uri.substring(0,firstColon); |
|
229 actualPath = uri.substring(firstColon + 1); |
|
230 } |
|
231 |
|
232 if(scheme != null) { |
|
233 is(scheme, actualScheme, assertID); |
|
234 } |
|
235 |
|
236 if(path != null) { |
|
237 is(path, actualPath, assertID); |
|
238 } |
|
239 |
|
240 if(host != null) { |
|
241 var actualHost = ""; |
|
242 if(actualPath.substring(0,2) == "//") { |
|
243 var termSlash = actualPath.substring(2).indexOf("/") + 2; |
|
244 actualHost = actualPath.substring(0,termSlash); |
|
245 } |
|
246 is(actualHost, host, assertID); |
|
247 } |
|
248 |
|
249 if(file != null || name != null) { |
|
250 var actualFile = actualPath; |
|
251 var finalSlash = actualPath.lastIndexOf("/"); |
|
252 if(finalSlash != -1) { |
|
253 actualFile = actualPath.substring(finalSlash+1); |
|
254 } |
|
255 if (file != null) { |
|
256 is(actualFile, file, assertID); |
|
257 } |
|
258 if (name != null) { |
|
259 var actualName = actualFile; |
|
260 var finalDot = actualFile.lastIndexOf("."); |
|
261 if (finalDot != -1) { |
|
262 actualName = actualName.substring(0, finalDot); |
|
263 } |
|
264 is(actualName, name, assertID); |
|
265 } |
|
266 } |
|
267 |
|
268 if(isAbsolute != null) { |
|
269 is(actualPath.substring(0,1) == "/", isAbsolute, assertID); |
|
270 } |
|
271 } |
|
272 |
|
273 |
|
274 // size() used by assertSize element |
|
275 function size(collection) |
|
276 { |
|
277 return collection.length; |
|
278 } |
|
279 |
|
280 function same(expected, actual) |
|
281 { |
|
282 return expected === actual; |
|
283 } |
|
284 |
|
285 function getSuffix(contentType) { |
|
286 switch(contentType) { |
|
287 case "text/html": |
|
288 return ".html"; |
|
289 |
|
290 case "text/xml": |
|
291 return ".xml"; |
|
292 |
|
293 case "application/xhtml+xml": |
|
294 return ".xhtml"; |
|
295 |
|
296 case "image/svg+xml": |
|
297 return ".svg"; |
|
298 |
|
299 case "text/mathml": |
|
300 return ".mml"; |
|
301 } |
|
302 return ".html"; |
|
303 } |
|
304 |
|
305 function equalsAutoCase(context, expected, actual) { |
|
306 if (builder.contentType == "text/html") { |
|
307 if (context == "attribute") { |
|
308 return expected.toLowerCase() == actual; |
|
309 } |
|
310 return expected.toUpperCase() == actual; |
|
311 } |
|
312 return expected == actual; |
|
313 } |
|
314 |
|
315 function catchInitializationError(blder, ex) { |
|
316 if (blder == null) { |
|
317 alert(ex); |
|
318 } else { |
|
319 blder.initializationError = ex; |
|
320 blder.initializationFatalError = ex; |
|
321 } |
|
322 } |
|
323 |
|
324 function checkInitialization(blder, testname) { |
|
325 if (blder.initializationError != null) { |
|
326 // Fake a "warn()" function, as it was missing :-| |
|
327 function warn(msg) { |
|
328 info("[checkInitialization() warning] " + msg); |
|
329 } |
|
330 |
|
331 if (blder.skipIncompatibleTests) { |
|
332 warn(testname + " not run:" + blder.initializationError); |
|
333 return blder.initializationError; |
|
334 } else { |
|
335 // |
|
336 // if an exception was thrown |
|
337 // rethrow it and do not run the test |
|
338 if (blder.initializationFatalError != null) { |
|
339 throw blder.initializationFatalError; |
|
340 } else { |
|
341 // |
|
342 // might be recoverable, warn but continue the test |
|
343 warn(testname + ": " + blder.initializationError); |
|
344 } |
|
345 } |
|
346 } |
|
347 return null; |
|
348 } |
|
349 function createTempURI(scheme) { |
|
350 if (scheme == "http") { |
|
351 return "http://localhost:8080/webdav/tmp" + Math.floor(Math.random() * 100000) + ".xml"; |
|
352 } |
|
353 return "file:///tmp/domts" + Math.floor(Math.random() * 100000) + ".xml"; |
|
354 } |
|
355 |
|
356 |
|
357 function EventMonitor() { |
|
358 this.atEvents = new Array(); |
|
359 this.bubbledEvents = new Array(); |
|
360 this.capturedEvents = new Array(); |
|
361 this.allEvents = new Array(); |
|
362 } |
|
363 |
|
364 EventMonitor.prototype.handleEvent = function(evt) { |
|
365 switch(evt.eventPhase) { |
|
366 case 1: |
|
367 monitor.capturedEvents[monitor.capturedEvents.length] = evt; |
|
368 break; |
|
369 |
|
370 case 2: |
|
371 monitor.atEvents[monitor.atEvents.length] = evt; |
|
372 break; |
|
373 |
|
374 case 3: |
|
375 monitor.bubbledEvents[monitor.bubbledEvents.length] = evt; |
|
376 break; |
|
377 } |
|
378 monitor.allEvents[monitor.allEvents.length] = evt; |
|
379 } |
|
380 |
|
381 function DOMErrorImpl(err) { |
|
382 this.severity = err.severity; |
|
383 this.message = err.message; |
|
384 this.type = err.type; |
|
385 this.relatedException = err.relatedException; |
|
386 this.relatedData = err.relatedData; |
|
387 this.location = err.location; |
|
388 } |
|
389 |
|
390 |
|
391 |
|
392 function DOMErrorMonitor() { |
|
393 this.allErrors = new Array(); |
|
394 } |
|
395 |
|
396 DOMErrorMonitor.prototype.handleError = function(err) { |
|
397 errorMonitor.allErrors[errorMonitor.allErrors.length] = new DOMErrorImpl(err); |
|
398 } |
|
399 |
|
400 DOMErrorMonitor.prototype.assertLowerSeverity = function(id, severity) { |
|
401 var i; |
|
402 for (i = 0; i < errorMonitor.allErrors.length; i++) { |
|
403 if (errorMonitor.allErrors[i].severity >= severity) { |
|
404 assertEquals(id, severity - 1, errorMonitor.allErrors[i].severity); |
|
405 } |
|
406 } |
|
407 } |
|
408 |
|
409 function UserDataNotification(operation, key, data, src, dst) { |
|
410 this.operation = operation; |
|
411 this.key = key; |
|
412 this.data = data; |
|
413 this.src = src; |
|
414 this.dst = dst; |
|
415 } |
|
416 |
|
417 function UserDataMonitor() { |
|
418 this.allNotifications = new Array(); |
|
419 } |
|
420 |
|
421 UserDataMonitor.prototype.handle = function(operation, key, data, src, dst) { |
|
422 userDataMonitor.allNotifications[this.allNotifications.length] = |
|
423 new UserDataNotification(operation, key, data, src, dst); |
|
424 } |
|
425 |
|
426 |
|
427 |
|
428 function IFrameBuilder() { |
|
429 this.contentType = "text/html"; |
|
430 this.supportedContentTypes = [ "text/html", |
|
431 "text/xml", |
|
432 "image/svg+xml", |
|
433 "application/xhtml+xml" ]; |
|
434 |
|
435 this.supportsAsyncChange = false; |
|
436 this.async = true; |
|
437 this.fixedAttributeNames = [ |
|
438 "validating", "expandEntityReferences", "coalescing", |
|
439 "signed", "hasNullString", "ignoringElementContentWhitespace", "namespaceAware", "ignoringComments", "schemaValidating"]; |
|
440 |
|
441 this.fixedAttributeValues = [false, true, false, true, true , false, false, true, false ]; |
|
442 this.configurableAttributeNames = [ ]; |
|
443 this.configurableAttributeValues = [ ]; |
|
444 this.initializationError = null; |
|
445 this.initializationFatalError = null; |
|
446 this.skipIncompatibleTests = false; |
|
447 } |
|
448 |
|
449 IFrameBuilder.prototype.hasFeature = function(feature, version) { |
|
450 return document.implementation.hasFeature(feature, version); |
|
451 } |
|
452 |
|
453 IFrameBuilder.prototype.getImplementation = function() { |
|
454 return document.implementation; |
|
455 } |
|
456 |
|
457 IFrameBuilder.prototype.setContentType = function(contentType) { |
|
458 this.contentType = contentType; |
|
459 if (contentType == "text/html") { |
|
460 this.fixedAttributeValues[6] = false; |
|
461 } else { |
|
462 this.fixedAttributeValues[6] = true; |
|
463 } |
|
464 } |
|
465 |
|
466 |
|
467 |
|
468 IFrameBuilder.prototype.preload = function(frame, varname, url) { |
|
469 var suffix; |
|
470 if (this.contentType == "text/html" || this.contentType == "application/xhtml+xml") { |
|
471 if (url.substring(0,5) == "staff" || url == "nodtdstaff" || url == "datatype_normalization") { |
|
472 suffix = ".xml"; |
|
473 } |
|
474 } |
|
475 |
|
476 if (!suffix) suffix = getSuffix(this.contentType); |
|
477 |
|
478 var iframe = document.createElement("iframe"); |
|
479 var srcname = url + suffix; |
|
480 iframe.setAttribute("name", srcname); |
|
481 iframe.setAttribute("src", fileBase + srcname); |
|
482 // |
|
483 // HTML and XHTML have onload attributes that will invoke loadComplete |
|
484 // |
|
485 if (suffix.indexOf("html") < 0) { |
|
486 iframe.addEventListener("load", loadComplete, false); |
|
487 } |
|
488 document.getElementsByTagName("body").item(0).appendChild(iframe); |
|
489 return 0; |
|
490 } |
|
491 |
|
492 IFrameBuilder.prototype.load = function(frame, varname, url) { |
|
493 var suffix; |
|
494 if (url.substring(0,5) == "staff" || url == "nodtdstaff" || url == "datatype_normalization") { |
|
495 suffix = ".xml"; |
|
496 } |
|
497 if (!suffix) suffix = getSuffix(this.contentType); |
|
498 var name = url + suffix; |
|
499 var iframes = document.getElementsByTagName("iframe"); |
|
500 for(var i = 0; i < iframes.length; i++) { |
|
501 if (iframes.item(i).getAttribute("name") == name) { |
|
502 var item = iframes.item(i); |
|
503 if (typeof(item.contentDocument) != 'undefined') { |
|
504 return item.contentDocument; |
|
505 } |
|
506 if (typeof(item.document) != 'undefined') { |
|
507 return item.document; |
|
508 } |
|
509 return null; |
|
510 } |
|
511 } |
|
512 return null; |
|
513 } |
|
514 |
|
515 IFrameBuilder.prototype.getImplementationAttribute = function(attr) { |
|
516 for (var i = 0; i < this.fixedAttributeNames.length; i++) { |
|
517 if (this.fixedAttributeNames[i] == attr) { |
|
518 return this.fixedAttributeValues[i]; |
|
519 } |
|
520 } |
|
521 throw "Unrecognized implementation attribute: " + attr; |
|
522 } |
|
523 |
|
524 |
|
525 |
|
526 IFrameBuilder.prototype.setImplementationAttribute = function(attribute, value) { |
|
527 var supported = this.getImplementationAttribute(attribute); |
|
528 if (supported != value) { |
|
529 this.initializationError = "IFrame loader does not support " + attribute + "=" + value; |
|
530 } |
|
531 } |
|
532 |
|
533 |
|
534 IFrameBuilder.prototype.canSetImplementationAttribute = function(attribute, value) { |
|
535 var supported = this.getImplementationAttribute(attribute); |
|
536 return (supported == value); |
|
537 } |
|
538 |
|
539 |
|
540 function createBuilder(implementation) { |
|
541 if (implementation == null) { |
|
542 return new IFrameBuilder(); |
|
543 } |
|
544 switch(implementation) { |
|
545 /* case "msxml3": |
|
546 return new MSXMLBuilder("Msxml2.DOMDocument.3.0"); |
|
547 |
|
548 case "msxml4": |
|
549 return new MSXMLBuilder("Msxml2.DOMDocument.4.0");*/ |
|
550 |
|
551 case "mozillaXML": |
|
552 return new MozillaXMLBuilder(); |
|
553 /* |
|
554 case "svgplugin": |
|
555 return new SVGPluginBuilder(); |
|
556 |
|
557 case "dom3ls": |
|
558 return new DOM3LSBuilder(); */ |
|
559 |
|
560 case "iframe": |
|
561 return new IFrameBuilder(); |
|
562 |
|
563 case "xmlhttprequest": |
|
564 return new XMLHttpRequestBuilder(); |
|
565 |
|
566 default: |
|
567 alert ("unrecognized implementation " + implementation); |
|
568 } |
|
569 return new IFrameBuilder(); |
|
570 } |
|
571 |
|
572 function checkFeature(feature, version) |
|
573 { |
|
574 if (!builder.hasFeature(feature, version)) |
|
575 { |
|
576 // |
|
577 // don't throw exception so that users can select to ignore the precondition |
|
578 // |
|
579 builder.initializationError = "builder does not support feature " + feature + " version " + version; |
|
580 } |
|
581 } |
|
582 |
|
583 function createConfiguredBuilder() { |
|
584 var builder = null; |
|
585 var contentType = null; |
|
586 var i; |
|
587 var contentTypeSet = false; |
|
588 var parm = null; |
|
589 builder = new IFrameBuilder(); |
|
590 return builder; |
|
591 } |
|
592 |
|
593 |
|
594 function preload(frame, varname, url) { |
|
595 return builder.preload(frame, varname, url); |
|
596 } |
|
597 |
|
598 function load(frame, varname, url) { |
|
599 return builder.load(frame, varname, url); |
|
600 } |
|
601 |
|
602 function getImplementationAttribute(attr) { |
|
603 return builder.getImplementationAttribute(attr); |
|
604 } |
|
605 |
|
606 |
|
607 function setImplementationAttribute(attribute, value) { |
|
608 builder.setImplementationAttribute(attribute, value); |
|
609 } |
|
610 |
|
611 function setAsynchronous(value) { |
|
612 if (builder.supportsAsyncChange) { |
|
613 builder.async = value; |
|
614 } else { |
|
615 update(); |
|
616 } |
|
617 } |
|
618 |
|
619 |
|
620 function createXPathEvaluator(doc) { |
|
621 try { |
|
622 return doc.getFeature("XPath", null); |
|
623 } |
|
624 catch(ex) { |
|
625 } |
|
626 return doc; |
|
627 } |
|
628 |
|
629 function toLowerArray(src) { |
|
630 var newArray = new Array(); |
|
631 var i; |
|
632 for (i = 0; i < src.length; i++) { |
|
633 newArray[i] = src[i].toLowerCase(); |
|
634 } |
|
635 return newArray; |
|
636 } |
|
637 |
|
638 function MSXMLBuilder_onreadystatechange() { |
|
639 if (builder.parser.readyState == 4) { |
|
640 loadComplete(); |
|
641 } |
|
642 } |
|
643 |
|
644 |
|
645 |
|
646 var fileBase = location.href; |
|
647 if (fileBase.indexOf('?') != -1) { |
|
648 fileBase = fileBase.substring(0, fileBase.indexOf('?')); |
|
649 } |
|
650 fileBase = fileBase.substring(0, fileBase.lastIndexOf('/') + 1) + "files/"; |
|
651 |
|
652 function getResourceURI(name, scheme, contentType) { |
|
653 return fileBase + name + getSuffix(contentType); |
|
654 } |
|
655 |
|
656 |
|
657 function getImplementation() { |
|
658 return builder.getImplementation(); |
|
659 } |
|
660 |
|
661 // Count of failures overridden as todos. |
|
662 var gFailuresAsTodos = 0; |
|
663 |
|
664 // Override SimpleTest result logger. |
|
665 var ST_logResult = SimpleTest._logResult; |
|
666 SimpleTest._logResult = function overrideSTlR(test, passString, failString) { |
|
667 if (todoTests[docName] && !test.result && !test.todo) { |
|
668 test.name = "[failure as todo] " + test.name; |
|
669 test.todo = true; |
|
670 failString = "TEST-KNOWN-FAIL"; |
|
671 |
|
672 ++gFailuresAsTodos; |
|
673 } |
|
674 |
|
675 ST_logResult(test, passString, failString); |
|
676 } |
|
677 |
|
678 // Actual marking code is in overrideSTlR() now. |
|
679 function markTodos() { |
|
680 if (todoTests[docName]) { |
|
681 isnot(gFailuresAsTodos, 0, "test marked todo should have failed somewhere"); |
|
682 } |
|
683 } |
|
684 |
|
685 function runJSUnitTests() { |
|
686 try { |
|
687 var tests = exposeTestFunctionNames(); |
|
688 for (var i = 0; i < tests.length; i++) { |
|
689 window[tests[i]](); |
|
690 } |
|
691 } catch (ex) { |
|
692 if (todoTests[docName]) { |
|
693 todo(false, "[failure as todo] Test threw exception: " + ex); |
|
694 ++gFailuresAsTodos; |
|
695 } else { |
|
696 ok(false, "Test threw exception: " + ex); |
|
697 } |
|
698 } |
|
699 } |