| OLD | NEW |
| (Empty) |
| 1 description( | |
| 2 "This test checks that parentheses are preserved when significant, and not added
where inappropriate. " + | |
| 3 "We need this test because the JavaScriptCore parser removes all parentheses and
the serializer then adds them back." | |
| 4 ); | |
| 5 | |
| 6 function compileAndSerialize(expression) | |
| 7 { | |
| 8 var f = eval("(function () { return " + expression + "; })"); | |
| 9 var serializedString = f.toString(); | |
| 10 serializedString = serializedString.replace(/[ \t\r\n]+/g, " "); | |
| 11 serializedString = serializedString.replace("function () { return ", ""); | |
| 12 serializedString = serializedString.replace("; }", ""); | |
| 13 return serializedString; | |
| 14 } | |
| 15 | |
| 16 function compileAndSerializeLeftmostTest(expression) | |
| 17 { | |
| 18 var f = eval("(function () { " + expression + "; })"); | |
| 19 var serializedString = f.toString(); | |
| 20 serializedString = serializedString.replace(/[ \t\r\n]+/g, " "); | |
| 21 serializedString = serializedString.replace("function () { ", ""); | |
| 22 serializedString = serializedString.replace("; }", ""); | |
| 23 return serializedString; | |
| 24 } | |
| 25 | |
| 26 var removesExtraParentheses = compileAndSerialize("(a + b) + c") == "a + b + c"; | |
| 27 | |
| 28 function testKeepParentheses(expression) | |
| 29 { | |
| 30 shouldBe("compileAndSerialize('" + expression + "')", | |
| 31 "'" + expression + "'"); | |
| 32 } | |
| 33 | |
| 34 function testOptionalParentheses(expression) | |
| 35 { | |
| 36 stripped_expression = removesExtraParentheses | |
| 37 ? expression.replace(/\(/g, '').replace(/\)/g, '') | |
| 38 : expression; | |
| 39 shouldBe("compileAndSerialize('" + expression + "')", | |
| 40 "'" + stripped_expression + "'"); | |
| 41 } | |
| 42 | |
| 43 function testLeftAssociativeSame(opA, opB) | |
| 44 { | |
| 45 testKeepParentheses("a " + opA + " b " + opB + " c"); | |
| 46 testOptionalParentheses("(a " + opA + " b) " + opB + " c"); | |
| 47 testKeepParentheses("a " + opA + " (b " + opB + " c)"); | |
| 48 } | |
| 49 | |
| 50 function testRightAssociativeSame(opA, opB) | |
| 51 { | |
| 52 testKeepParentheses("a " + opA + " b " + opB + " c"); | |
| 53 testKeepParentheses("(a " + opA + " b) " + opB + " c"); | |
| 54 testOptionalParentheses("a " + opA + " (b " + opB + " c)"); | |
| 55 } | |
| 56 | |
| 57 function testHigherFirst(opHigher, opLower) | |
| 58 { | |
| 59 testKeepParentheses("a " + opHigher + " b " + opLower + " c"); | |
| 60 testOptionalParentheses("(a " + opHigher + " b) " + opLower + " c"); | |
| 61 testKeepParentheses("a " + opHigher + " (b " + opLower + " c)"); | |
| 62 } | |
| 63 | |
| 64 function testLowerFirst(opLower, opHigher) | |
| 65 { | |
| 66 testKeepParentheses("a " + opLower + " b " + opHigher + " c"); | |
| 67 testKeepParentheses("(a " + opLower + " b) " + opHigher + " c"); | |
| 68 testOptionalParentheses("a " + opLower + " (b " + opHigher + " c)"); | |
| 69 } | |
| 70 | |
| 71 var binaryOperators = [ | |
| 72 [ "*", "/", "%" ], [ "+", "-" ], | |
| 73 [ "<<", ">>", ">>>" ], | |
| 74 [ "<", ">", "<=", ">=", "instanceof", "in" ], | |
| 75 [ "==", "!=", "===", "!==" ], | |
| 76 [ "&" ], [ "^" ], [ "|" ], | |
| 77 [ "&&" ], [ "||" ] | |
| 78 ]; | |
| 79 | |
| 80 for (i = 0; i < binaryOperators.length; ++i) { | |
| 81 var ops = binaryOperators[i]; | |
| 82 for (j = 0; j < ops.length; ++j) { | |
| 83 var op = ops[j]; | |
| 84 testLeftAssociativeSame(op, op); | |
| 85 if (j != 0) | |
| 86 testLeftAssociativeSame(ops[0], op); | |
| 87 if (i < binaryOperators.length - 1) { | |
| 88 var nextOps = binaryOperators[i + 1]; | |
| 89 if (j == 0) | |
| 90 for (k = 0; k < nextOps.length; ++k) | |
| 91 testHigherFirst(op, nextOps[k]); | |
| 92 else | |
| 93 testHigherFirst(op, nextOps[0]); | |
| 94 } | |
| 95 } | |
| 96 } | |
| 97 | |
| 98 var assignmentOperators = [ "=", "*=", "/=" , "%=", "+=", "-=", "<<=", ">>=", ">
>>=", "&=", "^=", "|=" ]; | |
| 99 | |
| 100 for (i = 0; i < assignmentOperators.length; ++i) { | |
| 101 var op = assignmentOperators[i]; | |
| 102 testRightAssociativeSame(op, op); | |
| 103 if (i != 0) | |
| 104 testRightAssociativeSame("=", op); | |
| 105 testLowerFirst(op, "+"); | |
| 106 shouldThrow("compileAndSerialize('a + b " + op + " c')"); | |
| 107 testKeepParentheses("(a + b) " + op + " c"); | |
| 108 testKeepParentheses("a + (b " + op + " c)"); | |
| 109 } | |
| 110 | |
| 111 var prefixOperators = [ "delete", "void", "typeof", "++", "--", "+", "-", "~", "
!" ]; | |
| 112 var prefixOperatorSpace = [ " ", " ", " ", "", "", " ", " ", "", "" ]; | |
| 113 | |
| 114 for (i = 0; i < prefixOperators.length; ++i) { | |
| 115 var op = prefixOperators[i] + prefixOperatorSpace[i]; | |
| 116 testKeepParentheses("" + op + "a + b"); | |
| 117 testOptionalParentheses("(" + op + "a) + b"); | |
| 118 testKeepParentheses("" + op + "(a + b)"); | |
| 119 testKeepParentheses("!" + op + "a"); | |
| 120 testOptionalParentheses("!(" + op + "a)"); | |
| 121 } | |
| 122 | |
| 123 | |
| 124 testKeepParentheses("!a++"); | |
| 125 testOptionalParentheses("!(a++)"); | |
| 126 testKeepParentheses("(!a)++"); | |
| 127 | |
| 128 testKeepParentheses("!a--"); | |
| 129 testOptionalParentheses("!(a--)"); | |
| 130 testKeepParentheses("(!a)--"); | |
| 131 | |
| 132 testKeepParentheses("(-1)[a]"); | |
| 133 testKeepParentheses("(-1)[a] = b"); | |
| 134 testKeepParentheses("(-1)[a] += b"); | |
| 135 testKeepParentheses("(-1)[a]++"); | |
| 136 testKeepParentheses("++(-1)[a]"); | |
| 137 testKeepParentheses("(-1)[a]()"); | |
| 138 | |
| 139 testKeepParentheses("new (-1)()"); | |
| 140 | |
| 141 testKeepParentheses("(-1).a"); | |
| 142 testKeepParentheses("(-1).a = b"); | |
| 143 testKeepParentheses("(-1).a += b"); | |
| 144 testKeepParentheses("(-1).a++"); | |
| 145 testKeepParentheses("++(-1).a"); | |
| 146 testKeepParentheses("(-1).a()"); | |
| 147 | |
| 148 testKeepParentheses("(- 0)[a]"); | |
| 149 testKeepParentheses("(- 0)[a] = b"); | |
| 150 testKeepParentheses("(- 0)[a] += b"); | |
| 151 testKeepParentheses("(- 0)[a]++"); | |
| 152 testKeepParentheses("++(- 0)[a]"); | |
| 153 testKeepParentheses("(- 0)[a]()"); | |
| 154 | |
| 155 testKeepParentheses("new (- 0)()"); | |
| 156 | |
| 157 testKeepParentheses("(- 0).a"); | |
| 158 testKeepParentheses("(- 0).a = b"); | |
| 159 testKeepParentheses("(- 0).a += b"); | |
| 160 testKeepParentheses("(- 0).a++"); | |
| 161 testKeepParentheses("++(- 0).a"); | |
| 162 testKeepParentheses("(- 0).a()"); | |
| 163 | |
| 164 testOptionalParentheses("(1)[a]"); | |
| 165 testOptionalParentheses("(1)[a] = b"); | |
| 166 testOptionalParentheses("(1)[a] += b"); | |
| 167 testOptionalParentheses("(1)[a]++"); | |
| 168 testOptionalParentheses("++(1)[a]"); | |
| 169 | |
| 170 shouldBe("compileAndSerialize('(1)[a]()')", | |
| 171 removesExtraParentheses ? "'1[a]()'" : "'(1)[a]()'"); | |
| 172 | |
| 173 shouldBe("compileAndSerialize('new (1)()')", | |
| 174 removesExtraParentheses ? "'new 1()'" : "'new (1)()'"); | |
| 175 | |
| 176 testKeepParentheses("(1).a"); | |
| 177 testKeepParentheses("(1).a = b"); | |
| 178 testKeepParentheses("(1).a += b"); | |
| 179 testKeepParentheses("(1).a++"); | |
| 180 testKeepParentheses("++(1).a"); | |
| 181 testKeepParentheses("(1).a()"); | |
| 182 | |
| 183 for (i = 0; i < assignmentOperators.length; ++i) { | |
| 184 var op = assignmentOperators[i]; | |
| 185 testKeepParentheses("(-1) " + op + " a"); | |
| 186 testKeepParentheses("(- 0) " + op + " a"); | |
| 187 testKeepParentheses("1 " + op + " a"); | |
| 188 } | |
| 189 | |
| 190 shouldBe("compileAndSerializeLeftmostTest('({ }).x')", "'({ }).x'"); | |
| 191 shouldBe("compileAndSerializeLeftmostTest('x = { }')", "'x = { }'"); | |
| 192 shouldBe("compileAndSerializeLeftmostTest('(function () { })()')", "'(function (
) { })()'"); | |
| 193 shouldBe("compileAndSerializeLeftmostTest('x = function () { }')", "'x = functio
n () { }'"); | |
| 194 | |
| 195 shouldBe("compileAndSerializeLeftmostTest('var a')", "'var a'"); | |
| 196 shouldBe("compileAndSerializeLeftmostTest('var a = 1')", "'var a = 1'"); | |
| 197 shouldBe("compileAndSerializeLeftmostTest('var a, b')", "'var a, b'"); | |
| 198 shouldBe("compileAndSerializeLeftmostTest('var a = 1, b = 2')", "'var a = 1, b =
2'"); | |
| 199 shouldBe("compileAndSerializeLeftmostTest('var a, b, c')", "'var a, b, c'"); | |
| 200 shouldBe("compileAndSerializeLeftmostTest('var a = 1, b = 2, c = 3')", "'var a =
1, b = 2, c = 3'"); | |
| 201 | |
| 202 shouldBe("compileAndSerializeLeftmostTest('const a = 1')", "'const a = 1'"); | |
| 203 shouldBe("compileAndSerializeLeftmostTest('const a = (1, 2)')", "'const a = (1,
2)'"); | |
| 204 shouldBe("compileAndSerializeLeftmostTest('const a, b = 1')", "'const a, b = 1'"
); | |
| 205 shouldBe("compileAndSerializeLeftmostTest('const a = 1, b')", "'const a = 1, b'"
); | |
| 206 shouldBe("compileAndSerializeLeftmostTest('const a = 1, b = 1')", "'const a = 1,
b = 1'"); | |
| 207 shouldBe("compileAndSerializeLeftmostTest('const a = (1, 2), b = 1')", "'const a
= (1, 2), b = 1'"); | |
| 208 shouldBe("compileAndSerializeLeftmostTest('const a = 1, b = (1, 2)')", "'const a
= 1, b = (1, 2)'"); | |
| 209 shouldBe("compileAndSerializeLeftmostTest('const a = (1, 2), b = (1, 2)')", "'co
nst a = (1, 2), b = (1, 2)'"); | |
| 210 | |
| 211 shouldBe("compileAndSerialize('(function () { new (a.b()).c })')", "'(function (
) { new (a.b()).c })'"); | |
| OLD | NEW |