tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

shell.js (10364B)


      1 /* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 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/. */
      5 
      6 /*---
      7 defines: [testRegExp, clone_object_check]
      8 allow_unused: True
      9 ---*/
     10 
     11 (function(global) {
     12  /*
     13   * Date: 07 February 2001
     14   *
     15   * Functionality common to RegExp testing -
     16   */
     17  //-----------------------------------------------------------------------------
     18 
     19  var MSG_PATTERN = '\nregexp = ';
     20  var MSG_STRING = '\nstring = ';
     21  var MSG_EXPECT = '\nExpect: ';
     22  var MSG_ACTUAL = '\nActual: ';
     23  var ERR_LENGTH = '\nERROR !!! match arrays have different lengths:';
     24  var ERR_MATCH = '\nERROR !!! regexp failed to give expected match array:';
     25  var ERR_NO_MATCH = '\nERROR !!! regexp FAILED to match anything !!!';
     26  var ERR_UNEXP_MATCH = '\nERROR !!! regexp MATCHED when we expected it to fail !!!';
     27  var CHAR_LBRACKET = '[';
     28  var CHAR_RBRACKET = ']';
     29  var CHAR_QT_DBL = '"';
     30  var CHAR_QT = "'";
     31  var CHAR_NL = '\n';
     32  var CHAR_COMMA = ',';
     33  var CHAR_SPACE = ' ';
     34  var TYPE_STRING = typeof 'abc';
     35 
     36 
     37 
     38  function testRegExp(statuses, patterns, strings, actualmatches, expectedmatches)
     39  {
     40    var status = '';
     41    var pattern = new RegExp();
     42    var string = '';
     43    var actualmatch = new Array();
     44    var expectedmatch = new Array();
     45    var state = '';
     46    var lActual = -1;
     47    var lExpect = -1;
     48 
     49 
     50    for (var i=0; i != patterns.length; i++)
     51    {
     52      status = statuses[i];
     53      pattern = patterns[i];
     54      string = strings[i];
     55      actualmatch=actualmatches[i];
     56      expectedmatch=expectedmatches[i];
     57      state = getState(status, pattern, string);
     58 
     59      description = status;
     60 
     61      if(actualmatch)
     62      {
     63        actual = formatArray(actualmatch);
     64        if(expectedmatch)
     65        {
     66          // expectedmatch and actualmatch are arrays -
     67          lExpect = expectedmatch.length;
     68          lActual = actualmatch.length;
     69 
     70          var expected = formatArray(expectedmatch);
     71 
     72          if (lActual != lExpect)
     73          {
     74            reportCompare(lExpect, lActual,
     75                          state + ERR_LENGTH +
     76                          MSG_EXPECT + expected +
     77                          MSG_ACTUAL + actual +
     78                          CHAR_NL
     79                        );
     80            continue;
     81          }
     82 
     83          // OK, the arrays have same length -
     84          if (expected != actual)
     85          {
     86            reportCompare(expected, actual,
     87                          state + ERR_MATCH +
     88                          MSG_EXPECT + expected +
     89                          MSG_ACTUAL + actual +
     90                          CHAR_NL
     91                        );
     92          }
     93          else
     94          {
     95            reportCompare(expected, actual, state)
     96         }
     97 
     98        }
     99        else //expectedmatch is null - that is, we did not expect a match -
    100        {
    101          expected = expectedmatch;
    102          reportCompare(expected, actual,
    103                        state + ERR_UNEXP_MATCH +
    104                        MSG_EXPECT + expectedmatch +
    105                        MSG_ACTUAL + actual +
    106                        CHAR_NL
    107                      );
    108        }
    109 
    110      }
    111      else // actualmatch is null
    112      {
    113        if (expectedmatch)
    114        {
    115          actual = actualmatch;
    116          reportCompare(expected, actual,
    117                        state + ERR_NO_MATCH +
    118                        MSG_EXPECT + expectedmatch +
    119                        MSG_ACTUAL + actualmatch +
    120                        CHAR_NL
    121                      );
    122        }
    123        else // we did not expect a match
    124        {
    125          // Being ultra-cautious. Presumably expectedmatch===actualmatch===null
    126          expected = expectedmatch;
    127          actual   = actualmatch;
    128          reportCompare (expectedmatch, actualmatch, state);
    129        }
    130      }
    131    }
    132  }
    133 
    134  global.testRegExp = testRegExp;
    135 
    136  function getState(status, pattern, string)
    137  {
    138    /*
    139     * Escape \n's, etc. to make them LITERAL in the presentation string.
    140     * We don't have to worry about this in |pattern|; such escaping is
    141     * done automatically by pattern.toString(), invoked implicitly below.
    142     *
    143     * One would like to simply do: string = string.replace(/(\s)/g, '\$1').
    144     * However, the backreference $1 is not a literal string value,
    145     * so this method doesn't work.
    146     *
    147     * Also tried string = string.replace(/(\s)/g, escape('$1'));
    148     * but this just inserts the escape of the literal '$1', i.e. '%241'.
    149     */
    150    string = string.replace(/\n/g, '\\n');
    151    string = string.replace(/\r/g, '\\r');
    152    string = string.replace(/\t/g, '\\t');
    153    string = string.replace(/\v/g, '\\v');
    154    string = string.replace(/\f/g, '\\f');
    155 
    156    return (status + MSG_PATTERN + pattern + MSG_STRING + singleQuote(string));
    157  }
    158 
    159 
    160  /*
    161   * If available, arr.toSource() gives more detail than arr.toString()
    162   *
    163   * var arr = Array(1,2,'3');
    164   *
    165   * arr.toSource()
    166   * [1, 2, "3"]
    167   *
    168   * arr.toString()
    169   * 1,2,3
    170   *
    171   * But toSource() doesn't exist in Rhino, so use our own imitation, below -
    172   *
    173   */
    174  function formatArray(arr)
    175  {
    176    try
    177    {
    178      return arr.toSource();
    179    }
    180    catch(e)
    181    {
    182      return toSource(arr);
    183    }
    184  }
    185 
    186 
    187  /*
    188   * Imitate SpiderMonkey's arr.toSource() method:
    189   *
    190   * a) Double-quote each array element that is of string type
    191   * b) Represent |undefined| and |null| by empty strings
    192   * c) Delimit elements by a comma + single space
    193   * d) Do not add delimiter at the end UNLESS the last element is |undefined|
    194   * e) Add square brackets to the beginning and end of the string
    195   */
    196  function toSource(arr)
    197  {
    198    var delim = CHAR_COMMA + CHAR_SPACE;
    199    var elt = '';
    200    var ret = '';
    201    var len = arr.length;
    202 
    203    for (i=0; i<len; i++)
    204    {
    205      elt = arr[i];
    206 
    207      switch(true)
    208      {
    209        case (typeof elt === TYPE_STRING) :
    210        ret += doubleQuote(elt);
    211        break;
    212 
    213        case (elt === undefined || elt === null) :
    214        break; // add nothing but the delimiter, below -
    215 
    216        default:
    217        ret += elt.toString();
    218      }
    219 
    220      if ((i < len-1) || (elt === undefined))
    221        ret += delim;
    222    }
    223 
    224    return  CHAR_LBRACKET + ret + CHAR_RBRACKET;
    225  }
    226 
    227 
    228  function doubleQuote(text)
    229  {
    230    return CHAR_QT_DBL + text + CHAR_QT_DBL;
    231  }
    232 
    233 
    234  function singleQuote(text)
    235  {
    236    return CHAR_QT + text + CHAR_QT;
    237 }
    238 
    239 })(this);
    240 
    241 
    242 (function(global) {
    243 
    244  // The Worker constructor can take a relative URL, but different test runners
    245  // run in different enough environments that it doesn't all just automatically
    246  // work. For the shell, we use just a filename; for the browser, see browser.js.
    247  var workerDir = '';
    248 
    249  // Assert that cloning b does the right thing as far as we can tell.
    250  // Caveat: getters in b must produce the same value each time they're
    251  // called. We may call them several times.
    252  //
    253  // If desc is provided, then the very first thing we do to b is clone it.
    254  // (The self-modifying object test counts on this.)
    255  //
    256  function clone_object_check(b, desc) {
    257    function classOf(obj) {
    258      return Object.prototype.toString.call(obj);
    259    }
    260 
    261    function ownProperties(obj) {
    262      return Object.getOwnPropertyNames(obj).
    263        map(function (p) { return [p, Object.getOwnPropertyDescriptor(obj, p)]; });
    264    }
    265 
    266    function isArrayLength(obj, pair) {
    267      return Array.isArray(obj) && pair[0] == "length";
    268    }
    269 
    270    function isCloneable(obj, pair) {
    271      return isArrayLength(obj, pair) || (typeof pair[0] === 'string' && pair[1].enumerable);
    272    }
    273 
    274    function notIndex(p) {
    275      var u = p >>> 0;
    276      return !("" + u == p && u != 0xffffffff);
    277    }
    278 
    279    function assertIsCloneOf(a, b, path) {
    280      assertEq(a === b, false);
    281 
    282      var ca = classOf(a);
    283      assertEq(ca, classOf(b), path);
    284 
    285      assertEq(Object.getPrototypeOf(a),
    286               ca == "[object Object]" ? Object.prototype : Array.prototype,
    287               path);
    288 
    289      // 'b', the original object, may have non-enumerable or XMLName
    290      // properties; ignore them (except .length, if it's an Array).
    291      // 'a', the clone, should not have any non-enumerable properties
    292      // (except .length, if it's an Array) or XMLName properties.
    293      var pb = ownProperties(b).filter(function(element) {
    294        return isCloneable(b, element);
    295      });
    296      var pa = ownProperties(a);
    297      for (var i = 0; i < pa.length; i++) {
    298        assertEq(typeof pa[i][0], "string", "clone should not have E4X properties " + path);
    299        if (!isCloneable(a, pa[i])) {
    300          throw new Error("non-cloneable clone property " + pa[i][0] + " " + path);
    301        }
    302      }
    303 
    304      // Check that, apart from properties whose names are array indexes, 
    305      // the enumerable properties appear in the same order.
    306      var aNames = pa.map(function (pair) { return pair[1]; }).filter(notIndex);
    307      var bNames = pa.map(function (pair) { return pair[1]; }).filter(notIndex);
    308      assertEq(aNames.join(","), bNames.join(","), path);
    309 
    310      // Check that the lists are the same when including array indexes.
    311      function byName(a, b) { a = a[0]; b = b[0]; return a < b ? -1 : a === b ? 0 : 1; }
    312      pa.sort(byName);
    313      pb.sort(byName);
    314      assertEq(pa.length, pb.length, "should see the same number of properties " + path);
    315      for (var i = 0; i < pa.length; i++) {
    316        var aName = pa[i][0];
    317        var bName = pb[i][0];
    318        assertEq(aName, bName, path);
    319 
    320        var path2 = path + "." + aName;
    321        var da = pa[i][1];
    322        var db = pb[i][1];
    323        if (!isArrayLength(a, pa[i])) {
    324          assertEq(da.configurable, true, path2);
    325        }
    326        assertEq(da.writable, true, path2);
    327        assertEq("value" in da, true, path2);
    328        var va = da.value;
    329        var vb = b[pb[i][0]];
    330        if (typeof va === "object" && va !== null)
    331          queue.push([va, vb, path2]);
    332        else
    333          assertEq(va, vb, path2);
    334      }
    335    }
    336 
    337    var banner = "while testing clone of " + (desc || JSON.stringify(b));
    338    var a = deserialize(serialize(b));
    339    var queue = [[a, b, banner]];
    340    while (queue.length) {
    341      var triple = queue.shift();
    342      assertIsCloneOf(triple[0], triple[1], triple[2]);
    343    }
    344 
    345    return a; // for further testing
    346  }
    347  global.clone_object_check = clone_object_check;
    348 
    349 })(this);