1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Bob Clary <http://bclary.com/>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
40 var gTotalSelected = 0;
42 function setCursor(aCursor)
44 if (document.body && document.body.style)
46 document.body.style.cursor = aCursor;
50 function selectAll(suiteName, testDirName)
54 suiteName = suiteName || '';
55 testDirName = testDirName || '';
57 setTimeout('_selectAll("' + suiteName + '", "' + testDirName + '")', 200);
60 function _selectAll(suiteName, testDirName)
64 for (suiteName in suites)
66 setAllDirs(suiteName, true);
69 else if (!testDirName)
71 setAllDirs(suiteName, true);
75 setAllTests(suiteName, testDirName, true);
81 function selectNone(suiteName, testDirName)
85 suiteName = suiteName || '';
86 testDirName = testDirName || '';
88 setTimeout('_selectNone("' + suiteName + '", "' + testDirName + '")', 200);
91 function _selectNone(suiteName, testDirName)
95 for (suiteName in suites)
97 setAllDirs(suiteName, false);
100 else if (!testDirName)
102 setAllDirs(suiteName, false);
106 setAllTests(suiteName, testDirName, false);
112 function updateCounts(suiteName)
114 var suite = suites[suiteName];
115 var pct = parseInt((suite.selected / suite.count) * 100);
119 document.forms.testCases.elements['SUMMARY_' + suiteName].value =
120 suite.selected + '/' + suite.count +
121 ' (' + pct + '%) selected';
123 pct = parseInt((gTotalSelected / gTotalCount) * 100);
127 document.forms.testCases.elements['TOTAL'].value =
128 gTotalSelected + '/' + gTotalCount + ' (' +
132 function onRadioClick(radio)
134 var info = radio.id.split(':');
135 var suiteName = info[0];
136 var suite = suites[suiteName];
137 var incr = (radio.checked ? 1 : -1);
138 suite.selected += incr;
139 gTotalSelected += incr;
141 updateCounts(suiteName);
146 function updateTotals()
150 setTimeout('_updateTotals()', 200);
153 function _updateTotals()
158 for (var suiteName in suites)
160 gTotalCount += suites[suiteName].count;
162 for (suiteName in suites)
164 updateCounts(suiteName);
169 function setAllDirs(suiteName, value)
171 var testDirs = suites[suiteName].testDirs;
173 for (var testDirName in testDirs)
175 setAllTests(suiteName, testDirName, value);
179 function setAllTests(suiteName, testDirName, value)
181 var suite = suites[suiteName];
182 var tests = suite.testDirs[testDirName].tests;
183 var elements = document.forms['testCases'].elements;
186 for (var testName in tests)
188 var radioName = tests[testName].id;
189 var radio = elements[radioName];
190 if (radio.checked && !value)
194 else if (!radio.checked && value)
198 radio.checked = value;
201 suite.selected += incr;
202 gTotalSelected += incr;
204 updateCounts(suiteName);
207 function createList()
210 var elements = document.forms['testCases'].elements;
211 var win = window.open('about:blank', 'other_window');
212 var writer = new CachedWriter(win.document);
215 writer.writeln('<pre>');
217 writer.writeln('# Created ' + new Date());
219 for (suiteName in suites)
221 writer.writeln('# ' + suiteName + ': ' +
222 elements['SUMMARY_' + suiteName].value);
225 writer.writeln('# TOTAL: ' + elements['TOTAL'].value);
227 for (suiteName in suites)
229 var testDirs = suites[suiteName].testDirs;
230 for (var testDirName in testDirs)
232 var tests = testDirs[testDirName].tests;
233 for (var testName in tests)
235 var radioName = tests[testName].id;
236 var radio = elements[radioName];
238 writer.writeln(suiteName + '/' + testDirName + '/' + radio.value);
242 writer.writeln('<\/pre>');
251 function executeList()
253 var elements = document.forms['testCases'].elements;
258 for (var suiteName in suites)
260 var testDirs = suites[suiteName].testDirs;
261 for (var testDirName in testDirs)
263 var tests = testDirs[testDirName].tests;
264 for (var testName in tests)
266 var test = tests[testName];
267 var radioName = test.id;
268 var radio = elements[radioName];
269 delete test.testCases;
272 gTests[gTests.length] = test;
273 test.path = suiteName + '/' + testDirName + '/' + radio.value;
281 function runNextTest()
285 if (gTestNumber != -1)
287 // tests have already run in gWindow, collect the results
288 // for later reporting.
293 var test = gTests[gTestNumber];
295 //test.testCases = test.testCases.concat(gWindow.gTestcases);
296 // note MSIE6 has a bug where instead of concating the new arrays
297 // it concats them to the first element. work around...
298 var origtestcases = gWindow.gTestcases;
299 for (iTestCase = 0; iTestCase < origtestcases.length; iTestCase++)
301 // test.testCases[test.testCases.length] = origtestcases[iTestCase];
302 var origtestcase = origtestcases[iTestCase];
303 var testCase = test.testCases[test.testCases.length] = {};
304 testCase.name = new String(origtestcase.name);
305 testCase.description = new String(origtestcase.description);
306 testCase.expect = new String(origtestcase.expect);
307 testCase.actual = new String(origtestcase.actual);
308 testCase.passed = origtestcase.passed ? true : false;
309 testCase.reason = new String(origtestcase.reason);
310 testCase.bugnumber = new String(origtestcase.bugnumber?origtestcase.bugnumber:'');
312 origtestcases = origtestcase = null;
322 if (gTestNumber < gTests.length)
325 test = gTests[gTestNumber];
327 gWindow = window.open('js-test-driver-' +
328 document.forms.testCases.doctype.value +
332 document.forms.testCases.language.value,
336 alert('This test suite requires popup windows.\n' +
337 'Please enable them for this site.');
340 else if (document.forms.testCases.outputformat.value == 'html')
342 // all tests completed, display report
345 else if (document.forms.testCases.outputformat.value == 'javascript')
347 // all tests completed, display report
353 function reportHTML()
355 var errorsOnly = document.forms.testCases.failures.checked;
356 var totalTestCases = 0;
357 var totalTestCasesPassed = 0;
358 var totalTestCasesFailed = 0;
360 gWindow.document.close();
362 var writer = new CachedWriter(gWindow.document);
364 writer.writeln('<!DOCTYPE HTML PUBLIC ' +
365 '"-//W3C//DTD HTML 4.01 Transitional//EN" ' +
366 '"http://www.w3.org/TR/html4/loose.dtd">');
368 writer.writeln('<html>');
369 writer.writeln('<head>');
370 writer.writeln('<title>JavaScript Tests Browser: ' +
371 navigator.userAgent + ' Language: ' +
372 document.forms.testCases.language.value +
374 writer.writeln('<style type="text/css">');
375 writer.writeln(' .passed { } .failed { background-color: red; }');
376 writer.writeln('table {}');
377 writer.writeln('th.description, th.actual, th.expect { width: 30em;}');
378 writer.writeln('<\/style>');
380 writer.writeln('<\/head>');
381 writer.writeln('<body>');
382 writer.writeln('<h2>JavaScript Tests Browser: ' +
383 navigator.userAgent + ' Language: ' +
384 document.forms.testCases.language.value +
387 writer.writeln('<table border="1">');
388 writer.writeln('<thead>');
389 writer.writeln('<tr>');
390 writer.writeln('<th>Suite<\/th>');
391 writer.writeln('<th>Directory<\/th>');
392 writer.writeln('<th>Test<\/th>');
393 writer.writeln('<th>Passed<\/th>');
394 writer.writeln('<th class="description">Description<\/th>');
395 writer.writeln('<th class="actual">Actual<\/th>');
396 writer.writeln('<th class="expect">Expect<\/th>');
397 writer.writeln('<th>BugNumber<\/th>');
398 writer.writeln('<th>Reason<\/th>');
399 writer.writeln('<\/tr>');
400 writer.writeln('<\/thead>');
401 writer.writeln('<tbody>');
403 writer.writeln('<\/tr>');
405 for (var suiteName in suites)
407 var suiteTotals = {passed: 0, failed: 0};
408 var testDirs = suites[suiteName].testDirs;
410 for (var testDirName in testDirs)
412 var dirTotals = {passed: 0, failed: 0};
413 var tests = testDirs[testDirName].tests;
415 for (var testName in tests)
417 var nameTotals = {passed: 0, failed: 0};
418 var test = tests[testName];
420 if (! ('testCases' in test) )
426 var testCases = test.testCases;
428 for (var iTestCase = 0; iTestCase < testCases.length; iTestCase++)
430 var testCase = testCases[iTestCase];
434 ++totalTestCasesPassed;
437 ++suiteTotals.passed;
441 ++totalTestCasesFailed;
444 ++suiteTotals.failed;
447 if (errorsOnly && testCase.passed)
452 writer.writeln('<tr class="' +
453 (testCase.passed ? 'passed' : 'failed') + '">' +
454 '<td title="Suite">' + suiteName + '<\/td>' +
455 '<td title="Directory">' + testDirName + '<\/td>' +
456 '<td title="Test">' + testName + '<\/td>' +
457 '<td title="Status">' +
458 (testCase.passed ? 'Test Passed':'Test Failed') +
460 '<td title="Description">' +
461 splitString(testCase.description, '<br>', 30) +
463 '<td title="Actual">' +
464 splitString(testCase.actual, '<br>', 30) +
466 '<td title="Expected">' +
467 splitString(testCase.expect, '<br>', 30) +
470 (testCase.bugnumber?testCase.bugnumber:'') +
472 '<td title="Reason">' + testCase.reason + '<\/td>' +
476 if (!errorsOnly && nameTotals.passed + nameTotals.failed > 0)
478 writer.writeln('<tr>' +
479 '<td>' + suiteName + '<\/td>' +
480 '<td>' + testDirName + '<\/td>' +
481 '<td colspan="7" style="font-weight:bold;">' +
483 'Passed = ' + nameTotals.passed.toString() + ' ' +
484 'Failed = ' + nameTotals.failed.toString() +
489 } // for (var testName in tests)
491 if (!errorsOnly && dirTotals.passed + dirTotals.failed > 0)
493 writer.writeln('<tr>' +
494 '<td>' + suiteName + '<\/td>' +
495 '<td colspan="8" style="font-weight:bold;">' +
497 'Passed = ' + dirTotals.passed.toString() + ' ' +
498 'Failed = ' + dirTotals.failed.toString() +
503 } // for (var testDirName in testDirs)
505 if (!errorsOnly && suiteTotals.passed + suiteTotals.failed > 0)
507 writer.writeln('<tr>' +
508 '<td colspan="9" style="font-weight:bold;">' +
510 'Passed = ' + suiteTotals.passed.toString() + ' ' +
511 'Failed = ' + suiteTotals.failed.toString() +
516 } // for (var suiteName in suites)
518 writer.writeln('<\/tbody>');
519 writer.writeln('<\/table>');
521 writer.writeln('<p>Total TestCases = ' + totalTestCases +
522 ', Passed = ' + totalTestCasesPassed +
523 ', Failed = ' + totalTestCasesFailed +
525 writer.writeln('<\/body>');
526 writer.writeln('<\/html>');
531 // return a string with delim inserted every pos characters
532 // if there are no spaces to break the line
533 function splitString(str, delim, pos)
536 var length = str.length;
538 if (str.indexOf(' ') != -1)
542 for (var i = 0; i < length; i += pos)
544 newstr += str.substr(i, pos) + delim;
548 function reportJavaScript()
550 gWindow.document.close();
552 var errorsOnly = document.forms.testCases.failures.checked;
553 var writer = new CachedWriter(gWindow.document);
555 writer.writeln('<html>');
556 writer.writeln('<head>');
557 writer.writeln('<title>JavaScript Tests Browser: ' +
558 navigator.userAgent + ' Language: ' +
559 document.forms.testCases.language.value +
561 writer.writeln('<script type="text/javascript">');
562 writer.writeln('var global = window.parent;');
563 writer.writeln('if (!global.gUAHash) {');
564 writer.writeln(' global.gUAHash = {};');
565 writer.writeln(' global.gUAList = {};');
566 writer.writeln(' global.gUA_id = -1;');
567 writer.writeln(' global.gTestResults = {};');
569 writer.writeln('var gUA = "' + navigator.userAgent + '";');
570 writer.writeln('var gUA_id = global.gUAHash[gUA];');
571 writer.writeln('if (typeof(gUA_id) != "number") {');
572 writer.writeln(' gUA_id = global.gUAHash[gUA] = ++global.gUA_id;');
573 writer.writeln(' global.gUAList[gUA_id] = gUA;');
575 writer.writeln('var gTestResults = global.gTestResults;');
576 writer.writeln('var gLanguage = \'' + document.forms.testCases.language.value + '\';');
577 writer.writeln('var gResult;');
578 writer.writeln('var gResultId;');
579 writer.writeln('var gUAResult;');
580 writer.writeln('var gJSResult;');
581 writer.writeln('var gSuiteId;');
582 writer.writeln('var gSuite;');
583 writer.writeln('var gDirId;');
584 writer.writeln('var gDir;');
585 writer.writeln('var gTestId;');
586 writer.writeln('var gTest;');
588 writer.writeln('gUAResult = gTestResults[gUA_id];');
589 writer.writeln('if (!gUAResult) {');
590 writer.writeln(' gUAResult = gTestResults[gUA_id] = {};');
592 writer.writeln('gJSResult = gUAResult[gLanguage];');
593 writer.writeln('if (!gJSResult) {');
594 writer.writeln(' gJSResult = gUAResult[gLanguage] = {};');
598 for (var suiteName in suites)
600 var suiteheader = '';
602 suiteheader += 'gSuiteId = "' + suiteName + '";\n';
603 suiteheader += 'gSuite = gJSResult[gSuiteId];\n';
604 suiteheader += 'if (!gSuite) {\n';
605 suiteheader += ' gSuite = gJSResult[gSuiteId] = {};\n';
606 suiteheader += '}\n';
608 var testDirs = suites[suiteName].testDirs;
610 for (var testDirName in testDirs)
614 dirheader += 'gDirId = "' + testDirName + '";\n';
615 dirheader += 'gDir = gSuite[gDirId];\n';
616 dirheader += 'if (!gDir) {\n';
617 dirheader += ' gDir = gSuite[gDirId] = {};\n';
620 var tests = testDirs[testDirName].tests;
622 for (var testName in tests)
624 var test = tests[testName];
626 if (! ('testCases' in test) )
632 var testCases = test.testCases;
633 var resultId = suiteName + '/' + testDirName + '/' + testName;
636 testheader += 'gTestId = "' + testName + '";\n';
637 testheader += 'gTest = gDir[gTestId];\n';
638 testheader += 'if (!gTest) {\n';
639 testheader += ' gTest = gDir[gTestId] = [];\n';
642 for (var iTestCase = 0; iTestCase < testCases.length; iTestCase++)
644 var testCase = testCases[iTestCase];
645 if (errorsOnly && testCase.passed)
652 writer.writeln(suiteheader);
657 writer.writeln(dirheader);
662 writer.writeln(testheader);
666 var name = escape(testCase.name);
667 var desc = escape(testCase.description);
668 var actual = escape(testCase.actual);
669 var expect = escape(testCase.expect);
670 var reason = escape(testCase.reason);
674 buffer += 'gTest[gTest.length] = \n';
676 buffer += 'name: "' + name + '",\n';
677 buffer += 'description: "' + desc + '",\n';
678 buffer += 'expect: "' + expect + '",\n';
679 buffer += 'actual: "' + actual + '",\n';
680 buffer += 'passed: ' + testCase.passed + ',\n';
681 buffer += 'reason: "' + reason + '",\n';
682 buffer += 'bugnumber: "' + (testCase.bugnumber ?
683 testCase.bugnumber : '') + '"\n';
686 writer.writeln(buffer);
695 } // for (var suiteName in suites)
697 writer.writeln('<\/script>');
698 writer.writeln('<\/head>');
699 writer.writeln('<body>');
700 writer.writeln('<p>JavaScript Tests Browser: ' +
701 navigator.userAgent + ' Language: ' +
702 document.forms.testCases.language.value +
704 writer.writeln('<\/body>')
705 writer.writeln('<\/html>');
709 // improve IE's performance. Mozilla's is fine. ;-)
710 function CachedWriter(doc, limit)
713 this.pendingCount = 0;
714 this.pendingLimit = limit ? limit : 100;
718 CachedWriter.prototype.destroy = function _cachedWriterDestroy()
720 this.document = null;
721 this.pendingCount = 0;
722 this.pendingLimit = 0;
726 CachedWriter.prototype.writeln = function _cachedWriterWriteLine(s)
728 this.lines[this.lines.length] = s;
729 if (++this.pendingCount >= this.pendingLimit)
735 CachedWriter.prototype.flush = function _cachedWriterFlush()
737 var s = this.lines.join('\n');
738 this.pendingCount = 0;
742 for (var ibadchar = 0; ibadchar < 32; ++ibadchar)
744 if (ibadchar != 10 && ibadchar != 13)
746 var badchar = String.fromCharCode(ibadchar);
747 var badregx = new RegExp(badchar, 'mg');
748 var escchar = '\\0x' + ibadchar.toString(16);
749 s = s.replace(badregx, escchar);
753 this.document.writeln(s);
756 CachedWriter.prototype.close = function _cachedWriterClose()
759 this.document.close();