Best Python code snippet using autotest_python
parser.js
Source:parser.js
...10 var code = [11 "var a\u000a = 'Here is a unsafe character';",12 ];13 TestRun(test)14 .addError(1, "This character may get silently deleted by one or more browsers.")15 .test(code, {es3: true});16 test.done();17};18exports.other = function (test) {19 var code = [20 "\\",21 "!",22 ];23 TestRun(test)24 .addError(1, "Unexpected '\\'.")25 .addError(2, "Unexpected early end of program.")26 .addError(2, "Expected an identifier and instead saw '(end)'.")27 .addError(2, "Unrecoverable syntax error. (100% scanned).")28 .test(code, {es3: true});29 // GH-81830 TestRun(test)31 .addError(1, "Expected an identifier and instead saw ')'.")32 .addError(1, "Unrecoverable syntax error. (100% scanned).")33 .test("if (product < ) {}", {es3: true});34 test.done();35};36exports.confusingOps = function (test) {37 var code = [38 "var a = 3 - -3;",39 "var b = 3 + +3;",40 "a = a - --a;",41 "a = b + ++b;",42 "a = a-- - 3;", // this is not confusing?!43 "a = a++ + 3;", // this is not confusing?!44 ];45 var run = TestRun(test)46 .addError(1, "Confusing minuses.")47 .addError(2, "Confusing plusses.")48 .addError(3, "Confusing minuses.")49 .addError(4, "Confusing plusses.");50 run.test(code, {es3: true});51 run.test(code, {}); // es552 run.test(code, {esnext: true});53 run.test(code, {moz: true});54 test.done();55};56exports.division = function (test) {57 var run;58 var code = [59 'var a=4,b=4,i=2;',60 'a/=b+2;',61 'a/=b/2;',62 'a/=b/i;',63 '/*jshint expr:true*/',64 '/=b/i;' // valid standalone RegExp expression65 ];66 run = TestRun(test);67 run.test(code);68 test.done();69};70exports.plusplus = function (test) {71 var run;72 var code = [73 "var a = ++[2];",74 "var b = --(2);",75 ];76 run = TestRun(test)77 .addError(1, "Unexpected use of '++'.")78 .addError(2, "Unexpected use of '--'.");79 run.test(code, { plusplus: true, es3: true });80 run.test(code, { plusplus: true }); // es581 run.test(code, { plusplus: true, esnext: true });82 run.test(code, { plusplus: true, moz: true });83 run = TestRun(test)84 .addError(2, "Bad operand.");85 run.test(code, { plusplus: false, es3: true });86 run.test(code, { plusplus: false }); // es587 run.test(code, { plusplus: false, esnext: true });88 run.test(code, { plusplus: false, moz: true });89 test.done();90};91exports.assignment = function (test) {92 var code = [93 "function test() {",94 "arguments.length = 2;",95 "arguments[0] = 3;",96 "}",97 "function test2() {",98 "\"use strict\";",99 "arguments.length = 2;",100 "arguments[0] = 3;",101 "}",102 "a() = 2;",103 ];104 var run = TestRun(test)105 .addError(2, "Bad assignment.")106 .addError(3, "Bad assignment.")107 .addError(10, "Bad assignment.")108 .addError(10, "Expected an assignment or function call and instead saw an expression.")109 .addError(10, "Missing semicolon.");110 run.test(code, { plusplus: true, es3: true });111 run.test(code, { plusplus: true }); // es5112 run.test(code, { plusplus: true, esnext: true });113 run.test(code, { plusplus: true, moz: true });114 test.done();115};116exports.relations = function (test) {117 var code = [118 "var a = 2 === NaN;",119 "var b = NaN == 2;",120 "var c = !2 < 3;",121 "var c = 2 < !3;",122 "var d = (!'x' in obj);",123 "var e = (!a === b);",124 "var f = (a === !'hi');",125 "var g = (!2 === 1);",126 "var h = (![1, 2, 3] === []);",127 ];128 var run = TestRun(test)129 .addError(1, "Use the isNaN function to compare with NaN.")130 .addError(2, "Use the isNaN function to compare with NaN.")131 .addError(3, "Confusing use of '!'.", {character : 9})132 .addError(4, "Confusing use of '!'.", {character : 13})133 .addError(5, "Confusing use of '!'.", {character : 10})134 .addError(6, "Confusing use of '!'.", {character : 10})135 .addError(7, "Confusing use of '!'.", {character : 16})136 .addError(8, "Confusing use of '!'.", {character : 10})137 .addError(9, "Confusing use of '!'.", {character : 10});138 run.test(code, {es3: true});139 run.test(code, {}); // es5140 run.test(code, {esnext: true});141 run.test(code, {moz: true});142 test.done();143};144exports.options = function (test) {145 var code = [146 "/*member a*/",147 "/*members b*/",148 "var x; x.a.b.c();",149 "/*jshint ++ */",150 "/*jslint indent: 0 */",151 "/*jslint indent: -2 */",152 "/*jslint indent: 100.4 */",153 "/*jslint maxlen: 200.4 */",154 "/*jslint maxerr: 300.4 */",155 "/*jslint maxerr: 0 */",156 "/*jslint maxerr: 20 */",157 "/*member c:true */",158 "/*jshint d:no */",159 "/*global xxx*/",160 "xxx = 2;",161 ];162 var run = TestRun(test)163 .addError(3, "Unexpected /*member 'c'.")164 .addError(4, "Bad option: '++'.")165 .addError(5, "Expected a small integer or 'false' and instead saw '0'.")166 .addError(6, "Expected a small integer or 'false' and instead saw '-2'.")167 .addError(7, "Expected a small integer or 'false' and instead saw '100.4'.")168 .addError(8, "Expected a small integer or 'false' and instead saw '200.4'.")169 .addError(9, "Expected a small integer or 'false' and instead saw '300.4'.")170 .addError(10, "Expected a small integer or 'false' and instead saw '0'.")171 .addError(13, "Bad option: 'd'.")172 .addError(15, "Read only.");173 run.test(code, {es3: true});174 run.test(code, {}); // es5175 run.test(code, {esnext: true});176 run.test(code, {moz: true});177 TestRun(test).test(fs.readFileSync(__dirname + "/fixtures/gh988.js", "utf8"));178 test.done();179};180exports["jshint option comments single line"] = function (test) {181 var src = fs.readFileSync(__dirname + "/fixtures/gh1768-1.js", "utf8");182 TestRun(test).test(src);183 test.done();184};185exports["jshint option comments single line, leading and trailing space"] = function (test) {186 var src = fs.readFileSync(__dirname + "/fixtures/gh1768-2.js", "utf8");187 TestRun(test).test(src);188 test.done();189};190exports["jshint option comments multi line"] = function (test) {191 var src = fs.readFileSync(__dirname + "/fixtures/gh1768-3.js", "utf8");192 TestRun(test).test(src);193 test.done();194};195exports["jshint option comments multi line, leading and trailing space"] = function (test) {196 var src = fs.readFileSync(__dirname + "/fixtures/gh1768-4.js", "utf8");197 TestRun(test)198 .addError(4, "'foo' is not defined.")199 .test(src);200 test.done();201};202exports["jshint option comments multi line/option"] = function (test) {203 var src = fs.readFileSync(__dirname + "/fixtures/gh1768-5.js", "utf8");204 TestRun(test)205 .addError(3, "'foo' is not defined.")206 .test(src);207 test.done();208};209exports["jshint option comments multi line/option, leading and trailing space"] = function (test) {210 var src = fs.readFileSync(__dirname + "/fixtures/gh1768-6.js", "utf8");211 TestRun(test)212 .addError(4, "'foo' is not defined.")213 .test(src);214 test.done();215};216exports.shebang = function (test) {217 var code = [218 "#!test",219 "var a = 'xxx';",220 "#!test"221 ];222 var run = TestRun(test)223 .addError(3, "Expected an identifier and instead saw '#'.")224 .addError(3, "Expected an operator and instead saw '!'.")225 .addError(3, "Expected an assignment or function call and instead saw an expression.")226 .addError(3, "Missing semicolon.");227 run.test(code, {es3: true});228 run.test(code, {}); // es5229 run.test(code, {esnext: true});230 run.test(code, {moz: true});231 test.done();232};233exports.shebangImpliesNode = function (test) {234 var code = [235 "#!usr/bin/env node",236 "require('module');",237 ];238 TestRun(test).test(code);239 test.done();240};241exports.numbers = function (test) {242 /*jshint maxlen: 300*/243 var code = [244 "var a = 10e307;",245 "var b = 10e308;",246 "var c = 0.03 + 0.3 + 3.0 + 30.00;",247 "var d = 03;",248 "var e = .3;",249 "var f = 0xAAg;",250 "var g = 0033;",251 "var h = 3.;",252 "var i = 3.7.toString();",253 "var j = 1e-10;" // GH-821254 ];255 TestRun(test)256 .addError(2, "Bad number '10e308'.")257 .addError(5, "A leading decimal point can be confused with a dot: '.3'.")258 .addError(6, "Unexpected '0'.")259 .addError(7, "Expected an identifier and instead saw 'var'.")260 .addError(7, "Missing semicolon.")261 .addError(7, "Don't use extra leading zeros '0033'.")262 .addError(8, "A trailing decimal point can be confused with a dot: '3.'.")263 .addError(9, "A dot following a number can be confused with a decimal point.")264 .test(code, {es3: true});265 // Octals are prohibited in strict mode.266 TestRun(test)267 .addError(3, "Octal literals are not allowed in strict mode.")268 .test([269 "(function () {",270 "'use strict';",271 "return 045;",272 "}());"273 ]);274 // GitHub #751 - an expression containing a number with a leading decimal point should be parsed in its entirety275 TestRun(test)276 .addError(1, "A leading decimal point can be confused with a dot: '.3'.")277 .addError(2, "A leading decimal point can be confused with a dot: '.3'.")278 .test([279 "var a = .3 + 1;",280 "var b = 1 + .3;",281 ]);282 test.done();283};284exports.comments = function (test) {285 var code = [286 "/*",287 "/* nested */",288 "*/",289 "/* unclosed ..",290 ];291 var run = TestRun(test)292 .addError(3, "Unbegun comment.")293 .addError(4, "Unclosed comment.");294 run.test(code, {es3: true});295 run.test(code, {}); // es5296 run.test(code, {esnext: true});297 run.test(code, {moz: true});298 var src = "/* this is a comment /* with nested slash-start */";299 TestRun(test).test(src);300 TestRun(test).test(fs.readFileSync(__dirname + "/fixtures/gruntComment.js", "utf8"));301 test.done();302};303exports.regexp = function (test) {304 var code = [305 "var a1 = /\\\x1f/;",306 "var a2 = /[\\\x1f]/;",307 "var b1 = /\\</;", // only \< is unexpected?!308 "var b2 = /[\\<]/;", // only \< is unexpected?!309 "var c = /(?(a)b)/;",310 "var d = /)[--aa-b-cde-]/;",311 "var e = /[]/;",312 "var f = /[^]/;",313 "var g = /[a^[]/;",314 // FIXME: Firefox doesn't handle [a-\\s] well.315 // See https://bugzilla.mozilla.org/show_bug.cgi?id=813249316 "", // "var h = /[a-\\s-\\w-\\d\\x10-\\x20--]/;",317 "var i = /[/-a1-/]/;",318 "var j = /[a-<<-3]./;",319 "var k = /]}/;",320 "var l = /?(*)(+)({)/;",321 "var m = /a{b}b{2,c}c{3,2}d{4,?}x{30,40}/;",322 "var n = /a??b+?c*?d{3,4}? a?b+c*d{3,4}/;",323 "var o = /a\\/* [a-^-22-]/;",324 "var p = /(?:(?=a|(?!b)))/;",325 "var q = /=;/;",326 "var r = /(/;",327 "var s = /(((/;",328 "var t = /x/* 2;",329 "var u = /x/;",330 "var v = /dsdg;",331 "var w = v + /s/;",332 "var x = w - /s/;",333 "var y = typeof /[a-z]/;" // GH-657334 ];335 var run = TestRun(test)336 .addError(1, "This character may get silently deleted by one or more browsers.")337 .addError(1, "Unexpected control character in regular expression.")338 .addError(2, "This character may get silently deleted by one or more browsers.")339 .addError(2, "Unexpected control character in regular expression.")340 .addError(3, "Unexpected escaped character '<' in regular expression.")341 .addError(4, "Unexpected escaped character '<' in regular expression.")342 .addError(5, "Invalid regular expression.")343 .addError(6, "Invalid regular expression.")344 .addError(11, "Invalid regular expression.")345 .addError(12, "Invalid regular expression.")346 .addError(14, "Invalid regular expression.")347 .addError(15, "Invalid regular expression.")348 .addError(17, "Invalid regular expression.")349 .addError(20, "Invalid regular expression.")350 .addError(21, "Invalid regular expression.")351 .addError(24, "Unclosed regular expression.")352 .addError(24, "Unrecoverable syntax error. (88% scanned).");353 run.test(code, {es3: true});354 run.test(code, {}); // es5355 run.test(code, {esnext: true});356 run.test(code, {moz: true});357 // Pre Regular Expression Punctuation358 // (See: token method, create function in lex.js)359 //360 // "."361 TestRun(test)362 .addError(1, "A trailing decimal point can be confused with a dot: '10.'.")363 .test("var y = 10. / 1;", {es3: true});364 TestRun(test)365 .addError(1, "A trailing decimal point can be confused with a dot: '10.'.")366 .test("var y = 10. / 1;", {}); // es5367 TestRun(test)368 .addError(1, "A trailing decimal point can be confused with a dot: '10.'.")369 .test("var y = 10. / 1;", {esnext: true});370 TestRun(test)371 .addError(1, "A trailing decimal point can be confused with a dot: '10.'.")372 .test("var y = 10. / 1;", {moz: true});373 // ")"374 TestRun(test).test("var y = Math.sqrt(16) / 180;", {es3: true});375 TestRun(test).test("var y = Math.sqrt(16) / 180;", {}); // es5376 TestRun(test).test("var y = Math.sqrt(16) / 180;", {esnext: true});377 TestRun(test).test("var y = Math.sqrt(16) / 180;", {moz: true});378 // "~"379 TestRun(test).test("var y = Math.sqrt(16) / 180;", {es3: true});380 TestRun(test).test("var y = Math.sqrt(16) / 180;", {}); // es5381 TestRun(test).test("var y = Math.sqrt(16) / 180;", {esnext: true});382 TestRun(test).test("var y = Math.sqrt(16) / 180;", {moz: true});383 // "]" (GH-803)384 TestRun(test).test("var x = [1]; var y = x[0] / 180;", {es3: true});385 TestRun(test).test("var x = [1]; var y = x[0] / 180;", {}); // es5386 TestRun(test).test("var x = [1]; var y = x[0] / 180;", {esnext: true});387 TestRun(test).test("var x = [1]; var y = x[0] / 180;", {moz: true});388 // "++" (GH-1787)389 TestRun(test).test("var a = 1; var b = a++ / 10;", {es3: true});390 TestRun(test).test("var a = 1; var b = a++ / 10;", {}); // es5391 TestRun(test).test("var a = 1; var b = a++ / 10;", {esnext: true});392 TestRun(test).test("var a = 1; var b = a++ / 10;", {moz: true});393 // "--" (GH-1787)394 TestRun(test).test("var a = 1; var b = a-- / 10;", {es3: true});395 TestRun(test).test("var a = 1; var b = a-- / 10;", {}); // es5396 TestRun(test).test("var a = 1; var b = a-- / 10;", {esnext: true});397 TestRun(test).test("var a = 1; var b = a-- / 10;", {moz: true});398 test.done();399};400exports.testRegexRegressions = function (test) {401 // GH-536402 TestRun(test).test("str /= 5;", {es3: true}, { str: true });403 TestRun(test).test("str /= 5;", {}, { str: true }); // es5404 TestRun(test).test("str /= 5;", {esnext: true}, { str: true });405 TestRun(test).test("str /= 5;", {moz: true}, { str: true });406 TestRun(test).test("str = str.replace(/=/g, '');", {es3: true}, { str: true });407 TestRun(test).test("str = str.replace(/=/g, '');", {}, { str: true }); // es5408 TestRun(test).test("str = str.replace(/=/g, '');", {esnext: true}, { str: true });409 TestRun(test).test("str = str.replace(/=/g, '');", {moz: true}, { str: true });410 TestRun(test).test("str = str.replace(/=abc/g, '');", {es3: true}, { str: true });411 TestRun(test).test("str = str.replace(/=abc/g, '');", {}, { str: true }); // es5412 TestRun(test).test("str = str.replace(/=abc/g, '');", {esnext: true}, { str: true });413 TestRun(test).test("str = str.replace(/=abc/g, '');", {moz: true}, { str: true });414 // GH-538415 TestRun(test).test("var exp = /function(.*){/gi;", {es3: true});416 TestRun(test).test("var exp = /function(.*){/gi;", {}); // es5417 TestRun(test).test("var exp = /function(.*){/gi;", {esnext: true});418 TestRun(test).test("var exp = /function(.*){/gi;", {moz: true});419 test.done();420};421exports.strings = function (test) {422 var code = [423 "var a = '\u0012\\r';",424 "var b = \'\\g\';",425 "var c = '\\u0022\\u0070\\u005C';",426 "var e = '\\x6b..\\x6e';",427 "var f = 'ax"428 ];429 var run = TestRun(test)430 .addError(1, "Control character in string: <non-printable>.", {character: 10})431 .addError(1, "This character may get silently deleted by one or more browsers.")432 .addError(2, "Bad or unnecessary escaping.")433 .addError(5, "Unclosed string.")434 .addError(5, "Missing semicolon.");435 run.test(code, {es3: true});436 run.test(code, {}); // es5437 run.test(code, {esnext: true});438 run.test(code, {moz: true});439 test.done();440};441exports.ownProperty = function (test) {442 var code = [443 "var obj = { hasOwnProperty: false };",444 "obj.hasOwnProperty = true;",445 "obj['hasOwnProperty'] = true;",446 "function test() { var hasOwnProperty = {}.hasOwnProperty; }"447 ];448 var run = TestRun(test)449 .addError(1, "'hasOwnProperty' is a really bad name.")450 .addError(2, "'hasOwnProperty' is a really bad name.")451 .addError(3, "'hasOwnProperty' is a really bad name.")452 .addError(3, "['hasOwnProperty'] is better written in dot notation.");453 run.test(code, {es3: true});454 run.test(code, {}); // es5455 run.test(code, {esnext: true});456 run.test(code, {moz: true});457 test.done();458};459exports.jsonMode = function (test) {460 var code = [461 '{',462 ' a: 2,',463 ' \'b\': "hallo\\"\\v\\x12\\\'world",',464 ' "c\\"\\v\\x12": \'4\',',465 ' "d": "4\\',466 ' ",',467 ' "e": 0x332,',468 ' "x": 0',469 '}',470 ];471 var run = TestRun(test)472 .addError(2, "Expected a string and instead saw a.")473 .addError(3, "Strings must use doublequote.")474 .addError(3, "Avoid \\v.")475 .addError(3, "Avoid \\x-.")476 .addError(3, "Avoid \\'.")477 .addError(4, "Avoid \\v.")478 .addError(4, "Avoid \\x-.")479 .addError(4, "Strings must use doublequote.")480 .addError(5, "Avoid EOL escaping.")481 .addError(7, "Avoid 0x-.");482 run.test(code, {multistr: true, es3: true});483 run.test(code, {multistr: true}); // es5484 run.test(code, {multistr: true, esnext: true});485 run.test(code, {multistr: true, moz: true});486 test.done();487};488exports.comma = function (test) {489 var src = fs.readFileSync(__dirname + "/fixtures/comma.js", "utf8");490 TestRun(test)491 .addError(2, "Expected an assignment or function call and instead saw an expression.")492 .addError(15, "Expected an assignment or function call and instead saw an expression.")493 .addError(15, "Missing semicolon.")494 .addError(20, "Expected an assignment or function call and instead saw an expression.")495 .addError(30, "Expected an assignment or function call and instead saw an expression.")496 .addError(35, "Expected an assignment or function call and instead saw an expression.")497 .addError(35, "Missing semicolon.")498 .addError(36, "Unexpected 'if'.")499 .addError(43, "Expected an assignment or function call and instead saw an expression.")500 .addError(43, "Missing semicolon.")501 .addError(44, "Unexpected '}'.")502 .test(src, {es3: true});503 // Regression test (GH-56)504 TestRun(test)505 .addError(4, "Expected an assignment or function call and instead saw an expression.")506 .test(fs.readFileSync(__dirname + "/fixtures/gh56.js", "utf8"));507 // Regression test (GH-363)508 TestRun(test)509 .addError(1, "Extra comma. (it breaks older versions of IE)")510 .test("var f = [1,];", {es3: true});511 test.done();512};513exports.withStatement = function (test) {514 var src = fs.readFileSync(__dirname + "/fixtures/with.js", "utf8");515 var run;516 run = TestRun(test)517 .addError(5, "Don't use 'with'.")518 .addError(13, "'with' is not allowed in strict mode.");519 run.test(src, {es3: true});520 run.test(src); // es5521 run.test(src, {esnext: true});522 run.test(src, {moz: true});523 run = TestRun(test)524 .addError(13, "'with' is not allowed in strict mode.");525 run.test(src, {withstmt: true, es3: true});526 run.test(src, {withstmt: true}); // es5527 run.test(src, {withstmt: true, esnext: true});528 run.test(src, {withstmt: true, moz: true});529 test.done();530};531exports.blocks = function (test) {532 var src = fs.readFileSync(__dirname + "/fixtures/blocks.js", "utf8");533 var run = TestRun(test)534 .addError(29, "Unmatched \'{\'.")535 .addError(31, "Unmatched \'{\'.");536 run.test(src, {es3: true});537 run.test(src, {}); // es5538 run.test(src, {esnext: true});539 run.test(src, {moz: true});540 test.done();541};542exports.functionCharacterLocation = function (test) {543 var i;544 var src = fs.readFileSync(__dirname + "/fixtures/nestedFunctions.js", "utf8");545 var locations = JSON.parse(546 fs.readFileSync(547 __dirname + "/fixtures/nestedFunctions-locations.js", "utf8"548 )549 );550 JSHINT(src);551 var report = JSHINT.data().functions;552 test.equal(locations.length, report.length);553 for (i = 0; i < locations.length; i += 1) {554 test.equal(locations[i].name, report[i].name);555 test.equal(locations[i].line, report[i].line);556 test.equal(locations[i].character, report[i].character);557 test.equal(locations[i].last, report[i].last);558 test.equal(locations[i].lastcharacter, report[i].lastcharacter);559 }560 test.done();561};562exports.exported = function (test) {563 var src = fs.readFileSync(__dirname + "/fixtures/exported.js", "utf8");564 var run = TestRun(test)565 .addError(5, "'unused' is defined but never used.")566 .addError(6, "'isDog' is defined but never used.")567 .addError(13, "'unusedDeclaration' is defined but never used.")568 .addError(14, "'unusedExpression' is defined but never used.")569 .addError(17, "'cannotBeExported' is defined but never used.");570 run.test(src, {es3: true, unused: true });571 run.test(src, {unused: true }); // es5572 run.test(src, {esnext: true, unused: true });573 run.test(src, {moz: true, unused: true });574 run = TestRun(test)575 .addError(1, "'unused' is defined but never used.")576 .test("var unused = 1; var used = 2;", {exported: ["used"], unused: true});577 test.done();578};579exports.testIdentifiers = function (test) {580 var src = fs.readFileSync(__dirname + "/fixtures/identifiers.js", "utf8");581 TestRun(test).test(src, {es3: true});582 var run = TestRun(test)583 .addError(1, "'ascii' is defined but never used.")584 .addError(2, "'num1' is defined but never used.")585 .addError(3, "'lifé' is defined but never used.")586 .addError(4, "'Ï' is defined but never used.")587 .addError(5, "'пÑивеÑ' is defined but never used.")588 .addError(6, "'\\u1d44' is defined but never used.")589 .addError(7, "'encoded\\u1d44' is defined but never used.")590 .addError(8, "'\\uFF38' is defined but never used.")591 .addError(9, "'\\uFF58' is defined but never used.")592 .addError(10, "'\\u1FBC' is defined but never used.")593 .addError(11, "'\\uFF70' is defined but never used.")594 .addError(12, "'\\u4DB3' is defined but never used.")595 .addError(13, "'\\u97CA' is defined but never used.")596 .addError(14, "'\\uD7A1' is defined but never used.")597 .addError(15, "'\\uFFDA' is defined but never used.")598 .addError(16, "'\\uA6ED' is defined but never used.")599 .addError(17, "'\\u0024' is defined but never used.")600 .addError(18, "'\\u005F' is defined but never used.")601 .addError(19, "'\\u0024\\uFF38' is defined but never used.")602 .addError(20, "'\\u0024\\uFF58' is defined but never used.")603 .addError(21, "'\\u0024\\u1FBC' is defined but never used.")604 .addError(22, "'\\u0024\\uFF70' is defined but never used.")605 .addError(23, "'\\u0024\\u4DB3' is defined but never used.")606 .addError(24, "'\\u0024\\u97CA' is defined but never used.")607 .addError(25, "'\\u0024\\uD7A1' is defined but never used.")608 .addError(26, "'\\u0024\\uFFDA' is defined but never used.")609 .addError(27, "'\\u0024\\uA6ED' is defined but never used.")610 .addError(28, "'\\u0024\\uFE24' is defined but never used.")611 .addError(29, "'\\u0024\\uABE9' is defined but never used.")612 .addError(30, "'\\u0024\\uFF17' is defined but never used.")613 .addError(31, "'\\u0024\\uFE4E' is defined but never used.")614 .addError(32, "'\\u0024\\u200C' is defined but never used.")615 .addError(33, "'\\u0024\\u200D' is defined but never used.")616 .addError(34, "'\\u0024\\u0024' is defined but never used.")617 .addError(35, "'\\u0024\\u005F' is defined but never used.");618 run.test(src, {es3: true, unused: true });619 run.test(src, {unused: true }); // es5620 run.test(src, {esnext: true, unused: true });621 run.test(src, {moz: true, unused: true });622 test.done();623};624exports["regression for GH-878"] = function (test) {625 var src = fs.readFileSync(__dirname + "/fixtures/gh878.js", "utf8");626 TestRun(test).test(src, {es3: true});627 test.done();628};629exports["regression for GH-910"] = function (test) {630 var src = "(function () { if (true) { foo.bar + } })();";631 TestRun(test)632 .addError(1, "Expected an identifier and instead saw '}'.")633 .addError(1, "Expected an assignment or function call and instead saw an expression.")634 .addError(1, "Missing semicolon.")635 .addError(1, "Expected an identifier and instead saw ')'.")636 .addError(1, "Expected an operator and instead saw '('.")637 .addError(1, "Unmatched '{'.")638 .addError(1, "Unmatched '('.")639 .addError(1, "Expected an assignment or function call and instead saw an expression.")640 .addError(1, "Missing semicolon.")641 .test(src, { es3: true, nonew: true });642 test.done();643};644exports.testHtml = function (test) {645 var html = "<html><body>Hello World</body></html>";646 TestRun(test)647 .addError(1, "Expected an identifier and instead saw '<'.")648 .addError(1, "Expected an assignment or function call and instead saw an expression.")649 .addError(1, "Missing semicolon.")650 .addError(1, "Expected an identifier and instead saw '<'.")651 .addError(1, "Unrecoverable syntax error. (100% scanned).")652 .test(html, {});653 test.done();654};655exports["test: destructuring var in function scope"] = function (test) {656 var code = [657 "function foobar() {",658 " var [ a, b, c ] = [ 1, 2, 3 ];",659 " var [ a ] = [ 1 ];",660 " var [ a ] = [ z ];",661 " var [ h, w ] = [ 'hello', 'world' ]; ",662 " var [ o ] = [ { o : 1 } ];",663 " var [ a, [ [ [ b ], c ], d ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",664 " var { foo : bar } = { foo : 1 };",665 " var [ a, { foo : bar } ] = [ 2, { foo : 1 } ];",666 " var [ 1 ] = [ a ];",667 " var [ a, b; c ] = [ 1, 2, 3 ];",668 " var [ a, b, c ] = [ 1, 2; 3 ];",669 "}"670 ];671 TestRun(test)672 .addError(1, "'foobar' is defined but never used.")673 .addError(3, "'a' is already defined.")674 .addError(4, "'a' is already defined.")675 .addError(7, "'a' is already defined.")676 .addError(7, "'b' is already defined.")677 .addError(7, "'c' is already defined.")678 .addError(9, "'a' is already defined.")679 .addError(9, "'bar' is already defined.")680 .addError(10, "Expected an identifier and instead saw '1'.")681 .addError(10, "Expected ',' and instead saw '1'.")682 .addError(10, "Expected an identifier and instead saw ']'.")683 .addError(11, "Expected ',' and instead saw ';'.")684 .addError(11, "'a' is already defined.")685 .addError(11, "'b' is already defined.")686 .addError(11, "'c' is already defined.")687 .addError(12, "'a' is already defined.")688 .addError(12, "'b' is already defined.")689 .addError(12, "'c' is already defined.")690 .addError(12, "Expected ']' to match '[' from line 12 and instead saw ';'.")691 .addError(12, "Missing semicolon.")692 .addError(12, "Expected an assignment or function call and instead saw an expression.")693 .addError(12, "Missing semicolon.")694 .addError(12, "Expected an identifier and instead saw ']'.")695 .addError(12, "Expected an assignment or function call and instead saw an expression.")696 .addError(4, "'z' is not defined.")697 .addError(12, "'a' is defined but never used.")698 .addError(12, "'b' is defined but never used.")699 .addError(12, "'c' is defined but never used.")700 .addError(5, "'h' is defined but never used.")701 .addError(5, "'w' is defined but never used.")702 .addError(6, "'o' is defined but never used.")703 .addError(7, "'d' is defined but never used.")704 .addError(9, "'bar' is defined but never used.")705 .test(code, {esnext: true, unused: true, undef: true});706 test.done();707};708exports["test: destructuring var as moz"] = function (test) {709 var code = [710 "var [ a, b, c ] = [ 1, 2, 3 ];",711 "var [ a ] = [ 1 ];",712 "var [ a ] = [ z ];",713 "var [ h, w ] = [ 'hello', 'world' ]; ",714 "var [ o ] = [ { o : 1 } ];",715 "var [ a, [ [ [ b ], c ], d ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",716 "var { foo : bar } = { foo : 1 };",717 "var [ a, { foo : bar } ] = [ 2, { foo : 1 } ];",718 ];719 TestRun(test)720 .addError(3, "'z' is not defined.")721 .addError(8, "'a' is defined but never used.")722 .addError(6, "'b' is defined but never used.")723 .addError(6, "'c' is defined but never used.")724 .addError(4, "'h' is defined but never used.")725 .addError(4, "'w' is defined but never used.")726 .addError(5, "'o' is defined but never used.")727 .addError(6, "'d' is defined but never used.")728 .addError(8, "'bar' is defined but never used.")729 .test(code, {moz: true, unused: true, undef: true});730 test.done();731};732exports["test: destructuring var as esnext"] = function (test) {733 var code = [734 "var [ a, b, c ] = [ 1, 2, 3 ];",735 "var [ a ] = [ 1 ];",736 "var [ a ] = [ z ];",737 "var [ h, w ] = [ 'hello', 'world' ]; ",738 "var [ o ] = [ { o : 1 } ];",739 "var [ a, [ [ [ b ], c ], d ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",740 "var { foo : bar } = { foo : 1 };",741 "var [ a, { foo : bar } ] = [ 2, { foo : 1 } ];",742 ];743 TestRun(test)744 .addError(3, "'z' is not defined.")745 .addError(8, "'a' is defined but never used.")746 .addError(6, "'b' is defined but never used.")747 .addError(6, "'c' is defined but never used.")748 .addError(4, "'h' is defined but never used.")749 .addError(4, "'w' is defined but never used.")750 .addError(5, "'o' is defined but never used.")751 .addError(6, "'d' is defined but never used.")752 .addError(8, "'bar' is defined but never used.")753 .test(code, {esnext: true, unused: true, undef: true});754 test.done();755};756exports["test: destructuring var as es5"] = function (test) {757 var code = [758 "var [ a, b, c ] = [ 1, 2, 3 ];",759 "var [ a ] = [ 1 ];",760 "var [ a ] = [ z ];",761 "var [ h, w ] = [ 'hello', 'world' ]; ",762 "var [ o ] = [ { o : 1 } ];",763 "var [ a, [ [ [ b ], c ], d ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",764 "var { foo : bar } = { foo : 1 };",765 "var [ a, { foo : bar } ] = [ 2, { foo : 1 } ];",766 ];767 TestRun(test)768 .addError(1, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")769 .addError(2, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")770 .addError(3, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")771 .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")772 .addError(5, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")773 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")774 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")775 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")776 .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")777 .addError(8, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")778 .addError(8, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")779 .addError(3, "'z' is not defined.")780 .addError(8, "'a' is defined but never used.")781 .addError(6, "'b' is defined but never used.")782 .addError(6, "'c' is defined but never used.")783 .addError(4, "'h' is defined but never used.")784 .addError(4, "'w' is defined but never used.")785 .addError(5, "'o' is defined but never used.")786 .addError(6, "'d' is defined but never used.")787 .addError(8, "'bar' is defined but never used.")788 .test(code, {unused: true, undef: true}); // es5789 test.done();790};791exports["test: destructuring var as legacy JS"] = function (test) {792 var code = [793 "var [ a, b, c ] = [ 1, 2, 3 ];",794 "var [ a ] = [ 1 ];",795 "var [ a ] = [ z ];",796 "var [ h, w ] = [ 'hello', 'world' ]; ",797 "var [ o ] = [ { o : 1 } ];",798 "var [ a, [ [ [ b ], c ], d ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",799 "var { foo : bar } = { foo : 1 };",800 "var [ a, { foo : bar } ] = [ 2, { foo : 1 } ];",801 ];802 TestRun(test)803 .addError(1, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")804 .addError(2, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")805 .addError(3, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")806 .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")807 .addError(5, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")808 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")809 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")810 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")811 .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")812 .addError(8, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")813 .addError(8, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")814 .addError(3, "'z' is not defined.")815 .addError(8, "'a' is defined but never used.")816 .addError(6, "'b' is defined but never used.")817 .addError(6, "'c' is defined but never used.")818 .addError(4, "'h' is defined but never used.")819 .addError(4, "'w' is defined but never used.")820 .addError(5, "'o' is defined but never used.")821 .addError(6, "'d' is defined but never used.")822 .addError(8, "'bar' is defined but never used.")823 .test(code, {es3: true, unused: true, undef: true});824 test.done();825};826exports["test: destructuring var errors"] = function (test) {827 var code = [828 "var [ a, b, c ] = [ 1, 2, 3 ];",829 "var [ a ] = [ 1 ];",830 "var [ a ] = [ z ];",831 "var [ h, w ] = [ 'hello', 'world' ]; ",832 "var [ o ] = [ { o : 1 } ];",833 "var [ a, [ [ [ b ], c ], d ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",834 "var { foo : bar } = { foo : 1 };",835 "var [ a, { foo : bar } ] = [ 2, { foo : 1 } ];",836 "var [ 1 ] = [ a ];",837 "var [ a, b; c ] = [ 1, 2, 3 ];",838 "var [ a, b, c ] = [ 1, 2; 3 ];"839 ];840 TestRun(test)841 .addError(9, "Expected an identifier and instead saw '1'.")842 .addError(9, "Expected ',' and instead saw '1'.")843 .addError(9, "Expected an identifier and instead saw ']'.")844 .addError(10, "Expected ',' and instead saw ';'.")845 .addError(11, "Expected ']' to match '[' from line 11 and instead saw ';'.")846 .addError(11, "Missing semicolon.")847 .addError(11, "Expected an assignment or function call and instead saw an expression.")848 .addError(11, "Missing semicolon.")849 .addError(11, "Expected an identifier and instead saw ']'.")850 .addError(11, "Expected an assignment or function call and instead saw an expression.")851 .addError(3, "'z' is not defined.")852 .addError(11, "'a' is defined but never used.")853 .addError(11, "'b' is defined but never used.")854 .addError(11, "'c' is defined but never used.")855 .addError(4, "'h' is defined but never used.")856 .addError(4, "'w' is defined but never used.")857 .addError(5, "'o' is defined but never used.")858 .addError(6, "'d' is defined but never used.")859 .addError(8, "'bar' is defined but never used.")860 .test(code, {esnext: true, unused: true, undef: true});861 test.done();862};863exports["test: destructuring const as moz"] = function (test) {864 var code = [865 "const [ a, b, c ] = [ 1, 2, 3 ];",866 "const [ d ] = [ 1 ];",867 "const [ e ] = [ z ];",868 "const [ hel, wor ] = [ 'hello', 'world' ]; ",869 "const [ o ] = [ { o : 1 } ];",870 "const [ f, [ [ [ g ], h ], i ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",871 "const { foo : bar } = { foo : 1 };",872 "const [ j, { foo : foobar } ] = [ 2, { foo : 1 } ];",873 "const [ aa, bb ] = yield func();"874 ];875 TestRun(test)876 .addError(1, "'a' is defined but never used.")877 .addError(1, "'b' is defined but never used.")878 .addError(1, "'c' is defined but never used.")879 .addError(2, "'d' is defined but never used.")880 .addError(3, "'e' is defined but never used.")881 .addError(4, "'hel' is defined but never used.")882 .addError(4, "'wor' is defined but never used.")883 .addError(5, "'o' is defined but never used.")884 .addError(6, "'f' is defined but never used.")885 .addError(6, "'g' is defined but never used.")886 .addError(6, "'h' is defined but never used.")887 .addError(6, "'i' is defined but never used.")888 .addError(7, "'bar' is defined but never used.")889 .addError(8, "'j' is defined but never used.")890 .addError(8, "'foobar' is defined but never used.")891 .addError(9, "'aa' is defined but never used.")892 .addError(9, "'bb' is defined but never used.")893 .addError(3, "'z' is not defined.")894 .addError(9, "'func' is not defined.")895 .test(code, {moz: true, unused: true, undef: true});896 test.done();897};898exports["test: destructuring const as esnext"] = function (test) {899 var code = [900 "const [ a, b, c ] = [ 1, 2, 3 ];",901 "const [ d ] = [ 1 ];",902 "const [ e ] = [ z ];",903 "const [ hel, wor ] = [ 'hello', 'world' ]; ",904 "const [ o ] = [ { o : 1 } ];",905 "const [ f, [ [ [ g ], h ], i ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",906 "const { foo : bar } = { foo : 1 };",907 "const [ j, { foo : foobar } ] = [ 2, { foo : 1 } ];",908 ];909 TestRun(test)910 .addError(1, "'a' is defined but never used.")911 .addError(1, "'b' is defined but never used.")912 .addError(1, "'c' is defined but never used.")913 .addError(2, "'d' is defined but never used.")914 .addError(3, "'e' is defined but never used.")915 .addError(4, "'hel' is defined but never used.")916 .addError(4, "'wor' is defined but never used.")917 .addError(5, "'o' is defined but never used.")918 .addError(6, "'f' is defined but never used.")919 .addError(6, "'g' is defined but never used.")920 .addError(6, "'h' is defined but never used.")921 .addError(6, "'i' is defined but never used.")922 .addError(7, "'bar' is defined but never used.")923 .addError(8, "'j' is defined but never used.")924 .addError(8, "'foobar' is defined but never used.")925 .addError(3, "'z' is not defined.")926 .test(code, {esnext: true, unused: true, undef: true});927 test.done();928};929exports["test: destructuring const as es5"] = function (test) {930 var code = [931 "const [ a, b, c ] = [ 1, 2, 3 ];",932 "const [ d ] = [ 1 ];",933 "const [ e ] = [ z ];",934 "const [ hel, wor ] = [ 'hello', 'world' ]; ",935 "const [ o ] = [ { o : 1 } ];",936 "const [ f, [ [ [ g ], h ], i ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",937 "const { foo : bar } = { foo : 1 };",938 "const [ j, { foo : foobar } ] = [ 2, { foo : 1 } ];",939 ];940 TestRun(test)941 .addError(1, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")942 .addError(1, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")943 .addError(2, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")944 .addError(2, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")945 .addError(3, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")946 .addError(3, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")947 .addError(4, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")948 .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")949 .addError(5, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")950 .addError(5, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")951 .addError(6, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")952 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")953 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")954 .addError(7, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")955 .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")956 .addError(8, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")957 .addError(8, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")958 .addError(8, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")959 .addError(1, "'a' is defined but never used.")960 .addError(1, "'b' is defined but never used.")961 .addError(1, "'c' is defined but never used.")962 .addError(2, "'d' is defined but never used.")963 .addError(3, "'e' is defined but never used.")964 .addError(4, "'hel' is defined but never used.")965 .addError(4, "'wor' is defined but never used.")966 .addError(5, "'o' is defined but never used.")967 .addError(6, "'f' is defined but never used.")968 .addError(6, "'g' is defined but never used.")969 .addError(6, "'h' is defined but never used.")970 .addError(6, "'i' is defined but never used.")971 .addError(7, "'bar' is defined but never used.")972 .addError(8, "'j' is defined but never used.")973 .addError(8, "'foobar' is defined but never used.")974 .addError(3, "'z' is not defined.")975 .test(code, {unused: true, undef: true}); // es5976 test.done();977};978exports["test: destructuring const as legacy JS"] = function (test) {979 var code = [980 "const [ a, b, c ] = [ 1, 2, 3 ];",981 "const [ d ] = [ 1 ];",982 "const [ e ] = [ z ];",983 "const [ hel, wor ] = [ 'hello', 'world' ]; ",984 "const [ o ] = [ { o : 1 } ];",985 "const [ f, [ [ [ g ], h ], i ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",986 "const { foo : bar } = { foo : 1 };",987 "const [ j, { foo : foobar } ] = [ 2, { foo : 1 } ];",988 ];989 TestRun(test)990 .addError(1, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")991 .addError(1, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")992 .addError(2, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")993 .addError(2, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")994 .addError(3, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")995 .addError(3, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")996 .addError(4, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")997 .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")998 .addError(5, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")999 .addError(5, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1000 .addError(6, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1001 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1002 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1003 .addError(7, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1004 .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1005 .addError(8, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1006 .addError(8, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1007 .addError(8, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1008 .addError(1, "'a' is defined but never used.")1009 .addError(1, "'b' is defined but never used.")1010 .addError(1, "'c' is defined but never used.")1011 .addError(2, "'d' is defined but never used.")1012 .addError(3, "'e' is defined but never used.")1013 .addError(4, "'hel' is defined but never used.")1014 .addError(4, "'wor' is defined but never used.")1015 .addError(5, "'o' is defined but never used.")1016 .addError(6, "'f' is defined but never used.")1017 .addError(6, "'g' is defined but never used.")1018 .addError(6, "'h' is defined but never used.")1019 .addError(6, "'i' is defined but never used.")1020 .addError(7, "'bar' is defined but never used.")1021 .addError(8, "'j' is defined but never used.")1022 .addError(8, "'foobar' is defined but never used.")1023 .addError(3, "'z' is not defined.")1024 .test(code, {es3: true, unused: true, undef: true});1025 test.done();1026};1027exports["test: destructuring const errors"] = function (test) {1028 var code = [1029 "const [ a, b, c ] = [ 1, 2, 3 ];",1030 "const [ a, b, c ] = [ 1, 2, 3 ];",1031 "const [ 1 ] = [ a ];",1032 "const [ k, l; m ] = [ 1, 2, 3 ];",1033 "const [ n, o, p ] = [ 1, 2; 3 ];"1034 ];1035 TestRun(test)1036 .addError(2, "'b' is defined but never used.")1037 .addError(2, "'c' is defined but never used.")1038 .addError(4, "'k' is defined but never used.")1039 .addError(4, "'l' is defined but never used.")1040 .addError(4, "'m' is defined but never used.")1041 .addError(5, "'n' is defined but never used.")1042 .addError(5, "'o' is defined but never used.")1043 .addError(5, "'p' is defined but never used.")1044 .addError(2, "const 'a' has already been declared.")1045 .addError(2, "const 'b' has already been declared.")1046 .addError(2, "const 'c' has already been declared.")1047 .addError(3, "Expected an identifier and instead saw '1'.")1048 .addError(3, "Expected ',' and instead saw '1'.")1049 .addError(3, "Expected an identifier and instead saw ']'.")1050 .addError(4, "Expected ',' and instead saw ';'.")1051 .addError(5, "Expected ']' to match '[' from line 5 and instead saw ';'.")1052 .addError(5, "Missing semicolon.")1053 .addError(5, "Expected an assignment or function call and instead saw an expression.")1054 .addError(5, "Missing semicolon.")1055 .addError(5, "Expected an identifier and instead saw ']'.")1056 .addError(5, "Expected an assignment or function call and instead saw an expression.")1057 .addError(5, "Missing semicolon.")1058 .test(code, {es3: true, esnext: true, unused: true, undef: true});1059 test.done();1060};1061exports["test: destructuring globals as moz"] = function (test) {1062 var code = [1063 "var a, b, c, d, h, w, o;",1064 "[ a, b, c ] = [ 1, 2, 3 ];",1065 "[ a ] = [ 1 ];",1066 "[ a ] = [ z ];",1067 "[ h, w ] = [ 'hello', 'world' ]; ",1068 "[ o ] = [ { o : 1 } ];",1069 "[ a, [ [ [ b ], c ], d ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",1070 "[ a, { foo : b } ] = [ 2, { foo : 1 } ];",1071 ];1072 TestRun(test)1073 .addError(4, "'z' is not defined.")1074 .test(code, {moz: true, unused: true, undef: true});1075 test.done();1076};1077exports["test: destructuring globals as esnext"] = function (test) {1078 var code = [1079 "var a, b, c, d, h, w, o;",1080 "[ a, b, c ] = [ 1, 2, 3 ];",1081 "[ a ] = [ 1 ];",1082 "[ a ] = [ z ];",1083 "[ h, w ] = [ 'hello', 'world' ]; ",1084 "[ o ] = [ { o : 1 } ];",1085 "[ a, [ [ [ b ], c ], d ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",1086 "[ a, { foo : b } ] = [ 2, { foo : 1 } ];",1087 ];1088 TestRun(test)1089 .addError(4, "'z' is not defined.")1090 .test(code, {esnext: true, unused: true, undef: true});1091 test.done();1092};1093exports["test: destructuring globals as es5"] = function (test) {1094 var code = [1095 "var a, b, c, d, h, w, o;",1096 "[ a, b, c ] = [ 1, 2, 3 ];",1097 "[ a ] = [ 1 ];",1098 "[ a ] = [ z ];",1099 "[ h, w ] = [ 'hello', 'world' ]; ",1100 "[ o ] = [ { o : 1 } ];",1101 "[ a, [ [ [ b ], c ], d ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",1102 "[ a, { foo : b } ] = [ 2, { foo : 1 } ];",1103 ];1104 TestRun(test)1105 .addError(4, "'z' is not defined.")1106 .addError(2, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1107 .addError(3, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1108 .addError(4, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1109 .addError(5, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1110 .addError(6, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1111 .addError(7, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1112 .addError(8, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1113 .test(code, {unused: true, undef: true}); // es51114 test.done();1115};1116exports["test: destructuring globals as legacy JS"] = function (test) {1117 var code = [1118 "var a, b, c, d, h, w, o;",1119 "[ a, b, c ] = [ 1, 2, 3 ];",1120 "[ a ] = [ 1 ];",1121 "[ a ] = [ z ];",1122 "[ h, w ] = [ 'hello', 'world' ]; ",1123 "[ o ] = [ { o : 1 } ];",1124 "[ a, [ [ [ b ], c ], d ] ] = [ 1, [ [ [ 2 ], 3], 4 ] ];",1125 "[ a, { foo : b } ] = [ 2, { foo : 1 } ];",1126 ];1127 TestRun(test)1128 .addError(4, "'z' is not defined.")1129 .addError(2, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1130 .addError(3, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1131 .addError(4, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1132 .addError(5, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1133 .addError(6, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1134 .addError(7, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1135 .addError(8, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1136 .test(code, {es3: true, unused: true, undef: true});1137 test.done();1138};1139exports["test: destructuring globals with syntax error"] = function (test) {1140 var code = [1141 "var a, b, c;",1142 "[ a ] = [ z ];",1143 "[ 1 ] = [ a ];",1144 "[ a, b; c ] = [ 1, 2, 3 ];",1145 "[ a, b, c ] = [ 1, 2; 3 ];"1146 ];1147 TestRun(test)1148 .addError(4, "Expected ']' to match '[' from line 4 and instead saw ';'.")1149 .addError(4, "Expected an assignment or function call and instead saw an expression.")1150 .addError(4, "Missing semicolon.")1151 .addError(4, "Expected an assignment or function call and instead saw an expression.")1152 .addError(4, "Missing semicolon.")1153 .addError(4, "Expected an identifier and instead saw ']'.")1154 .addError(4, "Expected an operator and instead saw '='.")1155 .addError(4, "Expected an operator and instead saw '['.")1156 .addError(4, "Expected an assignment or function call and instead saw an expression.")1157 .addError(4, "Missing semicolon.")1158 .addError(4, "Expected an assignment or function call and instead saw an expression.")1159 .addError(4, "Expected an assignment or function call and instead saw an expression.")1160 .addError(4, "Missing semicolon.")1161 .addError(4, "Expected an identifier and instead saw ']'.")1162 .addError(4, "Expected an assignment or function call and instead saw an expression.")1163 .addError(5, "Expected ']' to match '[' from line 5 and instead saw ';'.")1164 .addError(5, "Missing semicolon.")1165 .addError(5, "Expected an assignment or function call and instead saw an expression.")1166 .addError(5, "Missing semicolon.")1167 .addError(5, "Expected an identifier and instead saw ']'.")1168 .addError(5, "Expected an assignment or function call and instead saw an expression.")1169 .addError(2, "'z' is not defined.")1170 .test(code, {esnext: true, unused: true, undef: true});1171 test.done();1172};1173exports["test: destructuring assign of empty values as moz"] = function (test) {1174 var code = [1175 "var [ a ] = [ 1, 2 ];",1176 "var [ c, d ] = [ 1 ];",1177 "var [ e, , f ] = [ 3, , 4 ];"1178 ];1179 TestRun(test)1180 .addError(1, "'a' is defined but never used.")1181 .addError(2, "'c' is defined but never used.")1182 .addError(2, "'d' is defined but never used.")1183 .addError(3, "'e' is defined but never used.")1184 .addError(3, "'f' is defined but never used.")1185 .test(code, {moz: true, unused: true, undef: true, laxcomma: true});1186 test.done();1187};1188exports["test: destructuring assign of empty values as esnext"] = function (test) {1189 var code = [1190 "var [ a ] = [ 1, 2 ];",1191 "var [ c, d ] = [ 1 ];",1192 "var [ e, , f ] = [ 3, , 4 ];"1193 ];1194 TestRun(test)1195 .addError(1, "'a' is defined but never used.")1196 .addError(2, "'c' is defined but never used.")1197 .addError(2, "'d' is defined but never used.")1198 .addError(3, "'e' is defined but never used.")1199 .addError(3, "'f' is defined but never used.")1200 .test(code, {esnext: true, unused: true, undef: true});1201 test.done();1202};1203exports["test: destructuring assign of empty values as es5"] = function (test) {1204 var code = [1205 "var [ a ] = [ 1, 2 ];",1206 "var [ c, d ] = [ 1 ];",1207 "var [ e, , f ] = [ 3, , 4 ];"1208 ];1209 TestRun(test)1210 .addError(1, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1211 .addError(1, "'a' is defined but never used.")1212 .addError(2, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1213 .addError(2, "'c' is defined but never used.")1214 .addError(2, "'d' is defined but never used.")1215 .addError(3, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1216 .addError(3, "'e' is defined but never used.")1217 .addError(3, "'f' is defined but never used.")1218 .test(code, {unused: true, undef: true}); // es51219 test.done();1220};1221exports["test: destructuring assign of empty values as JS legacy"] = function (test) {1222 var code = [1223 "var [ a ] = [ 1, 2 ];",1224 "var [ c, d ] = [ 1 ];",1225 "var [ e, , f ] = [ 3, , 4 ];"1226 ];1227 TestRun(test)1228 .addError(1, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1229 .addError(1, "'a' is defined but never used.")1230 .addError(2, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1231 .addError(2, "'c' is defined but never used.")1232 .addError(2, "'d' is defined but never used.")1233 .addError(3, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1234 .addError(3, "'e' is defined but never used.")1235 .addError(3, "'f' is defined but never used.")1236 .addError(3, "Extra comma. (it breaks older versions of IE)")1237 .test(code, {es3: true, unused: true, undef: true});1238 test.done();1239};1240exports["test: array element assignment inside array"] = function (test) {1241 var code = [1242 "var a1 = {};",1243 "var a2 = [function f() {a1[0] = 1;}];",1244 ];1245 TestRun(test)1246 .test(code);1247 test.done();1248};1249exports["test: let statement as moz"] = function (test) {1250 var code = [1251 "let x = 1;",1252 "{",1253 " let y = 3 ;",1254 " {",1255 " let z = 2;",1256 " print(x + ' ' + y + ' ' + z);",1257 " }",1258 " print(x + ' ' + y);",1259 "}",1260 "print(x);"1261 ];1262 TestRun(test)1263 .test(code, {moz: true, unused: true, undef: true, predef: ["print"]});1264 test.done();1265};1266exports["test: let statement as esnext"] = function (test) {1267 var code = [1268 "let x = 1;",1269 "{",1270 " let y = 3 ;",1271 " {",1272 " let z = 2;",1273 " print(x + ' ' + y + ' ' + z);",1274 " }",1275 " print(x + ' ' + y);",1276 "}",1277 "print(x);"1278 ];1279 TestRun(test)1280 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});1281 test.done();1282};1283exports["test: let statement as es5"] = function (test) {1284 var code = [1285 "let x = 1;",1286 "{",1287 " let y = 3 ;",1288 " {",1289 " let z = 2;",1290 " print(x + ' ' + y + ' ' + z);",1291 " }",1292 " print(x + ' ' + y);",1293 "}",1294 "print(x);"1295 ];1296 TestRun(test)1297 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1298 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1299 .addError(5, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1300 .test(code, {unused: true, undef: true, predef: ["print"]}); // es51301 test.done();1302};1303exports["test: let statement as legacy JS"] = function (test) {1304 var code = [1305 "let x = 1;",1306 "{",1307 " let y = 3 ;",1308 " {",1309 " let z = 2;",1310 " print(x + ' ' + y + ' ' + z);",1311 " }",1312 " print(x + ' ' + y);",1313 "}",1314 "print(x);"1315 ];1316 TestRun(test)1317 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1318 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1319 .addError(5, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1320 .test(code, {es3: true, unused: true, undef: true, predef: ["print"]});1321 test.done();1322};1323exports["test: let statement out of scope as moz"] = function (test) {1324 var code = [1325 "let x = 1;",1326 "{",1327 " let y = 3 ;",1328 " {",1329 " let z = 2;",1330 " }",1331 " print(z);",1332 "}",1333 "print(y);",1334 ];1335 TestRun(test)1336 .addError(1, "'x' is defined but never used.")1337 .addError(5, "'z' is defined but never used.")1338 .addError(3, "'y' is defined but never used.")1339 .addError(7, "'z' is not defined.")1340 .addError(9, "'y' is not defined.")1341 .test(code, {moz: true, unused: true, undef: true, predef: ["print"]});1342 test.done();1343};1344exports["test: let statement out of scope as esnext"] = function (test) {1345 var code = [1346 "let x = 1;",1347 "{",1348 " let y = 3 ;",1349 " {",1350 " let z = 2;",1351 " }",1352 " print(z);",1353 "}",1354 "print(y);",1355 ];1356 TestRun(test)1357 .addError(1, "'x' is defined but never used.")1358 .addError(5, "'z' is defined but never used.")1359 .addError(3, "'y' is defined but never used.")1360 .addError(7, "'z' is not defined.")1361 .addError(9, "'y' is not defined.")1362 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});1363 test.done();1364};1365exports["test: let statement out of scope as es5"] = function (test) {1366 var code = [1367 "let x = 1;",1368 "{",1369 " let y = 3 ;",1370 " {",1371 " let z = 2;",1372 " }",1373 " print(z);",1374 "}",1375 "print(y);",1376 ];1377 TestRun(test)1378 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1379 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1380 .addError(5, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1381 .addError(1, "'x' is defined but never used.")1382 .addError(5, "'z' is defined but never used.")1383 .addError(3, "'y' is defined but never used.")1384 .addError(7, "'z' is not defined.")1385 .addError(9, "'y' is not defined.")1386 .test(code, {unused: true, undef: true, predef: ["print"]}); // es51387 test.done();1388};1389exports["test: let statement out of scope as legacy JS"] = function (test) {1390 var code = [1391 "let x = 1;",1392 "{",1393 " let y = 3 ;",1394 " {",1395 " let z = 2;",1396 " }",1397 " print(z);",1398 "}",1399 "print(y);",1400 ];1401 TestRun(test)1402 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1403 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1404 .addError(5, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1405 .addError(1, "'x' is defined but never used.")1406 .addError(5, "'z' is defined but never used.")1407 .addError(3, "'y' is defined but never used.")1408 .addError(7, "'z' is not defined.")1409 .addError(9, "'y' is not defined.")1410 .test(code, {es3: true, unused: true, undef: true, predef: ["print"]});1411 test.done();1412};1413exports["test: let statement in functions as moz"] = function (test) {1414 var code = [1415 "let x = 1;",1416 "function foo() {",1417 " let y = 3 ;",1418 " function bar() {",1419 " let z = 2;",1420 " print(x);",1421 " print(z);",1422 " }",1423 " print(y);",1424 " bar();",1425 "}",1426 "foo();"1427 ];1428 TestRun(test)1429 .test(code, {moz: true, unused: true, undef: true, predef: ["print"]});1430 test.done();1431};1432exports["test: let statement in functions as esnext"] = function (test) {1433 var code = [1434 "let x = 1;",1435 "function foo() {",1436 " let y = 3 ;",1437 " function bar() {",1438 " let z = 2;",1439 " print(x);",1440 " print(z);",1441 " }",1442 " print(y);",1443 " bar();",1444 "}",1445 "foo();"1446 ];1447 TestRun(test)1448 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});1449 test.done();1450};1451exports["test: let statement in functions as es5"] = function (test) {1452 var code = [1453 "let x = 1;",1454 "function foo() {",1455 " let y = 3 ;",1456 " function bar() {",1457 " let z = 2;",1458 " print(x);",1459 " print(z);",1460 " }",1461 " print(y);",1462 " bar();",1463 "}",1464 "foo();"1465 ];1466 TestRun(test)1467 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1468 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1469 .addError(5, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1470 .test(code, {unused: true, undef: true, predef: ["print"]}); // es51471 test.done();1472};1473exports["test: let statement in functions as legacy JS"] = function (test) {1474 var code = [1475 "let x = 1;",1476 "function foo() {",1477 " let y = 3 ;",1478 " function bar() {",1479 " let z = 2;",1480 " print(x);",1481 " print(z);",1482 " }",1483 " print(y);",1484 " bar();",1485 "}",1486 "foo();"1487 ];1488 TestRun(test)1489 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1490 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1491 .addError(5, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1492 .test(code, {es3: true, unused: true, undef: true, predef: ["print"]});1493 test.done();1494};1495exports["test: let statement not in scope as moz"] = function (test) {1496 var code = [1497 "let x = 1;",1498 "function foo() {",1499 " let y = 3 ;",1500 " let bar = function () {",1501 " print(x);",1502 " let z = 2;",1503 " };",1504 " print(z);",1505 "}",1506 "print(y);",1507 "bar();",1508 "foo();",1509 ];1510 TestRun(test)1511 .addError(6, "'z' is defined but never used.")1512 .addError(3, "'y' is defined but never used.")1513 .addError(4, "'bar' is defined but never used.")1514 .addError(8, "'z' is not defined.")1515 .addError(10, "'y' is not defined.")1516 .addError(11, "'bar' is not defined.")1517 .test(code, {moz: true, unused: true, undef: true, predef: ["print"]});1518 test.done();1519};1520exports["test: let statement not in scope as esnext"] = function (test) {1521 var code = [1522 "let x = 1;",1523 "function foo() {",1524 " let y = 3 ;",1525 " let bar = function () {",1526 " print(x);",1527 " let z = 2;",1528 " };",1529 " print(z);",1530 "}",1531 "print(y);",1532 "bar();",1533 "foo();",1534 ];1535 TestRun(test)1536 .addError(6, "'z' is defined but never used.")1537 .addError(3, "'y' is defined but never used.")1538 .addError(4, "'bar' is defined but never used.")1539 .addError(8, "'z' is not defined.")1540 .addError(10, "'y' is not defined.")1541 .addError(11, "'bar' is not defined.")1542 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});1543 test.done();1544};1545exports["test: let statement not in scope as es5"] = function (test) {1546 var code = [1547 "let x = 1;",1548 "function foo() {",1549 " let y = 3 ;",1550 " let bar = function () {",1551 " print(x);",1552 " let z = 2;",1553 " };",1554 " print(z);",1555 "}",1556 "print(y);",1557 "bar();",1558 "foo();",1559 ];1560 TestRun(test)1561 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1562 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1563 .addError(4, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1564 .addError(6, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1565 .addError(6, "'z' is defined but never used.")1566 .addError(3, "'y' is defined but never used.")1567 .addError(4, "'bar' is defined but never used.")1568 .addError(8, "'z' is not defined.")1569 .addError(10, "'y' is not defined.")1570 .addError(11, "'bar' is not defined.")1571 .test(code, {unused: true, undef: true, predef: ["print"]}); // es51572 test.done();1573};1574exports["test: let statement not in scope as legacy JS"] = function (test) {1575 var code = [1576 "let x = 1;",1577 "function foo() {",1578 " let y = 3 ;",1579 " let bar = function () {",1580 " print(x);",1581 " let z = 2;",1582 " };",1583 " print(z);",1584 "}",1585 "print(y);",1586 "bar();",1587 "foo();",1588 ];1589 TestRun(test)1590 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1591 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1592 .addError(4, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1593 .addError(6, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1594 .addError(6, "'z' is defined but never used.")1595 .addError(3, "'y' is defined but never used.")1596 .addError(4, "'bar' is defined but never used.")1597 .addError(8, "'z' is not defined.")1598 .addError(10, "'y' is not defined.")1599 .addError(11, "'bar' is not defined.")1600 .test(code, {es3: true, unused: true, undef: true, predef: ["print"]});1601 test.done();1602};1603exports["test: let statement in for loop as moz"] = function (test) {1604 var code = [1605 "var obj={foo: 'bar', bar: 'foo'};",1606 "for ( let [n, v] in Iterator(obj) ) {",1607 " print('Name: ' + n + ', Value: ' + v);",1608 "}",1609 "for (let i in [1, 2, 3, 4]) {",1610 " print(i);",1611 "}",1612 "for (let i in [1, 2, 3, 4]) {",1613 " print(i);",1614 "}",1615 "for (let i = 0; i<15; ++i) {",1616 " print(i);",1617 "}",1618 "for (let i=i ; i < 10 ; i++ ) {",1619 "print(i);",1620 "}"1621 ];1622 TestRun(test)1623 .test(code, {moz: true, unused: true, undef: true, predef: ["print", "Iterator"]});1624 test.done();1625};1626exports["test: let statement in for loop as esnext"] = function (test) {1627 var code = [1628 "var obj={foo: 'bar', bar: 'foo'};",1629 "for ( let [n, v] in Iterator(obj) ) {",1630 " print('Name: ' + n + ', Value: ' + v);",1631 "}",1632 "for (let i in [1, 2, 3, 4]) {",1633 " print(i);",1634 "}",1635 "for (let i in [1, 2, 3, 4]) {",1636 " print(i);",1637 "}",1638 "for (let i = 0; i<15; ++i) {",1639 " print(i);",1640 "}",1641 "for (let i=i ; i < 10 ; i++ ) {",1642 "print(i);",1643 "}"1644 ];1645 TestRun(test)1646 .test(code, {esnext: true, unused: true, undef: true, predef: ["print", "Iterator"]});1647 test.done();1648};1649exports["test: let statement in for loop as es5"] = function (test) {1650 var code = [1651 "var obj={foo: 'bar', bar: 'foo'};",1652 "for ( let [n, v] in Iterator(obj) ) {",1653 " print('Name: ' + n + ', Value: ' + v);",1654 "}",1655 "for (let i in [1, 2, 3, 4]) {",1656 " print(i);",1657 "}",1658 "for (let i in [1, 2, 3, 4]) {",1659 " print(i);",1660 "}",1661 "for (let i = 0; i<15; ++i) {",1662 " print(i);",1663 "}",1664 "for (let i=i ; i < 10 ; i++ ) {",1665 "print(i);",1666 "}"1667 ];1668 TestRun(test)1669 .addError(2, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1670 .addError(2, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1671 .addError(5, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1672 .addError(8, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1673 .addError(11, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1674 .addError(14, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1675 .test(code, {unused: true, undef: true, predef: ["print", "Iterator"]}); // es51676 test.done();1677};1678exports["test: let statement in for loop as legacy JS"] = function (test) {1679 var code = [1680 "var obj={foo: 'bar', bar: 'foo'};",1681 "for ( let [n, v] in Iterator(obj) ) {",1682 " print('Name: ' + n + ', Value: ' + v);",1683 "}",1684 "for (let i in [1, 2, 3, 4]) {",1685 " print(i);",1686 "}",1687 "for (let i in [1, 2, 3, 4]) {",1688 " print(i);",1689 "}",1690 "for (let i = 0; i<15; ++i) {",1691 " print(i);",1692 "}",1693 "for (let i=i ; i < 10 ; i++ ) {",1694 "print(i);",1695 "}"1696 ];1697 TestRun(test)1698 .addError(2, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1699 .addError(2, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1700 .addError(5, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1701 .addError(8, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1702 .addError(11, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1703 .addError(14, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1704 .test(code, {es3: true, unused: true, undef: true, predef: ["print", "Iterator"]});1705 test.done();1706};1707exports["test: let statement in destructured for loop as moz"] = function (test) {1708 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.71709 var code = [1710 "var people = [",1711 "{",1712 " name: 'Mike Smith',",1713 " family: {",1714 " mother: 'Jane Smith',",1715 " father: 'Harry Smith',",1716 " sister: 'Samantha Smith'",1717 " },",1718 " age: 35",1719 "},",1720 "{",1721 " name: 'Tom Jones',",1722 " family: {",1723 " mother: 'Norah Jones',",1724 " father: 'Richard Jones',",1725 " brother: 'Howard Jones'",1726 " },",1727 " age: 25",1728 "}",1729 "];",1730 "for (let {name: n, family: { father: f } } in people) {",1731 "print('Name: ' + n + ', Father: ' + f);",1732 "}"1733 ];1734 TestRun(test)1735 .test(code, {moz: true, unused: true,1736 undef: true, predef: ["print"]});1737 test.done();1738};1739exports["test: let statement in destructured for loop as esnext"] = function (test) {1740 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.71741 var code = [1742 "var people = [",1743 "{",1744 " name: 'Mike Smith',",1745 " family: {",1746 " mother: 'Jane Smith',",1747 " father: 'Harry Smith',",1748 " sister: 'Samantha Smith'",1749 " },",1750 " age: 35",1751 "},",1752 "{",1753 " name: 'Tom Jones',",1754 " family: {",1755 " mother: 'Norah Jones',",1756 " father: 'Richard Jones',",1757 " brother: 'Howard Jones'",1758 " },",1759 " age: 25",1760 "}",1761 "];",1762 "for (let {name: n, family: { father: f } } in people) {",1763 "print('Name: ' + n + ', Father: ' + f);",1764 "}"1765 ];1766 TestRun(test)1767 .test(code, {esnext: true, unused: true,1768 undef: true, predef: ["print"]});1769 test.done();1770};1771exports["test: let statement in destructured for loop as es5"] = function (test) {1772 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.71773 var code = [1774 "var people = [",1775 "{",1776 " name: 'Mike Smith',",1777 " family: {",1778 " mother: 'Jane Smith',",1779 " father: 'Harry Smith',",1780 " sister: 'Samantha Smith'",1781 " },",1782 " age: 35",1783 "},",1784 "{",1785 " name: 'Tom Jones',",1786 " family: {",1787 " mother: 'Norah Jones',",1788 " father: 'Richard Jones',",1789 " brother: 'Howard Jones'",1790 " },",1791 " age: 25",1792 "}",1793 "];",1794 "for (let {name: n, family: { father: f } } in people) {",1795 "print('Name: ' + n + ', Father: ' + f);",1796 "}"1797 ];1798 TestRun(test)1799 .addError(21, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1800 .addError(21, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1801 .test(code, {unused: true, undef: true, predef: ["print"]}); // es51802 test.done();1803};1804exports["test: let statement in destructured for loop as legacy JS"] = function (test) {1805 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.71806 var code = [1807 "var people = [",1808 "{",1809 " name: 'Mike Smith',",1810 " family: {",1811 " mother: 'Jane Smith',",1812 " father: 'Harry Smith',",1813 " sister: 'Samantha Smith'",1814 " },",1815 " age: 35",1816 "},",1817 "{",1818 " name: 'Tom Jones',",1819 " family: {",1820 " mother: 'Norah Jones',",1821 " father: 'Richard Jones',",1822 " brother: 'Howard Jones'",1823 " },",1824 " age: 25",1825 "}",1826 "];",1827 "for (let {name: n, family: { father: f } } in people) {",1828 "print('Name: ' + n + ', Father: ' + f);",1829 "}"1830 ];1831 TestRun(test)1832 .addError(21, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1833 .addError(21, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1834 .test(code, {es3: true, unused: true, undef: true, predef: ["print"]});1835 test.done();1836};1837exports["test: let statement (as seen in jetpack)"] = function (test) {1838 // Example taken from jetpack/addons sdk library from Mozilla project1839 var code = [1840 "const { Cc, Ci } = require('chrome');",1841 "// add a text/unicode flavor (html converted to plain text)",1842 "let (str = Cc['@mozilla.org/supports-string;1'].",1843 " createInstance(Ci.nsISupportsString),",1844 " converter = Cc['@mozilla.org/feed-textconstruct;1'].",1845 " createInstance(Ci.nsIFeedTextConstruct))",1846 "{",1847 "converter.type = 'html';",1848 "converter.text = options.data;",1849 "str.data = converter.plainText();",1850 "xferable.addDataFlavor('text/unicode');",1851 "xferable.setTransferData('text/unicode', str, str.data.length * 2);",1852 "}"1853 ];1854 TestRun(test)1855 .test(code, {moz: true, unused: true, undef: true,1856 predef: ["require", "xferable", "options"]});1857 test.done();1858};1859exports["test: let statement (as seen in jetpack) as esnext"] = function (test) {1860 // Example taken from jetpack/addons sdk library from Mozilla project1861 var code = [1862 "const { Cc, Ci } = require('chrome');",1863 "// add a text/unicode flavor (html converted to plain text)",1864 "let (str = Cc['@mozilla.org/supports-string;1'].",1865 " createInstance(Ci.nsISupportsString),",1866 " converter = Cc['@mozilla.org/feed-textconstruct;1'].",1867 " createInstance(Ci.nsIFeedTextConstruct))",1868 "{",1869 "converter.type = 'html';",1870 "converter.text = options.data;",1871 "str.data = converter.plainText();",1872 "xferable.addDataFlavor('text/unicode');",1873 "xferable.setTransferData('text/unicode', str, str.data.length * 2);",1874 "}"1875 ];1876 TestRun(test)1877 .addError(3, "'let block' is only available in Mozilla JavaScript extensions (use moz option).")1878 .test(code, {esnext: true, unused: true, undef: true,1879 predef: ["require", "xferable", "options"]});1880 test.done();1881};1882exports["test: let statement (as seen in jetpack) as es5"] = function (test) {1883 // Example taken from jetpack/addons sdk library from Mozilla project1884 var code = [1885 "const { Cc, Ci } = require('chrome');",1886 "// add a text/unicode flavor (html converted to plain text)",1887 "let (str = Cc['@mozilla.org/supports-string;1'].",1888 " createInstance(Ci.nsISupportsString),",1889 " converter = Cc['@mozilla.org/feed-textconstruct;1'].",1890 " createInstance(Ci.nsIFeedTextConstruct))",1891 "{",1892 "converter.type = 'html';",1893 "converter.text = options.data;",1894 "str.data = converter.plainText();",1895 "xferable.addDataFlavor('text/unicode');",1896 "xferable.setTransferData('text/unicode', str, str.data.length * 2);",1897 "}"1898 ];1899 TestRun(test)1900 .addError(1, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1901 .addError(1, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1902 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1903 .addError(3, "'let block' is only available in Mozilla JavaScript extensions (use moz option).")1904 .test(code, {unused: true, undef: true,1905 predef: ["require", "xferable", "options"]}); // es51906 test.done();1907};1908exports["test: let statement (as seen in jetpack) as legacy JS"] = function (test) {1909 // Example taken from jetpack/addons sdk library from Mozilla project1910 var code = [1911 "const { Cc, Ci } = require('chrome');",1912 "// add a text/unicode flavor (html converted to plain text)",1913 "let (str = Cc['@mozilla.org/supports-string;1'].",1914 " createInstance(Ci.nsISupportsString),",1915 " converter = Cc['@mozilla.org/feed-textconstruct;1'].",1916 " createInstance(Ci.nsIFeedTextConstruct))",1917 "{",1918 "converter.type = 'html';",1919 "converter.text = options.data;",1920 "str.data = converter.plainText();",1921 "xferable.addDataFlavor('text/unicode');",1922 "xferable.setTransferData('text/unicode', str, str.data.length * 2);",1923 "}"1924 ];1925 TestRun(test)1926 .addError(1, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1927 .addError(1, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1928 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1929 .addError(3, "'let block' is only available in Mozilla JavaScript extensions (use moz option).")1930 .test(code, {es3: true, unused: true, undef: true,1931 predef: ["require", "xferable", "options"]});1932 test.done();1933};1934exports["test: let block and let expression"] = function (test) {1935 // Example taken from jetpack/addons sdk library from Mozilla project1936 var code = [1937 "let (x=1, y=2, z=3)",1938 "{",1939 " let(t=4) print(x, y, z, t);",1940 " print(let(u=4) u,x);",1941 "}"1942 ];1943 TestRun(test)1944 .test(code, {moz: true, unused: true, undef: true, predef: ["print"]});1945 test.done();1946};1947exports["test: let block and let expression as esnext"] = function (test) {1948 // Example taken from jetpack/addons sdk library from Mozilla project1949 var code = [1950 "let (x=1, y=2, z=3)",1951 "{",1952 " let(t=4) print(x, y, z, t);",1953 " print(let(u=4) u,x);",1954 "}"1955 ];1956 TestRun(test)1957 .addError(1, "'let block' is only available in Mozilla JavaScript extensions (use moz option).")1958 .addError(3, "'let block' is only available in Mozilla JavaScript extensions (use moz option).")1959 .addError(4, "'let expressions' is only available in Mozilla JavaScript extensions " +1960 "(use moz option).")1961 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});1962 test.done();1963};1964exports["test: let block and let expression as es5"] = function (test) {1965 // Example taken from jetpack/addons sdk library from Mozilla project1966 var code = [1967 "let (x=1, y=2, z=3)",1968 "{",1969 " let(t=4) print(x, y, z, t);",1970 " print(let(u=4) u,x);",1971 "}"1972 ];1973 TestRun(test)1974 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1975 .addError(1, "'let block' is only available in Mozilla JavaScript extensions (use moz option).")1976 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1977 .addError(3, "'let block' is only available in Mozilla JavaScript extensions (use moz option).")1978 .addError(4, "'let expressions' is only available in Mozilla JavaScript extensions " +1979 "(use moz option).")1980 .addError(4, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1981 .test(code, {unused: true, undef: true, predef: ["print"]}); // es51982 test.done();1983};1984exports["test: let block and let expression as legacy JS"] = function (test) {1985 // Example taken from jetpack/addons sdk library from Mozilla project1986 var code = [1987 "let (x=1, y=2, z=3)",1988 "{",1989 " let(t=4) print(x, y, z, t);",1990 " print(let(u=4) u,x);",1991 "}"1992 ];1993 TestRun(test)1994 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1995 .addError(1, "'let block' is only available in Mozilla JavaScript extensions (use moz option).")1996 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")1997 .addError(3, "'let block' is only available in Mozilla JavaScript extensions (use moz option).")1998 .addError(4, "'let expressions' is only available in Mozilla JavaScript extensions " +1999 "(use moz option).")2000 .addError(4, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2001 .test(code, {es3: true, unused: true, undef: true, predef: ["print"]});2002 test.done();2003};2004exports["make sure let variables are not treated as globals"] = function (test) {2005 // This is a regression test for GH-13622006 var code = [2007 "function sup() {",2008 "if (true) {",2009 "let closed = 1;",2010 "closed = 2;",2011 "}",2012 "if (true) {",2013 "if (true) {",2014 "let closed = 1;",2015 "closed = 2;",2016 "}",2017 "}",2018 "}"2019 ];2020 TestRun(test).test(code, { esnext: true, browser: true });2021 test.done();2022};2023exports["make sure var variables can shadow let variables"] = function (test) {2024 // This is a regression test for GH-13942025 var code = [2026 "let a = 1;",2027 "let b = 2;",2028 "var c = 3;",2029 "function sup(a) {",2030 "var b = 4;",2031 "let c = 5;",2032 "let d = 6;",2033 "if (false) {",2034 "var d = 7;",2035 "}",2036 "return b + c + a + d;",2037 "}",2038 "sup();"2039 ];2040 TestRun(test)2041 .addError(1, "'a' is defined but never used.")2042 .addError(2, "'b' is defined but never used.")2043 .addError(3, "'c' is defined but never used.")2044 .addError(7, "'d' is defined but never used.")2045 .test(code, { esnext: true, unused: true, undef: true, funcscope: true });2046 test.done();2047};2048exports["test destructuring function as moz"] = function (test) {2049 // Example from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72050 var code = [2051 "function userId({id}) {",2052 " return id;",2053 "}",2054 "function whois({displayName: displayName, fullName: {firstName: name}}) {",2055 " print(displayName + ' is ' + name);",2056 "}",2057 "var user = {id: 42, displayName: 'jdoe', fullName: {firstName: 'John', lastName: 'Doe'}};",2058 "print('userId: ' + userId(user));",2059 "whois(user);"2060 ];2061 TestRun(test)2062 .test(code, {moz: true, unused: true, undef: true, predef: ["print"]});2063 test.done();2064};2065exports["test destructuring function as esnext"] = function (test) {2066 // Example from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72067 var code = [2068 "function userId({id}) {",2069 " return id;",2070 "}",2071 "function whois({displayName: displayName, fullName: {firstName: name}}) {",2072 " print(displayName + ' is ' + name);",2073 "}",2074 "var user = {id: 42, displayName: 'jdoe', fullName: {firstName: 'John', lastName: 'Doe'}};",2075 "print('userId: ' + userId(user));",2076 "whois(user);"2077 ];2078 TestRun(test)2079 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});2080 test.done();2081};2082exports["test destructuring function as es5"] = function (test) {2083 // Example from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72084 var code = [2085 "function userId({id}) {",2086 " return id;",2087 "}",2088 "function whois({displayName: displayName, fullName: {firstName: name}}) {",2089 " print(displayName + ' is ' + name);",2090 "}",2091 "var user = {id: 42, displayName: 'jdoe', fullName: {firstName: 'John', lastName: 'Doe'}};",2092 "print('userId: ' + userId(user));",2093 "whois(user);"2094 ];2095 TestRun(test)2096 .addError(1, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2097 .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2098 .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2099 .test(code, {unused: true, undef: true, predef: ["print"]}); // es52100 test.done();2101};2102exports["test destructuring function as legacy JS"] = function (test) {2103 // Example from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72104 var code = [2105 "function userId({id}) {",2106 " return id;",2107 "}",2108 "function whois({displayName: displayName, fullName: {firstName: name}}) {",2109 " print(displayName + ' is ' + name);",2110 "}",2111 "var user = {id: 42, displayName: 'jdoe', fullName: {firstName: 'John', lastName: 'Doe'}};",2112 "print('userId: ' + userId(user));",2113 "whois(user);"2114 ];2115 TestRun(test)2116 .addError(1, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2117 .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2118 .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2119 .test(code, {es3: true, unused: true, undef: true, predef: ["print"]});2120 test.done();2121};2122exports["test: invalid for each"] = function (test) {2123 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72124 var code = [2125 "for each (let i = 0; i<15; ++i) {",2126 " print(i);",2127 "}"2128 ];2129 TestRun(test)2130 .addError(1, "Invalid for each loop.")2131 .test(code, {moz: true, unused: true, undef: true, predef: ["print"]});2132 test.done();2133};2134exports["test: invalid for each as esnext"] = function (test) {2135 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72136 var code = [2137 "for each (let i = 0; i<15; ++i) {",2138 " print(i);",2139 "}"2140 ];2141 TestRun(test)2142 .addError(1, "Invalid for each loop.")2143 .addError(1, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2144 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});2145 test.done();2146};2147exports["test: invalid for each as ES5"] = function (test) {2148 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72149 var code = [2150 "for each (let i = 0; i<15; ++i) {",2151 " print(i);",2152 "}"2153 ];2154 TestRun(test)2155 .addError(1, "Invalid for each loop.")2156 .addError(1, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2157 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2158 .test(code, {unused: true, undef: true, predef: ["print"]}); // es52159 test.done();2160};2161exports["test: invalid for each as legacy JS"] = function (test) {2162 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72163 var code = [2164 "for each (let i = 0; i<15; ++i) {",2165 " print(i);",2166 "}"2167 ];2168 TestRun(test)2169 .addError(1, "Invalid for each loop.")2170 .addError(1, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2171 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2172 .test(code, {es3: true, unused: true, undef: true, predef: ["print"]});2173 test.done();2174};2175exports["test: esnext generator"] = function (test) {2176 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72177 var code = [2178 "function* fib() {",2179 " var i = 0, j = 1;",2180 " while (true) {",2181 " yield i;",2182 " [i, j] = [j, i + j];",2183 " }",2184 "}",2185 "var g = fib();",2186 "for (var i = 0; i < 10; i++)",2187 " print(g.next());"2188 ];2189 TestRun(test)2190 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});2191 test.done();2192};2193exports["test: esnext generator as moz extension"] = function (test) {2194 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72195 var code = [2196 "function* fib() {",2197 " var i = 0, j = 1;",2198 " while (true) {",2199 " yield i;",2200 " [i, j] = [j, i + j];",2201 " }",2202 "}",2203 "var g = fib();",2204 "for (var i = 0; i < 10; i++)",2205 " print(g.next());"2206 ];2207 TestRun(test)2208 .addError(1, "'function*' is only available in ES6 (use esnext option).")2209 .test(code, {moz: true, unused: true, undef: true, predef: ["print"]});2210 test.done();2211};2212exports["test: esnext generator as es5"] = function (test) {2213 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72214 var code = [2215 "function* fib() {",2216 " var i = 0, j = 1;",2217 " while (true) {",2218 " yield i;",2219 " [i, j] = [j, i + j];",2220 " }",2221 "}",2222 "var g = fib();",2223 "for (var i = 0; i < 10; i++)",2224 " print(g.next());"2225 ];2226 TestRun(test)2227 .addError(1, "'function*' is only available in ES6 (use esnext option).")2228 .addError(4, "'yield' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2229 .addError(5, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2230 .test(code, {unused: true, undef: true, predef: ["print"]}); // es52231 test.done();2232};2233exports["test: esnext generator as legacy JS"] = function (test) {2234 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72235 var code = [2236 "function* fib() {",2237 " var i = 0, j = 1;",2238 " while (true) {",2239 " yield i;",2240 " [i, j] = [j, i + j];",2241 " }",2242 "}",2243 "var g = fib();",2244 "for (var i = 0; i < 10; i++)",2245 " print(g.next());"2246 ];2247 TestRun(test)2248 .addError(1, "'function*' is only available in ES6 (use esnext option).")2249 .addError(4, "'yield' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2250 .addError(5, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2251 .test(code, {es3: true, unused: true, undef: true, predef: ["print"]});2252 test.done();2253};2254exports["test: esnext generator without yield"] = function (test) {2255 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72256 var code = [2257 "function* fib() {",2258 " var i = 0, j = 1;",2259 " while (true) {",2260 " [i, j] = [j, i + j];",2261 " return i;",2262 " }",2263 "}",2264 "var g = fib();",2265 "for (let i = 0; i < 10; i++)",2266 " print(g.next());"2267 ];2268 TestRun(test)2269 .addError(7, "A generator function shall contain a yield statement.")2270 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});2271 test.done();2272};2273exports["test: esnext generator without yield and check turned off"] = function (test) {2274 var code = [2275 "function* emptyGenerator() {}",2276 "emptyGenerator();"2277 ];2278 TestRun(test)2279 .test(code, {esnext: true, noyield: true, unused: true, undef: true, predef: ["print"]});2280 test.done();2281};2282exports["test: mozilla generator"] = function (test) {2283 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72284 var code = [2285 "function fib() {",2286 " var i = 0, j = 1;",2287 " while (true) {",2288 " yield i;",2289 " [i, j] = [j, i + j];",2290 " }",2291 "}",2292 "var g = fib();",2293 "for (let i = 0; i < 10; i++)",2294 " print(g.next());"2295 ];2296 TestRun(test)2297 .test(code, {moz: true, unused: true, undef: true, predef: ["print", "Iterator"]});2298 test.done();2299};2300exports["test: mozilla generator as esnext"] = function (test) {2301 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72302 var code = [2303 "function fib() {",2304 " var i = 0, j = 1;",2305 " while (true) {",2306 " yield i;",2307 " [i, j] = [j, i + j];",2308 " }",2309 "}",2310 "var g = fib();",2311 "for (let i = 0; i < 10; i++)",2312 " print(g.next());"2313 ];2314 TestRun(test)2315 .addError(4,2316 "A yield statement shall be within a generator function (with syntax: `function*`)")2317 .test(code, {esnext: true, unused: true, undef: true, predef: ["print", "Iterator"]});2318 test.done();2319};2320exports["test: yield statement within try-catch"] = function (test) {2321 // see issue: https://github.com/jshint/jshint/issues/15052322 var code = [2323 "function* fib() {",2324 " try {",2325 " yield 1;",2326 " } catch (err) {",2327 " yield err;",2328 " }",2329 "}",2330 "var g = fib();",2331 "for (let i = 0; i < 10; i++)",2332 " print(g.next());"2333 ];2334 TestRun(test)2335 .test(code, {esnext: true, unused: true, undef: true, predef: ["print", "Iterator"]});2336 test.done();2337};2338exports["test: mozilla generator as es5"] = function (test) {2339 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72340 var code = [2341 "function fib() {",2342 " var i = 0, j = 1;",2343 " while (true) {",2344 " yield i;",2345 " [i, j] = [j, i + j];",2346 " }",2347 "}",2348 "var g = fib();",2349 "for (let i = 0; i < 10; i++)",2350 " print(g.next());"2351 ];2352 TestRun(test)2353 .addError(4, "'yield' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2354 .addError(5, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2355 .addError(9, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2356 .test(code, {unused: true, undef: true, predef: ["print", "Iterator"]}); // es52357 test.done();2358};2359exports["test: mozilla generator as legacy JS"] = function (test) {2360 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72361 var code = [2362 "function fib() {",2363 " var i = 0, j = 1;",2364 " while (true) {",2365 " yield i;",2366 " [i, j] = [j, i + j];",2367 " }",2368 "}",2369 "var g = fib();",2370 "for (let i = 0; i < 10; i++)",2371 " print(g.next());"2372 ];2373 TestRun(test)2374 .addError(4, "'yield' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2375 .addError(5, "'destructuring assignment' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2376 .addError(9, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2377 .test(code, {es3: true, unused: true, undef: true, predef: ["print", "Iterator"]});2378 test.done();2379};2380exports["test: array comprehension"] = function (test) {2381 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72382 var code = [2383 "function *range(begin, end) {",2384 " for (let i = begin; i < end; ++i) {",2385 " yield i;",2386 " }",2387 "}",2388 "var ten_squares = [for (i of range(0, 10)) i * i];",2389 "var evens = [for (i of range(0, 21)) if (i % 2 === 0) i];",2390 "print('squares:', ten_squares);",2391 "print('evens:', evens);"2392 ];2393 TestRun(test)2394 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});2395 test.done();2396};2397exports["test: moz-style array comprehension"] = function (test) {2398 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72399 var code = [2400 "function range(begin, end) {",2401 " for (let i = begin; i < end; ++i) {",2402 " yield i;",2403 " }",2404 "}",2405 "var ten_squares = [i * i for each (i in range(0, 10))];",2406 "var evens = [i for each (i in range(0, 21)) if (i % 2 === 0)];",2407 "print('squares:', ten_squares);",2408 "print('evens:', evens);"2409 ];2410 TestRun(test)2411 .test(code, {moz: true, unused: true, undef: true, predef: ["print"]});2412 test.done();2413};2414exports["test: array comprehension with for..of"] = function (test) {2415 // example adapted from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72416 var code = [2417 "function *range(begin, end) {",2418 " for (let i = begin; i < end; ++i) {",2419 " yield i;",2420 " }",2421 "}",2422 "var ten_squares = [for (i of range(0, 10)) i * i];",2423 "var evens = [for (i of range(0, 21)) if (i % 2 === 0) i];",2424 "print('squares:', ten_squares);",2425 "print('evens:', evens);"2426 ];2427 TestRun(test)2428 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});2429 test.done();2430};2431exports["test: moz-style array comprehension with for..of"] = function (test) {2432 // example adapted from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72433 var code = [2434 "function range(begin, end) {",2435 " for (let i = begin; i < end; ++i) {",2436 " yield i;",2437 " }",2438 "}",2439 "var ten_squares = [i * i for (i of range(0, 10))];",2440 "var evens = [i for (i of range(0, 21)) if (i % 2 === 0)];",2441 "print('squares:', ten_squares);",2442 "print('evens:', evens);"2443 ];2444 TestRun(test)2445 .test(code, {moz: true, unused: true, undef: true, predef: ["print"]});2446 test.done();2447};2448exports["test: array comprehension with unused variables"] = function (test) {2449 var code = [2450 "var ret = [for (i of unknown) i];",2451 "print('ret:', ret);",2452 ];2453 TestRun(test)2454 .addError(1, "'unknown' is not defined.")2455 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});2456 test.done();2457};2458exports["test: moz-style array comprehension with unused variables"] = function (test) {2459 var code = [2460 "var ret = [i for (i of unknown)];",2461 "print('ret:', ret);",2462 ];2463 TestRun(test)2464 .addError(1, "'unknown' is not defined.")2465 .test(code, {moz: true, unused: true, undef: true, predef: ["print"]});2466 test.done();2467};2468exports["test: moz-style array comprehension as esnext"] = function (test) {2469 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72470 var code = [2471 "function range(begin, end) {",2472 " for (let i = begin; i < end; ++i) {",2473 " yield i;",2474 " }",2475 "}",2476 "var ten_squares = [i * i for each (i in range(0, 10))];",2477 "var evens = [i for each (i in range(0, 21)) if (i % 2 === 0)];",2478 "print('squares:', ten_squares);",2479 "print('evens:', evens);"2480 ];2481 TestRun(test)2482 .addError(3, "A yield statement shall be within a generator function (with syntax: " +2483 "`function*`)")2484 .addError(6, "Expected 'for' and instead saw 'i'.")2485 .addError(6, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2486 .addError(7, "Expected 'for' and instead saw 'i'.")2487 .addError(7, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2488 .test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});2489 test.done();2490};2491exports["test: array comprehension as es5"] = function (test) {2492 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72493 var code = [2494 "function *range(begin, end) {",2495 " for (let i = begin; i < end; ++i) {",2496 " yield i;",2497 " }",2498 "}",2499 "var ten_squares = [for (i of range(0, 10)) i * i];",2500 "var evens = [for (i of range(0, 21)) if (i % 2 === 0) i];",2501 "print('squares:', ten_squares);",2502 "print('evens:', evens);"2503 ];2504 TestRun(test)2505 .addError(1, "'function*' is only available in ES6 (use esnext option).")2506 .addError(2, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2507 .addError(3, "'yield' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2508 .addError(6, "'array comprehension' is only available in ES6 " +2509 "(use esnext option).")2510 .addError(7, "'array comprehension' is only available in ES6 " +2511 "(use esnext option).")2512 .test(code, {unused: true, undef: true, predef: ["print"]}); // es52513 test.done();2514};2515exports["test: moz-style array comprehension as es5"] = function (test) {2516 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72517 var code = [2518 "function range(begin, end) {",2519 " for (let i = begin; i < end; ++i) {",2520 " yield i;",2521 " }",2522 "}",2523 "var ten_squares = [i * i for each (i in range(0, 10))];",2524 "var evens = [i for each (i in range(0, 21)) if (i % 2 === 0)];",2525 "print('squares:', ten_squares);",2526 "print('evens:', evens);"2527 ];2528 TestRun(test)2529 .addError(2, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2530 .addError(3, "'yield' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2531 .addError(6, "'array comprehension' is only available in ES6 " +2532 "(use esnext option).")2533 .addError(6, "Expected 'for' and instead saw 'i'.")2534 .addError(6, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2535 .addError(7, "'array comprehension' is only available in ES6 " +2536 "(use esnext option).")2537 .addError(7, "Expected 'for' and instead saw 'i'.")2538 .addError(7, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2539 .test(code, {unused: true, undef: true, predef: ["print"]}); // es52540 test.done();2541};2542exports["test: array comprehension as legacy JS"] = function (test) {2543 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72544 var code = [2545 "function range(begin, end) {",2546 " for (let i = begin; i < end; ++i) {",2547 " yield i;",2548 " }",2549 "}",2550 "var ten_squares = [for (i of range(0, 10)) i * i];",2551 "var evens = [for (i of range(0, 21)) if (i % 2 === 0) i];",2552 "print('squares:', ten_squares);",2553 "print('evens:', evens);"2554 ];2555 TestRun(test)2556 .addError(2, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2557 .addError(3, "'yield' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2558 .addError(6, "'array comprehension' is only available in ES6 " +2559 "(use esnext option).")2560 .addError(7, "'array comprehension' is only available in ES6 " +2561 "(use esnext option).")2562 .test(code, {es3: true, unused: true, undef: true, predef: ["print"]});2563 test.done();2564};2565exports["test: moz-style array comprehension as legacy JS"] = function (test) {2566 // example taken from https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.72567 var code = [2568 "function range(begin, end) {",2569 " for (let i = begin; i < end; ++i) {",2570 " yield i;",2571 " }",2572 "}",2573 "var ten_squares = [i * i for each (i in range(0, 10))];",2574 "var evens = [i for each (i in range(0, 21)) if (i % 2 === 0)];",2575 "print('squares:', ten_squares);",2576 "print('evens:', evens);"2577 ];2578 TestRun(test)2579 .addError(2, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2580 .addError(3, "'yield' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2581 .addError(6, "'array comprehension' is only available in ES6 " +2582 "(use esnext option).")2583 .addError(6, "Expected 'for' and instead saw 'i'.")2584 .addError(6, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2585 .addError(7, "'array comprehension' is only available in ES6 " +2586 "(use esnext option).")2587 .addError(7, "Expected 'for' and instead saw 'i'.")2588 .addError(7, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2589 .test(code, {es3: true, unused: true, undef: true, predef: ["print"]});2590 test.done();2591};2592exports['test: array comprehension with dest array at global scope'] = function (test) {2593 var code = [2594 "[for ([i, j] of [[0,0], [1,1], [2,2]]) [i, j] ];",2595 "var destarray_comparray_1 = [for ([i, j] of [[0,0], [1,1], [2,2]]) [i, [j, j] ]];",2596 "var destarray_comparray_2 = [for ([i, j] of [[0,0], [1,1], [2,2]]) [i, {i: [i, j]} ]];",2597 ];2598 TestRun(test)2599 .test(code, {esnext: true, undef: true, predef: ["print"]});2600 test.done();2601};2602exports['test: moz-style array comprehension with dest array at global scope'] = function (test) {2603 var code = [2604 "[ [i, j] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2605 "var destarray_comparray_1 = [ [i, [j, j] ] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2606 "var destarray_comparray_2 = [ [i, {i: [i, j]} ] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2607 ];2608 TestRun(test)2609 .test(code, {moz: true, undef: true, predef: ["print"]});2610 test.done();2611};2612exports['test: moz-style array comprehension with dest array at global scope as esnext'] = function (test) {2613 var code = [2614 "[ [i, j] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2615 "var destarray_comparray_1 = [ [i, [j, j] ] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2616 "var destarray_comparray_2 = [ [i, {i: [i, j]} ] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2617 ];2618 TestRun(test)2619 .addError(1, "Expected 'for' and instead saw '['.")2620 .addError(1, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2621 .addError(2, "Expected 'for' and instead saw '['.")2622 .addError(2, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2623 .addError(3, "Expected 'for' and instead saw '['.")2624 .addError(3, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2625 .test(code, {esnext: true, undef: true, predef: ["print"]});2626 test.done();2627};2628exports['test: array comprehension with dest array at global scope as es5'] = function (test) {2629 var code = [2630 "[for ([i, j] of [[0,0], [1,1], [2,2]]) [i, j] ];",2631 "var destarray_comparray_1 = [for ([i, j] of [[0,0], [1,1], [2,2]]) [i, [j, j] ] ];",2632 "var destarray_comparray_2 = [for ([i, j] of [[0,0], [1,1], [2,2]]) [i, {i: [i, j]} ] ];",2633 ];2634 TestRun(test)2635 .addError(1, "'array comprehension' is only available in ES6 " +2636 "(use esnext option).")2637 .addError(2, "'array comprehension' is only available in ES6 " +2638 "(use esnext option).")2639 .addError(3, "'array comprehension' is only available in ES6 " +2640 "(use esnext option).")2641 .test(code, {undef: true, predef: ["print"]}); // es52642 test.done();2643};2644exports['test: moz-style array comprehension with dest array at global scope as es5'] = function (test) {2645 var code = [2646 "[ [i, j] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2647 "var destarray_comparray_1 = [ [i, [j, j] ] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2648 "var destarray_comparray_2 = [ [i, {i: [i, j]} ] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2649 ];2650 TestRun(test)2651 .addError(1, "'array comprehension' is only available in ES6 " +2652 "(use esnext option).")2653 .addError(1, "Expected 'for' and instead saw '['.")2654 .addError(1, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2655 .addError(2, "'array comprehension' is only available in ES6 " +2656 "(use esnext option).")2657 .addError(2, "Expected 'for' and instead saw '['.")2658 .addError(2, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2659 .addError(3, "'array comprehension' is only available in ES6 " +2660 "(use esnext option).")2661 .addError(3, "Expected 'for' and instead saw '['.")2662 .addError(3, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2663 .test(code, {undef: true, predef: ["print"]}); // es52664 test.done();2665};2666exports['test: array comprehension with dest array at global scope as JS legacy'] = function (test) {2667 var code = [2668 "[for ([i, j] of [[0,0], [1,1], [2,2]]) [i, j] ];",2669 "var destarray_comparray_1 = [for ([i, j] of [[0,0], [1,1], [2,2]]) [i, [j, j] ] ];",2670 "var destarray_comparray_2 = [for ([i, j] of [[0,0], [1,1], [2,2]]) [i, {i: [i, j]} ] ];",2671 ];2672 TestRun(test)2673 .addError(1, "'array comprehension' is only available in ES6 " +2674 "(use esnext option).")2675 .addError(2, "'array comprehension' is only available in ES6 " +2676 "(use esnext option).")2677 .addError(3, "'array comprehension' is only available in ES6 " +2678 "(use esnext option).")2679 .test(code, {es3: true, undef: true, predef: ["print"]});2680 test.done();2681};2682exports['test: moz-style array comprehension with dest array at global scope as JS legacy'] = function (test) {2683 var code = [2684 "[ [i, j] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2685 "var destarray_comparray_1 = [ [i, [j, j] ] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2686 "var destarray_comparray_2 = [ [i, {i: [i, j]} ] for each ([i, j] in [[0,0], [1,1], [2,2]])];",2687 ];2688 TestRun(test)2689 .addError(1, "'array comprehension' is only available in ES6 " +2690 "(use esnext option).")2691 .addError(1, "Expected 'for' and instead saw '['.")2692 .addError(1, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2693 .addError(2, "'array comprehension' is only available in ES6 " +2694 "(use esnext option).")2695 .addError(2, "Expected 'for' and instead saw '['.")2696 .addError(2, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2697 .addError(3, "'array comprehension' is only available in ES6 " +2698 "(use esnext option).")2699 .addError(3, "Expected 'for' and instead saw '['.")2700 .addError(3, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2701 .test(code, {es3: true, undef: true, predef: ["print"]});2702 test.done();2703};2704exports["test: array comprehension imbrication with dest array"] = function (test) {2705 var code = [2706 "[for ([i, j] of [for ([a, b] of [[2,2], [3,4]]) [a, b] ]) [i, j] ];"2707 ];2708 TestRun(test)2709 .test(code, {esnext: true, undef: true, predef: ["print"]});2710 test.done();2711};2712exports["test: moz-style array comprehension imbrication with dest array"] = function (test) {2713 var code = [2714 "[ [i, j] for ([i, j] in [[a, b] for each ([a, b] in [[2,2], [3,4]])]) ];"2715 ];2716 TestRun(test)2717 .test(code, {moz: true, undef: true, predef: ["print"]});2718 test.done();2719};2720exports["test: moz-style array comprehension imbrication with dest array using for..of"] = function (test) {2721 var code = [2722 "[ [i, j] for ([i, j] of [[a, b] for ([a, b] of [[2,2], [3,4]])]) ];"2723 ];2724 TestRun(test)2725 .test(code, {moz: true, undef: true, predef: ["print"]});2726 test.done();2727};2728exports["test: moz-style array comprehension imbrication with dest array as esnext"] = function (test) {2729 var code = [2730 "[ [i, j] for each ([i, j] in [[a, b] for each ([a, b] in [[2,2], [3,4]])]) ];"2731 ];2732 TestRun(test)2733 .addError(1, "Expected 'for' and instead saw '['.")2734 .addError(1, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2735 .test(code, {esnext: true, undef: true, predef: ["print"]});2736 test.done();2737};2738exports["test: array comprehension imbrication with dest array as es5"] = function (test) {2739 var code = [2740 "[for ([i, j] of [for ([a, b] of [[2,2], [3,4]]) [a, b] ]) [i, j] ];"2741 ];2742 TestRun(test)2743 .addError(1, "'array comprehension' is only available in ES6 " +2744 "(use esnext option).")2745 .addError(1, "'array comprehension' is only available in ES6 " +2746 "(use esnext option).")2747 .test(code, {undef: true, predef: ["print"]}); // es52748 test.done();2749};2750exports["test: moz-style array comprehension imbrication with dest array as es5"] = function (test) {2751 var code = [2752 "[for ([i, j] of [for ([a, b] of [[2,2], [3,4]]) [a, b] ]) [i, j] ];"2753 ];2754 TestRun(test)2755 .addError(1, "'array comprehension' is only available in ES6 " +2756 "(use esnext option).")2757 .addError(1, "'array comprehension' is only available in ES6 " +2758 "(use esnext option).")2759 .test(code, {undef: true, predef: ["print"]}); // es52760 test.done();2761};2762exports["test: array comprehension imbrication with dest array as legacy JS"] = function (test) {2763 var code = [2764 "[ [i, j] for each ([i, j] in [[a, b] for each ([a, b] in [[2,2], [3,4]])]) ];"2765 ];2766 TestRun(test)2767 .addError(1, "'array comprehension' is only available in ES6 " +2768 "(use esnext option).")2769 .addError(1, "'array comprehension' is only available in ES6 " +2770 "(use esnext option).")2771 .addError(1, "Expected 'for' and instead saw '['.")2772 .addError(1, "Expected 'for' and instead saw '['.")2773 .addError(1, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2774 .test(code, {es3: true, undef: true, predef: ["print"]});2775 test.done();2776};2777exports["test: moz-style array comprehension imbrication with dest array as legacy JS"] = function (test) {2778 var code = [2779 "[ [i, j] for each ([i, j] in [[a, b] for each ([a, b] in [[2,2], [3,4]])]) ];"2780 ];2781 TestRun(test)2782 .addError(1, "'array comprehension' is only available in ES6 " +2783 "(use esnext option).")2784 .addError(1, "'array comprehension' is only available in ES6 " +2785 "(use esnext option).")2786 .addError(1, "Expected 'for' and instead saw '['.")2787 .addError(1, "Expected 'for' and instead saw '['.")2788 .addError(1, "'for each' is only available in Mozilla JavaScript extensions (use moz option).")2789 .test(code, {es3: true, undef: true, predef: ["print"]});2790 test.done();2791};2792exports["test: no false positive array comprehension"] = function (test) {2793 var code = [2794 "var foo = []; for (let i in [1,2,3]) { print(i); }"2795 ];2796 TestRun(test)2797 .test(code, {moz: true, undef: true, predef: ["print"]});2798 test.done();2799};2800exports["try catch filters"] = function (test) {2801 var code = [2802 "try {",2803 " throw {name: 'foo', message: 'bar'};",2804 "}",2805 "catch (e if e.name === 'foo') {",2806 " print (e.message);",2807 "}"2808 ];2809 TestRun(test)2810 .test(code, {moz: true, undef: true, predef: ["print"]});2811 test.done();2812};2813exports["try catch filters as esnext"] = function (test) {2814 var code = [2815 "try {",2816 " throw {name: 'foo', message: 'bar'};",2817 "}",2818 "catch (e if e.name === 'foo') {",2819 " print (e.message);",2820 "}"2821 ];2822 TestRun(test)2823 .addError(4, "'catch filter' is only available in Mozilla JavaScript extensions " +2824 "(use moz option).")2825 .test(code, {esnext: true, undef: true, predef: ["print"]});2826 test.done();2827};2828exports["try catch filters as es5"] = function (test) {2829 var code = [2830 "try {",2831 " throw {name: 'foo', message: 'bar'};",2832 "}",2833 "catch (e if e.name === 'foo') {",2834 " print (e.message);",2835 "}"2836 ];2837 TestRun(test)2838 .addError(4, "'catch filter' is only available in Mozilla JavaScript extensions " +2839 "(use moz option).")2840 .test(code, {undef: true, predef: ["print"]}); // es52841 test.done();2842};2843exports["try catch filters as legacy JS"] = function (test) {2844 var code = [2845 "try {",2846 " throw {name: 'foo', message: 'bar'};",2847 "}",2848 "catch (e if e.name === 'foo') {",2849 " print (e.message);",2850 "}"2851 ];2852 TestRun(test)2853 .addError(4, "'catch filter' is only available in Mozilla JavaScript extensions " +2854 "(use moz option).")2855 .test(code, {es3: true, undef: true, predef: ["print"]});2856 test.done();2857};2858exports["test: function closure expression"] = function (test) {2859 var code = [2860 "let (arr = [1,2,3]) {",2861 " arr.every(function (o) o instanceof Object);",2862 "}"2863 ];2864 TestRun(test)2865 .test(code, {es3: true, moz: true, undef: true});2866 test.done();2867};2868exports["test: function closure expression as esnext"] = function (test) {2869 var code = [2870 "var arr = [1,2,3];",2871 "arr.every(function (o) o instanceof Object);",2872 ];2873 TestRun(test)2874 .addError(2, "'function closure expressions' is only available in Mozilla JavaScript " +2875 "extensions (use moz option).")2876 .test(code, {esnext: true, undef: true});2877 test.done();2878};2879exports["test: function closure expression as es5"] = function (test) {2880 var code = [2881 "var arr = [1,2,3];",2882 "arr.every(function (o) o instanceof Object);",2883 ];2884 TestRun(test)2885 .addError(2, "'function closure expressions' is only available in Mozilla JavaScript " +2886 "extensions (use moz option).")2887 .test(code, {undef: true}); // es52888 test.done();2889};2890exports["test: function closure expression as legacy JS"] = function (test) {2891 var code = [2892 "var arr = [1,2,3];",2893 "arr.every(function (o) o instanceof Object);",2894 ];2895 TestRun(test)2896 .addError(2, "'function closure expressions' is only available in Mozilla JavaScript " +2897 "extensions (use moz option).")2898 .test(code, {es3: true, undef: true});2899 test.done();2900};2901exports["test: for of as esnext"] = function (test) {2902 var code = [2903 "for (let x of [1,2,3,4]) {",2904 " print(x);",2905 "}",2906 "for (let x of [1,2,3,4]) print(x);"2907 ];2908 TestRun(test)2909 .test(code, {esnext: true, undef: true, predef: ["print"]});2910 test.done();2911};2912exports["test: for of as es5"] = function (test) {2913 var code = [2914 "for (let x of [1,2,3,4]) {",2915 " print(x);",2916 "}",2917 "for (let x of [1,2,3,4]) print(x);"2918 ];2919 TestRun(test)2920 .addError(1, "'for of' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2921 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2922 .addError(4, "'for of' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2923 .addError(4, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2924 .test(code, {undef: true, predef: ["print"]}); // es52925 test.done();2926};2927exports["test: for of as legacy JS"] = function (test) {2928 var code = [2929 "for (let x of [1,2,3,4]) {",2930 " print(x);",2931 "}",2932 "for (let x of [1,2,3,4]) print(x);"2933 ];2934 TestRun(test)2935 .addError(1, "'for of' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2936 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2937 .addError(4, "'for of' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2938 .addError(4, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")2939 .test(code, {undef: true, predef: ["print"]}); // es52940 test.done();2941};2942exports["test: try multi-catch for moz extensions"] = function (test) {2943 var code = [2944 "try {",2945 " print('X');",2946 "} catch (err) {",2947 " print(err);",2948 "} catch (err) {",2949 " print(err);",2950 "} finally {",2951 " print('Z');",2952 "}"2953 ];2954 TestRun(test)2955 .test(code, {moz: true, undef: true, predef: ["print"]});2956 test.done();2957};2958exports["test: try multi-catch as esnext"] = function (test) {2959 var code = [2960 "try {",2961 " print('X');",2962 "} catch (err) {",2963 " print(err);",2964 "} catch (err) {",2965 " print(err);",2966 "} finally {",2967 " print('Z');",2968 "}"2969 ];2970 TestRun(test)2971 .addError(5, "'multiple catch blocks' is only available in Mozilla JavaScript extensions " +2972 "(use moz option).")2973 .test(code, {esnext: true, undef: true, predef: ["print"]});2974 test.done();2975};2976exports["test: try multi-catch as es5"] = function (test) {2977 var code = [2978 "try {",2979 " print('X');",2980 "} catch (err) {",2981 " print(err);",2982 "} catch (err) {",2983 " print(err);",2984 "} finally {",2985 " print('Z');",2986 "}"2987 ];2988 TestRun(test)2989 .addError(5, "'multiple catch blocks' is only available in Mozilla JavaScript extensions " +2990 "(use moz option).")2991 .test(code, {undef: true, predef: ["print"]}); // es52992 test.done();2993};2994exports["test: try multi-catch as legacy JS"] = function (test) {2995 var code = [2996 "try {",2997 " print('X');",2998 "} catch (err) {",2999 " print(err);",3000 "} catch (err) {",3001 " print(err);",3002 "} finally {",3003 " print('Z');",3004 "}"3005 ];3006 TestRun(test)3007 .addError(5, "'multiple catch blocks' is only available in Mozilla JavaScript extensions " +3008 "(use moz option).")3009 .test(code, {es3: true, undef: true, predef: ["print"]});3010 test.done();3011};3012exports["test: no let not directly within a block"] = function (test) {3013 var code = [3014 "if (true) let x = 1;",3015 "function foo() {",3016 " if (true)",3017 " let x = 1;",3018 "}",3019 "if (true) let (x = 1) print(x);",3020 "for (let x = 0; x < 42; ++x) let a = 1;",3021 "for (let x in [1, 2, 3, 4] ) let a = 1;",3022 "for (let x of [1, 2, 3, 4] ) let a = 1;",3023 "while (true) let a = 1;",3024 "if (false) let a = 1; else if (true) let a = 1; else let a = 2;"3025 ];3026 TestRun(test)3027 .addError(1, "Let declaration not directly within block.")3028 .addError(4, "Let declaration not directly within block.")3029 .addError(7, "Let declaration not directly within block.")3030 .addError(8, "Let declaration not directly within block.")3031 .addError(9, "Let declaration not directly within block.")3032 .addError(10, "Let declaration not directly within block.")3033 .addError(11, "Let declaration not directly within block.")3034 .addError(11, "Let declaration not directly within block.")3035 .addError(11, "Let declaration not directly within block.")3036 .test(code, {moz: true, predef: ["print"]});3037 test.done();3038};3039exports["regression test for crash from GH-964"] = function (test) {3040 var code = [3041 "function test(a, b) {",3042 " return a[b] || a[b] = new A();",3043 "}"3044 ];3045 TestRun(test)3046 .addError(2, "Bad assignment.")3047 .addError(2, "Expected an operator and instead saw 'new'.")3048 .addError(2, "Missing semicolon.")3049 .test(code);3050 test.done();3051};3052exports["automatic comma insertion GH-950"] = function (test) {3053 var code = [3054 "var a = b",3055 "instanceof c;",3056 "var a = { b: 'X' }",3057 "delete a.b",3058 "var y = true",3059 " && true && false;",3060 "function test() {",3061 " return",3062 " { a: 1 }",3063 "}",3064 ];3065 var run = TestRun(test)3066 .addError(2, "Bad line breaking before 'instanceof'.")3067 .addError(6, "Bad line breaking before '&&'.")3068 .addError(8, "Line breaking error 'return'.")3069 .addError(9, "Label 'a' on 1 statement.")3070 .addError(9, "Expected an assignment or function call and instead saw an expression.");3071 run.test(code, {es3: true, asi: true});3072 run.test(code, {asi: true}); // es53073 run.test(code, {esnext: true, asi: true});3074 run.test(code, {moz: true, asi: true});3075 run = TestRun(test)3076 .addError(2, "Bad line breaking before 'instanceof'.")3077 .addError(3, "Missing semicolon.")3078 .addError(4, "Missing semicolon.")3079 .addError(6, "Bad line breaking before '&&'.")3080 .addError(8, "Line breaking error 'return'.")3081 .addError(8, "Missing semicolon.")3082 .addError(9, "Label 'a' on 1 statement.")3083 .addError(9, "Expected an assignment or function call and instead saw an expression.")3084 .addError(9, "Missing semicolon.");3085 run.test(code, {es3: true, asi: false});3086 run.test(code, {asi: false}); // es53087 run.test(code, {esnext: true, asi: false});3088 run.test(code, {moz: true, asi: false});3089 test.done();3090};3091exports["fat arrows support"] = function (test) {3092 var code = [3093 "let empty = () => {};",3094 "let identity = x => x;",3095 "let square = x => x * x;",3096 "let key_maker = val => ({key: val});",3097 "let odds = evens.map(v => v + 1);",3098 "let fives = []; nats.forEach(v => { if (v % 5 === 0) fives.push(v); });",3099 "let block = (x,y, { z: t }) => {",3100 " print(x,y,z);",3101 " print(j, t);",3102 "};",3103 // using lexical this3104 "const obj = {",3105 " method: function () {",3106 " return () => this;",3107 " }",3108 "};",3109 "let retnObj = () => ({});",3110 "let assgnRetnObj = (() => ({}))();",3111 "let retnObjLong = () => { return {}; };",3112 "let assgnRetnObjLong = (() => { return {}; })();",3113 "let objFns = {",3114 " retnObj: () => ({}),",3115 " assgnRetnObj: (() => ({}))(),",3116 " retnObjLong: () => { return {}; },",3117 " assgnRetnObjLong: (() => { return {}; })()",3118 "};"3119 ];3120 var run = TestRun(test)3121 .addError(5, "'evens' is not defined.")3122 .addError(6, "'nats' is not defined.")3123 .addError(8, "'print' is not defined.")3124 .addError(9, "'print' is not defined.")3125 .addError(9, "'j' is not defined.")3126 .addError(8, "'z' is not defined.");3127 run.test(code, { undef: true, esnext: true });3128 run = TestRun(test)3129 .addError(1, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3130 .addError(2, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3131 .addError(3, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3132 .addError(4, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3133 .addError(5, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3134 .addError(5, "'evens' is not defined.")3135 .addError(6, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3136 .addError(6, "'nats' is not defined.")3137 .addError(7, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3138 .addError(8, "'print' is not defined.")3139 .addError(8, "'z' is not defined.")3140 .addError(9, "'print' is not defined.")3141 .addError(9, "'j' is not defined.")3142 .addError(13, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3143 .addError(16, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3144 .addError(17, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3145 .addError(17, "Bad invocation.")3146 .addError(18, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3147 .addError(19, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3148 .addError(19, "Bad invocation.")3149 .addError(21, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3150 .addError(22, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3151 .addError(22, "Bad invocation.")3152 .addError(23, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3153 .addError(24, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3154 .addError(24, "Bad invocation.");3155 run.test(code, { undef: true, moz: true });3156 run = TestRun(test)3157 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3158 .addError(1, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3159 .addError(2, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3160 .addError(2, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3161 .addError(3, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3162 .addError(3, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3163 .addError(4, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3164 .addError(4, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3165 .addError(5, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3166 .addError(5, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3167 .addError(6, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3168 .addError(6, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3169 .addError(7, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3170 .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3171 .addError(7, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3172 .addError(11, "'const' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3173 .addError(13, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3174 .addError(16, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3175 .addError(16, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3176 .addError(17, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3177 .addError(17, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3178 .addError(17, "Bad invocation.")3179 .addError(18, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3180 .addError(18, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3181 .addError(19, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3182 .addError(19, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3183 .addError(19, "Bad invocation.")3184 .addError(20, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3185 .addError(21, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3186 .addError(22, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3187 .addError(22, "Bad invocation.")3188 .addError(23, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3189 .addError(24, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3190 .addError(24, "Bad invocation.");3191 run.test(code); // es53192 run.test(code, {es3: true});3193 test.done();3194};3195exports["concise methods support"] = function (test) {3196 var code = [3197 "var foobar = {",3198 " foo () {",3199 " return 'foo';",3200 " },",3201 " *bar () {",3202 " yield 'bar';",3203 " }",3204 "};"3205 ];3206 var run = TestRun(test);3207 run.test(code, {esnext: true});3208 run.test(code, {moz: true});3209 run = TestRun(test)3210 .addError(2, "'concise methods' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3211 .addError(5, "'generator functions' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3212 .addError(5, "'concise methods' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3213 .addError(6, "'yield' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).");3214 run.test(code); // es53215 run.test(code, {es3: true});3216 test.done();3217};3218exports["concise methods support for 'get' and 'set' function names"] = function (test) {3219 var code = [3220 "var a = [1, 2, 3, 4, 5];",3221 "var strange = {",3222 " get (i) {",3223 " return a[i];",3224 " },",3225 " set () {",3226 " a.forEach(function(v, i, l) { l[i] = v++; });",3227 " }",3228 "};"3229 ];3230 TestRun(test).test(code, {esnext: true});3231 test.done();3232};3233exports["concise methods support for 'get' without 'set'"] = function (test) {3234 var code = [3235 "var a = [1, 2, 3, 4, 5];",3236 "var strange = {",3237 " get () {",3238 " return a;",3239 " }",3240 "};"3241 ];3242 TestRun(test).test(code, {esnext: true});3243 test.done();3244};3245exports["concise methods support for 'set' without 'get'"] = function (test) {3246 var code = [3247 "var a = [1, 2, 3, 4, 5];",3248 "var strange = {",3249 " set (v) {",3250 " a = v;",3251 " }",3252 "};"3253 ];3254 TestRun(test).test(code, {esnext: true});3255 test.done();3256};3257exports["object short notation: basic"] = function (test) {3258 var code = [3259 "var foo = 42;",3260 "var bar = {foo};",3261 "var baz = {foo, bar};"3262 ];3263 TestRun(test).test(code, {esnext: true});3264 TestRun(test)3265 .addError(2, "'object short notation' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3266 .addError(3, "'object short notation' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3267 .test(code);3268 test.done();3269};3270exports["object short notation: mixed"] = function (test) {3271 var code = [3272 "var b = 1, c = 2;",3273 "var o1 = {a: 1, b, c};",3274 "var o2 = {b, a: 1, c};"3275 ].join("\n");3276 TestRun(test).test(code, { esnext: true });3277 TestRun(test)3278 .addError(2, "'object short notation' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3279 .addError(2, "'object short notation' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3280 .addError(3, "'object short notation' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3281 .addError(3, "'object short notation' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3282 .test(code);3283 test.done();3284};3285exports["spread & rest operator support"] = function (test) {3286 var code = [3287 // spread operator3288 "function foo(a, b, c) {",3289 " console.log(a, b, c); ",3290 "}",3291 "var args = [ 0, 1, 2 ];",3292 "foo(...args);",3293 // spread operator3294 "let initial = [ 1, 2, 3, 4, 5 ];",3295 "let extended = [ ...initial, 6, 7, 8, 9 ];",3296 // rest operator3297 "(function foo(i, j, ...args) {",3298 " return args;",3299 "}());",3300 // rest operator on a fat arrow function3301 "let bar = (...args) => args;"3302 ];3303 var run = TestRun(test);3304 run.test(code, {esnext: true});3305 run = TestRun(test)3306 .addError(11, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3307 .addError(5, "'spread/rest operator' is only available in ES6 (use esnext option).")3308 .addError(7, "'spread/rest operator' is only available in ES6 (use esnext option).")3309 .addError(8, "'spread/rest operator' is only available in ES6 (use esnext option).")3310 .addError(11, "'spread/rest operator' is only available in ES6 (use esnext option).");3311 run.test(code, {moz: true});3312 run = TestRun(test)3313 .addError(5, "'spread/rest operator' is only available in ES6 (use esnext option).")3314 .addError(6, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3315 .addError(7, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3316 .addError(7, "'spread/rest operator' is only available in ES6 (use esnext option).")3317 .addError(8, "'spread/rest operator' is only available in ES6 (use esnext option).")3318 .addError(11, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3319 .addError(11, "'spread/rest operator' is only available in ES6 (use esnext option).")3320 .addError(11, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).");3321 run.test(code);3322 test.done();3323};3324exports["parameter destructuring with rest"] = function (test) {3325 var code = [3326 // 13327 // parameter destructuring with rest operator, solo3328 "let b = ([...args]) => args;",3329 // 23330 // ...in function expression3331 "let c = function([...args]) { return args; };",3332 // 33333 // ...in function declaration3334 "function d([...args]) { return args; }",3335 // 43336 // default destructuring with rest operator, with leading param3337 "let e = ([first, ...args]) => args;",3338 // 53339 // ...in function expression3340 "let f = function([first, ...args]) { return args; };",3341 // 63342 // ...in function declaration3343 "function g([first, ...args]) { return args; }",3344 // 73345 // Just rest3346 "let h = (...args) => args;",3347 // 83348 // ...in function expression3349 "let i = function(...args) { return args; };",3350 // 93351 // ...in function declaration3352 "function j(...args) { return args; }"3353 ];3354 var run = TestRun(test);3355 run.test(code, {esnext: true});3356 run = TestRun(test)3357 .addError(1, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3358 .addError(1, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3359 .addError(4, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3360 .addError(7, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3361 .addError(7, "'spread/rest operator' is only available in ES6 (use esnext option).")3362 .addError(1, "'spread/rest operator' is only available in ES6 (use esnext option).")3363 .addError(1, "'spread/rest operator' is only available in ES6 (use esnext option).")3364 .addError(2, "'spread/rest operator' is only available in ES6 (use esnext option).")3365 .addError(2, "'spread/rest operator' is only available in ES6 (use esnext option).")3366 .addError(3, "'spread/rest operator' is only available in ES6 (use esnext option).")3367 .addError(3, "'spread/rest operator' is only available in ES6 (use esnext option).")3368 .addError(4, "'spread/rest operator' is only available in ES6 (use esnext option).")3369 .addError(4, "'spread/rest operator' is only available in ES6 (use esnext option).")3370 .addError(5, "'spread/rest operator' is only available in ES6 (use esnext option).")3371 .addError(5, "'spread/rest operator' is only available in ES6 (use esnext option).")3372 .addError(6, "'spread/rest operator' is only available in ES6 (use esnext option).")3373 .addError(6, "'spread/rest operator' is only available in ES6 (use esnext option).")3374 .addError(8, "'spread/rest operator' is only available in ES6 (use esnext option).")3375 .addError(9, "'spread/rest operator' is only available in ES6 (use esnext option).");3376 run.test(code, {moz: true});3377 run = TestRun(test)3378 .addError(1, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3379 .addError(1, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3380 .addError(1, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3381 .addError(1, "'spread/rest operator' is only available in ES6 (use esnext option).")3382 .addError(2, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3383 .addError(2, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3384 .addError(2, "'spread/rest operator' is only available in ES6 (use esnext option).")3385 .addError(3, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3386 .addError(3, "'spread/rest operator' is only available in ES6 (use esnext option).")3387 .addError(4, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3388 .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3389 .addError(4, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3390 .addError(4, "'spread/rest operator' is only available in ES6 (use esnext option).")3391 .addError(5, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3392 .addError(5, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3393 .addError(5, "'spread/rest operator' is only available in ES6 (use esnext option).")3394 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3395 .addError(6, "'spread/rest operator' is only available in ES6 (use esnext option).")3396 .addError(7, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3397 .addError(7, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3398 .addError(7, "'spread/rest operator' is only available in ES6 (use esnext option).")3399 .addError(8, "'let' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3400 .addError(8, "'spread/rest operator' is only available in ES6 (use esnext option).")3401 .addError(9, "'spread/rest operator' is only available in ES6 (use esnext option).");3402 run.test(code);3403 test.done();3404};3405exports["test for GH-1010"] = function (test) {3406 var code = [3407 "var x = 20, y, z; if(x < 30) y=7, z=2; else y=5;"3408 ];3409 var run = TestRun(test);3410 run.test(code, {expr: true, es3: true});3411 run.test(code, {expr: true}); // es53412 run.test(code, {expr: true, esnext: true});3413 run.test(code, {expr: true, moz: true});3414 test.done();3415};3416exports.classes = function (test) {3417 var cdecl = "// cdecl";3418 var cexpr = "// cexpr";3419 var cdeclAssn = "// cdeclAssn";3420 var cexprAssn = "// cexprAssn";3421 var code = [3422 "var Bar;",3423 // class declarations3424 cdecl,3425 "class Foo0 {}",3426 "class Foo1 extends Bar {}",3427 "class protected {",3428 " constructor(package) {}",3429 "}",3430 "class Foo3 extends interface {",3431 " constructor() {}",3432 "}",3433 "class Foo4 extends Bar {",3434 " constructor() {",3435 " super();",3436 " }",3437 "}",3438 "class Foo5 {",3439 " constructor() {",3440 " }",3441 " static create() {",3442 " }",3443 "}",3444 "class Foo6 extends Bar {",3445 " constructor() {",3446 " super();",3447 " }",3448 " static create() {",3449 " }",3450 "}",3451 // class expressions3452 cexpr,3453 "var Foo7 = class {};",3454 "let Foo8 = class extends Bar {};",3455 "var static = class protected {",3456 " constructor(package) {}",3457 "};",3458 "var Foo10 = class extends interface {",3459 " constructor() {}",3460 "};",3461 "var Foo11 = class extends Bar {",3462 " constructor() {",3463 " super();",3464 " }",3465 "};",3466 "var Foo12 = class {",3467 " constructor() {",3468 " }",3469 " static create() {",3470 " }",3471 "};",3472 "let Foo13 = class extends Bar {",3473 " constructor() {",3474 " super();",3475 " }",3476 " static create() {",3477 " }",3478 "};",3479 // mark these as used3480 "void (Foo1, Foo3, Foo4, Foo5, Foo6);",3481 "void (Foo8, Foo10, Foo11, Foo12, Foo13);",3482 // class declarations: extends AssignmentExpression3483 cdeclAssn,3484 "class Foo14 extends Bar[42] {}",3485 "class Foo15 extends { a: function() { return 42; } } {}",3486 "class Foo16 extends class Foo15 extends Bar {} {}",3487 "class Foo17 extends Foo15 = class Foo16 extends Bar {} {}",3488 "class Foo18 extends function () {} {}",3489 "class Foo19 extends class extends function () {} {} {}",3490 "class Foo20 extends Foo18 = class extends Foo17 = function () {} {} {}",3491 // class expressions: extends AssignmentExpression3492 cexprAssn,3493 "let Foo21 = class extends Bar[42] {};",3494 "let Foo22 = class extends { a() { return 42; } } {};",3495 "let Foo23 = class extends class Foo15 extends Bar {} {};",3496 "let Foo24 = class extends Foo15 = class Foo16 extends Bar {} {};",3497 "let Foo25 = class extends function () {} {};",3498 "let Foo26 = class extends class extends function () {} {} {};",3499 "let Foo27 = class extends Foo18 = class extends Foo17 = function () {} {} {};",3500 // mark these as used3501 "void (Foo14, Foo15, Foo16, Foo17, Foo18, Foo19, Foo20);",3502 "void (Foo21, Foo22, Foo23, Foo24, Foo25, Foo26, Foo27);"3503 ];3504 cdecl = code.indexOf(cdecl) + 1;3505 cexpr = code.indexOf(cexpr) + 1;3506 cdeclAssn = code.indexOf(cdeclAssn) + 1;3507 cexprAssn = code.indexOf(cexprAssn) + 1;3508 var run = TestRun(test)3509 .addError(cdecl + 4, "Expected an identifier and instead saw 'package' (a reserved word).")3510 .addError(cexpr + 4, "Expected an identifier and instead saw 'package' (a reserved word).");3511 run.test(code, {esnext: true});3512 run.test(code, {moz: true});3513 run3514 .addError(cdecl + 1, "'Foo0' is defined but never used.")3515 .addError(cdecl + 3, "Expected an identifier and instead saw 'protected' (a reserved word).")3516 .addError(cdecl + 3, "'protected' is defined but never used.")3517 .addError(cdecl + 4, "'package' is defined but never used.");3518 run3519 .addError(cexpr + 1, "'Foo7' is defined but never used.")3520 .addError(cexpr + 3, "Expected an identifier and instead saw 'static' (a reserved word).")3521 .addError(cexpr + 3, "'static' is defined but never used.")3522 .addError(cexpr + 3, "Expected an identifier and instead saw 'protected' (a reserved word).")3523 .addError(cexpr + 4, "'package' is defined but never used.");3524 code[0] = "'use strict';" + code[0];3525 run.test(code, {unused: true, globalstrict: true, esnext: true});3526 run.test(code, {unused: true, globalstrict: true, moz: true});3527 test.done();3528};3529exports["class and method naming"] = function (test) {3530 var code = [3531 "class eval {}",3532 "class arguments {}",3533 "class C {",3534 " get constructor() {}",3535 " set constructor(x) {}",3536 " prototype() {}",3537 "}"3538 ];3539 var run = TestRun(test)3540 .addError(1, "Expected an identifier and instead saw 'eval' (a reserved word).")3541 .addError(2, "Expected an identifier and instead saw 'arguments' (a reserved word).")3542 .addError(4, "A class getter method cannot be named 'constructor'.")3543 .addError(5, "A class setter method cannot be named 'constructor'.")3544 .addError(7, "A class method cannot be named 'prototype'.");3545 run.test(code, {esnext: true});3546 test.done();3547};3548exports["test for GH-1018"] = function (test) {3549 var code = [3550 "if (a = 42) {}",3551 "else if (a = 42) {}",3552 "while (a = 42) {}",3553 "for (a = 42; a = 42; a += 42) {}",3554 "do {} while (a = 42);",3555 "switch (a = 42) {}"3556 ];3557 var run = TestRun(test);3558 run.test(code, {boss: true});3559 for (var i = 0; i < code.length; i++) {3560 run.addError(i + 1, "Expected a conditional expression and instead saw an assignment.");3561 }3562 run.test(code);3563 test.done();3564};3565exports["test warnings for assignments in conditionals"] = function (test) {3566 var code = [3567 "if (a = b) { }",3568 "if ((a = b)) { }",3569 "if (a = b, a) { }",3570 "if (a = b, b = c) { }",3571 "if ((a = b, b = c)) { }",3572 "if (a = b, (b = c)) { }"3573 ];3574 var run = TestRun(test)3575 .addError(1, "Expected a conditional expression and instead saw an assignment.")3576 .addError(4, "Expected a conditional expression and instead saw an assignment.");3577 run.test(code); // es53578 test.done();3579};3580exports["test for GH-1089"] = function (test) {3581 var code = [3582 "function foo() {",3583 " 'use strict';",3584 " Object.defineProperty(foo, 'property', {",3585 " get: function() foo,",3586 " set: function(value) {},",3587 " enumerable: true",3588 " });",3589 "}",3590 "foo;"3591 ];3592 var run = TestRun(test)3593 .addError(9, "Expected an assignment or function call and instead saw an expression.");3594 run.test(code, {moz: true});3595 run3596 .addError(4, "'function closure expressions' is only available in Mozilla JavaScript " +3597 "extensions (use moz option).");3598 run.test(code);3599 test.done();3600};3601exports["test for GH-1103"] = function (test) {3602 var code = [ "var ohnoes = 42;" ];3603 var run = TestRun(test);3604 var patch = true;3605 JSHINT.addModule(function (linter) {3606 if (!patch) {3607 return;3608 }3609 patch = false;3610 var ohnoes = "oh noes";3611 Array.prototype.ohnoes = function () {3612 linter.warn("E024", { line: 1, char: 1, data: [ ohnoes += "!" ] });3613 };3614 });3615 run.test(code);3616 test.done();3617 delete Array.prototype.ohnoes;3618};3619exports["test for GH-1105"] = function (test) {3620 var code = [3621 "while (true) {",3622 " if (true) { break }",3623 "}"3624 ];3625 var run = TestRun(test)3626 .addError(2, "Missing semicolon.");3627 run.test(code);3628 test.done();3629};3630exports["test for crash with invalid condition"] = function (test) {3631 var code = [3632 "do {} while ();",3633 "do {} while (,);",3634 "do {} while (a,);",3635 "do {} while (,b);",3636 "do {} while (());",3637 "do {} while ((,));",3638 "do {} while ((a,));",3639 "do {} while ((,b));"3640 ];3641 // As long as jshint doesn't crash, it doesn't matter what these errors3642 // are. Feel free to adjust these if they don't match the output.3643 var run = TestRun(test)3644 .addError(1, "Expected an identifier and instead saw ')'.")3645 .addError(1, "Expected ')' to match '(' from line 1 and instead saw ';'.")3646 .addError(2, "Expected an identifier and instead saw ','.")3647 .addError(3, "Unexpected ')'.")3648 .addError(4, "Expected an identifier and instead saw ','.")3649 .addError(4, "Expected ')' to match '(' from line 4 and instead saw 'b'.")3650 .addError(4, "Expected an identifier and instead saw ')'.")3651 .addError(6, "Expected an identifier and instead saw ','.")3652 .addError(7, "Unexpected ')'.")3653 .addError(7, "Expected an identifier and instead saw ')'.")3654 .addError(7, "Expected ')' to match '(' from line 7 and instead saw ';'.")3655 .addError(8, "Expected an identifier and instead saw ','.")3656 .addError(8, "Expected ')' to match '(' from line 8 and instead saw 'b'.")3657 .addError(8, "Expected an identifier and instead saw ')'.");3658 run.test(code, {asi: true, expr: true});3659 test.done();3660};3661exports["test 'yield' in compound expressions."] = function (test) {3662 var code = fs.readFileSync(path.join(__dirname, "./fixtures/yield-expressions.js"), "utf8");3663 var run = TestRun(test)3664 .addError(22, "Did you mean to return a conditional instead of an assignment?")3665 .addError(31, "Did you mean to return a conditional instead of an assignment?");3666 run.test(code, {maxerr: 1000, expr: true, esnext: true});3667 // These are line-column pairs for the Mozilla paren errors.3668 var needparen = [3669 // comma3670 [ 5, 5], [ 6, 8], [ 7, 5], [11, 5], [12, 8], [13, 5],3671 // yield in yield3672 [18, 11], [19, 17], [19, 11], [20, 11], [20, 5], [21, 11], [21, 5], [21, 26], [22, 22],3673 [23, 22], [23, 11], [27, 11], [28, 17], [28, 11], [29, 11], [29, 5], [30, 11], [30, 5],3674 [30, 24], [31, 22], [32, 11], [32, 20],3675 // infix3676 [51, 10], [53, 10], [54, 16], [57, 10], [58, 5], [59, 10], [60, 5], [60, 14],3677 // prefix3678 [64, 6], [65, 7], [66, 6], [67, 7], [70, 6], [71, 7],3679 // ternary3680 [77, 5], [78, 5], [78, 13], [79, 5], [79, 13], [79, 41], [82, 5], [83, 5], [83, 13],3681 [84, 5], [84, 13], [84, 37]3682 ];3683 needparen.forEach(function (lc) {3684 run.addError(lc[0], "Mozilla requires the yield expression to be parenthesized here.",3685 {character: lc[1]});3686 });3687 run3688 .addError(1, "'function*' is only available in ES6 (use esnext option).")3689 .addError(74, "'function*' is only available in ES6 (use esnext option).");3690 run.test(code, {maxerr: 1000, expr: true, moz: true});3691 test.done();3692};3693exports["test for GH-387"] = function (test) {3694 var code = [3695 "var foo = a",3696 "delete foo.a;"3697 ];3698 var run = TestRun(test)3699 .addError(1, "Missing semicolon.");3700 run.test(code); // es53701 test.done();3702};3703exports["test for line breaks with 'yield'"] = function (test) {3704 var code = [3705 "function* F() {",3706 " a = b + (yield",3707 " c",3708 " );",3709 " d = yield",3710 " + e;",3711 " f = (yield",3712 " , g);",3713 " h = yield",3714 " ? i : j;",3715 " k = l ? yield",3716 " : m;",3717 " n = o ? p : yield",3718 " + r;",3719 "}"3720 ];3721 var run = TestRun(test)3722 .addError(3, "Bad line breaking before 'c'.")3723 .addError(6, "Bad line breaking before '+'.")3724 .addError(8, "Comma warnings can be turned off with 'laxcomma'.")3725 .addError(7, "Bad line breaking before ','.")3726 .addError(10, "Bad line breaking before '?'.")3727 .addError(14, "Bad line breaking before '+'.");3728 run.test(code, {esnext: true});3729 // Mozilla assumes the statement has ended if there is a line break3730 // following a `yield`. This naturally causes havoc with the subsequent3731 // parse.3732 //3733 // Note: there is one exception to the line-breaking rule:3734 // ```js3735 // a ? yield3736 // : b;3737 // ```3738 run = TestRun(test)3739 .addError(1, "'function*' is only available in ES6 (use esnext option).")3740 .addError(3, "Expected ')' to match '(' from line 2 and instead saw 'c'.")3741 .addError(4, "Expected an identifier and instead saw ')'.")3742 .addError(4, "Expected an assignment or function call and instead saw an expression.")3743 .addError(6, "Expected an assignment or function call and instead saw an expression.")3744 .addError(8, "Comma warnings can be turned off with 'laxcomma'.")3745 .addError(7, "Bad line breaking before ','.")3746 .addError(10, "Expected an identifier and instead saw '?'.")3747 .addError(10, "Expected an assignment or function call and instead saw an expression.")3748 .addError(10, "Label 'i' on j statement.")3749 .addError(10, "Expected an assignment or function call and instead saw an expression.")3750 .addError(14, "Expected an assignment or function call and instead saw an expression.");3751 run.test(code, {moz: true, asi: true});3752 run3753 .addError(2, "Line breaking error 'yield'.")3754 .addError(3, "Missing semicolon.")3755 .addError(5, "Line breaking error 'yield'.")3756 .addError(5, "Missing semicolon.")3757 .addError(7, "Line breaking error 'yield'.")3758 .addError(9, "Line breaking error 'yield'.")3759 .addError(9, "Missing semicolon.")3760 .addError(10, "Missing semicolon.")3761 .addError(11, "Line breaking error 'yield'.")3762 .addError(13, "Line breaking error 'yield'.")3763 .addError(13, "Missing semicolon.");3764 run.test(code, {moz: true});3765 test.done();3766};3767exports["regression for GH-1227"] = function (test) {3768 var src = fs.readFileSync(__dirname + "/fixtures/gh1227.js", "utf8");3769 TestRun(test)3770 .addError(14, "Unreachable 'return' after 'return'.")3771 .test(src);3772 test.done();3773};3774exports["test for 'break' in switch case + curly braces"] = function (test) {3775 var code = [3776 "switch (foo) {",3777 " case 1: { break; }",3778 " case 2: { return; }",3779 " case 3: { throw 'Error'; }",3780 " case 11: {",3781 " while (true) {",3782 " break;",3783 " }",3784 " }",3785 " default: break;",3786 "}"3787 ];3788 // No error for case 1, 2, 3.3789 var run = TestRun(test)3790 .addError(9, "Expected a 'break' statement before 'default'.")3791 .test(code);3792 test.done();3793};3794exports["test for 'break' in switch case in loop + curly braces"] = function (test) {3795 var code = [3796 "while (true) {",3797 " switch (foo) {",3798 " case 1: { break; }",3799 " case 2: { return; }",3800 " case 3: { throw 'Error'; }",3801 " case 4: { continue; }",3802 " case 11: {",3803 " while (true) {",3804 " break;",3805 " }",3806 " }",3807 " default: break;",3808 " }",3809 "}"3810 ];3811 // No error for case 1, 2, 3, 4.3812 var run = TestRun(test)3813 .addError(11, "Expected a 'break' statement before 'default'.")3814 .test(code);3815 test.done();3816};3817exports["allow expression with a comma in switch case condition"] = function (test) {3818 var code = [3819 "switch (false) {",3820 " case x = 1, y = x: { break; }",3821 "}"3822 ]3823 var run = TestRun(test).test(code);3824 test.done();3825};3826exports["/*jshint ignore */ should be a good option and only accept start, end or line as values"] = function (test) {3827 var code = [3828 "/*jshint ignore:start*/",3829 "/*jshint ignore:end*/",3830 "/*jshint ignore:line*/",3831 "/*jshint ignore:badvalue*/"3832 ];3833 TestRun(test)3834 .addError(4, "Bad option value.")3835 .test(code);3836 test.done();3837};3838exports["/*jshint ignore */ should allow the linter to skip blocked-out lines to continue finding errors in the rest of the code"] = function (test) {3839 var code = fs.readFileSync(__dirname + "/fixtures/gh826.js", "utf8");3840 TestRun(test)3841 .addError(33, "Use '===' to compare with '0'.")3842 .test(code);3843 test.done();3844};3845exports["/*jshint ignore */ should be detected even with leading and/or trailing whitespace"] = function (test) {3846 var code = [3847 " /*jshint ignore:start */", // leading whitespace3848 " if (true) { alert('sup') }", // should be ignored3849 " /*jshint ignore:end */ ", // leading and trailing whitespace3850 " if (true) { alert('sup') }", // should not be ignored3851 " /*jshint ignore:start */ ", // leading and trailing whitespace3852 " if (true) { alert('sup') }", // should be ignored3853 " /*jshint ignore:end */ " // leading and trailing whitespace3854 ];3855 TestRun(test)3856 .addError(4, "Missing semicolon.")3857 .test(code);3858 test.done();3859};3860exports["should be able to ignore a single line with a trailing comment: // jshint:ignore"] = function (test) {3861 var code = fs.readFileSync(__dirname + "/fixtures/gh870.js", "utf8");3862 TestRun(test).test(code, { unused: true });3863 test.done();3864};3865exports["regression test for GH-1431"] = function (test) {3866 // The code is invalid but it should not crash JSHint.3867 TestRun(test)3868 .addError(1, "Use '!==' to compare with 'null'.")3869 .addError(1, "Expected ';' and instead saw ')'.")3870 .addError(1, "Expected ')' and instead saw ';'.")3871 .addError(1, "Expected an identifier and instead saw ';'.")3872 .addError(1, "Expected ')' to match '(' from line 1 and instead saw 'i'.")3873 .addError(1, "Expected an identifier and instead saw ')'.")3874 .test("for (i=0; (arr[i])!=null); i++);");3875 test.done();3876};3877exports["jshint ignore:start/end should be detected using single line comments"] = function (test) {3878 var code = [3879 "// jshint ignore:start",3880 "var a;",3881 "// jshint ignore:end",3882 "var b;"3883 ];3884 TestRun(test)3885 .addError(4, "'b' is defined but never used.")3886 .test(code, { unused: true });3887 test.done();3888};3889exports["test destructuring function parameters as es5"] = function (test) {3890 var src = fs.readFileSync(__dirname + "/fixtures/destparam.js", "utf8");3891 TestRun(test)3892 .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3893 .addError(4, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3894 .addError(5, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3895 .addError(5, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3896 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3897 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3898 .addError(6, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3899 .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3900 .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3901 .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3902 .addError(7, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3903 .addError(10, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3904 .addError(10, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3905 .addError(11, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3906 .addError(11, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3907 .addError(14, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3908 .addError(14, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3909 .addError(15, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3910 .addError(15, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3911 .addError(16, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3912 .addError(16, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3913 .addError(16, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3914 .addError(17, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3915 .addError(17, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3916 .addError(18, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3917 .addError(18, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3918 .addError(21, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3919 .addError(21, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3920 .addError(21, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3921 .addError(22, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3922 .addError(22, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3923 .addError(22, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3924 .addError(23, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3925 .addError(23, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3926 .addError(23, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3927 .addError(24, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3928 .addError(24, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3929 .addError(24, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3930 .addError(27, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3931 .addError(27, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3932 .addError(27, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3933 .addError(28, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3934 .addError(28, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3935 .addError(28, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3936 .addError(29, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3937 .addError(29, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3938 .addError(29, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3939 .addError(30, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3940 .addError(30, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3941 .addError(30, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3942 .addError(31, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3943 .addError(31, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3944 .addError(31, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3945 .test(src, {unused: true, undef: true, maxerr: 100});3946 test.done();3947};3948exports["test destructuring function parameters as legacy JS"] = function (test) {3949 var src = fs.readFileSync(__dirname + "/fixtures/destparam.js", "utf8");3950 TestRun(test)3951 .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3952 .addError(4, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3953 .addError(5, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3954 .addError(5, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3955 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3956 .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3957 .addError(6, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3958 .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3959 .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3960 .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3961 .addError(7, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3962 .addError(10, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3963 .addError(10, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3964 .addError(11, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3965 .addError(11, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3966 .addError(14, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3967 .addError(14, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3968 .addError(15, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3969 .addError(15, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3970 .addError(16, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3971 .addError(16, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3972 .addError(16, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3973 .addError(17, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3974 .addError(17, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3975 .addError(18, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3976 .addError(18, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3977 .addError(21, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3978 .addError(21, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3979 .addError(21, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3980 .addError(22, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3981 .addError(22, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3982 .addError(22, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3983 .addError(23, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3984 .addError(23, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3985 .addError(23, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3986 .addError(24, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3987 .addError(24, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3988 .addError(24, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3989 .addError(27, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3990 .addError(27, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3991 .addError(27, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3992 .addError(28, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3993 .addError(28, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3994 .addError(28, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3995 .addError(29, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3996 .addError(29, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3997 .addError(29, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")3998 .addError(30, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")3999 .addError(30, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")4000 .addError(30, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")4001 .addError(31, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")4002 .addError(31, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")4003 .addError(31, "'arrow function syntax (=>)' is only available in ES6 (use esnext option).")4004 .test(src, {es3: true, unused: true, undef: true, maxerr: 100});4005 test.done();4006};4007exports["test for parentheses in odd-numbered token"] = function (test) {4008 var code = [4009 "let f, b;",4010 "let a = x => ({ f: f(x) });",4011 "b = x => x;"4012 ];4013 TestRun(test)4014 .test(code, {esnext: true});4015 test.done();4016};4017exports["regression crash from GH-1573"] = function (test) {4018 TestRun(test)4019 .addError(1, "Expected an identifier and instead saw 'var'.")4020 .addError(1, "Expected ']' to match '[' from line 1 and instead saw 'foo'.")4021 .addError(1, "Expected an identifier and instead saw ']'.")4022 .addError(1, "Expected an assignment or function call and instead saw an expression.")4023 .addError(1, "Missing semicolon.")4024 .test("[var foo = 1;]");4025 test.done();4026};4027exports["make sure we don't throw errors on removed options"] = function (test) {4028 TestRun(test).test("a();", { nomen: true, onevar: true, passfail: true, white: true });4029 test.done();4030};4031exports["'for of' shouldn't be subject to 'for in' rules"] = function (test) {4032 TestRun(test)4033 .test("for (let x of [1, 2, 3]) { console.log(x); }", { forin: true, esnext: true });4034 test.done();4035};4036exports["Ignore strings containing braces within array literal declarations"] = function (test) {4037 TestRun(test).test("var a = [ '[' ];");...
options.js
Source:options.js
...21exports.shadow = function (test) {22 var src = fs.readFileSync(__dirname + "/fixtures/redef.js", "utf8");23 // Do not tolerate variable shadowing by default24 TestRun(test)25 .addError(5, "'a' is already defined.")26 .addError(10, "'foo' is already defined.")27 .test(src, {es3: true});28 TestRun(test)29 .addError(5, "'a' is already defined.")30 .addError(10, "'foo' is already defined.")31 .test(src, {es3: true, shadow: false });32 TestRun(test)33 .addError(5, "'a' is already defined.")34 .addError(10, "'foo' is already defined.")35 .test(src, {es3: true, shadow: "inner" });36 // Allow variable shadowing when shadow is true37 TestRun(test)38 .test(src, { es3: true, shadow: true });39 test.done();40};41/**42 * Option `scopeshadow` allows you to re-define variables later in inner scopes.43 *44 * E.g.:45 * var a = 1;46 * function foo() {47 * var a = 2;48 * }49 */50exports.scopeshadow = function (test) {51 var src = fs.readFileSync(__dirname + "/fixtures/scope-redef.js", "utf8");52 // Do not tolarate inner scope variable shadowing by default53 TestRun(test)54 .addError(5, "'a' is already defined in outer scope.")55 .addError(12, "'b' is already defined in outer scope.")56 .addError(20, "'bar' is already defined in outer scope.")57 .addError(26, "'foo' is already defined.")58 .test(src, { es3: true, shadow: "outer" });59 test.done();60}61/**62 * Option `latedef` allows you to prohibit the use of variable before their63 * definitions.64 *65 * E.g.:66 * fn(); // fn will be defined later in code67 * function fn() {};68 *69 * Since JavaScript has function-scope only, you can define variables and70 * functions wherever you want. But if you want to be more strict, use71 * this option.72 */73exports.latedef = function (test) {74 var src = fs.readFileSync(__dirname + '/fixtures/latedef.js', 'utf8'),75 src1 = fs.readFileSync(__dirname + '/fixtures/redef.js', 'utf8');76 // By default, tolerate the use of variable before its definition77 TestRun(test)78 .test(src, {es3: true});79 // However, JSHint must complain if variable is actually missing80 TestRun(test)81 .addError(1, "'fn' is not defined.")82 .test('fn();', { es3: true, undef: true });83 // And it also must complain about the redefinition (see option `shadow`)84 TestRun(test)85 .addError(5, "'a' is already defined.")86 .addError(10, "'foo' is already defined.")87 .test(src1, { es3: true });88 // When latedef is true, JSHint must not tolerate the use before definition89 TestRun(test)90 .addError(10, "'vr' was used before it was defined.")91 .test(src, { es3: true, latedef: "nofunc" });92 // When latedef_func is true, JSHint must not tolerate the use before definition for functions93 TestRun(test)94 .addError(2, "'fn' was used before it was defined.")95 .addError(6, "'fn1' was used before it was defined.")96 .addError(10, "'vr' was used before it was defined.")97 .addError(18, "Inner functions should be listed at the top of the outer function.")98 .test(src, { es3: true, latedef: true });99 test.done();100};101exports.notypeof = function (test) {102 var src = fs.readFileSync(__dirname + '/fixtures/typeofcomp.js', 'utf8');103 TestRun(test)104 .addError(1, "Invalid typeof value 'funtion'")105 .addError(2, "Invalid typeof value 'double'")106 .addError(3, "Invalid typeof value 'bool'")107 .addError(4, "Invalid typeof value 'obj'")108 .test(src);109 TestRun(test)110 .test(src, { notypeof: true });111 test.done();112}113exports['combination of latedef and undef'] = function (test) {114 var src = fixture('latedefundef.js');115 // Assures that when `undef` is set to true, it'll report undefined variables116 // and late definitions won't be reported as `latedef` is set to false.117 TestRun(test)118 .addError(29, "'hello' is not defined.")119 .addError(35, "'world' is not defined.")120 .test(src, { es3: true, latedef: false, undef: true });121 // When we suppress `latedef` and `undef` then we get no warnings.122 TestRun(test)123 .test(src, { es3: true, latedef: false, undef: false });124 // If we warn on `latedef` but supress `undef` we only get the125 // late definition warnings.126 TestRun(test)127 .addError(5, "'func2' was used before it was defined.")128 .addError(12, "'foo' was used before it was defined.")129 .addError(18, "'fn1' was used before it was defined.")130 .addError(26, "'baz' was used before it was defined.")131 .addError(34, "'fn' was used before it was defined.")132 .addError(41, "'q' was used before it was defined.")133 .addError(46, "'h' was used before it was defined.")134 .test(src, { es3: true, latedef: true, undef: false });135 // But we get all the functions warning if we disable latedef func136 TestRun(test)137 .addError(41, "'q' was used before it was defined.")138 .addError(46, "'h' was used before it was defined.")139 .test(src, { es3: true, latedef: "nofunc", undef: false });140 // If we warn on both options we get all the warnings.141 TestRun(test)142 .addError(5, "'func2' was used before it was defined.")143 .addError(12, "'foo' was used before it was defined.")144 .addError(18, "'fn1' was used before it was defined.")145 .addError(26, "'baz' was used before it was defined.")146 .addError(29, "'hello' is not defined.")147 .addError(34, "'fn' was used before it was defined.")148 .addError(35, "'world' is not defined.")149 .addError(41, "'q' was used before it was defined.")150 .addError(46, "'h' was used before it was defined.")151 .test(src, { es3: true, latedef: true, undef: true });152 // If we remove latedef_func, we don't get the functions warning153 TestRun(test)154 .addError(29, "'hello' is not defined.")155 .addError(35, "'world' is not defined.")156 .addError(41, "'q' was used before it was defined.")157 .addError(46, "'h' was used before it was defined.")158 .test(src, { es3: true, latedef: "nofunc", undef: true });159 test.done();160};161exports.undefwstrict = function (test) {162 var src = fs.readFileSync(__dirname + '/fixtures/undefstrict.js', 'utf8');163 TestRun(test).test(src, { es3: true, undef: false });164 test.done();165};166// Regression test for GH-431167exports["implied and unused should respect hoisting"] = function (test) {168 var src = fs.readFileSync(__dirname + '/fixtures/gh431.js', 'utf8');169 TestRun(test)170 .addError(14, "'fun4' is not defined.")171 .test(src, { undef: true }); // es5172 JSHINT.flag = true;173 JSHINT(src, { undef: true });174 var report = JSHINT.data();175 test.equal(report.implieds.length, 1);176 test.equal(report.implieds[0].name, 'fun4');177 test.deepEqual(report.implieds[0].line, [14]);178 test.equal(report.unused.length, 3);179 test.done();180};181/**182 * The `proto` and `iterator` options allow you to prohibit the use of the183 * special `__proto__` and `__iterator__` properties, respectively.184 */185exports.testProtoAndIterator = function (test) {186 var source = fs.readFileSync(__dirname + '/fixtures/protoiterator.js', 'utf8');187 var json = '{"__proto__": true, "__iterator__": false, "_identifier": null, "property": 123}';188 // JSHint should not allow the `__proto__` and189 // `__iterator__` properties by default190 TestRun(test)191 .addError(7, "The '__proto__' property is deprecated.")192 .addError(8, "The '__proto__' property is deprecated.")193 .addError(10, "The '__proto__' property is deprecated.")194 .addError(27, "'__iterator__' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")195 .addError(33, "The '__proto__' property is deprecated.")196 .addError(37, "The '__proto__' property is deprecated.")197 .test(source, {es3: true});198 TestRun(test)199 .addError(1, "The '__proto__' key may produce unexpected results.")200 .addError(1, "The '__iterator__' key may produce unexpected results.")201 .test(json, {es3: true});202 // Should not report any errors when proto and iterator203 // options are on204 TestRun("source").test(source, { es3: true, proto: true, iterator: true });205 TestRun("json").test(json, { es3: true, proto: true, iterator: true });206 test.done();207};208/**209 * The `camelcase` option allows you to enforce use of the camel case convention.210 */211exports.testCamelcase = function (test) {212 var source = fs.readFileSync(__dirname + '/fixtures/camelcase.js', 'utf8');213 // By default, tolerate arbitrary identifiers214 TestRun(test)215 .test(source, {es3: true});216 // Require identifiers in camel case if camelcase is true217 TestRun(test)218 .addError(5, "Identifier 'Foo_bar' is not in camel case.")219 .addError(5, "Identifier 'test_me' is not in camel case.")220 .addError(6, "Identifier 'test_me' is not in camel case.")221 .addError(6, "Identifier 'test_me' is not in camel case.")222 .addError(13, "Identifier 'test_1' is not in camel case.")223 .test(source, { es3: true, camelcase: true });224 test.done();225};226/**227 * Option `curly` allows you to enforce the use of curly braces around228 * control blocks. JavaScript allows one-line blocks to go without curly229 * braces but some people like to always use curly bracse. This option is230 * for them.231 *232 * E.g.:233 * if (cond) return;234 * vs.235 * if (cond) { return; }236 */237exports.curly = function (test) {238 var src = fs.readFileSync(__dirname + '/fixtures/curly.js', 'utf8'),239 src1 = fs.readFileSync(__dirname + '/fixtures/curly2.js', 'utf8');240 // By default, tolerate one-line blocks since they are valid JavaScript241 TestRun(test).test(src, {es3: true});242 TestRun(test).test(src1, {es3: true});243 // Require all blocks to be wrapped with curly braces if curly is true244 TestRun(test)245 .addError(2, "Expected '{' and instead saw 'return'.")246 .addError(5, "Expected '{' and instead saw 'doSomething'.")247 .addError(8, "Expected '{' and instead saw 'doSomething'.")248 .addError(11, "Expected '{' and instead saw 'doSomething'.")249 .test(src, { es3: true, curly: true });250 TestRun(test).test(src1, { es3: true, curly: true });251 test.done();252};253/** Option `noempty` prohibits the use of empty blocks. */254exports.noempty = function (test) {255 var code = 'for (;;) {}';256 // By default, tolerate empty blocks since they are valid JavaScript257 TestRun(test).test(code, { es3: true });258 // Do not tolerate, when noempty is true259 TestRun(test)260 .addError(1, 'Empty block.')261 .test(code, { es3: true, noempty: true });262 test.done();263};264/**265 * Option `noarg` prohibits the use of arguments.callee and arguments.caller.266 * JSHint allows them by default but you have to know what you are doing since:267 * - They are not supported by all JavaScript implementations268 * - They might prevent an interpreter from doing some optimization tricks269 * - They are prohibited in the strict mode270 */271exports.noarg = function (test) {272 var src = fs.readFileSync(__dirname + '/fixtures/noarg.js', 'utf8');273 // By default, tolerate both arguments.callee and arguments.caller274 TestRun(test).test(src, { es3: true });275 // Do not tolerate both .callee and .caller when noarg is true276 TestRun(test)277 .addError(2, 'Avoid arguments.callee.')278 .addError(6, 'Avoid arguments.caller.')279 .test(src, { es3: true, noarg: true });280 test.done();281};282/** Option `nonew` prohibits the use of constructors for side-effects */283exports.nonew = function (test) {284 var code = "new Thing();",285 code1 = "var obj = new Thing();";286 TestRun(test).test(code, { es3: true });287 TestRun(test).test(code1, { es3: true });288 TestRun(test)289 .addError(1, "Do not use 'new' for side effects.", {290 character: 1291 })292 .test(code, { es3: true, nonew: true });293 test.done();294};295exports.shelljs = function (test) {296 var src = fs.readFileSync(__dirname + '/fixtures/shelljs.js', 'utf8');297 TestRun(test, 1)298 .addError(1, "'target' is not defined.")299 .addError(3, "'echo' is not defined.")300 .addError(4, "'exit' is not defined.")301 .addError(5, "'cd' is not defined.")302 .addError(6, "'pwd' is not defined.")303 .addError(7, "'ls' is not defined.")304 .addError(8, "'find' is not defined.")305 .addError(9, "'cp' is not defined.")306 .addError(10, "'rm' is not defined.")307 .addError(11, "'mv' is not defined.")308 .addError(12, "'mkdir' is not defined.")309 .addError(13, "'test' is not defined.")310 .addError(14, "'cat' is not defined.")311 .addError(15, "'sed' is not defined.")312 .addError(16, "'grep' is not defined.")313 .addError(17, "'which' is not defined.")314 .addError(18, "'dirs' is not defined.")315 .addError(19, "'pushd' is not defined.")316 .addError(20, "'popd' is not defined.")317 .addError(21, "'env' is not defined.")318 .addError(22, "'exec' is not defined.")319 .addError(23, "'chmod' is not defined.")320 .addError(24, "'config' is not defined.")321 .addError(25, "'error' is not defined.")322 .addError(26, "'tempdir' is not defined.")323 .addError(29, "'require' is not defined.")324 .addError(30, "'module' is not defined.")325 .addError(31, "'process' is not defined.")326 .test(src, { undef: true });327 TestRun(test, 2)328 .test(src, { undef: true, shelljs: true });329 test.done();330};331// Option `asi` allows you to use automatic-semicolon insertion332exports.asi = function (test) {333 var src = fs.readFileSync(__dirname + '/fixtures/asi.js', 'utf8');334 TestRun(test, 1)335 .addError(2, "Missing semicolon.")336 .addError(4, "Missing semicolon.")337 .addError(5, "Missing semicolon.")338 .addError(9, "Line breaking error 'continue'.")339 .addError(9, "Missing semicolon.")340 .addError(10, "Missing semicolon.")341 .addError(11, "Line breaking error 'break'.")342 .addError(11, "Missing semicolon.")343 .addError(12, "Missing semicolon.")344 .addError(16, "Missing semicolon.")345 .addError(17, "Missing semicolon.")346 .addError(19, "Line breaking error 'break'.")347 .addError(19, "Missing semicolon.")348 .addError(21, "Line breaking error 'break'.")349 .addError(21, "Missing semicolon.")350 .addError(25, "Missing semicolon.")351 .addError(26, "Missing semicolon.", { character: 10 })352 .addError(27, "Missing semicolon.", { character: 12 })353 .addError(28, "Missing semicolon.", { character: 12 })354 .test(src, { es3: true });355 TestRun(test, 2)356 .addError(2, "Missing semicolon.") // throw on "use strict", even option asi is used357 .test(src, { es3: true, asi: true });358 test.done();359};360// Option `asi` extended for safety -- warn in scenarios that would be unsafe when using asi.361exports.safeasi = function (test) {362 var src = fs.readFileSync(__dirname + '/fixtures/safeasi.js', 'utf8');363 TestRun(test, 1)364 // TOOD consider setting an option to suppress these errors so that365 // the tests don't become tightly interdependent366 .addError(10, "Bad line breaking before '/'.")367 .addError(10, "Expected an identifier and instead saw '.'.")368 .addError(10, "Expected an assignment or function call and instead saw an expression.")369 .addError(10, "Missing semicolon.")370 .addError(10, "Missing semicolon.")371 .addError(11, "Missing semicolon.")372 .addError(21, "Missing semicolon.")373 .test(src, {});374 TestRun(test, 2)375 .addError(5, "Bad line breaking before '('.")376 .addError(8, "Bad line breaking before '('.")377 .addError(10, "Bad line breaking before '/'.")378 .addError(10, "Bad line breaking before '/'.")379 .addError(10, "Expected an identifier and instead saw '.'.")380 .addError(10, "Expected an assignment or function call and instead saw an expression.")381 .test(src, { asi: true });382 test.done();383};384/** Option `lastsemic` allows you to skip the semicolon after last statement in a block,385 * if that statement is followed by the closing brace on the same line. */386exports.lastsemic = function (test) {387 var src = fs.readFileSync(__dirname + '/fixtures/lastsemic.js', 'utf8');388 // without lastsemic389 TestRun(test)390 .addError(2, "Missing semicolon.") // missing semicolon in the middle of a block391 .addError(4, "Missing semicolon.") // missing semicolon in a one-liner function392 .addError(5, "Missing semicolon.") // missing semicolon at the end of a block393 .test(src, {es3: true});394 // with lastsemic395 TestRun(test)396 .addError(2, "Missing semicolon.")397 .addError(5, "Missing semicolon.")398 .test(src, { es3: true, lastsemic: true });399 // this line is valid now: [1, 2, 3].forEach(function(i) { print(i) });400 // line 5 isn't, because the block doesn't close on the same line401 test.done();402};403/**404 * Option `expr` allows you to use ExpressionStatement as a Program code.405 *406 * Even though ExpressionStatement as a Program (i.e. without assingment407 * of its result) is a valid JavaScript, more often than not it is a typo.408 * That's why by default JSHint complains about it. But if you know what409 * are you doing, there is nothing wrong with it.410 */411exports.expr = function (test) {412 var exps = [413 "obj && obj.method && obj.method();",414 "myvar && func(myvar);",415 "1;",416 "true;",417 "+function (test) {};"418 ];419 for (var i = 0, exp; exp = exps[i]; i += 1) {420 TestRun(test)421 .addError(1, 'Expected an assignment or function call and instead saw an expression.')422 .test(exp, { es3: true });423 }424 for (i = 0, exp = null; exp = exps[i]; i += 1) {425 TestRun(test).test(exp, { es3: true, expr: true });426 }427 test.done();428};429// Option `undef` requires you to always define variables you use.430exports.undef = function (test) {431 var src = fs.readFileSync(__dirname + '/fixtures/undef.js', 'utf8');432 // Make sure there are no other errors433 TestRun(test).test(src, { es3: true });434 // Make sure it fails when undef is true435 TestRun(test)436 .addError(1, "'undef' is not defined.")437 .addError(5, "'undef' is not defined.")438 .addError(6, "'undef' is not defined.")439 .addError(8, "'undef' is not defined.")440 .addError(9, "'undef' is not defined.")441 .addError(13, "'localUndef' is not defined.")442 .addError(18, "'localUndef' is not defined.")443 .addError(19, "'localUndef' is not defined.")444 .addError(21, "'localUndef' is not defined.")445 .addError(22, "'localUndef' is not defined.")446 .test(src, { es3: true, undef: true });447 // Regression test for GH-668.448 src = fs.readFileSync(__dirname + "/fixtures/gh668.js", "utf8");449 test.ok(JSHINT(src, { undef: true }));450 test.ok(!JSHINT.data().implieds);451 test.ok(JSHINT(src));452 test.ok(!JSHINT.data().implieds);453 test.done();454};455exports.unused = function (test) {456 var src = fs.readFileSync(__dirname + '/fixtures/unused.js', 'utf8');457 TestRun(test).test(src, { esnext: true });458 var var_errors = [459 [1, "'a' is defined but never used."],460 [7, "'c' is defined but never used."],461 [15, "'foo' is defined but never used."],462 [20, "'bar' is defined but never used."],463 [22, "'i' is defined but never used."],464 [36, "'cc' is defined but never used."],465 [39, "'dd' is defined but never used."]466 ];467 var last_param_errors = [468 [6, "'f' is defined but never used."],469 [22, "'i' is defined but never used."],470 [28, "'a' is defined but never used."],471 [28, "'b' is defined but never used."],472 [28, "'c' is defined but never used."]473 ];474 var all_param_errors = [475 [15, "'err' is defined but never used."],476 [22, "'i' is defined but never used."],477 [28, "'a' is defined but never used."],478 [28, "'b' is defined but never used."],479 [28, "'c' is defined but never used."]480 ];481 var true_run = TestRun(test, {esnext: true});482 var_errors.concat(last_param_errors).forEach(function (e) {483 true_run.addError.apply(true_run, e);484 });485 true_run.test(src, { esnext: true, unused: true });486 test.ok(!JSHINT(src, { esnext: true, unused: true }));487 // Test checking all function params via unused="strict"488 var all_run = TestRun(test);489 var_errors.concat(last_param_errors, all_param_errors).forEach(function (e) {490 all_run.addError.apply(true_run, e);491 });492 all_run.test(src, { esnext: true, unused: "strict"});493 // Test checking everything except function params494 var vars_run = TestRun(test);495 var_errors.forEach(function (e) { vars_run.addError.apply(vars_run, e); });496 vars_run.test(src, { esnext: true, unused: "vars"});497 var unused = JSHINT.data().unused;498 test.equal(12, unused.length);499 test.ok(unused.some(function (err) { return err.line === 1 && err.character == 5 && err.name === "a"; }));500 test.ok(unused.some(function (err) { return err.line === 6 && err.character == 18 && err.name === "f"; }));501 test.ok(unused.some(function (err) { return err.line === 7 && err.character == 9 && err.name === "c"; }));502 test.ok(unused.some(function (err) { return err.line === 15 && err.character == 10 && err.name === "foo"; }));503 test.done();504};505// Regressions for "unused" getting overwritten via comment (GH-778)506exports['unused overrides'] = function (test) {507 var code;508 code = ['function foo(a) {', '/*jshint unused:false */', '}', 'foo();'];509 TestRun(test).test(code, {es3: true, unused: true});510 code = ['function foo(a, b, c) {', '/*jshint unused:vars */', 'var i = b;', '}', 'foo();'];511 TestRun(test)512 .addError(3, "'i' is defined but never used.")513 .test(code, {es3: true, unused: true});514 code = ['function foo(a, b, c) {', '/*jshint unused:true */', 'var i = b;', '}', 'foo();'];515 TestRun(test)516 .addError(1, "'c' is defined but never used.")517 .addError(3, "'i' is defined but never used.")518 .test(code, {es3: true, unused: "strict"});519 code = ['function foo(a, b, c) {', '/*jshint unused:strict */', 'var i = b;', '}', 'foo();'];520 TestRun(test)521 .addError(1, "'a' is defined but never used.")522 .addError(1, "'c' is defined but never used.")523 .addError(3, "'i' is defined but never used.")524 .test(code, {es3: true, unused: true});525 code = ['/*jshint unused:vars */', 'function foo(a, b) {}', 'foo();'];526 TestRun(test).test(code, {es3: true, unused: "strict"});527 code = ['/*jshint unused:vars */', 'function foo(a, b) {', 'var i = 3;', '}', 'foo();'];528 TestRun(test)529 .addError(3, "'i' is defined but never used.")530 .test(code, {es3: true, unused: "strict"});531 test.done();532};533// Regression test for `undef` to make sure that ...534exports['undef in a function scope'] = function (test) {535 var src = fixture('undef_func.js');536 // Make sure that the lint is clean with and without undef.537 TestRun(test).test(src, {es3: true});538 TestRun(test).test(src, {es3: true, undef: true });539 test.done();540};541/** Option `scripturl` allows the use of javascript-type URLs */542exports.scripturl = function (test) {543 var code = [544 "var foo = { 'count': 12, 'href': 'javascript:' };",545 "foo = 'javascript:' + 'xyz';"546 ],547 src = fs.readFileSync(__dirname + '/fixtures/scripturl.js', 'utf8');548 // Make sure there is an error549 TestRun(test)550 .addError(1, "Script URL.")551 .addError(2, "Script URL.") // 2 times?552 .addError(2, "JavaScript URL.")553 .test(code, {es3: true});554 // Make sure the error goes away when javascript URLs are tolerated555 TestRun(test).test(code, { es3: true, scripturl: true });556 // Make sure an error does not exist for labels that look like URLs (GH-1013)557 TestRun(test)558 .test(src, {es3: true});559 test.done();560};561/**562 * Option `forin` disallows the use of for in loops without hasOwnProperty.563 *564 * The for in statement is used to loop through the names of properties565 * of an object, including those inherited through the prototype chain.566 * The method hasOwnPropery is used to check if the property belongs to567 * an object or was inherited through the prototype chain.568 */569exports.forin = function (test) {570 var src = fs.readFileSync(__dirname + '/fixtures/forin.js', 'utf8');571 var msg = 'The body of a for in should be wrapped in an if statement to filter unwanted ' +572 'properties from the prototype.';573 // Make sure there are no other errors574 TestRun(test).test(src, {es3: true});575 // Make sure it fails when forin is true576 TestRun(test)577 .addError(15, msg)578 .addError(23, msg)579 .addError(37, msg)580 .addError(43, msg)581 .addError(73, msg)582 .test(src, { es3: true, forin: true });583 test.done();584};585/**586 * Option `loopfunc` allows you to use function expression in the loop.587 * E.g.:588 * while (true) x = function (test) {};589 *590 * This is generally a bad idea since it is too easy to make a591 * closure-related mistake.592 */593exports.loopfunc = function (test) {594 var src = fs.readFileSync(__dirname + '/fixtures/loopfunc.js', 'utf8');595 // By default, not functions are allowed inside loops596 TestRun(test)597 .addError(2, "Don't make functions within a loop.")598 .addError(6, "Don't make functions within a loop.")599 .addError(10, "Function declarations should not be placed in blocks. Use a function " +600 "expression or move the statement to the top of the outer function.")601 .test(src, {es3: true});602 // When loopfunc is true, only function declaration should fail.603 // Expressions are okay.604 TestRun(test)605 .addError(10, "Function declarations should not be placed in blocks. Use a function " +606 "expression or move the statement to the top of the outer function.")607 .test(src, { es3: true, loopfunc: true });608 test.done();609};610/** Option `boss` unlocks some useful but unsafe features of JavaScript. */611exports.boss = function (test) {612 var src = fs.readFileSync(__dirname + '/fixtures/boss.js', 'utf8');613 // By default, warn about suspicious assignments614 TestRun(test)615 .addError(1, 'Expected a conditional expression and instead saw an assignment.')616 .addError(4, 'Expected a conditional expression and instead saw an assignment.')617 .addError(7, 'Expected a conditional expression and instead saw an assignment.')618 .addError(12, 'Expected a conditional expression and instead saw an assignment.')619 // GH-657620 .addError(14, 'Expected a conditional expression and instead saw an assignment.')621 .addError(17, 'Expected a conditional expression and instead saw an assignment.')622 .addError(20, 'Expected a conditional expression and instead saw an assignment.')623 .addError(25, 'Expected a conditional expression and instead saw an assignment.')624 // GH-670625 .addError(28, "Did you mean to return a conditional instead of an assignment?")626 .addError(32, "Did you mean to return a conditional instead of an assignment?")627 .test(src, {es3: true});628 // But if you are the boss, all is good629 TestRun(test).test(src, { es3: true, boss: true });630 test.done();631};632/**633 * Options `eqnull` allows you to use '== null' comparisons.634 * It is useful when you want to check if value is null _or_ undefined.635 */636exports.eqnull = function (test) {637 var code = [638 'if (e == null) doSomething();',639 'if (null == e) doSomething();',640 'if (e != null) doSomething();',641 'if (null != e) doSomething();',642 ];643 // By default, warn about `== null` comparison644 TestRun(test)645 .addError(1, "Use '===' to compare with 'null'.")646 .addError(2, "Use '===' to compare with 'null'.")647 .addError(3, "Use '!==' to compare with 'null'.")648 .addError(4, "Use '!==' to compare with 'null'.")649 .test(code, {es3: true});650 // But when `eqnull` is true, no questions asked651 TestRun(test).test(code, { es3: true, eqnull: true });652 // Make sure that `eqnull` has precedence over `eqeqeq`653 TestRun(test).test(code, { es3: true, eqeqeq: true, eqnull: true });654 test.done();655};656/**657 * Option `supernew` allows you to use operator `new` with anonymous functions658 * and objects without invocation.659 *660 * Ex.:661 * new function (test) { ... };662 * new Date;663 */664exports.supernew = function (test) {665 var src = fs.readFileSync(__dirname + '/fixtures/supernew.js', 'utf8');666 TestRun(test)667 .addError(1, "Weird construction. Is 'new' necessary?")668 .addError(9, "Missing '()' invoking a constructor.", { character: 1 })669 .addError(11, "Missing '()' invoking a constructor.", {670 character: 13671 })672 .test(src, {es3: true});673 TestRun(test).test(src, { es3: true, supernew: true });674 test.done();675};676/** Option `bitwise` disallows the use of bitwise operators. */677exports.bitwise = function (test) {678 var ops = [ '&', '|', '^', '<<', '>>', '>>>' ];679 var moreTests = [680 'var c = ~a;',681 'c &= 2;'682 ];683 // By default allow bitwise operators684 for (var i = 0, op; op = ops[i]; i += 1) {685 TestRun(test).test('var c = a ' + op + ' b;', {es3: true});686 }687 TestRun(test).test(moreTests, {es3: true});688 for (i = 0, op = null; op = ops[i]; i += 1) {689 TestRun(test)690 .addError(1, "Unexpected use of '" + op + "'.")691 .test('var c = a ' + op + ' b;', { es3: true, bitwise: true });692 }693 TestRun(test)694 .addError(1, "Unexpected '~'.")695 .addError(2, "Unexpected use of '&='.")696 .test(moreTests, { es3: true, bitwise: true });697 test.done();698};699/** Option `debug` allows the use of debugger statements. */700exports.debug = function (test) {701 var code = 'function test () { debugger; return true; }';702 // By default disallow debugger statements.703 TestRun(test)704 .addError(1, "Forgotten 'debugger' statement?")705 .test(code, {es3: true});706 // But allow them if debug is true.707 TestRun(test).test(code, { es3: true, debug: true });708 test.done();709};710/** `debugger` statements without semicolons are found on the correct line */711exports.debug = function (test) {712 var src = [713 "function test () {",714 "debugger",715 "return true; }"716 ];717 // Ensure we mark the correct line when finding debugger statements718 TestRun(test)719 .addError(2, "Forgotten 'debugger' statement?")720 .test(src, {es3: true, asi: true});721 test.done();722};723/** Option `eqeqeq` requires you to use === all the time. */724exports.eqeqeq = function (test) {725 var src = fs.readFileSync(__dirname + '/fixtures/eqeqeq.js', 'utf8');726 TestRun(test)727 .addError(8, "Use '===' to compare with 'null'.")728 .test(src, {es3: true});729 TestRun(test)730 .addError(2, "Expected '===' and instead saw '=='.")731 .addError(5, "Expected '!==' and instead saw '!='.")732 .addError(8, "Expected '===' and instead saw '=='.")733 .test(src, { es3: true, eqeqeq: true });734 test.done();735};736/** Option `evil` allows the use of eval. */737exports.evil = function (test) {738 var src = [739 "eval('hey();');",740 "document.write('');",741 "document.writeln('');",742 "window.execScript('xyz');",743 "new Function('xyz();');",744 "setTimeout('xyz();', 2);",745 "setInterval('xyz();', 2);",746 "var t = document['eval']('xyz');"747 ];748 TestRun(test)749 .addError(1, "eval can be harmful.")750 .addError(2, "document.write can be a form of eval.")751 .addError(3, "document.write can be a form of eval.")752 .addError(4, "eval can be harmful.")753 .addError(5, "The Function constructor is a form of eval.")754 .addError(6, "Implied eval. Consider passing a function instead of a string.")755 .addError(7, "Implied eval. Consider passing a function instead of a string.")756 .addError(8, "eval can be harmful.")757 .test(src, { es3: true, browser: true });758 TestRun(test).test(src, { es3: true, evil: true, browser: true });759 test.done();760};761/**762 * Option `immed` forces you to wrap immediate invocations in parens.763 *764 * Functions in JavaScript can be immediately invoce but that can confuse765 * readers of your code. To make it less confusing, wrap the invocations in766 * parens.767 *768 * E.g. (note the parens):769 * var a = (function (test) {770 * return 'a';771 * }());772 * console.log(a); // --> 'a'773 */774exports.immed = function (test) {775 var src = fs.readFileSync(__dirname + '/fixtures/immed.js', 'utf8');776 TestRun(test).test(src, {es3: true});777 TestRun(test)778 .addError(3, "Wrap an immediate function invocation in parens " +779 "to assist the reader in understanding that the expression " +780 "is the result of a function, and not the function itself.")781 .addError(13, "Wrapping non-IIFE function literals in parens is unnecessary.")782 .test(src, { es3: true, immed: true });783 // Regression for GH-900784 TestRun(test)785 .addError(1, "Expected an assignment or function call and instead saw an expression.")786 .addError(1, "Missing semicolon.")787 .addError(1, "Expected an identifier and instead saw ')'.")788 .addError(1, "Expected an assignment or function call and instead saw an expression.")789 .addError(1, "Unmatched '{'.")790 .addError(1, "Unmatched '('.")791 .addError(1, "Wrapping non-IIFE function literals in parens is unnecessary.")792 .addError(1, "Expected an assignment or function call and instead saw an expression.")793 .addError(1, "Missing semicolon.")794 .test("(function () { if (true) { }());", { es3: true, immed: true });795 test.done();796};797/** Option `plusplus` prohibits the use of increments/decrements. */798exports.plusplus = function (test) {799 var ops = [ '++', '--' ];800 for (var i = 0, op; op = ops[i]; i += 1) {801 TestRun(test).test('var i = j' + op + ';', {es3: true});802 TestRun(test).test('var i = ' + op + 'j;', {es3: true});803 }804 for (i = 0, op = null; op = ops[i]; i += 1) {805 TestRun(test)806 .addError(1, "Unexpected use of '" + op + "'.")807 .test('var i = j' + op + ';', { es3: true, plusplus: true });808 TestRun(test)809 .addError(1, "Unexpected use of '" + op + "'.")810 .test('var i = ' + op + 'j;', { es3: true, plusplus: true });811 }812 test.done();813};814/**815 * Option `newcap` requires constructors to be capitalized.816 *817 * Constructors are functions that are designed to be used with the `new` statement.818 * `new` creates a new object and binds it to the implied this parameter.819 * A constructor executed without new will have its this assigned to a global object,820 * leading to errors.821 *822 * Unfortunately, JavaScript gives us absolutely no way of telling if a function is a823 * constructor. There is a convention to capitalize all constructor names to prevent824 * those mistakes. This option enforces that convention.825 */826exports.newcap = function (test) {827 var src = fs.readFileSync(__dirname + '/fixtures/newcap.js', 'utf8');828 TestRun(test).test(src, {es3: true}); // By default, everything is fine829 // When newcap is true, enforce the conventions830 TestRun(test)831 .addError(1, 'A constructor name should start with an uppercase letter.')832 .addError(5, "Missing 'new' prefix when invoking a constructor.")833 .addError(10, "A constructor name should start with an uppercase letter.")834 .test(src, { es3: true, newcap: true });835 test.done();836};837/** Option `sub` allows all forms of subscription. */838exports.sub = function (test) {839 TestRun(test)840 .addError(1, "['prop'] is better written in dot notation.", {841 character: 17842 })843 .test("window.obj = obj['prop'];", {es3: true});844 TestRun(test).test("window.obj = obj['prop'];", { es3: true, sub: true });845 test.done();846};847/** Option `strict` requires you to use "use strict"; */848exports.strict = function (test) {849 var code = "(function (test) { return; }());";850 var code1 = '(function (test) { "use strict"; return; }());';851 var src = fs.readFileSync(__dirname + '/fixtures/strict_violations.js', 'utf8');852 var src2 = fs.readFileSync(__dirname + '/fixtures/strict_incorrect.js', 'utf8');853 var src3 = fs.readFileSync(__dirname + '/fixtures/strict_newcap.js', 'utf8');854 TestRun(test).test(code, {es3: true});855 TestRun(test).test(code1, {es3: true});856 TestRun(test)857 .addError(1, 'Missing "use strict" statement.')858 .test(code, { es3: true, strict: true });859 TestRun(test).test(code1, { es3: true, strict: true });860 // Test for strict mode violations861 TestRun(test)862 .addError(4, 'Possible strict violation.')863 .addError(7, 'Strict violation.')864 .addError(8, 'Strict violation.')865 .test(src, { es3: true, strict: true });866 TestRun(test)867 .addError(4, 'Expected an assignment or function call and instead saw an expression.')868 .addError(9, 'Missing semicolon.')869 .addError(28, 'Expected an assignment or function call and instead saw an expression.')870 .addError(53, 'Expected an assignment or function call and instead saw an expression.')871 .test(src2, { es3: true, strict: false });872 TestRun(test)873 .addError(6, "Missing 'new' prefix when invoking a constructor.")874 .test(src3, {es3 : true});875 TestRun(test).test("var obj = Object({ foo: 'bar' });", { es3: true, strict: true });876 test.done();877};878/** Option `globalstrict` allows you to use global "use strict"; */879exports.globalstrict = function (test) {880 var code = [881 '"use strict";',882 'function hello() { return; }'883 ];884 TestRun(test)885 .addError(1, 'Use the function form of "use strict".')886 .test(code, { es3: true, strict: true });887 TestRun(test).test(code, { es3: true, globalstrict: true });888 // Check that globalstrict also enabled strict889 TestRun(test)890 .addError(1, 'Missing "use strict" statement.')891 .test(code[1], { es3: true, globalstrict: true });892 // Don't enforce "use strict"; if strict has been explicitly set to false893 TestRun(test).test(code[1], { es3: true, globalstrict: true, strict: false });894 // Check that we can detect missing "use strict"; statement for code that is895 // not inside a function896 code = [897 "var a = 1;",898 "a += 1;",899 "function func() {}"900 ];901 TestRun(test)902 .addError(1, 'Missing "use strict" statement.')903 .test(code, { globalstrict: true, strict: true });904 // globalscript does not prevent you from using only the function-mode905 // "use strict";906 code = '(function (test) { "use strict"; return; }());';907 TestRun(test).test(code, { globalstrict: true, strict: true });908 test.done();909};910/** Option `laxbreak` allows you to insert newlines before some operators. */911exports.laxbreak = function (test) {912 var src = fs.readFileSync(__dirname + '/fixtures/laxbreak.js', 'utf8');913 TestRun(test)914 .addError(2, "Bad line breaking before ','.")915 .addError(3, "Comma warnings can be turned off with 'laxcomma'.")916 .addError(12, "Bad line breaking before ','.")917 .test(src, { es3: true });918 var ops = [ '||', '&&', '*', '/', '%', '+', '-', '>=',919 '==', '===', '!=', '!==', '>', '<', '<=', 'instanceof' ];920 for (var i = 0, op, code; op = ops[i]; i += 1) {921 code = ['var a = b ', op + ' c;'];922 TestRun(test)923 .addError(2, "Bad line breaking before '" + op + "'.")924 .test(code, { es3: true });925 TestRun(test).test(code, { es3: true, laxbreak: true });926 }927 code = [ 'var a = b ', '? c : d;' ];928 TestRun(test)929 .addError(2, "Bad line breaking before '?'.")930 .test(code, { es3: true });931 TestRun(test).test(code, { es3: true, laxbreak: true });932 test.done();933};934exports.validthis = function (test) {935 var src = fs.readFileSync(__dirname + '/fixtures/strict_this.js', 'utf8');936 TestRun(test)937 .addError(8, "Possible strict violation.")938 .addError(9, "Possible strict violation.")939 .addError(11, "Possible strict violation.")940 .test(src, {es3: true});941 src = fs.readFileSync(__dirname + '/fixtures/strict_this2.js', 'utf8');942 TestRun(test).test(src, {es3: true});943 // Test for erroneus use of validthis944 var code = ['/*jshint validthis:true */', 'hello();'];945 TestRun(test)946 .addError(1, "Option 'validthis' can't be used in a global scope.")947 .test(code, {es3: true});948 code = ['function x() {', '/*jshint validthis:heya */', 'hello();', '}'];949 TestRun(test)950 .addError(2, "Bad option value.")951 .test(code, {es3: true});952 test.done();953};954/*955 * Test string relevant options956 * multistr allows multiline strings957 */958exports.strings = function (test) {959 var src = fs.readFileSync(__dirname + '/fixtures/strings.js', 'utf8');960 TestRun(test)961 .addError(9, "Unclosed string.")962 .addError(10, "Unclosed string.")963 .addError(15, "Unclosed string.")964 .addError(23, "Octal literals are not allowed in strict mode.")965 .test(src, { es3: true, multistr: true });966 TestRun(test)967 .addError(3, "Bad escaping of EOL. Use option multistr if needed.")968 .addError(4, "Bad escaping of EOL. Use option multistr if needed.")969 .addError(9, "Unclosed string.")970 .addError(10, "Unclosed string.")971 .addError(14, "Bad escaping of EOL. Use option multistr if needed.")972 .addError(15, "Unclosed string.")973 .addError(23, "Octal literals are not allowed in strict mode.")974 .test(src, { es3: true });975 test.done();976};977/*978 * Test the `quotmark` option979 * quotmark quotation mark or true (=ensure consistency)980 */981exports.quotes = function (test) {982 var src = fs.readFileSync(__dirname + '/fixtures/quotes.js', 'utf8');983 var src2 = fs.readFileSync(__dirname + '/fixtures/quotes2.js', 'utf8');984 TestRun(test)985 .test(src, { es3: true });986 TestRun(test)987 .addError(3, "Mixed double and single quotes.")988 .test(src, { es3: true, quotmark: true });989 TestRun(test)990 .addError(3, "Strings must use singlequote.")991 .test(src, { es3: true, quotmark: 'single' });992 TestRun(test)993 .addError(2, "Strings must use doublequote.")994 .test(src, { es3: true, quotmark: 'double' });995 // test multiple runs (must have the same result)996 var run = TestRun(test);997 run.addError(3, "Mixed double and single quotes.")998 .test(src, { es3: true, quotmark: true });999 run.addError(3, "Mixed double and single quotes.")1000 .test(src2, { es3: true, quotmark: true });1001 test.done();1002};1003// Test the `quotmark` option when defined as a JSHint comment.1004exports.quotesInline = function (test) {1005 TestRun(test)1006 .addError(6, "Strings must use doublequote.")1007 .addError(14, "Strings must use singlequote.")1008 .addError(21, "Mixed double and single quotes.")1009 .addError(32, "Bad option value.")1010 .test(fs.readFileSync(__dirname + "/fixtures/quotes3.js", "utf8"));1011 test.done();1012};1013// Test the `quotmark` option along with TemplateLiterals.1014exports.quotesAndTemplateLiterals = function (test) {1015 var src = fs.readFileSync(__dirname + '/fixtures/quotes4.js', 'utf8');1016 // Without esnext1017 TestRun(test)1018 .addError(2, "Unexpected '`'.")1019 .addError(2, "Unexpected early end of program.")1020 .addError(2, "Expected an identifier and instead saw '(end)'.")1021 .addError(2, "Missing semicolon.")1022 .test(src);1023 // With esnext1024 TestRun(test)1025 .test(src, {esnext: true});1026 // With esnext and single quotemark1027 TestRun(test)1028 .test(src, {esnext: true, quotmark: 'single'});1029 // With esnext and double quotemark1030 TestRun(test)1031 .addError(1, "Strings must use doublequote.")1032 .test(src, {esnext: true, quotmark: 'double'});1033 test.done();1034};1035exports.scope = function (test) {1036 var src = fs.readFileSync(__dirname + '/fixtures/scope.js', 'utf8');1037 TestRun(test, 1)1038 .addError(11, "'j' used out of scope.") // 3x1039 .addError(12, "'x' used out of scope.")1040 .addError(20, "'aa' used out of scope.")1041 .addError(27, "'bb' used out of scope.")1042 .addError(37, "'cc' is not defined.")1043 .addError(42, "'bb' is not defined.")1044 .addError(53, "'xx' used out of scope.")1045 .addError(54, "'yy' used out of scope.")1046 .test(src, {es3: true});1047 TestRun(test, 2)1048 .addError(37, "'cc' is not defined.")1049 .addError(42, "'bb' is not defined.")1050 .test(src, { es3: true, funcscope: true });1051 test.done();1052};1053/*1054 * Tests `esnext` and `moz` options.1055 *1056 * This test simply makes sure that options are recognizable1057 * and do not reset ES5 mode (see GH-1068)1058 *1059 */1060exports.esnext = function (test) {1061 var src = fs.readFileSync(__dirname + '/fixtures/const.js', 'utf8');1062 var code = [1063 'const myConst = true;',1064 'const foo = 9;',1065 'var myConst = function (test) { };',1066 'foo = "hello world";',1067 'var a = { get x() {} };'1068 ];1069 TestRun(test)1070 .addError(21, "const 'immutable4' is initialized to 'undefined'.")1071 .test(src, { esnext: true });1072 TestRun(test)1073 .addError(21, "const 'immutable4' is initialized to 'undefined'.")1074 .test(src, { moz: true });1075 TestRun(test)1076 .addError(3, "const 'myConst' has already been declared.")1077 .addError(4, "Attempting to override 'foo' which is a constant.")1078 .test(code, { esnext: true });1079 TestRun(test)1080 .addError(3, "const 'myConst' has already been declared.")1081 .addError(4, "Attempting to override 'foo' which is a constant.")1082 .test(code, { moz: true });1083 test.done();1084};1085/*1086 * Tests the `maxlen` option1087 */1088exports.maxlen = function (test) {1089 var src = fs.readFileSync(__dirname + '/fixtures/maxlen.js', 'utf8');1090 TestRun(test)1091 .addError(3, "Line is too long.")1092 .addError(4, "Line is too long.")1093 .addError(5, "Line is too long.")1094 .addError(6, "Line is too long.")1095 // line 7 and more are exceptions and won't trigger the error1096 .test(src, { es3: true, maxlen: 23 });1097 test.done();1098};1099/*1100 * Tests the `laxcomma` option1101 */1102exports.laxcomma = function (test) {1103 var src = fs.readFileSync(__dirname + '/fixtures/laxcomma.js', 'utf8');1104 // All errors.1105 TestRun(test)1106 .addError(1, "Bad line breaking before ','.")1107 .addError(2, "Comma warnings can be turned off with 'laxcomma'.")1108 .addError(2, "Bad line breaking before ','.")1109 .addError(6, "Bad line breaking before ','.")1110 .addError(10, "Bad line breaking before '&&'.")1111 .addError(15, "Bad line breaking before '?'.")1112 .test(src, {es3: true});1113 // Allows bad line breaking, but not on commas.1114 TestRun(test)1115 .addError(1, "Bad line breaking before ','.")1116 .addError(2, "Comma warnings can be turned off with 'laxcomma'.")1117 .addError(2, "Bad line breaking before ','.")1118 .addError(6, "Bad line breaking before ','.")1119 .test(src, {es3: true, laxbreak: true });1120 // Allows comma-first style but warns on bad line breaking1121 TestRun(test)1122 .addError(10, "Bad line breaking before '&&'.")1123 .addError(15, "Bad line breaking before '?'.")1124 .test(src, {es3: true, laxcomma: true });1125 // No errors if both laxbreak and laxcomma are turned on1126 TestRun(test).test(src, {es3: true, laxbreak: true, laxcomma: true });1127 test.done();1128};1129/*1130 * Tests the `browser` option1131 */1132exports.browser = function (test) {1133 var src = fs.readFileSync(__dirname + '/fixtures/browser.js', 'utf8');1134 TestRun(test)1135 .addError(2, "'atob' is not defined.")1136 .addError(3, "'btoa' is not defined.")1137 .addError(6, "'DOMParser' is not defined.")1138 .addError(10, "'XMLSerializer' is not defined.")1139 .addError(14, "'NodeFilter' is not defined.")1140 .addError(15, "'Node' is not defined.")