toolkit/devtools/pretty-fast/tests/unit/test.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/devtools/pretty-fast/tests/unit/test.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,524 @@
     1.4 +/*
     1.5 + * Copyright 2013 Mozilla Foundation and contributors
     1.6 + * Licensed under the New BSD license. See LICENSE.md or:
     1.7 + * http://opensource.org/licenses/BSD-2-Clause
     1.8 + */
     1.9 +var prettyFast = this.prettyFast || require("./pretty-fast");
    1.10 +
    1.11 +var testCases = [
    1.12 +
    1.13 +  {
    1.14 +    name: "Simple function",
    1.15 +    input: "function foo() { bar(); }",
    1.16 +    output: "function foo() {\n" +
    1.17 +            "  bar();\n" +
    1.18 +            "}\n",
    1.19 +    mappings: [
    1.20 +      // function foo() {
    1.21 +      {
    1.22 +        inputLine: 1,
    1.23 +        outputLine: 1
    1.24 +      },
    1.25 +      // bar();
    1.26 +      {
    1.27 +        inputLine: 1,
    1.28 +        outputLine: 2
    1.29 +      },
    1.30 +      // }
    1.31 +      {
    1.32 +        inputLine: 1,
    1.33 +        outputLine: 3
    1.34 +      },
    1.35 +    ]
    1.36 +  },
    1.37 +
    1.38 +  {
    1.39 +    name: "Nested function",
    1.40 +    input: "function foo() { function bar() { debugger; } bar(); }",
    1.41 +    output: "function foo() {\n" +
    1.42 +            "  function bar() {\n" +
    1.43 +            "    debugger;\n" +
    1.44 +            "  }\n" +
    1.45 +            "  bar();\n" +
    1.46 +            "}\n",
    1.47 +    mappings: [
    1.48 +      // function bar() {
    1.49 +      {
    1.50 +        inputLine: 1,
    1.51 +        outputLine: 2
    1.52 +      },
    1.53 +      // debugger;
    1.54 +      {
    1.55 +        inputLine: 1,
    1.56 +        outputLine: 3
    1.57 +      },
    1.58 +      // bar();
    1.59 +      {
    1.60 +        inputLine: 1,
    1.61 +        outputLine: 5
    1.62 +      },
    1.63 +    ]
    1.64 +  },
    1.65 +
    1.66 +  {
    1.67 +    name: "Immediately invoked function expression",
    1.68 +    input: "(function(){thingy()}())",
    1.69 +    output: "(function () {\n" +
    1.70 +            "  thingy()\n" +
    1.71 +            "}())\n"
    1.72 +  },
    1.73 +
    1.74 +  {
    1.75 +    name: "Single line comment",
    1.76 +    input: "// Comment\n" +
    1.77 +           "function foo() { bar(); }\n",
    1.78 +    output: "// Comment\n" +
    1.79 +            "function foo() {\n" +
    1.80 +            "  bar();\n" +
    1.81 +            "}\n",
    1.82 +    mappings: [
    1.83 +      // // Comment
    1.84 +      {
    1.85 +        inputLine: 1,
    1.86 +        outputLine: 1
    1.87 +      }
    1.88 +    ]
    1.89 +  },
    1.90 +
    1.91 +  {
    1.92 +    name: "Multi line comment",
    1.93 +    input: "/* Comment\n" +
    1.94 +           "more comment */\n" +
    1.95 +           "function foo() { bar(); }\n",
    1.96 +    output: "/* Comment\n" +
    1.97 +            "more comment */\n" +
    1.98 +            "function foo() {\n" +
    1.99 +            "  bar();\n" +
   1.100 +            "}\n",
   1.101 +    mappings: [
   1.102 +      // /* Comment
   1.103 +      {
   1.104 +        inputLine: 1,
   1.105 +        outputLine: 1
   1.106 +      },
   1.107 +      // \nmore comment */
   1.108 +      {
   1.109 +        inputLine: 1,
   1.110 +        outputLine: 2
   1.111 +      }
   1.112 +    ]
   1.113 +  },
   1.114 +
   1.115 +  {
   1.116 +    name: "Null assignment",
   1.117 +    input: "var i=null;\n",
   1.118 +    output: "var i = null;\n",
   1.119 +    mappings: [
   1.120 +      {
   1.121 +        inputLine: 1,
   1.122 +        outputLine: 1
   1.123 +      }
   1.124 +    ]
   1.125 +  },
   1.126 +
   1.127 +  {
   1.128 +    name: "Undefined assignment",
   1.129 +    input: "var i=undefined;\n",
   1.130 +    output: "var i = undefined;\n"
   1.131 +  },
   1.132 +
   1.133 +  {
   1.134 +    name: "Void 0 assignment",
   1.135 +    input: "var i=void 0;\n",
   1.136 +    output: "var i = void 0;\n"
   1.137 +  },
   1.138 +
   1.139 +  {
   1.140 +    name: "This property access",
   1.141 +    input: "var foo=this.foo;\n",
   1.142 +    output: "var foo = this.foo;\n"
   1.143 +  },
   1.144 +
   1.145 +  {
   1.146 +    name: "True assignment",
   1.147 +    input: "var foo=true;\n",
   1.148 +    output: "var foo = true;\n"
   1.149 +  },
   1.150 +
   1.151 +  {
   1.152 +    name: "False assignment",
   1.153 +    input: "var foo=false;\n",
   1.154 +    output: "var foo = false;\n"
   1.155 +  },
   1.156 +
   1.157 +  {
   1.158 +    name: "For loop",
   1.159 +    input: "for (var i = 0; i < n; i++) { console.log(i); }",
   1.160 +    output: "for (var i = 0; i < n; i++) {\n" +
   1.161 +            "  console.log(i);\n" +
   1.162 +            "}\n",
   1.163 +    mappings: [
   1.164 +      // for (var i = 0; i < n; i++) {
   1.165 +      {
   1.166 +        inputLine: 1,
   1.167 +        outputLine: 1
   1.168 +      },
   1.169 +      // console.log(i);
   1.170 +      {
   1.171 +        inputLine: 1,
   1.172 +        outputLine: 2
   1.173 +      },
   1.174 +    ]
   1.175 +  },
   1.176 +
   1.177 +  {
   1.178 +    name: "String with semicolon",
   1.179 +    input: "var foo = ';';\n",
   1.180 +    output: "var foo = ';';\n"
   1.181 +  },
   1.182 +
   1.183 +  {
   1.184 +    name: "String with quote",
   1.185 +    input: "var foo = \"'\";\n",
   1.186 +    output: "var foo = '\\'';\n"
   1.187 +  },
   1.188 +
   1.189 +  {
   1.190 +    name: "Function calls",
   1.191 +    input: "var result=func(a,b,c,d);",
   1.192 +    output: "var result = func(a, b, c, d);\n"
   1.193 +  },
   1.194 +
   1.195 +  {
   1.196 +    name: "Regexp",
   1.197 +    input: "var r=/foobar/g;",
   1.198 +    output: "var r = /foobar/g;\n"
   1.199 +  },
   1.200 +
   1.201 +  {
   1.202 +    name: "In operator",
   1.203 +    input: "if(foo in bar){doThing()}",
   1.204 +    output: "if (foo in bar) {\n" +
   1.205 +            "  doThing()\n" +
   1.206 +            "}\n"
   1.207 +  },
   1.208 +
   1.209 +  {
   1.210 +    name: "With statement",
   1.211 +    input: "with(obj){crock()}",
   1.212 +    output: "with (obj) {\n" +
   1.213 +            "  crock()\n" +
   1.214 +            "}\n"
   1.215 +  },
   1.216 +
   1.217 +  {
   1.218 +    name: "New expression",
   1.219 +    input: "var foo=new Foo();",
   1.220 +    output: "var foo = new Foo();\n"
   1.221 +  },
   1.222 +
   1.223 +  {
   1.224 +    name: "Continue/break statements",
   1.225 +    input: "while(1){if(x){continue}if(y){break}if(z){break foo}}",
   1.226 +    output: "while (1) {\n" +
   1.227 +            "  if (x) {\n" +
   1.228 +            "    continue\n" +
   1.229 +            "  }\n" +
   1.230 +            "  if (y) {\n" +
   1.231 +            "    break\n" +
   1.232 +            "  }\n" +
   1.233 +            "  if (z) {\n" +
   1.234 +            "    break foo\n" +
   1.235 +            "  }\n" +
   1.236 +            "}\n"
   1.237 +  },
   1.238 +
   1.239 +  {
   1.240 +    name: "Instanceof",
   1.241 +    input: "var a=x instanceof y;",
   1.242 +    output: "var a = x instanceof y;\n"
   1.243 +  },
   1.244 +
   1.245 +  {
   1.246 +    name: "Binary operators",
   1.247 +    input: "var a=5*30;var b=5>>3;",
   1.248 +    output: "var a = 5 * 30;\n" +
   1.249 +            "var b = 5 >> 3;\n"
   1.250 +  },
   1.251 +
   1.252 +  {
   1.253 +    name: "Delete",
   1.254 +    input: "delete obj.prop;",
   1.255 +    output: "delete obj.prop;\n"
   1.256 +  },
   1.257 +
   1.258 +  {
   1.259 +    name: "Try/catch/finally statement",
   1.260 +    input: "try{dangerous()}catch(e){handle(e)}finally{cleanup()}",
   1.261 +    output: "try {\n" +
   1.262 +            "  dangerous()\n" +
   1.263 +            "} catch (e) {\n" +
   1.264 +            "  handle(e)\n" +
   1.265 +            "} finally {\n" +
   1.266 +            "  cleanup()\n" +
   1.267 +            "}\n"
   1.268 +  },
   1.269 +
   1.270 +  {
   1.271 +    name: "If/else statement",
   1.272 +    input: "if(c){then()}else{other()}",
   1.273 +    output: "if (c) {\n" +
   1.274 +            "  then()\n" +
   1.275 +            "} else {\n" +
   1.276 +            "  other()\n" +
   1.277 +            "}\n"
   1.278 +  },
   1.279 +
   1.280 +  {
   1.281 +    name: "If/else without curlies",
   1.282 +    input: "if(c) a else b",
   1.283 +    output: "if (c) a else b\n"
   1.284 +  },
   1.285 +
   1.286 +  {
   1.287 +    name: "Objects",
   1.288 +    input: "var o={a:1,\n" +
   1.289 +           "       b:2};",
   1.290 +    output: "var o = {\n" +
   1.291 +            "  a: 1,\n" +
   1.292 +            "  b: 2\n" +
   1.293 +            "};\n",
   1.294 +    mappings: [
   1.295 +      // a: 1,
   1.296 +      {
   1.297 +        inputLine: 1,
   1.298 +        outputLine: 2
   1.299 +      },
   1.300 +      // b: 2
   1.301 +      {
   1.302 +        inputLine: 2,
   1.303 +        outputLine: 3
   1.304 +      },
   1.305 +    ]
   1.306 +  },
   1.307 +
   1.308 +  {
   1.309 +    name: "Do/while loop",
   1.310 +    input: "do{x}while(y)",
   1.311 +    output: "do {\n" +
   1.312 +            "  x\n" +
   1.313 +            "} while (y)\n"
   1.314 +  },
   1.315 +
   1.316 +  {
   1.317 +    name: "Arrays",
   1.318 +    input: "var a=[1,2,3];",
   1.319 +    output: "var a = [\n" +
   1.320 +            "  1,\n" +
   1.321 +            "  2,\n" +
   1.322 +            "  3\n" +
   1.323 +            "];\n"
   1.324 +  },
   1.325 +
   1.326 +  {
   1.327 +    name: "Code that relies on ASI",
   1.328 +    input: "var foo = 10\n" +
   1.329 +           "var bar = 20\n" +
   1.330 +           "function g() {\n" +
   1.331 +           "  a()\n" +
   1.332 +           "  b()\n" +
   1.333 +           "}",
   1.334 +    output: "var foo = 10\n" +
   1.335 +            "var bar = 20\n" +
   1.336 +            "function g() {\n" +
   1.337 +            "  a()\n" +
   1.338 +            "  b()\n" +
   1.339 +            "}\n"
   1.340 +  },
   1.341 +
   1.342 +  {
   1.343 +    name: "Ternary operator",
   1.344 +    input: "bar?baz:bang;",
   1.345 +    output: "bar ? baz : bang;\n"
   1.346 +  },
   1.347 +
   1.348 +  {
   1.349 +    name: "Switch statements",
   1.350 +    input: "switch(x){case a:foo();break;default:bar()}",
   1.351 +    output: "switch (x) {\n" +
   1.352 +            "case a:\n" +
   1.353 +            "  foo();\n" +
   1.354 +            "  break;\n" +
   1.355 +            "default:\n" +
   1.356 +            "  bar()\n" +
   1.357 +            "}\n"
   1.358 +  },
   1.359 +
   1.360 +  {
   1.361 +    name: "Multiple single line comments",
   1.362 +    input: "function f() {\n" +
   1.363 +           "  // a\n" +
   1.364 +           "  // b\n" +
   1.365 +           "  // c\n" +
   1.366 +           "}\n",
   1.367 +    output: "function f() {\n" +
   1.368 +            "  // a\n" +
   1.369 +            "  // b\n" +
   1.370 +            "  // c\n" +
   1.371 +            "}\n",
   1.372 +  },
   1.373 +
   1.374 +  {
   1.375 +    name: "Indented multiline comment",
   1.376 +    input: "function foo() {\n" +
   1.377 +           "  /**\n" +
   1.378 +           "   * java doc style comment\n" +
   1.379 +           "   * more comment\n" +
   1.380 +           "   */\n" +
   1.381 +           "  bar();\n" +
   1.382 +           "}\n",
   1.383 +    output: "function foo() {\n" +
   1.384 +            "  /**\n" +
   1.385 +            "   * java doc style comment\n" +
   1.386 +            "   * more comment\n" +
   1.387 +            "   */\n" +
   1.388 +            "  bar();\n" +
   1.389 +            "}\n",
   1.390 +  },
   1.391 +
   1.392 +  {
   1.393 +    name: "ASI return",
   1.394 +    input: "function f() {\n" +
   1.395 +           "  return\n" +
   1.396 +           "  {}\n" +
   1.397 +           "}\n",
   1.398 +    output: "function f() {\n" +
   1.399 +            "  return\n" +
   1.400 +            "  {\n" +
   1.401 +            "  }\n" +
   1.402 +            "}\n",
   1.403 +  },
   1.404 +
   1.405 +  {
   1.406 +    name: "Non-ASI property access",
   1.407 +    input: "[1,2,3]\n" +
   1.408 +           "[0]",
   1.409 +    output: "[\n" +
   1.410 +            "  1,\n" +
   1.411 +            "  2,\n" +
   1.412 +            "  3\n" +
   1.413 +            "]\n" +
   1.414 +            "[0]\n"
   1.415 +  },
   1.416 +
   1.417 +  {
   1.418 +    name: "Non-ASI in",
   1.419 +    input: "'x'\n" +
   1.420 +           "in foo",
   1.421 +    output: "'x' in foo\n"
   1.422 +  },
   1.423 +
   1.424 +  {
   1.425 +    name: "Non-ASI function call",
   1.426 +    input: "f\n" +
   1.427 +           "()",
   1.428 +    output: "f()\n"
   1.429 +  },
   1.430 +
   1.431 +  {
   1.432 +    name: "Non-ASI new",
   1.433 +    input: "new\n" +
   1.434 +           "F()",
   1.435 +    output: "new F()\n"
   1.436 +  },
   1.437 +
   1.438 +  {
   1.439 +    name: "Getter and setter literals",
   1.440 +    input: "var obj={get foo(){return this._foo},set foo(v){this._foo=v}}",
   1.441 +    output: "var obj = {\n" +
   1.442 +            "  get foo() {\n" +
   1.443 +            "    return this._foo\n" +
   1.444 +            "  },\n" +
   1.445 +            "  set foo(v) {\n" +
   1.446 +            "    this._foo = v\n" +
   1.447 +            "  }\n" +
   1.448 +            "}\n"
   1.449 +  },
   1.450 +
   1.451 +  {
   1.452 +    name: "Escaping backslashes in strings",
   1.453 +    input: "'\\\\'\n",
   1.454 +    output: "'\\\\'\n"
   1.455 +  },
   1.456 +
   1.457 +  {
   1.458 +    name: "Escaping carriage return in strings",
   1.459 +    input: "'\\r'\n",
   1.460 +    output: "'\\r'\n"
   1.461 +  },
   1.462 +
   1.463 +  {
   1.464 +    name: "Escaping tab in strings",
   1.465 +    input: "'\\t'\n",
   1.466 +    output: "'\\t'\n"
   1.467 +  },
   1.468 +
   1.469 +  {
   1.470 +    name: "Escaping vertical tab in strings",
   1.471 +    input: "'\\v'\n",
   1.472 +    output: "'\\v'\n"
   1.473 +  },
   1.474 +
   1.475 +  {
   1.476 +    name: "Escaping form feed in strings",
   1.477 +    input: "'\\f'\n",
   1.478 +    output: "'\\f'\n"
   1.479 +  },
   1.480 +
   1.481 +  {
   1.482 +    name: "Escaping null character in strings",
   1.483 +    input: "'\\0'\n",
   1.484 +    output: "'\\0'\n"
   1.485 +  },
   1.486 +
   1.487 +];
   1.488 +
   1.489 +var sourceMap = this.sourceMap || require("source-map");
   1.490 +
   1.491 +function run_test() {
   1.492 +  testCases.forEach(function (test) {
   1.493 +    console.log(test.name);
   1.494 +
   1.495 +    var actual = prettyFast(test.input, {
   1.496 +      indent: "  ",
   1.497 +      url: "test.js"
   1.498 +    });
   1.499 +
   1.500 +    if (actual.code !== test.output) {
   1.501 +      throw new Error("Expected:\n" + test.output
   1.502 +                      + "\nGot:\n" + actual.code);
   1.503 +    }
   1.504 +
   1.505 +    if (test.mappings) {
   1.506 +      var smc = new sourceMap.SourceMapConsumer(actual.map.toJSON());
   1.507 +      test.mappings.forEach(function (m) {
   1.508 +        var query = { line: m.outputLine, column: 0 };
   1.509 +        var original = smc.originalPositionFor(query);
   1.510 +        if (original.line != m.inputLine) {
   1.511 +          throw new Error("Querying:\n" + JSON.stringify(query, null, 2) + "\n"
   1.512 +                          + "Expected line:\n" + m.inputLine + "\n"
   1.513 +                          + "Got:\n" + JSON.stringify(original, null, 2));
   1.514 +        }
   1.515 +      });
   1.516 +    }
   1.517 +  });
   1.518 +  console.log("✓ All tests pass!");
   1.519 +}
   1.520 +
   1.521 +// Only run the tests if this is node and we are running this file
   1.522 +// directly. (Firefox's test runner will import this test file, and then call
   1.523 +// run_test itself.)
   1.524 +if (typeof require == "function" && typeof module == "object"
   1.525 +    && require.main === module) {
   1.526 +  run_test();
   1.527 +}

mercurial