js/src/tests/js1_5/extensions/regress-350531.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/tests/js1_5/extensions/regress-350531.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,156 @@
     1.4 +// |reftest| skip -- slow
     1.5 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +//-----------------------------------------------------------------------------
    1.11 +var BUGNUMBER = 350531;
    1.12 +var summary = 'exhaustively test parenthesization of binary operator subsets';
    1.13 +var actual = '';
    1.14 +var expect = '';
    1.15 +
    1.16 +
    1.17 +//-----------------------------------------------------------------------------
    1.18 +test();
    1.19 +//-----------------------------------------------------------------------------
    1.20 +
    1.21 +function test()
    1.22 +{
    1.23 +  enterFunc ('test');
    1.24 +  printBugNumber(BUGNUMBER);
    1.25 +  printStatus (summary);
    1.26 + 
    1.27 +// Translated from permcomb.py, found at
    1.28 +// http://biotech.embl-ebi.ac.uk:8400/sw/common/share/python/examples/dstruct/classics/permcomb.py
    1.29 +// by searching for "permcomb.py".
    1.30 +//
    1.31 +// This shows bugs, gaps, and verbosities in JS compared to Python:
    1.32 +// 1. Lack of range([start, ] end[, step]).
    1.33 +// 2. ![] => false, indeed !<any-object> => false.
    1.34 +// 3. Missing append or push for strings (if append, then we'd want append for
    1.35 +//    arrays too).
    1.36 +// 4. Missing slice operator syntax s[i:j].
    1.37 +// 5. Lack of + for array concatenation.
    1.38 +
    1.39 +  String.prototype.push = function (str) { return this + str; };
    1.40 +
    1.41 +  function permute(list) {
    1.42 +    if (!list.length)                                   // shuffle any sequence
    1.43 +      return [list];                                    // empty sequence
    1.44 +    var res = [];
    1.45 +    for (var i = 0, n = list.length; i < n; i++) {      // delete current node
    1.46 +      var rest = list.slice(0, i).concat(list.slice(i+1));
    1.47 +      for each (var x in permute(rest))                 // permute the others
    1.48 +        res.push(list.slice(i, i+1).concat(x));         // add node at front
    1.49 +    }
    1.50 +    return res;
    1.51 +  }
    1.52 +
    1.53 +  function subset(list, size) {
    1.54 +    if (size == 0 || !list.length)                      // order matters here
    1.55 +      return [list.slice(0, 0)];                        // an empty sequence
    1.56 +    var result = [];
    1.57 +    for (var i = 0, n = list.length; i < n; i++) {
    1.58 +      var pick = list.slice(i, i+1);                    // sequence slice
    1.59 +      var rest = list.slice(0, i).concat(list.slice(i+1)); // keep [:i] part
    1.60 +      for each (var x in subset(rest, size-1))
    1.61 +	result.push(pick.concat(x));
    1.62 +    }
    1.63 +    return result;
    1.64 +  }
    1.65 +
    1.66 +  function combo(list, size) {
    1.67 +    if (size == 0 || !list.length)                      // order doesn't matter
    1.68 +      return [list.slice(0, 0)];                        // xyz == yzx
    1.69 +    var result = [];
    1.70 +    for (var i = 0, n = (list.length - size) + 1; i < n; i++) {
    1.71 +      // iff enough left
    1.72 +      var pick = list.slice(i, i+1);
    1.73 +      var rest = list.slice(i+1);                       // drop [:i] part
    1.74 +      for each (var x in combo(rest, size - 1))
    1.75 +	result.push(pick.concat(x));
    1.76 +    }
    1.77 +    return result;
    1.78 +  }
    1.79 +
    1.80 +
    1.81 +// Generate all subsets of distinct binary operators and join them from left
    1.82 +// to right, parenthesizing minimally.  Decompile, recompile, compress spaces
    1.83 +// and compare to test correct parenthesization.
    1.84 +
    1.85 +//  load("permcomb.js");
    1.86 +
    1.87 +  var bops = [
    1.88 +    ["=", "|=", "^=", "&=", "<<=", ">>=", ">>>=", "+=", "-=", "*=", "/=", "%="],
    1.89 +    ["||"],
    1.90 +    ["&&"],
    1.91 +    ["|"],
    1.92 +    ["^"],
    1.93 +    ["&"],
    1.94 +    ["==", "!=", "===", "!=="],
    1.95 +    ["<", "<=", ">=", ">", "in", "instanceof"],
    1.96 +    ["<<", ">>", ">>>"],
    1.97 +    ["+", "-"],
    1.98 +    ["*", "/", "%"],
    1.99 +    ];
   1.100 +
   1.101 +  var prec = {};
   1.102 +  var aops = [];
   1.103 +
   1.104 +  for (var i = 0; i < bops.length; i++) {
   1.105 +    for (var j = 0; j < bops[i].length; j++) {
   1.106 +      var k = bops[i][j];
   1.107 +      prec[k] = i;
   1.108 +      aops.push(k);
   1.109 +    }
   1.110 +  }
   1.111 +
   1.112 +// Theoretically all subsets of size 2 should be enough to test, but in case
   1.113 +// there's some large-scale bug, try up to 5 (or higher? The cost in memory is
   1.114 +// factorially explosive).
   1.115 +next_subset:
   1.116 +  for (i = 2; i < 5; i++) {
   1.117 +    var sets = subset(aops, i);
   1.118 +    gc();
   1.119 +
   1.120 +    for each (var set in sets) {
   1.121 +      //print('for each set in sets: ' + (uneval(set)) );
   1.122 +      var src = "(function () {";
   1.123 +      for (j in set) {
   1.124 +        var op = set[j], op2 = set[j-1];
   1.125 +
   1.126 +        // Precedence 0 is for assignment ops, which are right-
   1.127 +        // associative, so don't force left associativity using
   1.128 +        // parentheses.
   1.129 +        if (prec[op] && prec[op] < prec[op2])
   1.130 +          src += "(";
   1.131 +      }
   1.132 +      src += "x ";
   1.133 +      for (j in set) {
   1.134 +        var op = set[j], op2 = set[j+1];
   1.135 +
   1.136 +        // Parenthesize only if not right-associative (precedence 0) and
   1.137 +        // the next op is higher precedence than current.
   1.138 +        var term = (prec[op] && prec[op] < prec[op2]) ? " x)" : " x";
   1.139 +
   1.140 +        src += op + term;
   1.141 +        if (j < set.length - 1)
   1.142 +          src += " ";
   1.143 +      }
   1.144 +      src += ";})";
   1.145 +      try {
   1.146 +        var ref = uneval(eval(src)).replace(/\s+/g, ' ');
   1.147 +        if (ref != src) {
   1.148 +          actual += "BROKEN! input: " + src + " output: " + ref + " ";
   1.149 +          print("BROKEN! input: " + src + " output: " + ref);
   1.150 +          break next_subset;
   1.151 +        }
   1.152 +      } catch (e) {}
   1.153 +    }
   1.154 +  }
   1.155 +
   1.156 +  reportCompare(expect, actual, summary);
   1.157 +
   1.158 +  exitFunc ('test');
   1.159 +}

mercurial