/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Bob Clary * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ var gTotalCount = 0; var gTotalSelected = 0; function setCursor(aCursor) { if (document.body && document.body.style) { document.body.style.cursor = aCursor; } } function selectAll(suiteName, testDirName) { setCursor('wait'); suiteName = suiteName || ''; testDirName = testDirName || ''; setTimeout('_selectAll("' + suiteName + '", "' + testDirName + '")', 200); } function _selectAll(suiteName, testDirName) { if (!suiteName) { for (suiteName in suites) { setAllDirs(suiteName, true); } } else if (!testDirName) { setAllDirs(suiteName, true); } else { setAllTests(suiteName, testDirName, true); } setCursor('auto'); } function selectNone(suiteName, testDirName) { setCursor('wait'); suiteName = suiteName || ''; testDirName = testDirName || ''; setTimeout('_selectNone("' + suiteName + '", "' + testDirName + '")', 200); } function _selectNone(suiteName, testDirName) { if (!suiteName) { for (suiteName in suites) { setAllDirs(suiteName, false); } } else if (!testDirName) { setAllDirs(suiteName, false); } else { setAllTests(suiteName, testDirName, false); } setCursor('auto'); } function updateCounts(suiteName) { var suite = suites[suiteName]; var pct = parseInt((suite.selected / suite.count) * 100); if (isNaN(pct)) pct = 0; document.forms.testCases.elements['SUMMARY_' + suiteName].value = suite.selected + '/' + suite.count + ' (' + pct + '%) selected'; pct = parseInt((gTotalSelected / gTotalCount) * 100); if (isNaN(pct)) pct = 0; document.forms.testCases.elements['TOTAL'].value = gTotalSelected + '/' + gTotalCount + ' (' + pct + '%) selected'; } function onRadioClick(radio) { var info = radio.id.split(':'); var suiteName = info[0]; var suite = suites[suiteName]; var incr = (radio.checked ? 1 : -1); suite.selected += incr; gTotalSelected += incr; updateCounts(suiteName); return true; } function updateTotals() { setCursor('wait'); setTimeout('_updateTotals()', 200); } function _updateTotals() { gTotalCount = 0; gTotalSelected = 0; for (var suiteName in suites) { gTotalCount += suites[suiteName].count; } for (suiteName in suites) { updateCounts(suiteName); } setCursor('auto'); } function setAllDirs(suiteName, value) { var testDirs = suites[suiteName].testDirs; for (var testDirName in testDirs) { setAllTests(suiteName, testDirName, value); } } function setAllTests(suiteName, testDirName, value) { var suite = suites[suiteName]; var tests = suite.testDirs[testDirName].tests; var elements = document.forms['testCases'].elements; var incr = 0; for (var testName in tests) { var radioName = tests[testName].id; var radio = elements[radioName]; if (radio.checked && !value) { incr--; } else if (!radio.checked && value) { incr++; } radio.checked = value; } suite.selected += incr; gTotalSelected += incr; updateCounts(suiteName); } function createList() { var suiteName; var elements = document.forms['testCases'].elements; var win = window.open('about:blank', 'other_window'); var writer = new CachedWriter(win.document); win.document.open(); writer.writeln('
');
    
  writer.writeln('# Created ' + new Date());

  for (suiteName in suites)
  {
    writer.writeln('# ' + suiteName + ': ' + 
                   elements['SUMMARY_' + suiteName].value);
  }

  writer.writeln('# TOTAL: ' + elements['TOTAL'].value);

  for (suiteName in suites)
  {
    var testDirs = suites[suiteName].testDirs;
    for (var testDirName in testDirs)
    {
      var tests = testDirs[testDirName].tests;
      for (var testName in tests) 
      {  
        var radioName = tests[testName].id;
        var radio     = elements[radioName];
        if (radio.checked)
          writer.writeln(suiteName + '/' + testDirName + '/' + radio.value);
      }
    }
  }
  writer.writeln('<\/pre>');
    
  writer.close();
}

var gTests;
var gTestNumber;
var gWindow;

function executeList()
{
  var elements = document.forms['testCases'].elements;

  gTests = [];
  gTestNumber = -1;

  for (var suiteName in suites)
  {
    var testDirs = suites[suiteName].testDirs;
    for (var testDirName in testDirs)
    {
      var tests = testDirs[testDirName].tests;
      for (var testName in tests)
      {  
        var test      = tests[testName];
        var radioName = test.id;
        var radio     = elements[radioName];
        delete test.testCases;
        if (radio.checked)
        {
          gTests[gTests.length] = test;
          test.path = suiteName + '/' + testDirName + '/' + radio.value;
        }
      }
    }
  }
  runNextTest();
}

function runNextTest()
{
  var iTestCase;

  if (gTestNumber != -1)
  {
    // tests have already run in gWindow, collect the results
    // for later reporting.

    var e;
    try
    {
      var test  = gTests[gTestNumber];
      test.testCases = [];
      //test.testCases = test.testCases.concat(gWindow.testcases);
      // note MSIE6 has a bug where instead of concating the new arrays
      // it concats them to the first element. work around...
      var origtestcases = gWindow.testcases;
      for (iTestCase = 0; iTestCase < origtestcases.length; iTestCase++)
      {
//        test.testCases[test.testCases.length] = origtestcases[iTestCase];
        var origtestcase = origtestcases[iTestCase];
        var testCase = test.testCases[test.testCases.length] = {};
        testCase.name = new String(origtestcase.name);
        testCase.description = new String(origtestcase.description);
        testCase.expect = new String(origtestcase.expect);
        testCase.actual = new String(origtestcase.actual);
        testCase.passed = origtestcase.passed ? true : false;
        testCase.reason = new String(origtestcase.reason);
        testCase.bugnumber = new String(origtestcase.bugnumber?origtestcase.bugnumber:'');
      }
      origtestcases = origtestcase = null;
    }
    catch(e)
    {
      ;
    }
  }

  ++gTestNumber;

  if (gTestNumber < gTests.length)
  {
    // run test
    test      = gTests[gTestNumber];

    gWindow = window.open('js-test-driver-' + 
                          document.forms.testCases.doctype.value + 
                          '.html?test=' + 
                          test.path + 
                          ';language=' + 
                          document.forms.testCases.language.value, 
                          'output');
    if (!gWindow)
    {
      alert('This test suite requires popup windows.\n' + 
            'Please enable them for this site.');
    }
  }
  else if (document.forms.testCases.outputformat.value == 'html')
  {
    // all tests completed, display report
    reportHTML();
  }
  else if (document.forms.testCases.outputformat.value == 'javascript')
  {
    // all tests completed, display report
    reportJavaScript();
  }

}

function reportHTML()
{
  var errorsOnly = document.forms.testCases.failures.checked;
  var totalTestCases = 0;
  var totalTestCasesPassed = 0;
  var totalTestCasesFailed = 0;

  gWindow.document.close();

  var writer = new CachedWriter(gWindow.document);

  writer.writeln('');

  writer.writeln('');
  writer.writeln('');
  writer.writeln('JavaScript Tests Browser: ' + 
                 navigator.userAgent + ' Language: ' + 
                 document.forms.testCases.language.value + 
                 '<\/title>');
  writer.writeln('<style type="text/css">');
  writer.writeln(' .passed { } .failed { background-color: red; }');
  writer.writeln('table {}');
  writer.writeln('th.description, th.actual, th.expect { width: 30em;}');
  writer.writeln('<\/style>');

  writer.writeln('<\/head>');
  writer.writeln('<body>');
  writer.writeln('<h2>JavaScript Tests Browser: ' + 
                 navigator.userAgent + ' Language: ' + 
                 document.forms.testCases.language.value + 
                 '<\/h2>');

  writer.writeln('<table border="1">');
  writer.writeln('<thead>');
  writer.writeln('<tr>');
  writer.writeln('<th>Suite<\/th>');
  writer.writeln('<th>Directory<\/th>');
  writer.writeln('<th>Test<\/th>');
  writer.writeln('<th>Passed<\/th>');
  writer.writeln('<th class="description">Description<\/th>');
  writer.writeln('<th class="actual">Actual<\/th>');
  writer.writeln('<th class="expect">Expect<\/th>');
  writer.writeln('<th>BugNumber<\/th>');
  writer.writeln('<th>Reason<\/th>');
  writer.writeln('<\/tr>');
  writer.writeln('<\/thead>');
  writer.writeln('<tbody>');

  writer.writeln('<\/tr>');

  for (var suiteName in suites)
  {
    var suiteTotals = {passed: 0, failed: 0};
    var testDirs = suites[suiteName].testDirs;

    for (var testDirName in testDirs)
    {
      var dirTotals   = {passed: 0, failed: 0};
      var tests = testDirs[testDirName].tests;

      for (var testName in tests)
      {
        var nameTotals  = {passed: 0, failed: 0};
        var test = tests[testName];

        if (! ('testCases' in test) )
        {
          // test not run
          continue;
        }

        var testCases = test.testCases;

        for (var iTestCase = 0; iTestCase < testCases.length; iTestCase++)
        {
          var testCase = testCases[iTestCase];
          ++totalTestCases;
          if (testCase.passed)
          {
            ++totalTestCasesPassed;
            ++nameTotals.passed;
            ++dirTotals.passed;
            ++suiteTotals.passed;
          }
          else
          {
            ++totalTestCasesFailed;
            ++nameTotals.failed;
            ++dirTotals.failed;
            ++suiteTotals.failed;
          }

          if (errorsOnly && testCase.passed)
          {
            continue;
          }

          writer.writeln('<tr class="' + 
                         (testCase.passed ? 'passed' : 'failed') + '">' +
                         '<td title="Suite">' + suiteName + '<\/td>' +
                         '<td title="Directory">' + testDirName   + '<\/td>' +
                         '<td title="Test">' + testName + '<\/td>' +
                         '<td title="Status">' + 
                         (testCase.passed ? 'Test Passed':'Test Failed') + 
                         '<\/td>' +
                         '<td title="Description">' + 
                         splitString(testCase.description, '<br>', 30) + 
                         '<\/td>' +
                         '<td title="Actual">' + 
                         splitString(testCase.actual, '<br>', 30) + 
                         '<\/td>' +
                         '<td title="Expected">' + 
                         splitString(testCase.expect, '<br>', 30) + 
                         '<\/td>' +
                         '<td title="Bug">' + 
                         (testCase.bugnumber?testCase.bugnumber:'') + 
                         '<\/td>' +
                         '<td title="Reason">' + testCase.reason + '<\/td>' +
                         '<\/tr>');
        } // for iTestCase

        if (!errorsOnly && nameTotals.passed + nameTotals.failed > 0)
        {
          writer.writeln('<tr>' +
                         '<td>' + suiteName + '<\/td>' +
                         '<td>' + testDirName   + '<\/td>' +
                         '<td colspan="7" style="font-weight:bold;">' + 
                         testName + ' ' +
                         'Passed = ' + nameTotals.passed.toString() + ' ' +
                         'Failed = ' + nameTotals.failed.toString() +
                         '<\/td>' +
                         '<\/tr>');
        }

      } // for (var testName in tests)

      if (!errorsOnly && dirTotals.passed + dirTotals.failed > 0)
      {
        writer.writeln('<tr>' +
                       '<td>' + suiteName + '<\/td>' +
                       '<td colspan="8" style="font-weight:bold;">' + 
                       testDirName  + ' ' +
                       'Passed = ' + dirTotals.passed.toString() + ' ' +
                       'Failed = ' + dirTotals.failed.toString() +
                       '<\/td>' +
                       '<\/tr>');
      }

    } // for (var testDirName in testDirs)

    if (!errorsOnly && suiteTotals.passed + suiteTotals.failed > 0)
    {
      writer.writeln('<tr>' +
                     '<td colspan="9" style="font-weight:bold;">' + 
                     suiteName + ' ' +
                     'Passed = ' + suiteTotals.passed.toString() + ' ' +
                     'Failed = ' + suiteTotals.failed.toString() +
                     '<\/td>' +
                     '<\/tr>');
    }

  } // for (var suiteName in suites)

  writer.writeln('<\/tbody>');
  writer.writeln('<\/table>');
    
  writer.writeln('<p>Total TestCases = ' + totalTestCases + 
                 ', Passed = ' + totalTestCasesPassed + 
                 ', Failed = ' + totalTestCasesFailed + 
                 '<\/p>');
  writer.writeln('<\/body>');
  writer.writeln('<\/html>');

  writer.close();
}

// return a string with delim inserted every pos characters
// if there are no spaces to break the line
function splitString(str, delim, pos)
{
  var newstr = '';
  var length = str.length;

  if (str.indexOf(' ') != -1)
  {
    return str;
  }
  for (var i = 0; i < length; i += pos)
  {
    newstr += str.substr(i, pos) + delim;
  }
  return newstr;
}
function reportJavaScript()
{
  gWindow.document.close();

  var errorsOnly = document.forms.testCases.failures.checked;
  var writer = new CachedWriter(gWindow.document);

  writer.writeln('<html>');
  writer.writeln('<head>');
  writer.writeln('<title>JavaScript Tests Browser: ' + 
                 navigator.userAgent + ' Language: ' + 
                 document.forms.testCases.language.value + 
                 '<\/title>');
  writer.writeln('<script type="text/javascript">');
  writer.writeln('var global = window.parent;');
  writer.writeln('if (!global.gUAHash) {');
  writer.writeln('  global.gUAHash = {};');
  writer.writeln('  global.gUAList = {};');
  writer.writeln('  global.gUA_id = -1;');
  writer.writeln('  global.gTestResults = {};');
  writer.writeln('}');
  writer.writeln('var gUA = "' + navigator.userAgent + '";');
  writer.writeln('var gUA_id = global.gUAHash[gUA];');
  writer.writeln('if (typeof(gUA_id) != "number") {');
  writer.writeln('  gUA_id = global.gUAHash[gUA] = ++global.gUA_id;');
  writer.writeln('  global.gUAList[gUA_id] = gUA;');
  writer.writeln('}');
  writer.writeln('var gTestResults = global.gTestResults;');
  writer.writeln('var gLanguage = \'' + document.forms.testCases.language.value + '\';');
  writer.writeln('var gResult;');
  writer.writeln('var gResultId;');
  writer.writeln('var gUAResult;');
  writer.writeln('var gJSResult;');
  writer.writeln('var gSuiteId;');
  writer.writeln('var gSuite;');
  writer.writeln('var gDirId;');
  writer.writeln('var gDir;');
  writer.writeln('var gTestId;');
  writer.writeln('var gTest;');

  writer.writeln('gUAResult = gTestResults[gUA_id];');
  writer.writeln('if (!gUAResult) {');
  writer.writeln('  gUAResult = gTestResults[gUA_id] = {};');
  writer.writeln('}');
  writer.writeln('gJSResult = gUAResult[gLanguage];');
  writer.writeln('if (!gJSResult) {');
  writer.writeln('  gJSResult = gUAResult[gLanguage] = {};');
  writer.writeln('}');


  for (var suiteName in suites)
  {
    var suiteheader = '';

    suiteheader += 'gSuiteId = "' + suiteName + '";\n';
    suiteheader += 'gSuite = gJSResult[gSuiteId];\n';
    suiteheader += 'if (!gSuite) {\n';
    suiteheader += '  gSuite = gJSResult[gSuiteId] = {};\n';
    suiteheader += '}\n';

    var testDirs = suites[suiteName].testDirs;

    for (var testDirName in testDirs)
    {
      var dirheader = '';

      dirheader += 'gDirId = "' + testDirName + '";\n';
      dirheader += 'gDir = gSuite[gDirId];\n';
      dirheader += 'if (!gDir) {\n';
      dirheader += '  gDir = gSuite[gDirId] = {};\n';
      dirheader += '}\n';

      var tests = testDirs[testDirName].tests;

      for (var testName in tests)
      {
        var test = tests[testName];

        if (! ('testCases' in test) )
        {
          // test not run
          continue;
        }

        var testCases = test.testCases;
        var resultId = suiteName + '/' + testDirName + '/' + testName;

        var testheader = '';
        testheader += 'gTestId = "' + testName + '";\n';
        testheader += 'gTest  = gDir[gTestId];\n';
        testheader += 'if (!gTest) {\n';
        testheader += '  gTest = gDir[gTestId] = [];\n';
        testheader += '}\n';

        for (var iTestCase = 0; iTestCase < testCases.length; iTestCase++)
        {
          var testCase = testCases[iTestCase];
          if (errorsOnly && testCase.passed)
          {
            continue;
          }

          if (suiteheader)
          {
            writer.writeln(suiteheader);
            suiteheader = '';
          }
          if (dirheader)
          {
            writer.writeln(dirheader);
            dirheader = '';
          }
          if (testheader)
          {
            writer.writeln(testheader);
            testheader = '';
          }

          var name   = escape(testCase.name);
          var desc   = escape(testCase.description);
          var actual = escape(testCase.actual);
          var expect = escape(testCase.expect);
          var reason = escape(testCase.reason);
          
          var buffer = '';

          buffer += 'gTest[gTest.length] = \n';
          buffer += '{\n';
          buffer += 'name: "' + name + '",\n';
          buffer += 'description: "' + desc +  '",\n';
          buffer += 'expect: "' + expect + '",\n';
          buffer += 'actual: "' + actual + '",\n';
          buffer += 'passed: ' + testCase.passed + ',\n';
          buffer += 'reason: "' + reason + '",\n';
          buffer += 'bugnumber: "' + (testCase.bugnumber ? 
                                      testCase.bugnumber : '') + '"\n';
          buffer += '};\n';

          writer.writeln(buffer);
          buffer = '';

        } // for iTestCase
 
      }  // for testName

    } // for testDirName

  } // for (var suiteName in suites)

  writer.writeln('<\/script>');
  writer.writeln('<\/head>');
  writer.writeln('<body>');
  writer.writeln('<p>JavaScript Tests Browser: ' + 
                 navigator.userAgent + ' Language: ' + 
                 document.forms.testCases.language.value + 
                 '<\/p>');
  writer.writeln('<\/body>')
  writer.writeln('<\/html>');
  writer.close();
}
   
// improve IE's performance. Mozilla's is fine. ;-)
function CachedWriter(doc, limit)
{
  this.document     = doc;
  this.pendingCount = 0;
  this.pendingLimit = limit ? limit : 100;
  this.lines        = [];
}

CachedWriter.prototype.destroy = function _cachedWriterDestroy()
{
  this.document     = null;
  this.pendingCount = 0;
  this.pendingLimit = 0;
  this.lines        = null;
}

CachedWriter.prototype.writeln = function _cachedWriterWriteLine(s)
{
  this.lines[this.lines.length] = s;
  if (++this.pendingCount >= this.pendingLimit)
  {
    this.flush();
  }
}

CachedWriter.prototype.flush = function _cachedWriterFlush()
{
  var s = this.lines.join('\n');
  this.pendingCount = 0;
  this.lines = [];
  if (!window.opera)
  {
    for (var ibadchar = 0; ibadchar < 32; ++ibadchar)
    {
      if (ibadchar != 10 && ibadchar != 13)
      {
        var badchar = String.fromCharCode(ibadchar);
        var badregx = new RegExp(badchar, 'mg');
        var escchar = '\\0x' + ibadchar.toString(16);
        s = s.replace(badregx, escchar);
      }
    }
  }
  this.document.writeln(s);
}

CachedWriter.prototype.close = function _cachedWriterClose()
{
  this.flush();
  this.document.close();
  this.destroy();
}