js/src/tests/shell.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 // Explicitly set the default version.
     7 // See https://bugzilla.mozilla.org/show_bug.cgi?id=522760#c11
     8 if (typeof version != 'undefined')
     9 {
    10   version(0);
    11 }
    13 var STATUS = "STATUS: ";
    14 var VERBOSE = false;
    15 var SECT_PREFIX = 'Section ';
    16 var SECT_SUFFIX = ' of test - ';
    17 var callStack = new Array();
    19 var gDelayTestDriverEnd = false;
    21 var gTestcases = new Array();
    22 var gTc = gTestcases.length;
    23 var BUGNUMBER = '';
    24 var summary = '';
    25 var description = '';
    26 var expected = '';
    27 var actual = '';
    28 var msg = '';
    30 var SECTION = "";
    31 var VERSION = "";
    32 var BUGNUMBER = "";
    34 /*
    35  * constant strings
    36  */
    37 var GLOBAL = this + '';
    38 var PASSED = " PASSED! ";
    39 var FAILED = " FAILED! ";
    41 var DEBUG = false;
    43 var DESCRIPTION;
    44 var EXPECTED;
    46 /*
    47  * Signals to results.py that the current test case should be considered to
    48  * have passed if it doesn't throw an exception.
    49  *
    50  * When the test suite is run in the browser, this function gets overridden by
    51  * the same-named function in browser.js.
    52  */
    53 function testPassesUnlessItThrows() {
    54   print(PASSED);
    55 }
    57 /*
    58  * wrapper for test case constructor that doesn't require the SECTION
    59  * argument.
    60  */
    62 function AddTestCase( description, expect, actual ) {
    63   new TestCase( SECTION, description, expect, actual );
    64 }
    66 /*
    67  * Set up test environment.
    68  *
    69  */
    70 function startTest() {
    71   // print out bugnumber
    73   if ( BUGNUMBER ) {
    74     print ("BUGNUMBER: " + BUGNUMBER );
    75   }
    76 }
    78 function TestCase(n, d, e, a)
    79 {
    80   this.name = n;
    81   this.description = d;
    82   this.expect = e;
    83   this.actual = a;
    84   this.passed = getTestCaseResult(e, a);
    85   this.reason = '';
    86   this.bugnumber = typeof(BUGNUMER) != 'undefined' ? BUGNUMBER : '';
    87   this.type = (typeof window == 'undefined' ? 'shell' : 'browser');
    88   gTestcases[gTc++] = this;
    89 }
    91 gFailureExpected = false;
    93 TestCase.prototype.dump = function () {
    94   // let reftest handle error reporting, otherwise
    95   // output a summary line.
    96   if (typeof document != "object" ||
    97       !document.location.href.match(/jsreftest.html/))
    98   {
    99     dump('\njstest: ' + this.path + ' ' +
   100          'bug: '         + this.bugnumber + ' ' +
   101          'result: '      + (this.passed ? 'PASSED':'FAILED') + ' ' +
   102          'type: '        + this.type + ' ' +
   103          'description: ' + toPrinted(this.description) + ' ' +
   104 //       'expected: '    + toPrinted(this.expect) + ' ' +
   105 //       'actual: '      + toPrinted(this.actual) + ' ' +
   106          'reason: '      + toPrinted(this.reason) + '\n');
   107   }
   108 };
   110 TestCase.prototype.testPassed = (function TestCase_testPassed() { return this.passed; });
   111 TestCase.prototype.testFailed = (function TestCase_testFailed() { return !this.passed; });
   112 TestCase.prototype.testDescription = (function TestCase_testDescription() { return this.description + ' ' + this.reason; });
   114 function getTestCases()
   115 {
   116   return gTestcases;
   117 }
   119 /*
   120  * The test driver searches for such a phrase in the test output.
   121  * If such phrase exists, it will set n as the expected exit code.
   122  */
   123 function expectExitCode(n)
   124 {
   125   print('--- NOTE: IN THIS TESTCASE, WE EXPECT EXIT CODE ' + n + ' ---');
   126 }
   128 /*
   129  * Statuses current section of a test
   130  */
   131 function inSection(x)
   132 {
   133   return SECT_PREFIX + x + SECT_SUFFIX;
   134 }
   136 /*
   137  * Report a failure in the 'accepted' manner
   138  */
   139 function reportFailure (msg)
   140 {
   141   var lines = msg.split ("\n");
   142   var l;
   143   var funcName = currentFunc();
   144   var prefix = (funcName) ? "[reported from " + funcName + "] ": "";
   146   for (var i=0; i<lines.length; i++)
   147     print (FAILED + prefix + lines[i]);
   148 }
   150 /*
   151  * Print a non-failure message.
   152  */
   153 function printStatus (msg)
   154 {
   155 /* js1_6 had...
   156    msg = String(msg);
   157    msg = msg.toString();
   158 */
   159   msg = msg.toString();
   160   var lines = msg.split ("\n");
   161   var l;
   163   for (var i=0; i<lines.length; i++)
   164     print (STATUS + lines[i]);
   165 }
   167 /*
   168  * Print a bugnumber message.
   169  */
   170 function printBugNumber (num)
   171 {
   172   BUGNUMBER = num;
   173   print ('BUGNUMBER: ' + num);
   174 }
   176 function toPrinted(value)
   177 {
   178   value = String(value);
   179   value = value.replace(/\\n/g, 'NL')
   180                .replace(/\n/g, 'NL')
   181                .replace(/\\r/g, 'CR')
   182                .replace(/[^\x20-\x7E]+/g, escapeString);
   183   return value;
   184 }
   186 function escapeString (str)
   187 {
   188   var a, b, c, d;
   189   var len = str.length;
   190   var result = "";
   191   var digits = ["0", "1", "2", "3", "4", "5", "6", "7",
   192                 "8", "9", "A", "B", "C", "D", "E", "F"];
   194   for (var i=0; i<len; i++)
   195   {
   196     var ch = str.charCodeAt(i);
   198     a = digits[ch & 0xf];
   199     ch >>= 4;
   200     b = digits[ch & 0xf];
   201     ch >>= 4;
   203     if (ch)
   204     {
   205       c = digits[ch & 0xf];
   206       ch >>= 4;
   207       d = digits[ch & 0xf];
   209       result += "\\u" + d + c + b + a;
   210     }
   211     else
   212     {
   213       result += "\\x" + b + a;
   214     }
   215   }
   217   return result;
   218 }
   220 /*
   221  * assertEq(actual, expected [, message])
   222  *   Throw if the two arguments are not the same.  The sameness of two values
   223  *   is determined as follows.  If both values are zero, they are the same iff
   224  *   their signs are the same.  Otherwise, if both values are NaN, they are the
   225  *   same.  Otherwise, they are the same if they compare equal using ===.
   226  * see https://bugzilla.mozilla.org/show_bug.cgi?id=480199 and
   227  *     https://bugzilla.mozilla.org/show_bug.cgi?id=515285
   228  */
   229 if (typeof assertEq == 'undefined')
   230 {
   231   var assertEq =
   232     function (actual, expected, message)
   233     {
   234       function SameValue(v1, v2)
   235       {
   236         if (v1 === 0 && v2 === 0)
   237           return 1 / v1 === 1 / v2;
   238         if (v1 !== v1 && v2 !== v2)
   239           return true;
   240         return v1 === v2;
   241       }
   242       if (!SameValue(actual, expected))
   243       {
   244         throw new TypeError('Assertion failed: got "' + actual + '", expected "' + expected +
   245                             (message ? ": " + message : ""));
   246       }
   247     };
   248 }
   250 /*
   251  * Compare expected result to actual result, if they differ (in value and/or
   252  * type) report a failure.  If description is provided, include it in the
   253  * failure report.
   254  */
   255 function reportCompare (expected, actual, description) {
   256   var expected_t = typeof expected;
   257   var actual_t = typeof actual;
   258   var output = "";
   260   if (typeof description == "undefined")
   261   {
   262     description = '';
   263   }
   264   else if (VERBOSE)
   265   {
   266     printStatus ("Comparing '" + description + "'");
   267   }
   269   if (expected_t != actual_t)
   270   {
   271     output += "Type mismatch, expected type " + expected_t +
   272       ", actual type " + actual_t + " ";
   273   }
   274   else if (VERBOSE)
   275   {
   276     printStatus ("Expected type '" + expected_t + "' matched actual " +
   277                  "type '" + actual_t + "'");
   278   }
   280   if (expected != actual)
   281   {
   282     output += "Expected value '" + toPrinted(expected) +
   283       "', Actual value '" + toPrinted(actual) + "' ";
   284   }
   285   else if (VERBOSE)
   286   {
   287     printStatus ("Expected value '" + toPrinted(expected) +
   288                  "' matched actual value '" + toPrinted(actual) + "'");
   289   }
   291   var testcase = new TestCase("unknown-test-name", description, expected, actual);
   292   testcase.reason = output;
   294   // if running under reftest, let it handle result reporting.
   295   if (typeof document != "object" ||
   296       !document.location.href.match(/jsreftest.html/)) {
   297     if (testcase.passed)
   298     {
   299       print(PASSED + description);
   300     }
   301     else
   302     {
   303       reportFailure (description + " : " + output);
   304     }
   305   }
   306   return testcase.passed;
   307 }
   309 /*
   310  * Attempt to match a regular expression describing the result to
   311  * the actual result, if they differ (in value and/or
   312  * type) report a failure.  If description is provided, include it in the
   313  * failure report.
   314  */
   315 function reportMatch (expectedRegExp, actual, description) {
   316   var expected_t = "string";
   317   var actual_t = typeof actual;
   318   var output = "";
   320   if (typeof description == "undefined")
   321   {
   322     description = '';
   323   }
   324   else if (VERBOSE)
   325   {
   326     printStatus ("Comparing '" + description + "'");
   327   }
   329   if (expected_t != actual_t)
   330   {
   331     output += "Type mismatch, expected type " + expected_t +
   332       ", actual type " + actual_t + " ";
   333   }
   334   else if (VERBOSE)
   335   {
   336     printStatus ("Expected type '" + expected_t + "' matched actual " +
   337                  "type '" + actual_t + "'");
   338   }
   340   var matches = expectedRegExp.test(actual);
   341   if (!matches)
   342   {
   343     output += "Expected match to '" + toPrinted(expectedRegExp) +
   344       "', Actual value '" + toPrinted(actual) + "' ";
   345   }
   346   else if (VERBOSE)
   347   {
   348     printStatus ("Expected match to '" + toPrinted(expectedRegExp) +
   349                  "' matched actual value '" + toPrinted(actual) + "'");
   350   }
   352   var testcase = new TestCase("unknown-test-name", description, true, matches);
   353   testcase.reason = output;
   355   // if running under reftest, let it handle result reporting.
   356   if (typeof document != "object" ||
   357       !document.location.href.match(/jsreftest.html/)) {
   358     if (testcase.passed)
   359     {
   360       print(PASSED + description);
   361     }
   362     else
   363     {
   364       reportFailure (description + " : " + output);
   365     }
   366   }
   367   return testcase.passed;
   368 }
   370 /*
   371  * Puts funcName at the top of the call stack.  This stack is used to show
   372  * a function-reported-from field when reporting failures.
   373  */
   374 function enterFunc (funcName)
   375 {
   376   if (!funcName.match(/\(\)$/))
   377     funcName += "()";
   379   callStack.push(funcName);
   380 }
   382 /*
   383  * Pops the top funcName off the call stack.  funcName is optional, and can be
   384  * used to check push-pop balance.
   385  */
   386 function exitFunc (funcName)
   387 {
   388   var lastFunc = callStack.pop();
   390   if (funcName)
   391   {
   392     if (!funcName.match(/\(\)$/))
   393       funcName += "()";
   395     if (lastFunc != funcName)
   396       reportCompare(funcName, lastFunc, "Test driver failure wrong exit function ");
   397   }
   398 }
   400 /*
   401  * Peeks at the top of the call stack.
   402  */
   403 function currentFunc()
   404 {
   405   return callStack[callStack.length - 1];
   406 }
   408 /*
   409   Calculate the "order" of a set of data points {X: [], Y: []}
   410   by computing successive "derivatives" of the data until
   411   the data is exhausted or the derivative is linear.
   412 */
   413 function BigO(data)
   414 {
   415   var order = 0;
   416   var origLength = data.X.length;
   418   while (data.X.length > 2)
   419   {
   420     var lr = new LinearRegression(data);
   421     if (lr.b > 1e-6)
   422     {
   423       // only increase the order if the slope
   424       // is "great" enough
   425       order++;
   426     }
   428     if (lr.r > 0.98 || lr.Syx < 1 || lr.b < 1e-6)
   429     {
   430       // terminate if close to a line lr.r
   431       // small error lr.Syx
   432       // small slope lr.b
   433       break;
   434     }
   435     data = dataDeriv(data);
   436   }
   438   if (2 == origLength - order)
   439   {
   440     order = Number.POSITIVE_INFINITY;
   441   }
   442   return order;
   444   function LinearRegression(data)
   445   {
   446     /*
   447       y = a + bx
   448       for data points (Xi, Yi); 0 <= i < n
   450       b = (n*SUM(XiYi) - SUM(Xi)*SUM(Yi))/(n*SUM(Xi*Xi) - SUM(Xi)*SUM(Xi))
   451       a = (SUM(Yi) - b*SUM(Xi))/n
   452     */
   453     var i;
   455     if (data.X.length != data.Y.length)
   456     {
   457       throw 'LinearRegression: data point length mismatch';
   458     }
   459     if (data.X.length < 3)
   460     {
   461       throw 'LinearRegression: data point length < 2';
   462     }
   463     var n = data.X.length;
   464     var X = data.X;
   465     var Y = data.Y;
   467     this.Xavg = 0;
   468     this.Yavg = 0;
   470     var SUM_X  = 0;
   471     var SUM_XY = 0;
   472     var SUM_XX = 0;
   473     var SUM_Y  = 0;
   474     var SUM_YY = 0;
   476     for (i = 0; i < n; i++)
   477     {
   478       SUM_X  += X[i];
   479       SUM_XY += X[i]*Y[i];
   480       SUM_XX += X[i]*X[i];
   481       SUM_Y  += Y[i];
   482       SUM_YY += Y[i]*Y[i];
   483     }
   485     this.b = (n * SUM_XY - SUM_X * SUM_Y)/(n * SUM_XX - SUM_X * SUM_X);
   486     this.a = (SUM_Y - this.b * SUM_X)/n;
   488     this.Xavg = SUM_X/n;
   489     this.Yavg = SUM_Y/n;
   491     var SUM_Ydiff2 = 0;
   492     var SUM_Xdiff2 = 0;
   493     var SUM_XdiffYdiff = 0;
   495     for (i = 0; i < n; i++)
   496     {
   497       var Ydiff = Y[i] - this.Yavg;
   498       var Xdiff = X[i] - this.Xavg;
   500       SUM_Ydiff2 += Ydiff * Ydiff;
   501       SUM_Xdiff2 += Xdiff * Xdiff;
   502       SUM_XdiffYdiff += Xdiff * Ydiff;
   503     }
   505     var Syx2 = (SUM_Ydiff2 - Math.pow(SUM_XdiffYdiff/SUM_Xdiff2, 2))/(n - 2);
   506     var r2   = Math.pow((n*SUM_XY - SUM_X * SUM_Y), 2) /
   507       ((n*SUM_XX - SUM_X*SUM_X)*(n*SUM_YY-SUM_Y*SUM_Y));
   509     this.Syx = Math.sqrt(Syx2);
   510     this.r = Math.sqrt(r2);
   512   }
   514   function dataDeriv(data)
   515   {
   516     if (data.X.length != data.Y.length)
   517     {
   518       throw 'length mismatch';
   519     }
   520     var length = data.X.length;
   522     if (length < 2)
   523     {
   524       throw 'length ' + length + ' must be >= 2';
   525     }
   526     var X = data.X;
   527     var Y = data.Y;
   529     var deriv = {X: [], Y: [] };
   531     for (var i = 0; i < length - 1; i++)
   532     {
   533       deriv.X[i] = (X[i] + X[i+1])/2;
   534       deriv.Y[i] = (Y[i+1] - Y[i])/(X[i+1] - X[i]);
   535     }
   536     return deriv;
   537   }
   539   return 0;
   540 }
   542 function compareSource(expect, actual, summary)
   543 {
   544   // compare source
   545   var expectP = expect.
   546     replace(/([(){},.:\[\]])/mg, ' $1 ').
   547     replace(/(\w+)/mg, ' $1 ').
   548     replace(/<(\/)? (\w+) (\/)?>/mg, '<$1$2$3>').
   549     replace(/\s+/mg, ' ').
   550     replace(/new (\w+)\s*\(\s*\)/mg, 'new $1');
   552   var actualP = actual.
   553     replace(/([(){},.:\[\]])/mg, ' $1 ').
   554     replace(/(\w+)/mg, ' $1 ').
   555     replace(/<(\/)? (\w+) (\/)?>/mg, '<$1$2$3>').
   556     replace(/\s+/mg, ' ').
   557     replace(/new (\w+)\s*\(\s*\)/mg, 'new $1');
   559   print('expect:\n' + expectP);
   560   print('actual:\n' + actualP);
   562   reportCompare(expectP, actualP, summary);
   564   // actual must be compilable if expect is?
   565   try
   566   {
   567     var expectCompile = 'No Error';
   568     var actualCompile;
   570     eval(expect);
   571     try
   572     {
   573       eval(actual);
   574       actualCompile = 'No Error';
   575     }
   576     catch(ex1)
   577     {
   578       actualCompile = ex1 + '';
   579     }
   580     reportCompare(expectCompile, actualCompile,
   581                   summary + ': compile actual');
   582   }
   583   catch(ex)
   584   {
   585   }
   586 }
   588 function optionsInit() {
   590   // record initial values to support resetting
   591   // options to their initial values
   592   options.initvalues  = {};
   594   // record values in a stack to support pushing
   595   // and popping options
   596   options.stackvalues = [];
   598   var optionNames = options().split(',');
   600   for (var i = 0; i < optionNames.length; i++)
   601   {
   602     var optionName = optionNames[i];
   603     if (optionName)
   604     {
   605       options.initvalues[optionName] = '';
   606     }
   607   }
   608 }
   610 function optionsClear() {
   612   // turn off current settings
   613   // except jit.
   614   var optionNames = options().split(',');
   615   for (var i = 0; i < optionNames.length; i++)
   616   {
   617     var optionName = optionNames[i];
   618     if (optionName &&
   619         optionName != "methodjit" &&
   620         optionName != "methodjit_always" &&
   621         optionName != "ion")
   622     {
   623       options(optionName);
   624     }
   625   }
   626 }
   628 function optionsPush()
   629 {
   630   var optionsframe = {};
   632   options.stackvalues.push(optionsframe);
   634   var optionNames = options().split(',');
   636   for (var i = 0; i < optionNames.length; i++)
   637   {
   638     var optionName = optionNames[i];
   639     if (optionName)
   640     {
   641       optionsframe[optionName] = '';
   642     }
   643   }
   645   optionsClear();
   646 }
   648 function optionsPop()
   649 {
   650   var optionsframe = options.stackvalues.pop();
   652   optionsClear();
   654   for (optionName in optionsframe)
   655   {
   656     options(optionName);
   657   }
   659 }
   661 function optionsReset() {
   663   try
   664   {
   665     optionsClear();
   667     // turn on initial settings
   668     for (var optionName in options.initvalues)
   669     {
   670       if (!options.hasOwnProperty(optionName))
   671         continue;
   672       options(optionName);
   673     }
   674   }
   675   catch(ex)
   676   {
   677     print('optionsReset: caught ' + ex);
   678   }
   680 }
   682 if (typeof options == 'function')
   683 {
   684   optionsInit();
   685   optionsClear();
   686 }
   688 function getTestCaseResult(expected, actual)
   689 {
   690   if (typeof expected != typeof actual)
   691     return false;
   692   if (typeof expected != 'number')
   693     // Note that many tests depend on the use of '==' here, not '==='.
   694     return actual == expected;
   696   // Distinguish NaN from other values.  Using x != x comparisons here
   697   // works even if tests redefine isNaN.
   698   if (actual != actual)
   699     return expected != expected;
   700   if (expected != expected)
   701     return false;
   703   // Tolerate a certain degree of error.
   704   if (actual != expected)
   705     return Math.abs(actual - expected) <= 1E-10;
   707   // Here would be a good place to distinguish 0 and -0, if we wanted
   708   // to.  However, doing so would introduce a number of failures in
   709   // areas where they don't seem important.  For example, the WeekDay
   710   // function in ECMA-262 returns -0 for Sundays before the epoch, but
   711   // the Date functions in SpiderMonkey specified in terms of WeekDay
   712   // often don't.  This seems unimportant.
   713   return true;
   714 }
   716 if (typeof dump == 'undefined')
   717 {
   718   if (typeof window == 'undefined' &&
   719       typeof print == 'function')
   720   {
   721     dump = print;
   722   }
   723   else
   724   {
   725     dump = (function () {});
   726   }
   727 }
   729 function test() {
   730   for ( gTc=0; gTc < gTestcases.length; gTc++ ) {
   731     // temporary hack to work around some unknown issue in 1.7
   732     try
   733     {
   734       gTestcases[gTc].passed = writeTestCaseResult(
   735         gTestcases[gTc].expect,
   736         gTestcases[gTc].actual,
   737         gTestcases[gTc].description +" = "+ gTestcases[gTc].actual );
   738       gTestcases[gTc].reason += ( gTestcases[gTc].passed ) ? "" : "wrong value ";
   739     }
   740     catch(e)
   741     {
   742       print('test(): empty testcase for gTc = ' + gTc + ' ' + e);
   743     }
   744   }
   745   stopTest();
   746   return ( gTestcases );
   747 }
   749 /*
   750  * Begin printing functions.  These functions use the shell's
   751  * print function.  When running tests in the browser, these
   752  * functions, override these functions with functions that use
   753  * document.write.
   754  */
   756 function writeTestCaseResult( expect, actual, string ) {
   757   var passed = getTestCaseResult( expect, actual );
   758   // if running under reftest, let it handle result reporting.
   759   if (typeof document != "object" ||
   760       !document.location.href.match(/jsreftest.html/)) {
   761     writeFormattedResult( expect, actual, string, passed );
   762   }
   763   return passed;
   764 }
   765 function writeFormattedResult( expect, actual, string, passed ) {
   766   var s = ( passed ? PASSED : FAILED ) + string + ' expected: ' + expect;
   767   print(s);
   768   return passed;
   769 }
   771 function writeHeaderToLog( string ) {
   772   print( string );
   773 }
   774 /* end of print functions */
   777 /*
   778  * When running in the shell, run the garbage collector after the
   779  * test has completed.
   780  */
   782 function stopTest() {
   783   var gc;
   784   if ( gc != undefined ) {
   785     gc();
   786   }
   787 }
   789 /*
   790  * Convenience function for displaying failed test cases.  Useful
   791  * when running tests manually.
   792  *
   793  */
   794 function getFailedCases() {
   795   for ( var i = 0; i < gTestcases.length; i++ ) {
   796     if ( ! gTestcases[i].passed ) {
   797       print( gTestcases[i].description + " = " +gTestcases[i].actual +
   798              " expected: " + gTestcases[i].expect );
   799     }
   800   }
   801 }
   803 function jsTestDriverEnd()
   804 {
   805   // gDelayTestDriverEnd is used to
   806   // delay collection of the test result and
   807   // signal to Spider so that tests can continue
   808   // to run after page load has fired. They are
   809   // responsible for setting gDelayTestDriverEnd = true
   810   // then when completed, setting gDelayTestDriverEnd = false
   811   // then calling jsTestDriverEnd()
   813   if (gDelayTestDriverEnd)
   814   {
   815     return;
   816   }
   818   try
   819   {
   820     optionsReset();
   821   }
   822   catch(ex)
   823   {
   824     dump('jsTestDriverEnd ' + ex);
   825   }
   827   for (var i = 0; i < gTestcases.length; i++)
   828   {
   829     gTestcases[i].dump();
   830   }
   832 }
   834 function jit(on)
   835 {
   836 }
   838 function assertEqArray(a1, a2) {
   839   assertEq(a1.length, a2.length);
   840   for (var i = 0; i < a1.length; i++) {
   841     try {
   842       assertEq(a1[i], a2[i]);
   843     } catch (e) {
   844       throw new Error("At index " + i + ": " + e);
   845     }
   846   }
   847 }
   849 function assertThrows(f) {
   850     var ok = false;
   851     try {
   852         f();
   853     } catch (exc) {
   854         ok = true;
   855     }
   856     if (!ok)
   857         throw new Error("Assertion failed: " + f + " did not throw as expected");
   858 }
   860 /*
   861  * Some tests need to know if we are in Rhino as opposed to SpiderMonkey
   862  */
   863 function inRhino()
   864 {
   865   return (typeof defineClass == "function");
   866 }
   868 /* these functions are useful for running tests manually in Rhino */
   870 function GetContext() {
   871   return Packages.com.netscape.javascript.Context.getCurrentContext();
   872 }
   873 function OptLevel( i ) {
   874   i = Number(i);
   875   var cx = GetContext();
   876   cx.setOptimizationLevel(i);
   877 }
   878 /* end of Rhino functions */

mercurial