corrade-nucleus-nucleons – Blame information for rev 20

Subversion Repositories:
Rev:
Rev Author Line No. Line
20 office 1 /*
2 The MIT License (MIT)
3  
4 Copyright (c) 2007-2017 Einar Lielmanis, Liam Newman, and contributors.
5  
6 Permission is hereby granted, free of charge, to any person
7 obtaining a copy of this software and associated documentation files
8 (the "Software"), to deal in the Software without restriction,
9 including without limitation the rights to use, copy, modify, merge,
10 publish, distribute, sublicense, and/or sell copies of the Software,
11 and to permit persons to whom the Software is furnished to do so,
12 subject to the following conditions:
13  
14 The above copyright notice and this permission notice shall be
15 included in all copies or substantial portions of the Software.
16  
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 SOFTWARE.
25 */
26  
27 var inputlib = require('./inputlib');
28  
29 exports.test_data = {
30 default_options: [
31 { name: "indent_size", value: "4" },
32 { name: "indent_char", value: "' '" },
33 { name: "preserve_newlines", value: "true" },
34 { name: "jslint_happy", value: "false" },
35 { name: "keep_array_indentation", value: "false" },
36 { name: "brace_style", value: "'collapse'" },
37 { name: "operator_position", value: "'before-newline'" }
38 ],
39 groups: [{
40 name: "Unicode Support",
41 description: "",
42 tests: [{
43 unchanged: "var ' + unicode_char(3232) + '_' + unicode_char(3232) + ' = \"hi\";"
44 }, {
45 unchanged: [
46 "var ' + unicode_char(228) + 'x = {",
47 " ' + unicode_char(228) + 'rgerlich: true",
48 "};"
49 ]
50 }]
51 }, {
52 name: "Test template and continuation strings",
53 description: "",
54 tests: [
55 { unchanged: '`This is a ${template} string.`' },
56 { unchanged: '`This\n is\n a\n ${template}\n string.`' },
57 { unchanged: 'a = `This is a continuation\\\\\nstring.`' },
58 { unchanged: 'a = "This is a continuation\\\\\nstring."' },
59 { unchanged: '`SELECT\n nextval(\\\'${this.options.schema ? `${this.options.schema}.` : \\\'\\\'}"${this.tableName}_${this.autoIncrementField}_seq"\\\'::regclass\n ) nextval;`' },
60 {
61 comment: 'Tests for #1030',
62 unchanged: [
63 'const composeUrl = (host) => {',
64 ' return `${host `test`}`;',
65 '};'
66 ]
67 }, {
68 unchanged: [
69 'const composeUrl = (host, api, key, data) => {',
70 ' switch (api) {',
71 ' case "Init":',
72 ' return `${host}/vwapi/Init?VWID=${key}&DATA=${encodeURIComponent(',
73 ' Object.keys(data).map((k) => `${k}=${ data[k]}` ).join(";")',
74 ' )}`;',
75 ' case "Pay":',
76 ' return `${host}/vwapi/Pay?SessionId=${par}`;',
77 ' };',
78 '};'
79 ]
80 }
81 ]
82 }, {
83 name: "ES7 Decorators",
84 description: "Permit ES7 decorators, which are invoked with a leading \"@\".",
85 tests: [
86 { unchanged: '@foo' },
87 { unchanged: '@foo(bar)' },
88 {
89 unchanged: [
90 '@foo(function(k, v) {',
91 ' implementation();',
92 '})'
93 ]
94 }
95 ]
96 }, {
97 name: "ES7 exponential",
98 description: "ES7 exponential",
99 tests: [
100 { unchanged: 'x ** 2' },
101 { unchanged: 'x ** -2' }
102 ]
103 }, {
104 name: "Spread operator",
105 description: "Spread operator",
106 options: [
107 { name: 'brace_style', value: '"collapse,preserve-inline"' }
108 ],
109 tests: [
110 { unchanged: 'const m = { ...item, c: 3 };' },
111 { unchanged: 'const m = {\n ...item,\n c: 3\n};' },
112 { unchanged: 'const m = { c: 3, ...item };' },
113 { unchanged: 'const m = [...item, 3];' },
114 { unchanged: 'const m = [3, ...item];' }
115 ]
116 }, {
117 name: "Object literal shorthand functions",
118 description: "Object literal shorthand functions",
119 tests: [
120 { unchanged: 'return {\n foo() {\n return 42;\n }\n}' },
121 {
122 unchanged: [
123 'var foo = {',
124 ' * bar() {',
125 ' yield 42;',
126 ' }',
127 '};'
128 ]
129 },
130 {
131 input: 'var foo = {bar(){return 42;},*barGen(){yield 42;}};',
132 output: ['var foo = {',
133 ' bar() {',
134 ' return 42;',
135 ' },',
136 ' * barGen() {',
137 ' yield 42;',
138 ' }',
139 '};'
140 ]
141 }, {
142 comment: 'also handle generator shorthand in class - #1013',
143 unchanged: [
144 'class A {',
145 ' fn() {',
146 ' return true;',
147 ' }',
148 '',
149 ' * gen() {',
150 ' return true;',
151 ' }',
152 '}'
153 ]
154 }, {
155 unchanged: [
156 'class A {',
157 ' * gen() {',
158 ' return true;',
159 ' }',
160 '',
161 ' fn() {',
162 ' return true;',
163 ' }',
164 '}'
165 ]
166 }
167 ]
168 }, {
169 name: "End With Newline",
170 description: "",
171 matrix: [{
172 options: [
173 { name: "end_with_newline", value: "true" }
174 ],
175 eof: '\n'
176 }, {
177 options: [
178 { name: "end_with_newline", value: "false" }
179 ],
180 eof: ''
181 }
182  
183 ],
184 tests: [
185 { fragment: true, input: '', output: '{{eof}}' },
186 { fragment: true, input: ' return .5', output: ' return .5{{eof}}' },
187 { fragment: true, input: ' \n\nreturn .5\n\n\n\n', output: ' return .5{{eof}}' },
188 { fragment: true, input: '\n', output: '{{eof}}' }
189 ],
190 }, {
191 name: "Support simple language specific option inheritance/overriding",
192 description: "Support simple language specific option inheritance/overriding",
193 matrix: [{
194 options: [
195 { name: "js", value: "{ 'indent_size': 3 }" },
196 { name: "css", value: "{ 'indent_size': 5 }" }
197 ],
198 j: ' '
199 },
200 {
201 options: [
202 { name: "html", value: "{ 'js': { 'indent_size': 3 }, 'css': { 'indent_size': 5 } }" }
203 ],
204 j: ' '
205 },
206 {
207 options: [
208 { name: "indent_size", value: "9" },
209 { name: "html", value: "{ 'js': { 'indent_size': 3 }, 'css': { 'indent_size': 5 }, 'indent_size': 2}" },
210 { name: "js", value: "{ 'indent_size': 4 }" },
211 { name: "css", value: "{ 'indent_size': 3 }" }
212 ],
213 j: ' '
214 }
215 ],
216 tests: [{
217 unchanged: [
218 'if (a == b) {',
219 '{{j}}test();',
220 '}'
221 ]
222 }, ]
223 }, {
224 name: "Brace style permutations",
225 description: "",
226 template: "< >",
227 matrix: [
228 // brace_style collapse,preserve-inline - Should preserve if no newlines
229 {
230 options: [
231 { name: "brace_style", value: "'collapse,preserve-inline'" }
232 ],
233 ibo: '',
234 iao: '',
235 ibc: '',
236 iac: '',
237 obo: ' ',
238 oao: ' ',
239 obc: ' ',
240 oac: ' '
241 },
242 {
243 options: [
244 { name: "brace_style", value: "'collapse,preserve-inline'" }
245 ],
246 ibo: '\n',
247 iao: '\n',
248 ibc: '\n',
249 iac: '\n',
250 obo: ' ',
251 oao: '\n ',
252 obc: '\n',
253 oac: ' '
254 },
255  
256 // brace_style collapse - Shouldn't preserve if no newlines (uses collapse styling)
257 {
258 options: [
259 { name: "brace_style", value: "'collapse'" }
260 ],
261 ibo: '',
262 iao: '',
263 ibc: '',
264 iac: '',
265 obo: ' ',
266 oao: '\n ',
267 obc: '\n',
268 oac: ' '
269 },
270 {
271 options: [
272 { name: "brace_style", value: "'collapse'" }
273 ],
274 ibo: '\n',
275 iao: '\n',
276 ibc: '\n',
277 iac: '\n',
278 obo: ' ',
279 oao: '\n ',
280 obc: '\n',
281 oac: ' '
282 },
283 ],
284 tests: [{
285 input: 'var a =<ibo>{<iao>a: 2<ibc>}<iac>;\nvar a =<ibo>{<iao>a: 2<ibc>}<iac>;',
286 output: 'var a =<obo>{<oao>a: 2<obc>};\nvar a =<obo>{<oao>a: 2<obc>};'
287 },
288 // {
289 // input: 'var a =<ibo>{<iao>a:<ibo>{<iao>a:<ibo>{<iao>a:2<ibc>}<iac><ibc>}<iac>}<iac>;\nvar a =<ibo>{<iao>a:<ibo>{<iao>a:<ibo>{<iao>a:2<ibc>}<iac><ibc>}<iac>}<iac>;',
290 // output: 'var a =<obo>{<oao>a:<obo>{<oao>a:<obo>{<oao>a: 2<obc>}<oac><obc>}<oac><obc>};\nvar a =<obo>{<oao>a:<obo>{<oao>a:<obo>{<oao>a: 2<obc>}<oac><obc>}<oac><obc>};'
291 // },
292 {
293 input: '//case 1\nif (a == 1)<ibo>{}\n//case 2\nelse if (a == 2)<ibo>{}',
294 output: '//case 1\nif (a == 1)<obo>{}\n//case 2\nelse if (a == 2)<obo>{}'
295 },
296 {
297 input: 'if(1)<ibo>{<iao>2<ibc>}<iac>else<ibo>{<iao>3<ibc>}',
298 output: 'if (1)<obo>{<oao>2<obc>}<oac>else<obo>{<oao>3<obc>}'
299 },
300 {
301 input: 'try<ibo>{<iao>a();<ibc>}<iac>' +
302 'catch(b)<ibo>{<iao>c();<ibc>}<iac>' +
303 'catch(d)<ibo>{}<iac>' +
304 'finally<ibo>{<iao>e();<ibc>}',
305 output:
306 // expected
307 'try<obo>{<oao>a();<obc>}<oac>' +
308 'catch (b)<obo>{<oao>c();<obc>}<oac>' +
309 'catch (d)<obo>{}<oac>' +
310 'finally<obo>{<oao>e();<obc>}'
311 }
312 ],
313 }, {
314 name: "Comma-first option",
315 description: "Put commas at the start of lines instead of the end",
316 matrix: [{
317 options: [
318 { name: "comma_first", value: "false" }
319 ],
320 c0: ',\n',
321 c1: ',\n ',
322 c2: ',\n ',
323 c3: ',\n ',
324 // edge cases where engine bails
325 f1: ' ,\n '
326 }, {
327 options: [
328 { name: "comma_first", value: "true" }
329 ],
330 c0: '\n, ',
331 c1: '\n , ',
332 c2: '\n , ',
333 c3: '\n , ',
334 // edge cases where engine bails
335 f1: ', '
336 }],
337 tests: [
338 { input: '{a:1, b:2}', output: "{\n a: 1{{c1}}b: 2\n}" },
339 { input: 'var a=1, b=c[d], e=6;', output: 'var a = 1{{c1}}b = c[d]{{c1}}e = 6;' },
340 { input: "for(var a=1,b=2,c=3;d<3;d++)\ne", output: "for (var a = 1, b = 2, c = 3; d < 3; d++)\n e" },
341 { input: "for(var a=1,b=2,\nc=3;d<3;d++)\ne", output: "for (var a = 1, b = 2{{c2}}c = 3; d < 3; d++)\n e" },
342 { unchanged: 'function foo() {\n return [\n "one"{{c2}}"two"\n ];\n}' },
343 { input: 'a=[[1,2],[4,5],[7,8]]', output: "a = [\n [1, 2]{{c1}}[4, 5]{{c1}}[7, 8]\n]" },
344 { input: 'a=[[1,2],[4,5],[7,8],]', output: "a = [\n [1, 2]{{c1}}[4, 5]{{c1}}[7, 8]{{c0}}]" },
345 {
346 input: 'a=[[1,2],[4,5],function(){},[7,8]]',
347 output: "a = [\n [1, 2]{{c1}}[4, 5]{{c1}}function() {}{{c1}}[7, 8]\n]"
348 },
349 {
350 input: 'a=[[1,2],[4,5],function(){},function(){},[7,8]]',
351 output: "a = [\n [1, 2]{{c1}}[4, 5]{{c1}}function() {}{{c1}}function() {}{{c1}}[7, 8]\n]"
352 },
353 {
354 input: 'a=[[1,2],[4,5],function(){},[7,8]]',
355 output: "a = [\n [1, 2]{{c1}}[4, 5]{{c1}}function() {}{{c1}}[7, 8]\n]"
356 },
357 {
358 input: 'a=[b,c,function(){},function(){},d]',
359 output: "a = [b, c, function() {}, function() {}, d]"
360 },
361 {
362 input: 'a=[b,c,\nfunction(){},function(){},d]',
363 output: "a = [b, c{{c1}}function() {}{{c1}}function() {}{{c1}}d\n]"
364 },
365 { input: 'a=[a[1],b[4],c[d[7]]]', output: "a = [a[1], b[4], c[d[7]]]" },
366 { input: '[1,2,[3,4,[5,6],7],8]', output: "[1, 2, [3, 4, [5, 6], 7], 8]" },
367  
368 {
369 input: '[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]',
370 output: '[\n [\n ["1", "2"]{{c2}}["3", "4"]\n ]{{c1}}[\n ["5", "6", "7"]{{c2}}["8", "9", "0"]\n ]{{c1}}[\n ["1", "2", "3"]{{c2}}["4", "5", "6", "7"]{{c2}}["8", "9", "0"]\n ]\n]'
371 },
372 {
373 input: [
374 'changeCollection.add({',
375 ' name: "Jonathan" // New line inserted after this line on every save',
376 ' , age: 25',
377 '});'
378 ],
379 output: [
380 'changeCollection.add({',
381 ' name: "Jonathan" // New line inserted after this line on every save',
382 ' {{f1}}age: 25',
383 '});'
384 ]
385 },
386 {
387 input: [
388 'changeCollection.add(',
389 ' function() {',
390 ' return true;',
391 ' },',
392 ' function() {',
393 ' return true;',
394 ' }',
395 ');'
396 ],
397 output: [
398 'changeCollection.add(',
399 ' function() {',
400 ' return true;',
401 ' }{{c1}}function() {',
402 ' return true;',
403 ' }',
404 ');'
405 ]
406 },
407 ],
408 }, {
409 name: "Space in parens tests",
410 description: "put space inside parens",
411 matrix: [{
412 options: [
413 { name: "space_in_paren", value: "false" },
414 { name: "space_in_empty_paren", value: "false" },
415 ],
416 s: '',
417 e: '',
418 }, {
419 options: [
420 { name: "space_in_paren", value: "false" },
421 { name: "space_in_empty_paren", value: "true" },
422 ],
423 s: '',
424 e: '',
425 }, {
426 options: [
427 { name: "space_in_paren", value: "true" },
428 { name: "space_in_empty_paren", value: "false" },
429 ],
430 s: ' ',
431 e: '',
432 }, {
433 options: [
434 { name: "space_in_paren", value: "true" },
435 { name: "space_in_empty_paren", value: "true" },
436 ],
437 s: ' ',
438 e: ' ',
439 }],
440 tests: [{
441 input: 'if(p) foo(a,b);',
442 output: 'if ({{s}}p{{s}}) foo({{s}}a, b{{s}});'
443 },
444 {
445 input: 'try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }',
446 output: 'try {\n while ({{s}}true{{s}}) {\n willThrow({{e}})\n }\n} catch ({{s}}result{{s}}) switch ({{s}}result{{s}}) {\n case 1:\n ++result\n}'
447 },
448 {
449 input: '((e/((a+(b)*c)-d))^2)*5;',
450 output: '({{s}}({{s}}e / ({{s}}({{s}}a + ({{s}}b{{s}}) * c{{s}}) - d{{s}}){{s}}) ^ 2{{s}}) * 5;'
451 },
452 {
453 input: 'function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
454 output: 'function f({{s}}a, b{{s}}) {\n if ({{s}}a{{s}}) b({{e}})\n}\n\nfunction g({{s}}a, b{{s}}) {\n if ({{s}}!a{{s}}) b({{e}})\n}'
455 },
456 {
457 input: 'a=[];',
458 output: 'a = [{{e}}];'
459 },
460 {
461 input: 'a=[b,c,d];',
462 output: 'a = [{{s}}b, c, d{{s}}];'
463 },
464 {
465 input: 'a= f[b];',
466 output: 'a = f[{{s}}b{{s}}];'
467 },
468 {
469 input: [
470 '{',
471 ' files: [ {',
472 ' expand: true,',
473 ' cwd: "www/gui/",',
474 ' src: [ "im/design_standards/*.*" ],',
475 ' dest: "www/gui/build"',
476 ' } ]',
477 '}'
478 ],
479 output: [
480 '{',
481 ' files: [{{s}}{',
482 ' expand: true,',
483 ' cwd: "www/gui/",',
484 ' src: [{{s}}"im/design_standards/*.*"{{s}}],',
485 ' dest: "www/gui/build"',
486 ' }{{s}}]',
487 '}'
488 ],
489 },
490 ],
491 }, {
492 name: "operator_position option - ensure no neswlines if preserve_newlines is false",
493 matrix: [{
494 options: [
495 { name: "operator_position", value: "'before-newline'" },
496 { name: "preserve_newlines", value: "false" }
497 ]
498 }, {
499 options: [
500 { name: "operator_position", value: "'after-newline'" },
501 { name: "preserve_newlines", value: "false" }
502 ]
503 }, {
504 options: [
505 { name: "operator_position", value: "'preserve-newline'" },
506 { name: "preserve_newlines", value: "false" }
507 ]
508 }],
509 tests: [{
510 unchanged: inputlib.operator_position.sanity
511 }, {
512 input: inputlib.operator_position.comprehensive,
513 output: inputlib.operator_position.sanity,
514 }]
515 }, {
516 name: "operator_position option - set to 'before-newline' (default value)",
517 tests: [{
518 comment: 'comprehensive, various newlines',
519 input: inputlib.operator_position.comprehensive,
520 output: [
521 'var res = a + b -',
522 ' c /',
523 ' d * e %',
524 ' f;',
525 'var res = g & h |',
526 ' i ^',
527 ' j;',
528 'var res = (k &&',
529 ' l ||',
530 ' m) ?',
531 ' n :',
532 ' o;',
533 'var res = p >>',
534 ' q <<',
535 ' r >>>',
536 ' s;',
537 'var res = t',
538 '',
539 ' ===',
540 ' u !== v !=',
541 ' w ==',
542 ' x >=',
543 ' y <= z > aa <',
544 ' ab;',
545 'ac +',
546 ' -ad'
547 ]
548 }, {
549 comment: 'colon special case',
550 input: inputlib.operator_position.colon_special_case,
551 output: [
552 'var a = {',
553 ' b: bval,',
554 ' c: cval,',
555 ' d: dval',
556 '};',
557 'var e = f ? g :',
558 ' h;',
559 'var i = j ? k :',
560 ' l;'
561 ]
562 }, {
563 comment: 'catch-all, includes brackets and other various code',
564 input: inputlib.operator_position.catch_all,
565 output: [
566 'var d = 1;',
567 'if (a === b &&',
568 ' c) {',
569 ' d = (c * everything /',
570 ' something_else) %',
571 ' b;',
572 ' e',
573 ' += d;',
574 '',
575 '} else if (!(complex && simple) ||',
576 ' (emotion && emotion.name === "happy")) {',
577 ' cryTearsOfJoy(many ||',
578 ' anOcean ||',
579 ' aRiver);',
580 '}'
581 ]
582 }]
583 }, {
584 name: "operator_position option - set to 'after_newline'",
585 options: [{
586 name: "operator_position",
587 value: "'after-newline'"
588 }],
589 tests: [{
590 comment: 'comprehensive, various newlines',
591 input: inputlib.operator_position.comprehensive,
592 output: [
593 'var res = a + b',
594 ' - c',
595 ' / d * e',
596 ' % f;',
597 'var res = g & h',
598 ' | i',
599 ' ^ j;',
600 'var res = (k',
601 ' && l',
602 ' || m)',
603 ' ? n',
604 ' : o;',
605 'var res = p',
606 ' >> q',
607 ' << r',
608 ' >>> s;',
609 'var res = t',
610 '',
611 ' === u !== v',
612 ' != w',
613 ' == x',
614 ' >= y <= z > aa',
615 ' < ab;',
616 'ac',
617 ' + -ad'
618 ]
619 }, {
620 comment: 'colon special case',
621 input: inputlib.operator_position.colon_special_case,
622 output: [
623 'var a = {',
624 ' b: bval,',
625 ' c: cval,',
626 ' d: dval',
627 '};',
628 'var e = f ? g',
629 ' : h;',
630 'var i = j ? k',
631 ' : l;'
632 ]
633 }, {
634 comment: 'catch-all, includes brackets and other various code',
635 input: inputlib.operator_position.catch_all,
636 output: [
637 'var d = 1;',
638 'if (a === b',
639 ' && c) {',
640 ' d = (c * everything',
641 ' / something_else)',
642 ' % b;',
643 ' e',
644 ' += d;',
645 '',
646 '} else if (!(complex && simple)',
647 ' || (emotion && emotion.name === "happy")) {',
648 ' cryTearsOfJoy(many',
649 ' || anOcean',
650 ' || aRiver);',
651 '}'
652 ]
653 }]
654 }, {
655 name: "operator_position option - set to 'preserve-newline'",
656 options: [{
657 name: "operator_position",
658 value: "'preserve-newline'"
659 }],
660 tests: [{
661 comment: 'comprehensive, various newlines',
662 input: inputlib.operator_position.comprehensive,
663 output: [
664 'var res = a + b',
665 ' - c /',
666 ' d * e',
667 ' %',
668 ' f;',
669 'var res = g & h',
670 ' | i ^',
671 ' j;',
672 'var res = (k &&',
673 ' l',
674 ' || m) ?',
675 ' n',
676 ' : o;',
677 'var res = p',
678 ' >> q <<',
679 ' r',
680 ' >>> s;',
681 'var res = t',
682 '',
683 ' === u !== v',
684 ' !=',
685 ' w',
686 ' == x >=',
687 ' y <= z > aa <',
688 ' ab;',
689 'ac +',
690 ' -ad'
691 ]
692 }, {
693 comment: 'colon special case',
694 input: inputlib.operator_position.colon_special_case,
695 output: [
696 'var a = {',
697 ' b: bval,',
698 ' c: cval,',
699 ' d: dval',
700 '};',
701 'var e = f ? g',
702 ' : h;',
703 'var i = j ? k :',
704 ' l;'
705 ]
706 }, {
707 comment: 'catch-all, includes brackets and other various code',
708 unchanged: inputlib.operator_position.catch_all
709 }]
710 }, {
711 name: "Yield tests",
712 description: "ES6 yield tests",
713 tests: [
714 { unchanged: 'yield /foo\\\\//;' },
715 { unchanged: 'result = yield pgClient.query_(queryString);' },
716 { unchanged: 'yield [1, 2]' },
717 { unchanged: "yield* bar();" },
718 {
719 comment: "yield should have no space between yield and star",
720 input: "yield * bar();",
721 output: "yield* bar();"
722 },
723 {
724 comment: "yield should have space between star and generator",
725 input: "yield *bar();",
726 output: "yield* bar();"
727 }
728 ]
729 }, {
730 name: "Async / await tests",
731 description: "ES7 async / await tests",
732 tests: [
733 { unchanged: "async function foo() {}" },
734 { unchanged: "let w = async function foo() {}" },
735 { unchanged: "async function foo() {}\nvar x = await foo();" },
736 {
737 comment: "async function as an input to another function",
738 unchanged: "wrapper(async function foo() {})"
739 },
740 {
741 comment: "await on inline anonymous function. should have a space after await",
742 input_: "async function() {\n var w = await(async function() {\n return await foo();\n })();\n}",
743 output: "async function() {\n var w = await (async function() {\n return await foo();\n })();\n}"
744 },
745 {
746 comment: "ensure that this doesn't break anyone with the async library",
747 unchanged: "async.map(function(t) {})"
748 }
749 ]
750 }, {
751 name: "e4x - Test that e4x literals passed through when e4x-option is enabled",
752 description: "",
753 options: [
754 { name: 'e4x', value: true }
755 ],
756 tests: [
757 { input: 'xml=<a b="c"><d/><e>\n foo</e>x</a>;', output: 'xml = <a b="c"><d/><e>\n foo</e>x</a>;' },
758 { unchanged: '<a b=\\\'This is a quoted "c".\\\'/>' },
759 { unchanged: '<a b="This is a quoted \\\'c\\\'."/>' },
760 { unchanged: '<a b="A quote \\\' inside string."/>' },
761 { unchanged: '<a b=\\\'A quote " inside string.\\\'/>' },
762 { unchanged: '<a b=\\\'Some """ quotes "" inside string.\\\'/>' },
763  
764 {
765 comment: 'Handles inline expressions',
766 input: 'xml=<{a} b="c"><d/><e v={z}>\n foo</e>x</{a}>;',
767 output: 'xml = <{a} b="c"><d/><e v={z}>\n foo</e>x</{a}>;'
768 },
769 {
770 input: 'xml=<{a} b="c">\n <e v={z}>\n foo</e>x</{a}>;',
771 output: 'xml = <{a} b="c">\n <e v={z}>\n foo</e>x</{a}>;'
772 },
773 {
774 comment: 'xml literals with special characters in elem names - see http://www.w3.org/TR/REC-xml/#NT-NameChar',
775 unchanged: 'xml = <_:.valid.xml- _:.valid.xml-="123"/>;'
776 },
777 {
778 comment: 'xml literals with attributes without equal sign',
779 unchanged: 'xml = <elem someAttr/>;'
780 },
781  
782 {
783 comment: 'Handles CDATA',
784 input: 'xml=<![CDATA[ b="c"><d/><e v={z}>\n foo</e>x/]]>;',
785 output: 'xml = <![CDATA[ b="c"><d/><e v={z}>\n foo</e>x/]]>;'
786 },
787 { input: 'xml=<![CDATA[]]>;', output: 'xml = <![CDATA[]]>;' },
788 { input: 'xml=<a b="c"><![CDATA[d/></a></{}]]></a>;', output: 'xml = <a b="c"><![CDATA[d/></a></{}]]></a>;' },
789  
790 {
791 comment: 'JSX - working jsx from http://prettydiff.com/unit_tests/beautification_javascript_jsx.txt',
792 unchanged: [
793 'var ListItem = React.createClass({',
794 ' render: function() {',
795 ' return (',
796 ' <li className="ListItem">',
797 ' <a href={ "/items/" + this.props.item.id }>',
798 ' this.props.item.name',
799 ' </a>',
800 ' </li>',
801 ' );',
802 ' }',
803 '});'
804 ]
805 },
806 {
807 unchanged: [
808 'var List = React.createClass({',
809 ' renderList: function() {',
810 ' return this.props.items.map(function(item) {',
811 ' return <ListItem item={item} key={item.id} />;',
812 ' });',
813 ' },',
814 '',
815 ' render: function() {',
816 ' return <ul className="List">',
817 ' this.renderList()',
818 ' </ul>',
819 ' }',
820 '});'
821 ]
822 },
823 {
824 unchanged: [
825 'var Mist = React.createClass({',
826 ' renderList: function() {',
827 ' return this.props.items.map(function(item) {',
828 ' return <ListItem item={return <tag>{item}</tag>} key={item.id} />;',
829 ' });',
830 ' }',
831 '});',
832 ]
833 },
834 {
835 unchanged: [
836 '// JSX',
837 'var box = <Box>',
838 ' {shouldShowAnswer(user) ?',
839 ' <Answer value={false}>no</Answer> : <Box.Comment>',
840 ' Text Content',
841 ' </Box.Comment>}',
842 ' </Box>;',
843 'var a = function() {',
844 ' return <tsdf>asdf</tsdf>;',
845 '};',
846 '',
847 'var HelloMessage = React.createClass({',
848 ' render: function() {',
849 ' return <div {someAttr}>Hello {this.props.name}</div>;',
850 ' }',
851 '});',
852 'React.render(<HelloMessage name="John" />, mountNode);',
853 ]
854 },
855 {
856 unchanged: [
857 'var Timer = React.createClass({',
858 ' getInitialState: function() {',
859 ' return {',
860 ' secondsElapsed: 0',
861 ' };',
862 ' },',
863 ' tick: function() {',
864 ' this.setState({',
865 ' secondsElapsed: this.state.secondsElapsed + 1',
866 ' });',
867 ' },',
868 ' componentDidMount: function() {',
869 ' this.interval = setInterval(this.tick, 1000);',
870 ' },',
871 ' componentWillUnmount: function() {',
872 ' clearInterval(this.interval);',
873 ' },',
874 ' render: function() {',
875 ' return (',
876 ' <div>Seconds Elapsed: {this.state.secondsElapsed}</div>',
877 ' );',
878 ' }',
879 '});',
880 'React.render(<Timer />, mountNode);'
881 ]
882 },
883 {
884 unchanged: [
885 'var TodoList = React.createClass({',
886 ' render: function() {',
887 ' var createItem = function(itemText) {',
888 ' return <li>{itemText}</li>;',
889 ' };',
890 ' return <ul>{this.props.items.map(createItem)}</ul>;',
891 ' }',
892 '});'
893 ]
894 },
895 {
896 unchanged: [
897 'var TodoApp = React.createClass({',
898 ' getInitialState: function() {',
899 ' return {',
900 ' items: [],',
901 ' text: \\\'\\\'',
902 ' };',
903 ' },',
904 ' onChange: function(e) {',
905 ' this.setState({',
906 ' text: e.target.value',
907 ' });',
908 ' },',
909 ' handleSubmit: function(e) {',
910 ' e.preventDefault();',
911 ' var nextItems = this.state.items.concat([this.state.text]);',
912 ' var nextText = \\\'\\\';',
913 ' this.setState({',
914 ' items: nextItems,',
915 ' text: nextText',
916 ' });',
917 ' },',
918 ' render: function() {',
919 ' return (',
920 ' <div>',
921 ' <h3 {someAttr}>TODO</h3>',
922 ' <TodoList items={this.state.items} />',
923 ' <form onSubmit={this.handleSubmit}>',
924 ' <input onChange={this.onChange} value={this.state.text} />',
925 ' <button>{\\\'Add #\\\' + (this.state.items.length + 1)}</button>',
926 ' </form>',
927 ' </div>',
928 ' );',
929 ' }',
930 '});',
931 'React.render(<TodoApp />, mountNode);'
932 ]
933 },
934 {
935 input: [
936 'var converter = new Showdown.converter();',
937 'var MarkdownEditor = React.createClass({',
938 ' getInitialState: function() {',
939 ' return {value: \\\'Type some *markdown* here!\\\'};',
940 ' },',
941 ' handleChange: function() {',
942 ' this.setState({value: this.refs.textarea.getDOMNode().value});',
943 ' },',
944 ' render: function() {',
945 ' return (',
946 ' <div className="MarkdownEditor">',
947 ' <h3>Input</h3>',
948 ' <textarea',
949 ' onChange={this.handleChange}',
950 ' ref="textarea"',
951 ' defaultValue={this.state.value} />',
952 ' <h3>Output</h3>',
953 ' <div',
954 ' className="content"',
955 ' dangerouslySetInnerHTML={{',
956 ' __html: converter.makeHtml(this.state.value)',
957 ' }}',
958 ' />',
959 ' </div>',
960 ' );',
961 ' }',
962 '});',
963 'React.render(<MarkdownEditor />, mountNode);'
964  
965 ],
966 output: [
967 'var converter = new Showdown.converter();',
968 'var MarkdownEditor = React.createClass({',
969 ' getInitialState: function() {',
970 ' return {',
971 ' value: \\\'Type some *markdown* here!\\\'',
972 ' };',
973 ' },',
974 ' handleChange: function() {',
975 ' this.setState({',
976 ' value: this.refs.textarea.getDOMNode().value',
977 ' });',
978 ' },',
979 ' render: function() {',
980 ' return (',
981 ' <div className="MarkdownEditor">',
982 ' <h3>Input</h3>',
983 ' <textarea',
984 ' onChange={this.handleChange}',
985 ' ref="textarea"',
986 ' defaultValue={this.state.value} />',
987 ' <h3>Output</h3>',
988 ' <div',
989 ' className="content"',
990 ' dangerouslySetInnerHTML={{',
991 ' __html: converter.makeHtml(this.state.value)',
992 ' }}',
993 ' />',
994 ' </div>',
995 ' );',
996 ' }',
997 '});',
998 'React.render(<MarkdownEditor />, mountNode);'
999 ]
1000 },
1001 {
1002 comment: 'JSX - Not quite correct jsx formatting that still works',
1003 input: [
1004 'var content = (',
1005 ' <Nav>',
1006 ' {/* child comment, put {} around */}',
1007 ' <Person',
1008 ' /* multi',
1009 ' line',
1010 ' comment */',
1011 ' //attr="test"',
1012 ' name={window.isLoggedIn ? window.name : \\\'\\\'} // end of line comment',
1013 ' />',
1014 ' </Nav>',
1015 ' );',
1016 'var qwer = <DropDown> A dropdown list <Menu> <MenuItem>Do Something</MenuItem> <MenuItem>Do Something Fun!</MenuItem> <MenuItem>Do Something Else</MenuItem> </Menu> </DropDown>;',
1017 'render(dropdown);',
1018 ],
1019 output: [
1020 'var content = (',
1021 ' <Nav>',
1022 ' {/* child comment, put {} around */}',
1023 ' <Person',
1024 ' /* multi',
1025 ' line',
1026 ' comment */',
1027 ' //attr="test"',
1028 ' name={window.isLoggedIn ? window.name : \\\'\\\'} // end of line comment',
1029 ' />',
1030 ' </Nav>',
1031 ');',
1032 'var qwer = <DropDown> A dropdown list <Menu> <MenuItem>Do Something</MenuItem> <MenuItem>Do Something Fun!</MenuItem> <MenuItem>Do Something Else</MenuItem> </Menu> </DropDown>;',
1033 'render(dropdown);',
1034 ]
1035 },
1036 {
1037 comment: [
1038 "Handles messed up tags, as long as it isn't the same name",
1039 "as the root tag. Also handles tags of same name as root tag",
1040 "as long as nesting matches."
1041 ],
1042 input_: 'xml=<a x="jn"><c></b></f><a><d jnj="jnn"><f></a ></nj></a>;',
1043 output: 'xml = <a x="jn"><c></b></f><a><d jnj="jnn"><f></a ></nj></a>;'
1044 },
1045  
1046 {
1047 comment: [
1048 "If xml is not terminated, the remainder of the file is treated",
1049 "as part of the xml-literal (passed through unaltered)"
1050 ],
1051 fragment: true,
1052 input_: 'xml=<a></b>\nc<b;',
1053 output: 'xml = <a></b>\nc<b;'
1054 },
1055 {
1056 comment: 'Issue #646 = whitespace is allowed in attribute declarations',
1057 unchanged: [
1058 'let a = React.createClass({',
1059 ' render() {',
1060 ' return (',
1061 ' <p className=\\\'a\\\'>',
1062 ' <span>c</span>',
1063 ' </p>',
1064 ' );',
1065 ' }',
1066 '});'
1067 ]
1068 },
1069 {
1070 unchanged: [
1071 'let a = React.createClass({',
1072 ' render() {',
1073 ' return (',
1074 ' <p className = \\\'b\\\'>',
1075 ' <span>c</span>',
1076 ' </p>',
1077 ' );',
1078 ' }',
1079 '});'
1080 ]
1081 },
1082 {
1083 unchanged: [
1084 'let a = React.createClass({',
1085 ' render() {',
1086 ' return (',
1087 ' <p className = "c">',
1088 ' <span>c</span>',
1089 ' </p>',
1090 ' );',
1091 ' }',
1092 '});'
1093 ]
1094 },
1095 {
1096 unchanged: [
1097 'let a = React.createClass({',
1098 ' render() {',
1099 ' return (',
1100 ' <{e} className = {d}>',
1101 ' <span>c</span>',
1102 ' </{e}>',
1103 ' );',
1104 ' }',
1105 '});'
1106 ]
1107 },
1108 {
1109 comment: 'Issue #914 - Multiline attribute in root tag',
1110 unchanged: [
1111 'return (',
1112 ' <a href="#"',
1113 ' onClick={e => {',
1114 ' e.preventDefault()',
1115 ' onClick()',
1116 ' }}>',
1117 ' {children}',
1118 ' </a>',
1119 ');'
1120 ]
1121 },
1122 {
1123 unchanged: [
1124 'return (',
1125 ' <{',
1126 ' a + b',
1127 ' } href="#"',
1128 ' onClick={e => {',
1129 ' e.preventDefault()',
1130 ' onClick()',
1131 ' }}>',
1132 ' {children}',
1133 ' </{',
1134 ' a + b',
1135 ' }>',
1136 ');'
1137 ]
1138 },
1139 {
1140 input: [
1141 'return (',
1142 ' <{',
1143 ' a + b',
1144 ' } href="#"',
1145 ' onClick={e => {',
1146 ' e.preventDefault()',
1147 ' onClick()',
1148 ' }}>',
1149 ' {children}',
1150 ' </{a + b}>',
1151 ' );'
1152 ],
1153 output: [
1154 'return (',
1155 ' <{',
1156 ' a + b',
1157 ' } href="#"',
1158 ' onClick={e => {',
1159 ' e.preventDefault()',
1160 ' onClick()',
1161 ' }}>',
1162 ' {children}',
1163 ' </{a + b}>',
1164 ');'
1165 ]
1166 }
1167 ]
1168 }, {
1169 name: "e4x disabled",
1170 description: "",
1171 options: [
1172 { name: 'e4x', value: false }
1173 ],
1174 tests: [{
1175 input_: 'xml=<a b="c"><d/><e>\n foo</e>x</a>;',
1176 output: 'xml = < a b = "c" > < d / > < e >\n foo < /e>x</a > ;'
1177 }]
1178 }, {
1179 name: "Multiple braces",
1180 description: "",
1181 template: "^^^ $$$",
1182 options: [],
1183 tests: [
1184 { input: '{{}/z/}', output: '{\n {}\n /z/\n}' }
1185 ]
1186 }, {
1187 name: "Beautify preserve formatting",
1188 description: "Allow beautifier to preserve sections",
1189 tests: [
1190 { unchanged: "/* beautify preserve:start */\n/* beautify preserve:end */" },
1191 { unchanged: "/* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */" },
1192 { unchanged: "var a = 1;\n/* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */" },
1193 { unchanged: "/* beautify preserve:start */ {asdklgh;y;;{}dd2d}/* beautify preserve:end */" },
1194 {
1195 input_: "var a = 1;\n/* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */",
1196 output: "var a = 1;\n/* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */"
1197 },
1198 {
1199 input_: "var a = 1;\n /* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */",
1200 output: "var a = 1;\n/* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */"
1201 },
1202 {
1203 unchanged: [
1204 'var a = {',
1205 ' /* beautify preserve:start */',
1206 ' one : 1',
1207 ' two : 2,',
1208 ' three : 3,',
1209 ' ten : 10',
1210 ' /* beautify preserve:end */',
1211 '};'
1212 ]
1213 },
1214 {
1215 input: [
1216 'var a = {',
1217 '/* beautify preserve:start */',
1218 ' one : 1,',
1219 ' two : 2,',
1220 ' three : 3,',
1221 ' ten : 10',
1222 '/* beautify preserve:end */',
1223 '};'
1224 ],
1225 output: [
1226 'var a = {',
1227 ' /* beautify preserve:start */',
1228 ' one : 1,',
1229 ' two : 2,',
1230 ' three : 3,',
1231 ' ten : 10',
1232 '/* beautify preserve:end */',
1233 '};'
1234 ]
1235 },
1236 {
1237 comment: 'one space before and after required, only single spaces inside.',
1238 input: [
1239 'var a = {',
1240 '/* beautify preserve:start */',
1241 ' one : 1,',
1242 ' two : 2,',
1243 ' three : 3,',
1244 ' ten : 10',
1245 '};'
1246 ],
1247 output: [
1248 'var a = {',
1249 ' /* beautify preserve:start */',
1250 ' one: 1,',
1251 ' two: 2,',
1252 ' three: 3,',
1253 ' ten: 10',
1254 '};'
1255 ]
1256 },
1257 {
1258 input: [
1259 'var a = {',
1260 '/*beautify preserve:start*/',
1261 ' one : 1,',
1262 ' two : 2,',
1263 ' three : 3,',
1264 ' ten : 10',
1265 '};'
1266 ],
1267 output: [
1268 'var a = {',
1269 ' /*beautify preserve:start*/',
1270 ' one: 1,',
1271 ' two: 2,',
1272 ' three: 3,',
1273 ' ten: 10',
1274 '};'
1275 ]
1276 },
1277 {
1278 input: [
1279 'var a = {',
1280 '/*beautify preserve:start*/',
1281 ' one : 1,',
1282 ' two : 2,',
1283 ' three : 3,',
1284 ' ten : 10',
1285 '};'
1286 ],
1287 output: [
1288 'var a = {',
1289 ' /*beautify preserve:start*/',
1290 ' one: 1,',
1291 ' two: 2,',
1292 ' three: 3,',
1293 ' ten: 10',
1294 '};'
1295 ]
1296 },
1297  
1298 {
1299 comment: 'Directive: ignore',
1300 unchanged: "/* beautify ignore:start */\n/* beautify ignore:end */"
1301 },
1302 { unchanged: "/* beautify ignore:start */\n var a,,,{ 1;\n/* beautify ignore:end */" },
1303 { unchanged: "var a = 1;\n/* beautify ignore:start */\n var a = 1;\n/* beautify ignore:end */" },
1304 { unchanged: "/* beautify ignore:start */ {asdklgh;y;+++;dd2d}/* beautify ignore:end */" },
1305 {
1306 input_: "var a = 1;\n/* beautify ignore:start */\n var a,,,{ 1;\n/* beautify ignore:end */",
1307 output: "var a = 1;\n/* beautify ignore:start */\n var a,,,{ 1;\n/* beautify ignore:end */"
1308 },
1309 {
1310 input_: "var a = 1;\n /* beautify ignore:start */\n var a,,,{ 1;\n/* beautify ignore:end */",
1311 output: "var a = 1;\n/* beautify ignore:start */\n var a,,,{ 1;\n/* beautify ignore:end */"
1312 },
1313 {
1314 unchanged: [
1315 'var a = {',
1316 ' /* beautify ignore:start */',
1317 ' one : 1',
1318 ' two : 2,',
1319 ' three : {',
1320 ' ten : 10',
1321 ' /* beautify ignore:end */',
1322 '};'
1323 ]
1324 },
1325 {
1326 input: [
1327 'var a = {',
1328 '/* beautify ignore:start */',
1329 ' one : 1',
1330 ' two : 2,',
1331 ' three : {',
1332 ' ten : 10',
1333 '/* beautify ignore:end */',
1334 '};'
1335 ],
1336 output: [
1337 'var a = {',
1338 ' /* beautify ignore:start */',
1339 ' one : 1',
1340 ' two : 2,',
1341 ' three : {',
1342 ' ten : 10',
1343 '/* beautify ignore:end */',
1344 '};'
1345 ]
1346 },
1347 {
1348 comment: 'Directives - multiple and interacting',
1349 input: [
1350 'var a = {',
1351 '/* beautify preserve:start */',
1352 '/* beautify preserve:start */',
1353 ' one : 1,',
1354 ' /* beautify preserve:end */',
1355 ' two : 2,',
1356 ' three : 3,',
1357 '/* beautify preserve:start */',
1358 ' ten : 10',
1359 '/* beautify preserve:end */',
1360 '};'
1361 ],
1362 output: [
1363 'var a = {',
1364 ' /* beautify preserve:start */',
1365 '/* beautify preserve:start */',
1366 ' one : 1,',
1367 ' /* beautify preserve:end */',
1368 ' two: 2,',
1369 ' three: 3,',
1370 ' /* beautify preserve:start */',
1371 ' ten : 10',
1372 '/* beautify preserve:end */',
1373 '};'
1374 ]
1375 },
1376 {
1377 input: [
1378 'var a = {',
1379 '/* beautify ignore:start */',
1380 ' one : 1',
1381 ' /* beautify ignore:end */',
1382 ' two : 2,',
1383 '/* beautify ignore:start */',
1384 ' three : {',
1385 ' ten : 10',
1386 '/* beautify ignore:end */',
1387 '};'
1388 ],
1389 output: [
1390 'var a = {',
1391 ' /* beautify ignore:start */',
1392 ' one : 1',
1393 ' /* beautify ignore:end */',
1394 ' two: 2,',
1395 ' /* beautify ignore:start */',
1396 ' three : {',
1397 ' ten : 10',
1398 '/* beautify ignore:end */',
1399 '};'
1400 ]
1401 },
1402 {
1403 comment: 'Starts can occur together, ignore:end must occur alone.',
1404 input: [
1405 'var a = {',
1406 '/* beautify ignore:start */',
1407 ' one : 1',
1408 ' NOTE: ignore end block does not support starting other directives',
1409 ' This does not match the ending the ignore...',
1410 ' /* beautify ignore:end preserve:start */',
1411 ' two : 2,',
1412 '/* beautify ignore:start */',
1413 ' three : {',
1414 ' ten : 10',
1415 ' ==The next comment ends the starting ignore==',
1416 '/* beautify ignore:end */',
1417 '};'
1418 ],
1419 output: [
1420 'var a = {',
1421 ' /* beautify ignore:start */',
1422 ' one : 1',
1423 ' NOTE: ignore end block does not support starting other directives',
1424 ' This does not match the ending the ignore...',
1425 ' /* beautify ignore:end preserve:start */',
1426 ' two : 2,',
1427 '/* beautify ignore:start */',
1428 ' three : {',
1429 ' ten : 10',
1430 ' ==The next comment ends the starting ignore==',
1431 '/* beautify ignore:end */',
1432 '};'
1433 ]
1434 },
1435 {
1436 input: [
1437 'var a = {',
1438 '/* beautify ignore:start preserve:start */',
1439 ' one : {',
1440 ' /* beautify ignore:end */',
1441 ' two : 2,',
1442 ' /* beautify ignore:start */',
1443 ' three : {',
1444 '/* beautify ignore:end */',
1445 ' ten : 10',
1446 ' // This is all preserved',
1447 '};'
1448 ],
1449 output: [
1450 'var a = {',
1451 ' /* beautify ignore:start preserve:start */',
1452 ' one : {',
1453 ' /* beautify ignore:end */',
1454 ' two : 2,',
1455 ' /* beautify ignore:start */',
1456 ' three : {',
1457 '/* beautify ignore:end */',
1458 ' ten : 10',
1459 ' // This is all preserved',
1460 '};'
1461 ]
1462 },
1463 {
1464 input: [
1465 'var a = {',
1466 '/* beautify ignore:start preserve:start */',
1467 ' one : {',
1468 ' /* beautify ignore:end */',
1469 ' two : 2,',
1470 ' /* beautify ignore:start */',
1471 ' three : {',
1472 '/* beautify ignore:end */',
1473 ' ten : 10,',
1474 '/* beautify preserve:end */',
1475 ' eleven: 11',
1476 '};'
1477 ],
1478 output: [
1479 'var a = {',
1480 ' /* beautify ignore:start preserve:start */',
1481 ' one : {',
1482 ' /* beautify ignore:end */',
1483 ' two : 2,',
1484 ' /* beautify ignore:start */',
1485 ' three : {',
1486 '/* beautify ignore:end */',
1487 ' ten : 10,',
1488 '/* beautify preserve:end */',
1489 ' eleven: 11',
1490 '};'
1491 ]
1492 },
1493 ]
1494 }, {
1495 name: "Comments and tests",
1496 description: "Comments should be in the right indent and not side-ffect.",
1497 options: [],
1498 tests: [{
1499 comment: '#913',
1500  
1501 unchanged: [
1502 'class test {',
1503 ' method1() {',
1504 ' let resp = null;',
1505 ' }',
1506 ' /**',
1507 ' * @param {String} id',
1508 ' */',
1509 ' method2(id) {',
1510 ' let resp2 = null;',
1511 ' }',
1512 '}'
1513 ]
1514 },
1515 {
1516 comment: '#1090',
1517 unchanged: [
1518 'for (var i = 0; i < 20; ++i) // loop',
1519 ' if (i % 3) {',
1520 ' console.log(i);',
1521 ' }',
1522 'console.log("done");',
1523 ]
1524 },
1525 {
1526 comment: '#1043',
1527 unchanged: [
1528 'var o = {',
1529 ' k: 0',
1530 '}',
1531 '// ...',
1532 'foo(o)',
1533 ]
1534 },
1535 {
1536 comment: '#713 and #964',
1537 unchanged: [
1538 'Meteor.call("foo", bar, function(err, result) {',
1539 ' Session.set("baz", result.lorem)',
1540 '})',
1541 '//blah blah',
1542 ]
1543 },
1544 {
1545 comment: '#815',
1546 unchanged: [
1547 'foo()',
1548 '// this is a comment',
1549 'bar()',
1550 '',
1551 'const foo = 5',
1552 '// comment',
1553 'bar()',
1554 ]
1555 },
1556 {
1557 comment: 'This shows current behavior. Note #1069 is not addressed yet.',
1558 unchanged: [
1559 'if (modulus === 2) {',
1560 ' // i might be odd here',
1561 ' i += (i & 1);',
1562 ' // now i is guaranteed to be even',
1563 ' // this block is obviously about the statement above',
1564 '',
1565 ' // #1069 This should attach to the block below',
1566 ' // this comment is about the block after it.',
1567 '} else {',
1568 ' // rounding up using integer arithmetic only',
1569 ' if (i % modulus)',
1570 ' i += modulus - (i % modulus);',
1571 ' // now i is divisible by modulus',
1572 ' // behavior of comments should be different for single statements vs block statements/expressions',
1573 '}',
1574 '',
1575 'if (modulus === 2)',
1576 ' // i might be odd here',
1577 ' i += (i & 1);',
1578 '// now i is guaranteed to be even',
1579 '// non-braced comments unindent immediately',
1580 '',
1581 '// this comment is about the block after it.',
1582 'else',
1583 ' // rounding up using integer arithmetic only',
1584 ' if (i % modulus)',
1585 ' i += modulus - (i % modulus);',
1586 '// behavior of comments should be different for single statements vs block statements/expressions',
1587 ]
1588 },
1589  
1590 ]
1591 }, {
1592 name: "Template Formatting",
1593 description: "Php (<?php ... ?>) and underscore.js templating treated as strings.",
1594 options: [],
1595 tests: [
1596 { unchanged: '<?=$view["name"]; ?>' },
1597 { unchanged: 'a = <?= external() ?>;' },
1598 {
1599 unchanged: [
1600 '<?php',
1601 'for($i = 1; $i <= 100; $i++;) {',
1602 ' #count to 100!',
1603 ' echo($i . "</br>");',
1604 '}',
1605 '?>'
1606 ]
1607 },
1608 { unchanged: 'a = <%= external() %>;' }
1609 ]
1610 }, {
1611 name: "jslint and space after anon function",
1612 description: "jslint_happy and space_after_anon_function tests",
1613 matrix: [{
1614 options: [
1615 { name: "jslint_happy", value: "true" },
1616 { name: "space_after_anon_function", value: "true" }
1617 ],
1618 f: ' ',
1619 c: ''
1620 }, {
1621 options: [
1622 { name: "jslint_happy", value: "true" },
1623 { name: "space_after_anon_function", value: "false" }
1624 ],
1625 f: ' ',
1626 c: ''
1627 }, {
1628 options: [
1629 { name: "jslint_happy", value: "false" },
1630 { name: "space_after_anon_function", value: "true" }
1631 ],
1632 f: ' ',
1633 c: ' '
1634 }, {
1635 options: [
1636 { name: "jslint_happy", value: "false" },
1637 { name: "space_after_anon_function", value: "false" }
1638 ],
1639 f: '',
1640 c: ' '
1641 }
1642  
1643  
1644 ],
1645 tests: [{
1646 input_: 'a=typeof(x)',
1647 output: 'a = typeof{{f}}(x)'
1648 },
1649 {
1650 input_: 'x();\n\nfunction(){}',
1651 output: 'x();\n\nfunction{{f}}() {}'
1652 },
1653 {
1654 input_: 'x();\n\nvar x = {\nx: function(){}\n}',
1655 output: 'x();\n\nvar x = {\n x: function{{f}}() {}\n}'
1656 },
1657 {
1658 input_: 'function () {\n var a, b, c, d, e = [],\n f;\n}',
1659 output: 'function{{f}}() {\n var a, b, c, d, e = [],\n f;\n}'
1660 },
1661  
1662 {
1663 input_: 'switch(x) {case 0: case 1: a(); break; default: break}',
1664 output: 'switch (x) {\n{{c}}case 0:\n{{c}}case 1:\n{{c}} a();\n{{c}} break;\n{{c}}default:\n{{c}} break\n}'
1665 },
1666 {
1667 input: 'switch(x){case -1:break;case !y:break;}',
1668 output: 'switch (x) {\n{{c}}case -1:\n{{c}} break;\n{{c}}case !y:\n{{c}} break;\n}'
1669 },
1670 {
1671 comment: 'typical greasemonkey start',
1672 fragment: true,
1673 unchanged: '// comment 2\n(function{{f}}()'
1674 },
1675  
1676 {
1677 input_: 'var a2, b2, c2, d2 = 0, c = function() {}, d = \\\'\\\';',
1678 output: 'var a2, b2, c2, d2 = 0,\n c = function{{f}}() {},\n d = \\\'\\\';'
1679 },
1680 {
1681 input_: 'var a2, b2, c2, d2 = 0, c = function() {},\nd = \\\'\\\';',
1682 output: 'var a2, b2, c2, d2 = 0,\n c = function{{f}}() {},\n d = \\\'\\\';'
1683 },
1684 {
1685 input_: 'var o2=$.extend(a);function(){alert(x);}',
1686 output: 'var o2 = $.extend(a);\n\nfunction{{f}}() {\n alert(x);\n}'
1687 },
1688 { input: 'function*() {\n yield 1;\n}', output: 'function*{{f}}() {\n yield 1;\n}' },
1689 { unchanged: 'function* x() {\n yield 1;\n}' },
1690 ]
1691 }, {
1692 name: "Regression tests",
1693 description: "Ensure specific bugs do not recur",
1694 options: [],
1695 tests: [{
1696 comment: "Issue 241",
1697 unchanged: [
1698 'obj',
1699 ' .last({',
1700 ' foo: 1,',
1701 ' bar: 2',
1702 ' });',
1703 'var test = 1;'
1704 ]
1705 },
1706 {
1707 unchanged: [
1708 'obj',
1709 ' .last(a, function() {',
1710 ' var test;',
1711 ' });',
1712 'var test = 1;'
1713 ]
1714 },
1715 {
1716 unchanged: [
1717 'obj.first()',
1718 ' .second()',
1719 ' .last(function(err, response) {',
1720 ' console.log(err);',
1721 ' });'
1722 ]
1723 },
1724 {
1725 comment: "Issue 268 and 275",
1726 unchanged: [
1727 'obj.last(a, function() {',
1728 ' var test;',
1729 '});',
1730 'var test = 1;'
1731 ]
1732 },
1733 {
1734 unchanged: [
1735 'obj.last(a,',
1736 ' function() {',
1737 ' var test;',
1738 ' });',
1739 'var test = 1;'
1740 ]
1741 },
1742 {
1743 input: '(function() {if (!window.FOO) window.FOO || (window.FOO = function() {var b = {bar: "zort"};});})();',
1744 output: [
1745 '(function() {',
1746 ' if (!window.FOO) window.FOO || (window.FOO = function() {',
1747 ' var b = {',
1748 ' bar: "zort"',
1749 ' };',
1750 ' });',
1751 '})();'
1752 ]
1753 },
1754 {
1755 comment: "Issue 281",
1756 unchanged: [
1757 'define(["dojo/_base/declare", "my/Employee", "dijit/form/Button",',
1758 ' "dojo/_base/lang", "dojo/Deferred"',
1759 '], function(declare, Employee, Button, lang, Deferred) {',
1760 ' return declare(Employee, {',
1761 ' constructor: function() {',
1762 ' new Button({',
1763 ' onClick: lang.hitch(this, function() {',
1764 ' new Deferred().then(lang.hitch(this, function() {',
1765 ' this.salary * 0.25;',
1766 ' }));',
1767 ' })',
1768 ' });',
1769 ' }',
1770 ' });',
1771 '});'
1772 ]
1773 },
1774 {
1775 unchanged: [
1776 'define(["dojo/_base/declare", "my/Employee", "dijit/form/Button",',
1777 ' "dojo/_base/lang", "dojo/Deferred"',
1778 ' ],',
1779 ' function(declare, Employee, Button, lang, Deferred) {',
1780 ' return declare(Employee, {',
1781 ' constructor: function() {',
1782 ' new Button({',
1783 ' onClick: lang.hitch(this, function() {',
1784 ' new Deferred().then(lang.hitch(this, function() {',
1785 ' this.salary * 0.25;',
1786 ' }));',
1787 ' })',
1788 ' });',
1789 ' }',
1790 ' });',
1791 ' });'
1792 ]
1793 },
1794 {
1795 comment: "Issue 459",
1796 unchanged: [
1797 '(function() {',
1798 ' return {',
1799 ' foo: function() {',
1800 ' return "bar";',
1801 ' },',
1802 ' bar: ["bar"]',
1803 ' };',
1804 '}());'
1805 ]
1806 },
1807 {
1808 comment: "Issue 505 - strings should end at newline unless continued by backslash",
1809 unchanged: [
1810 'var name = "a;',
1811 'name = "b";'
1812 ]
1813 },
1814 {
1815 unchanged: [
1816 'var name = "a;\\\\',
1817 ' name = b";'
1818 ]
1819 },
1820 {
1821 comment: "Issue 514 - some operators require spaces to distinguish them",
1822 unchanged: 'var c = "_ACTION_TO_NATIVEAPI_" + ++g++ + +new Date;'
1823 },
1824 {
1825 unchanged: 'var c = "_ACTION_TO_NATIVEAPI_" - --g-- - -new Date;'
1826 },
1827 {
1828 comment: "Issue 440 - reserved words can be used as object property names",
1829 unchanged: [
1830 'a = {',
1831 ' function: {},',
1832 ' "function": {},',
1833 ' throw: {},',
1834 ' "throw": {},',
1835 ' var: {},',
1836 ' "var": {},',
1837 ' set: {},',
1838 ' "set": {},',
1839 ' get: {},',
1840 ' "get": {},',
1841 ' if: {},',
1842 ' "if": {},',
1843 ' then: {},',
1844 ' "then": {},',
1845 ' else: {},',
1846 ' "else": {},',
1847 ' yay: {}',
1848 '};'
1849 ]
1850 },
1851 {
1852 comment: "Issue 331 - if-else with braces edge case",
1853 input: 'if(x){a();}else{b();}if(y){c();}',
1854 output: [
1855 'if (x) {',
1856 ' a();',
1857 '} else {',
1858 ' b();',
1859 '}',
1860 'if (y) {',
1861 ' c();',
1862 '}'
1863 ]
1864 },
1865 {
1866 comment: "Issue 485 - ensure function declarations behave the same in arrays as elsewhere",
1867 unchanged: [
1868 'var v = ["a",',
1869 ' function() {',
1870 ' return;',
1871 ' }, {',
1872 ' id: 1',
1873 ' }',
1874 '];'
1875 ]
1876 },
1877 {
1878 unchanged: [
1879 'var v = ["a", function() {',
1880 ' return;',
1881 '}, {',
1882 ' id: 1',
1883 '}];'
1884 ]
1885 },
1886 {
1887 comment: "Issue 382 - initial totally cursory support for es6 module export",
1888 unchanged: [
1889 'module "Even" {',
1890 ' import odd from "Odd";',
1891 ' export function sum(x, y) {',
1892 ' return x + y;',
1893 ' }',
1894 ' export var pi = 3.141593;',
1895 ' export default moduleName;',
1896 '}'
1897 ]
1898 },
1899 {
1900 unchanged: [
1901 'module "Even" {',
1902 ' export default function div(x, y) {}',
1903 '}'
1904 ]
1905 },
1906 {
1907 comment: 'Issue 889 - export default { ... }',
1908 unchanged: [
1909 'export default {',
1910 ' func1() {},',
1911 ' func2() {}',
1912 ' func3() {}',
1913 '}'
1914 ]
1915 },
1916 {
1917 unchanged: [
1918 'export default {',
1919 ' a() {',
1920 ' return 1;',
1921 ' },',
1922 ' b() {',
1923 ' return 2;',
1924 ' },',
1925 ' c() {',
1926 ' return 3;',
1927 ' }',
1928 '}'
1929 ]
1930 },
1931 {
1932 comment: "Issue 508",
1933 unchanged: 'set["name"]'
1934 },
1935 {
1936 unchanged: 'get["name"]'
1937 },
1938 {
1939 fragmeent: true,
1940 unchanged: [
1941 'a = {',
1942 ' set b(x) {},',
1943 ' c: 1,',
1944 ' d: function() {}',
1945 '};'
1946 ]
1947 },
1948 {
1949 fragmeent: true,
1950 unchanged: [
1951 'a = {',
1952 ' get b() {',
1953 ' retun 0;',
1954 ' },',
1955 ' c: 1,',
1956 ' d: function() {}',
1957 '};'
1958 ]
1959 },
1960 {
1961 comment: "Issue 298 - do not under indent if/while/for condtionals experesions",
1962 unchanged: [
1963 '\\\'use strict\\\';',
1964 'if ([].some(function() {',
1965 ' return false;',
1966 ' })) {',
1967 ' console.log("hello");',
1968 '}'
1969 ]
1970 },
1971 {
1972 comment: "Issue 298 - do not under indent if/while/for condtionals experesions",
1973 unchanged: [
1974 '\\\'use strict\\\';',
1975 'if ([].some(function() {',
1976 ' return false;',
1977 ' })) {',
1978 ' console.log("hello");',
1979 '}'
1980 ]
1981 },
1982 {
1983 comment: "Issue 552 - Typescript? Okay... we didn't break it before, so try not to break it now.",
1984 unchanged: [
1985 'class Test {',
1986 ' blah: string[];',
1987 ' foo(): number {',
1988 ' return 0;',
1989 ' }',
1990 ' bar(): number {',
1991 ' return 0;',
1992 ' }',
1993 '}'
1994 ]
1995 },
1996 {
1997 unchanged: [
1998 'interface Test {',
1999 ' blah: string[];',
2000 ' foo(): number {',
2001 ' return 0;',
2002 ' }',
2003 ' bar(): number {',
2004 ' return 0;',
2005 ' }',
2006 '}'
2007 ]
2008 },
2009 {
2010 comment: "Issue 583 - Functions with comments after them should still indent correctly.",
2011 unchanged: [
2012 'function exit(code) {',
2013 ' setTimeout(function() {',
2014 ' phantom.exit(code);',
2015 ' }, 0);',
2016 ' phantom.onError = function() {};',
2017 '}',
2018 '// Comment'
2019 ]
2020 },
2021 {
2022 comment: "Issue 806 - newline arrow functions",
2023 unchanged: [
2024 'a.b("c",',
2025 ' () => d.e',
2026 ')'
2027 ]
2028 },
2029 {
2030 comment: "Issue 810 - es6 object literal detection",
2031 unchanged: [
2032 'function badFormatting() {',
2033 ' return {',
2034 ' a,',
2035 ' b: c,',
2036 ' d: e,',
2037 ' f: g,',
2038 ' h,',
2039 ' i,',
2040 ' j: k',
2041 ' }',
2042 '}',
2043 '',
2044 'function goodFormatting() {',
2045 ' return {',
2046 ' a: b,',
2047 ' c,',
2048 ' d: e,',
2049 ' f: g,',
2050 ' h,',
2051 ' i,',
2052 ' j: k',
2053 ' }',
2054 '}'
2055 ]
2056 },
2057 {
2058 comment: "Issue 602 - ES6 object literal shorthand functions",
2059 unchanged: [
2060 'return {',
2061 ' fn1() {},',
2062 ' fn2() {}',
2063 '}'
2064 ]
2065 }, {
2066 unchanged: [
2067 'throw {',
2068 ' fn1() {},',
2069 ' fn2() {}',
2070 '}'
2071 ]
2072 }, {
2073 unchanged: [
2074 'foo({',
2075 ' fn1(a) {}',
2076 ' fn2(a) {}',
2077 '})'
2078 ]
2079 }, {
2080 unchanged: [
2081 'foo("text", {',
2082 ' fn1(a) {}',
2083 ' fn2(a) {}',
2084 '})'
2085 ]
2086 }, {
2087 unchanged: [
2088 'oneArg = {',
2089 ' fn1(a) {',
2090 ' do();',
2091 ' },',
2092 ' fn2() {}',
2093 '}'
2094 ]
2095 }, {
2096 unchanged: [
2097 'multiArg = {',
2098 ' fn1(a, b, c) {',
2099 ' do();',
2100 ' },',
2101 ' fn2() {}',
2102 '}'
2103 ]
2104 }, {
2105 unchanged: [
2106 'noArgs = {',
2107 ' fn1() {',
2108 ' do();',
2109 ' },',
2110 ' fn2() {}',
2111 '}'
2112 ]
2113 }, {
2114 unchanged: [
2115 'emptyFn = {',
2116 ' fn1() {},',
2117 ' fn2() {}',
2118 '}'
2119 ]
2120 }, {
2121 unchanged: [
2122 'nested = {',
2123 ' fns: {',
2124 ' fn1() {},',
2125 ' fn2() {}',
2126 ' }',
2127 '}'
2128 ]
2129 }, {
2130 unchanged: [
2131 'array = [{',
2132 ' fn1() {},',
2133 ' prop: val,',
2134 ' fn2() {}',
2135 '}]'
2136 ]
2137 }, {
2138 unchanged: [
2139 'expr = expr ? expr : {',
2140 ' fn1() {},',
2141 ' fn2() {}',
2142 '}'
2143 ]
2144 }, {
2145 unchanged: [
2146 'strange = valid + {',
2147 ' fn1() {},',
2148 ' fn2() {',
2149 ' return 1;',
2150 ' }',
2151 '}.fn2()'
2152 ]
2153 },
2154 {
2155 comment: "Issue 854 - Arrow function with statement block",
2156 unchanged: [
2157 'test(() => {',
2158 ' var a = {}',
2159 '',
2160 ' a.what = () => true ? 1 : 2',
2161 '',
2162 ' a.thing = () => {',
2163 ' b();',
2164 ' }',
2165 '})'
2166 ]
2167 },
2168 {
2169 comment: "Issue 406 - Multiline array",
2170 unchanged: [
2171 'var tempName = [',
2172 ' "temp",',
2173 ' process.pid,',
2174 ' (Math.random() * 0x1000000000).toString(36),',
2175 ' new Date().getTime()',
2176 '].join("-");'
2177 ]
2178 },
2179 {
2180 comment: "Issue #996 - Input ends with backslash throws exception",
2181 fragment: true,
2182 unchanged: [
2183 'sd = 1;',
2184 '/'
2185 ]
2186 },
2187 {
2188 comment: "Issue #1079 - unbraced if with comments should still look right",
2189 unchanged: [
2190 'if (console.log)',
2191 ' for (var i = 0; i < 20; ++i)',
2192 ' if (i % 3)',
2193 ' console.log(i);',
2194 '// all done',
2195 'console.log("done");'
2196 ]
2197 },
2198 {
2199 comment: "Issue #1085 - function should not have blank line in a number of cases",
2200 unchanged: [
2201 'var transformer =',
2202 ' options.transformer ||',
2203 ' globalSettings.transformer ||',
2204 ' function(x) {',
2205 ' return x;',
2206 ' };'
2207 ]
2208 },
2209 {
2210 comment: "Issue #569 - function should not have blank line in a number of cases",
2211 unchanged: [
2212 '(function(global) {',
2213 ' "use strict";',
2214 '',
2215 ' /* jshint ignore:start */',
2216 ' include "somefile.js"',
2217 ' /* jshint ignore:end */',
2218 '}(this));'
2219 ]
2220 },
2221 {
2222 unchanged: [
2223 'function bindAuthEvent(eventName) {',
2224 ' self.auth.on(eventName, function(event, meta) {',
2225 ' self.emit(eventName, event, meta);',
2226 ' });',
2227 '}',
2228 '["logged_in", "logged_out", "signed_up", "updated_user"].forEach(bindAuthEvent);',
2229 '',
2230 'function bindBrowserEvent(eventName) {',
2231 ' browser.on(eventName, function(event, meta) {',
2232 ' self.emit(eventName, event, meta);',
2233 ' });',
2234 '}',
2235 '["navigating"].forEach(bindBrowserEvent);'
2236 ]
2237 },
2238 {
2239 comment: "Issue #892 - new line between chained methods ",
2240 unchanged: [
2241 'foo',
2242 ' .who()',
2243 '',
2244 ' .knows()',
2245 ' // comment',
2246 ' .nothing() // comment',
2247 '',
2248 ' .more()'
2249 ]
2250 }
2251 ]
2252 }, {
2253 name: "Test non-positionable-ops",
2254 description: "Ensure specific bugs do not recur",
2255 tests: [
2256 { unchanged: 'a += 2;' },
2257 { unchanged: 'a -= 2;' },
2258 { unchanged: 'a *= 2;' },
2259 { unchanged: 'a /= 2;' },
2260 { unchanged: 'a %= 2;' },
2261 { unchanged: 'a &= 2;' },
2262 { unchanged: 'a ^= 2;' },
2263 { unchanged: 'a |= 2;' },
2264 { unchanged: 'a **= 2;' },
2265 { unchanged: 'a <<= 2;' },
2266 { unchanged: 'a >>= 2;' },
2267 ]
2268 }, {
2269 //Relies on the tab being four spaces as default for the tests
2270 name: "brace_style ,preserve-inline tests",
2271 description: "brace_style *,preserve-inline varying different brace_styles",
2272 template: "< >",
2273 matrix: [
2274 //test for all options of brace_style
2275 {
2276 options: [
2277 { name: "brace_style", value: "'collapse,preserve-inline'" }
2278 ],
2279 obo: ' ',
2280 obot: '', //Output Before Open curlybrace & Tab character
2281 oao: '\n',
2282 oaot: ' ', //Output After Open curlybrace & corresponding Tab
2283 obc: '\n', //Output Before Close curlybrace
2284 oac: ' ',
2285 oact: '' //Output After Close curlybrace & corresponding Tab character
2286 },
2287 {
2288 options: [
2289 { name: "brace_style", value: "'expand,preserve-inline'" }
2290 ],
2291 obo: '\n',
2292 obot: ' ',
2293 oao: '\n',
2294 oaot: ' ',
2295 obc: '\n',
2296 oac: '\n',
2297 oact: ' '
2298 },
2299 {
2300 options: [
2301 { name: "brace_style", value: "'end-expand,preserve-inline'" }
2302 ],
2303 obo: ' ',
2304 obot: '',
2305 oao: '\n',
2306 oaot: ' ',
2307 obc: '\n',
2308 oac: '\n',
2309 oact: ' '
2310 },
2311 {
2312 //None tries not to touch brace style so all the tests in this
2313 //matrix were formatted as if they were collapse
2314 options: [
2315 { name: "brace_style", value: "'none,preserve-inline'" }
2316 ],
2317 obo: ' ',
2318 obot: '',
2319 oao: '\n',
2320 oaot: ' ',
2321 obc: '\n',
2322 oac: ' ',
2323 oact: ''
2324 },
2325 //Test for backward compatibility
2326 {
2327 options: [
2328 { name: "brace_style", value: "'collapse-preserve-inline'" }
2329 ],
2330 //Equivalent to the output of the first test
2331 obo: ' ',
2332 obot: '',
2333 oao: '\n',
2334 oaot: ' ',
2335 obc: '\n',
2336 oac: ' ',
2337 oact: ''
2338 }
2339 ],
2340 tests: [
2341 //Test single inline blocks
2342 {
2343 unchanged: 'import { asdf } from "asdf";'
2344 },
2345 {
2346 unchanged: 'import { get } from "asdf";'
2347 },
2348 {
2349 unchanged: 'function inLine() { console.log("oh em gee"); }'
2350 },
2351 {
2352 unchanged: 'if (cancer) { console.log("Im sorry but you only have so long to live..."); }'
2353 },
2354 //Test more complex inliners
2355 {
2356 input: 'if (ding) { console.log("dong"); } else { console.log("dang"); }',
2357 output: 'if (ding) { console.log("dong"); }<oac>else { console.log("dang"); }'
2358 },
2359 //Test complex mixes of the two
2360 {
2361 //The outer function and the third object (obj3) should not
2362 //be preserved. All other objects should be
2363 input: [
2364 'function kindaComplex() {',
2365 ' var a = 2;',
2366 ' var obj = {};',
2367 ' var obj2 = { a: "a", b: "b" };',
2368 ' var obj3 = {',
2369 ' c: "c",',
2370 ' d: "d",',
2371 ' e: "e"',
2372 ' };',
2373 '}'
2374 ],
2375 output: [
2376 'function kindaComplex()<obo>{<oao>' + //NL in templates
2377 '<oaot>var a = 2;',
2378 ' var obj = {};',
2379 ' var obj2 = { a: "a", b: "b" };',
2380 ' var obj3 = {<oao>' + //NL in templates, Expand doesnt affect js objects
2381 '<oaot><oaot>c: "c",',
2382 ' d: "d",',
2383 ' e: "e"' + //NL in templates
2384 '<obc> };' + //NL in templates
2385 '<obc>}'
2386 ]
2387 },
2388 {
2389 //All inlines should be preserved, all non-inlines (specifically
2390 //complex(), obj, and obj.b should not be preserved (and hence
2391 //have the template spacing defined in output)
2392 input: [
2393 'function complex() {',
2394 ' console.log("wowe");',
2395 ' (function() { var a = 2; var b = 3; })();',
2396 ' $.each(arr, function(el, idx) { return el; });',
2397 ' var obj = {',
2398 ' a: function() { console.log("test"); },',
2399 ' b() {',
2400 ' console.log("test2");',
2401 ' }',
2402 ' };',
2403 '}'
2404  
2405 ],
2406 output: [
2407 'function complex()<obo>{<oao>' + //NL in templates
2408 '<oaot>console.log("wowe");',
2409 ' (function() { var a = 2; var b = 3; })();',
2410 ' $.each(arr, function(el, idx) { return el; });',
2411 ' var obj = {<oao>' + //NL in templates
2412 '<oaot><oaot>a: function() { console.log("test"); },',
2413 ' b()<obo><obot><obot>{<oao>' + //NL in templates
2414 '<oaot><oaot><oaot>console.log("test2");' +
2415 '<obc> }' + //NL in templates
2416 '<obc> };' + //NL in templates
2417 '<obc>}'
2418 ]
2419 }
2420 ]
2421 }, {
2422 name: "Destructured and related",
2423 description: "Ensure specific bugs do not recur",
2424 options: [
2425 { name: "brace_style", value: "'collapse,preserve-inline'" }
2426 ], //Issue 1052, now collapse,preserve-inline instead of collapse-preserve-inline
2427 tests: [{
2428 comment: "Issue 382 - import destructured ",
2429 unchanged: [
2430 'module "Even" {',
2431 ' import { odd, oddly } from "Odd";',
2432 '}'
2433 ]
2434 },
2435 {
2436 unchanged: [
2437 'import defaultMember from "module-name";',
2438 'import * as name from "module-name";',
2439 'import { member } from "module-name";',
2440 'import { member as alias } from "module-name";',
2441 'import { member1, member2 } from "module-name";',
2442 'import { member1, member2 as alias2 } from "module-name";',
2443 'import defaultMember, { member, member2 } from "module-name";',
2444 'import defaultMember, * as name from "module-name";',
2445 'import "module-name";'
2446 ]
2447 },
2448 {
2449 comment: "Issue 858 - from is a keyword only after import",
2450 unchanged: [
2451 'if (from < to) {',
2452 ' from++;',
2453 '} else {',
2454 ' from--;',
2455 '}'
2456 ]
2457 },
2458 {
2459 comment: "Issue 511 - destrutured",
2460 unchanged: [
2461 'var { b, c } = require("../stores");',
2462 'var { ProjectStore } = require("../stores");',
2463 '',
2464 'function takeThing({ prop }) {',
2465 ' console.log("inner prop", prop)',
2466 '}'
2467 ]
2468 },
2469 {
2470 comment: "Issue 315 - Short objects",
2471 unchanged: [
2472 'var a = { b: { c: { d: e } } };'
2473 ]
2474 },
2475 {
2476 unchanged: [
2477 'var a = {',
2478 ' b: {',
2479 ' c: { d: e }',
2480 ' c3: { d: e }',
2481 ' },',
2482 ' b2: { c: { d: e } }',
2483 '};'
2484 ]
2485 },
2486 {
2487 comment: "Issue 370 - Short objects in array",
2488 unchanged: [
2489 'var methods = [',
2490 ' { name: "to" },',
2491 ' { name: "step" },',
2492 ' { name: "move" },',
2493 ' { name: "min" },',
2494 ' { name: "max" }',
2495 '];'
2496 ]
2497 },
2498 {
2499 comment: "Issue 838 - Short objects in array",
2500 unchanged: [
2501 'function(url, callback) {',
2502 ' var script = document.createElement("script")',
2503 ' if (true) script.onreadystatechange = function() {',
2504 ' foo();',
2505 ' }',
2506 ' else script.onload = callback;',
2507 '}'
2508 ]
2509 },
2510 {
2511 comment: "Issue 578 - Odd indenting after function",
2512 unchanged: [
2513 'function bindAuthEvent(eventName) {',
2514 ' self.auth.on(eventName, function(event, meta) {',
2515 ' self.emit(eventName, event, meta);',
2516 ' });',
2517 '}',
2518 '["logged_in", "logged_out", "signed_up", "updated_user"].forEach(bindAuthEvent);',
2519 ]
2520 },
2521 {
2522 comment: "Issue #487 - some short expressions examples",
2523 unchanged: [
2524 'if (a == 1) { a++; }',
2525 'a = { a: a };',
2526 'UserDB.findOne({ username: "xyz" }, function(err, user) {});',
2527 'import { fs } from "fs";'
2528 ]
2529 },
2530 {
2531 comment: "Issue #982 - Fixed return expression collapse-preserve-inline",
2532 unchanged: [
2533 'function foo(arg) {',
2534 ' if (!arg) { a(); }',
2535 ' if (!arg) { return false; }',
2536 ' if (!arg) { throw "inline"; }',
2537 ' return true;',
2538 '}'
2539 ]
2540 },
2541 {
2542 comment: "Issue #338 - Short expressions ",
2543 unchanged: [
2544 'if (someCondition) { return something; }',
2545 'if (someCondition) {',
2546 ' return something;',
2547 '}',
2548 'if (someCondition) { break; }',
2549 'if (someCondition) {',
2550 ' return something;',
2551 '}'
2552 ]
2553 }
2554 ]
2555 }, {
2556 // =======================================================
2557 // New tests groups should be added above this line.
2558 // Everything below is a work in progress - converting
2559 // old test to generated form.
2560 // =======================================================
2561 name: "Old tests",
2562 description: "Largely unorganized pile of tests",
2563 options: [],
2564 tests: [
2565 { unchanged: '' },
2566 { fragment: true, unchanged: ' return .5' },
2567 { fragment: true, unchanged: ' return .5;\n a();' },
2568 { fragment: true, unchanged: ' return .5;\n a();' },
2569 { fragment: true, unchanged: ' return .5;\n a();' },
2570 { fragment: true, unchanged: ' < div' },
2571 { input: 'a = 1', output: 'a = 1' },
2572 { input: 'a=1', output: 'a = 1' },
2573 { unchanged: '(3) / 2' },
2574 { unchanged: '["a", "b"].join("")' },
2575 { unchanged: 'a();\n\nb();' },
2576 { input: 'var a = 1 var b = 2', output: 'var a = 1\nvar b = 2' },
2577 { input: 'var a=1, b=c[d], e=6;', output: 'var a = 1,\n b = c[d],\n e = 6;' },
2578 { unchanged: 'var a,\n b,\n c;' },
2579 { input: 'let a = 1 let b = 2', output: 'let a = 1\nlet b = 2' },
2580 { input: 'let a=1, b=c[d], e=6;', output: 'let a = 1,\n b = c[d],\n e = 6;' },
2581 { unchanged: 'let a,\n b,\n c;' },
2582 { input: 'const a = 1 const b = 2', output: 'const a = 1\nconst b = 2' },
2583 { input: 'const a=1, b=c[d], e=6;', output: 'const a = 1,\n b = c[d],\n e = 6;' },
2584 { unchanged: 'const a,\n b,\n c;' },
2585 { unchanged: 'a = " 12345 "' },
2586 { unchanged: "a = \\' 12345 \\'" },
2587 { unchanged: 'if (a == 1) b = 2;' },
2588 { input: 'if(1){2}else{3}', output: 'if (1) {\n 2\n} else {\n 3\n}' },
2589 { input: 'if(1||2);', output: 'if (1 || 2);' },
2590 { input: '(a==1)||(b==2)', output: '(a == 1) || (b == 2)' },
2591 { input: 'var a = 1 if (2) 3;', output: 'var a = 1\nif (2) 3;' },
2592 { unchanged: 'a = a + 1' },
2593 { unchanged: 'a = a == 1' },
2594 { unchanged: '/12345[^678]*9+/.match(a)' },
2595 { unchanged: 'a /= 5' },
2596 { unchanged: 'a = 0.5 * 3' },
2597 { unchanged: 'a *= 10.55' },
2598 { unchanged: 'a < .5' },
2599 { unchanged: 'a <= .5' },
2600 { input: 'a<.5', output: 'a < .5' },
2601 { input: 'a<=.5', output: 'a <= .5' },
2602  
2603 {
2604 comment: 'exponent literals',
2605 unchanged: 'a = 1e10'
2606 },
2607 { unchanged: 'a = 1.3e10' },
2608 { unchanged: 'a = 1.3e-10' },
2609 { unchanged: 'a = -12345.3e-10' },
2610 { unchanged: 'a = .12345e-10' },
2611 { unchanged: 'a = 06789e-10' },
2612 { unchanged: 'a = e - 10' },
2613 { unchanged: 'a = 1.3e+10' },
2614 { unchanged: 'a = 1.e-7' },
2615 { unchanged: 'a = -12345.3e+10' },
2616 { unchanged: 'a = .12345e+10' },
2617 { unchanged: 'a = 06789e+10' },
2618 { unchanged: 'a = e + 10' },
2619 { input: 'a=0e-12345.3e-10', output: 'a = 0e-12345 .3e-10' },
2620 { input: 'a=0.e-12345.3e-10', output: 'a = 0.e-12345 .3e-10' },
2621 { input: 'a=0x.e-12345.3e-10', output: 'a = 0x.e - 12345.3e-10' },
2622 { input: 'a=0x0.e-12345.3e-10', output: 'a = 0x0.e - 12345.3e-10' },
2623 { input: 'a=0x0.0e-12345.3e-10', output: 'a = 0x0 .0e-12345 .3e-10' },
2624 { input: 'a=0g-12345.3e-10', output: 'a = 0 g - 12345.3e-10' },
2625 { input: 'a=0.g-12345.3e-10', output: 'a = 0. g - 12345.3e-10' },
2626 { input: 'a=0x.g-12345.3e-10', output: 'a = 0x.g - 12345.3e-10' },
2627 { input: 'a=0x0.g-12345.3e-10', output: 'a = 0x0.g - 12345.3e-10' },
2628 { input: 'a=0x0.0g-12345.3e-10', output: 'a = 0x0 .0 g - 12345.3e-10' },
2629  
2630 {
2631 comment: 'Decimal literals',
2632 unchanged: 'a = 0123456789;'
2633 },
2634 { unchanged: 'a = 9876543210;' },
2635 { unchanged: 'a = 5647308291;' },
2636 { input: 'a=030e-5', output: 'a = 030e-5' },
2637 { input: 'a=00+4', output: 'a = 00 + 4' },
2638 { input: 'a=32+4', output: 'a = 32 + 4' },
2639 { input: 'a=0.6g+4', output: 'a = 0.6 g + 4' },
2640 { input: 'a=01.10', output: 'a = 01.10' },
2641 { input: 'a=a.10', output: 'a = a .10' },
2642 { input: 'a=00B0x0', output: 'a = 00 B0x0' },
2643 { input: 'a=00B0xb0', output: 'a = 00 B0xb0' },
2644 { input: 'a=00B0x0b0', output: 'a = 00 B0x0b0' },
2645 { input: 'a=0090x0', output: 'a = 0090 x0' },
2646 { input: 'a=0g0b0o0', output: 'a = 0 g0b0o0' },
2647  
2648 {
2649 comment: 'Hexadecimal literals',
2650 unchanged: 'a = 0x0123456789abcdef;'
2651 },
2652 { unchanged: 'a = 0X0123456789ABCDEF;' },
2653 { unchanged: 'a = 0xFeDcBa9876543210;' },
2654 { input: 'a=0x30e-5', output: 'a = 0x30e - 5' },
2655 { input: 'a=0xF0+4', output: 'a = 0xF0 + 4' },
2656 { input: 'a=0Xff+4', output: 'a = 0Xff + 4' },
2657 { input: 'a=0Xffg+4', output: 'a = 0Xff g + 4' },
2658 { input: 'a=0x01.10', output: 'a = 0x01 .10' },
2659 { unchanged: 'a = 0xb0ce;' },
2660 { unchanged: 'a = 0x0b0;' },
2661 { input: 'a=0x0B0x0', output: 'a = 0x0B0 x0' },
2662 { input: 'a=0x0B0xb0', output: 'a = 0x0B0 xb0' },
2663 { input: 'a=0x0B0x0b0', output: 'a = 0x0B0 x0b0' },
2664 { input: 'a=0X090x0', output: 'a = 0X090 x0' },
2665 { input: 'a=0Xg0b0o0', output: 'a = 0X g0b0o0' },
2666  
2667 {
2668 comment: 'Octal literals',
2669 unchanged: 'a = 0o01234567;'
2670 },
2671 { unchanged: 'a = 0O01234567;' },
2672 { unchanged: 'a = 0o34120675;' },
2673 { input: 'a=0o30e-5', output: 'a = 0o30 e - 5' },
2674 { input: 'a=0o70+4', output: 'a = 0o70 + 4' },
2675 { input: 'a=0O77+4', output: 'a = 0O77 + 4' },
2676 { input: 'a=0O778+4', output: 'a = 0O77 8 + 4' },
2677 { input: 'a=0O77a+4', output: 'a = 0O77 a + 4' },
2678 { input: 'a=0o01.10', output: 'a = 0o01 .10' },
2679 { input: 'a=0o0B0x0', output: 'a = 0o0 B0x0' },
2680 { input: 'a=0o0B0xb0', output: 'a = 0o0 B0xb0' },
2681 { input: 'a=0o0B0x0b0', output: 'a = 0o0 B0x0b0' },
2682 { input: 'a=0O090x0', output: 'a = 0O0 90 x0' },
2683 { input: 'a=0Og0b0o0', output: 'a = 0O g0b0o0' },
2684  
2685 {
2686 comment: 'Binary literals',
2687 unchanged: 'a = 0b010011;'
2688 },
2689 { unchanged: 'a = 0B010011;' },
2690 { unchanged: 'a = 0b01001100001111;' },
2691 { input: 'a=0b10e-5', output: 'a = 0b10 e - 5' },
2692 { input: 'a=0b10+4', output: 'a = 0b10 + 4' },
2693 { input: 'a=0B11+4', output: 'a = 0B11 + 4' },
2694 { input: 'a=0B112+4', output: 'a = 0B11 2 + 4' },
2695 { input: 'a=0B11a+4', output: 'a = 0B11 a + 4' },
2696 { input: 'a=0b01.10', output: 'a = 0b01 .10' },
2697 { input: 'a=0b0B0x0', output: 'a = 0b0 B0x0' },
2698 { input: 'a=0b0B0xb0', output: 'a = 0b0 B0xb0' },
2699 { input: 'a=0b0B0x0b0', output: 'a = 0b0 B0x0b0' },
2700 { input: 'a=0B090x0', output: 'a = 0B0 90 x0' },
2701 { input: 'a=0Bg0b0o0', output: 'a = 0B g0b0o0' },
2702 { unchanged: 'a = [1, 2, 3, 4]' },
2703 { input: 'F*(g/=f)*g+b', output: 'F * (g /= f) * g + b' },
2704 { input: 'a.b({c:d})', output: 'a.b({\n c: d\n})' },
2705 { input: 'a.b\n(\n{\nc:\nd\n}\n)', output: 'a.b({\n c: d\n})' },
2706 { input: 'a.b({c:"d"})', output: 'a.b({\n c: "d"\n})' },
2707 { input: 'a.b\n(\n{\nc:\n"d"\n}\n)', output: 'a.b({\n c: "d"\n})' },
2708 { input: 'a=!b', output: 'a = !b' },
2709 { input: 'a=!!b', output: 'a = !!b' },
2710 { input: 'a?b:c', output: 'a ? b : c' },
2711 { input: 'a?1:2', output: 'a ? 1 : 2' },
2712 { input: 'a?(b):c', output: 'a ? (b) : c' },
2713 { input: 'x={a:1,b:w=="foo"?x:y,c:z}', output: 'x = {\n a: 1,\n b: w == "foo" ? x : y,\n c: z\n}' },
2714 { input: 'x=a?b?c?d:e:f:g;', output: 'x = a ? b ? c ? d : e : f : g;' },
2715 { input: 'x=a?b?c?d:{e1:1,e2:2}:f:g;', output: 'x = a ? b ? c ? d : {\n e1: 1,\n e2: 2\n} : f : g;' },
2716 { unchanged: 'function void(void) {}' },
2717 { input: 'if(!a)foo();', output: 'if (!a) foo();' },
2718 { input: 'a=~a', output: 'a = ~a' },
2719 { input: 'a;/*comment*/b;', output: "a; /*comment*/\nb;" },
2720 { input: 'a;/* comment */b;', output: "a; /* comment */\nb;" },
2721 { fragment: true, input: 'a;/*\ncomment\n*/b;', output: "a;\n/*\ncomment\n*/\nb;", comment: "simple comments don't get touched at all" },
2722 { input: 'a;/**\n* javadoc\n*/b;', output: "a;\n/**\n * javadoc\n */\nb;" },
2723 { fragment: true, input: 'a;/**\n\nno javadoc\n*/b;', output: "a;\n/**\n\nno javadoc\n*/\nb;" },
2724 { input: 'a;/*\n* javadoc\n*/b;', output: "a;\n/*\n * javadoc\n */\nb;", comment: 'comment blocks detected and reindented even w/o javadoc starter' },
2725 { input: 'if(a)break;', output: "if (a) break;" },
2726 { input: 'if(a){break}', output: "if (a) {\n break\n}" },
2727 { input: 'if((a))foo();', output: 'if ((a)) foo();' },
2728 { input: 'for(var i=0;;) a', output: 'for (var i = 0;;) a' },
2729 { input: 'for(var i=0;;)\na', output: 'for (var i = 0;;)\n a' },
2730 { unchanged: 'a++;' },
2731 { input: 'for(;;i++)a()', output: 'for (;; i++) a()' },
2732 { input: 'for(;;i++)\na()', output: 'for (;; i++)\n a()' },
2733 { input: 'for(;;++i)a', output: 'for (;; ++i) a' },
2734 { input: 'return(1)', output: 'return (1)' },
2735 { input: 'try{a();}catch(b){c();}finally{d();}', output: "try {\n a();\n} catch (b) {\n c();\n} finally {\n d();\n}" },
2736 { unchanged: '(xx)()', comment: ' magic function call' },
2737 { unchanged: 'a[1]()', comment: 'another magic function call' },
2738 { input: 'if(a){b();}else if(c) foo();', output: "if (a) {\n b();\n} else if (c) foo();" },
2739 { input: 'switch(x) {case 0: case 1: a(); break; default: break}', output: "switch (x) {\n case 0:\n case 1:\n a();\n break;\n default:\n break\n}" },
2740 { input: 'switch(x){case -1:break;case !y:break;}', output: 'switch (x) {\n case -1:\n break;\n case !y:\n break;\n}' },
2741 { unchanged: 'a !== b' },
2742 { input: 'if (a) b(); else c();', output: "if (a) b();\nelse c();" },
2743 { unchanged: "// comment\n(function something() {})", comment: 'typical greasemonkey start' },
2744 { unchanged: "{\n\n x();\n\n}", comment: 'duplicating newlines' },
2745 { unchanged: 'if (a in b) foo();' },
2746 { unchanged: 'if (a of b) foo();' },
2747 { unchanged: 'if (a of [1, 2, 3]) foo();' },
2748 {
2749 input: 'if(X)if(Y)a();else b();else c();',
2750 output: "if (X)\n if (Y) a();\n else b();\nelse c();"
2751 },
2752 { unchanged: 'if (foo) bar();\nelse break' },
2753 { unchanged: 'var a, b;' },
2754 { unchanged: 'var a = new function();' },
2755 { fragment: true, unchanged: 'new function' },
2756 { unchanged: 'var a, b' },
2757 { input: '{a:1, b:2}', output: "{\n a: 1,\n b: 2\n}" },
2758 { input: 'a={1:[-1],2:[+1]}', output: 'a = {\n 1: [-1],\n 2: [+1]\n}' },
2759 { input: "var l = {\\'a\\':\\'1\\', \\'b\\':\\'2\\'}", output: "var l = {\n \\'a\\': \\'1\\',\n \\'b\\': \\'2\\'\n}" },
2760 { unchanged: 'if (template.user[n] in bk) foo();' },
2761 { unchanged: 'return 45' },
2762 { unchanged: 'return this.prevObject ||\n\n this.constructor(null);' },
2763 { unchanged: 'If[1]' },
2764 { unchanged: 'Then[1]' },
2765 { input: "a = 1;// comment", output: "a = 1; // comment" },
2766 { unchanged: "a = 1; // comment" },
2767 { input: "a = 1;\n // comment", output: "a = 1;\n// comment" },
2768 { unchanged: 'a = [-1, -1, -1]' },
2769  
2770 // These must work as non-fragments.
2771 { unchanged: ['// a', '// b', '', '', '', '// c', '// d'] },
2772 { unchanged: ['// func-comment', '', 'function foo() {}', '', '// end-func-comment'] },
2773  
2774 {
2775 comment: 'The exact formatting these should have is open for discussion, but they are at least reasonable',
2776 unchanged: 'a = [ // comment\n -1, -1, -1\n]'
2777 },
2778 { unchanged: 'var a = [ // comment\n -1, -1, -1\n]' },
2779 { unchanged: 'a = [ // comment\n -1, // comment\n -1, -1\n]' },
2780 { unchanged: 'var a = [ // comment\n -1, // comment\n -1, -1\n]' },
2781  
2782 { input: 'o = [{a:b},{c:d}]', output: 'o = [{\n a: b\n}, {\n c: d\n}]' },
2783  
2784 {
2785 comment: 'was: extra space appended',
2786 unchanged: "if (a) {\n do();\n}"
2787 },
2788  
2789 {
2790 comment: 'if/else statement with empty body',
2791 input: "if (a) {\n// comment\n}else{\n// comment\n}",
2792 output: "if (a) {\n // comment\n} else {\n // comment\n}"
2793 },
2794 { comment: 'multiple comments indentation', input: "if (a) {\n// comment\n// comment\n}", output: "if (a) {\n // comment\n // comment\n}" },
2795 { input: "if (a) b() else c();", output: "if (a) b()\nelse c();" },
2796 { input: "if (a) b() else if c() d();", output: "if (a) b()\nelse if c() d();" },
2797  
2798 { unchanged: "{}" },
2799 { unchanged: "{\n\n}" },
2800 { input: "do { a(); } while ( 1 );", output: "do {\n a();\n} while (1);" },
2801 { unchanged: "do {} while (1);" },
2802 { input: "do {\n} while (1);", output: "do {} while (1);" },
2803 { unchanged: "do {\n\n} while (1);" },
2804 { unchanged: "var a = x(a, b, c)" },
2805 { input: "delete x if (a) b();", output: "delete x\nif (a) b();" },
2806 { input: "delete x[x] if (a) b();", output: "delete x[x]\nif (a) b();" },
2807 { input: "for(var a=1,b=2)d", output: "for (var a = 1, b = 2) d" },
2808 { input: "for(var a=1,b=2,c=3) d", output: "for (var a = 1, b = 2, c = 3) d" },
2809 { input: "for(var a=1,b=2,c=3;d<3;d++)\ne", output: "for (var a = 1, b = 2, c = 3; d < 3; d++)\n e" },
2810 { input: "function x(){(a||b).c()}", output: "function x() {\n (a || b).c()\n}" },
2811 { input: "function x(){return - 1}", output: "function x() {\n return -1\n}" },
2812 { input: "function x(){return ! a}", output: "function x() {\n return !a\n}" },
2813 { unchanged: "x => x" },
2814 { unchanged: "(x) => x" },
2815 { input: "x => { x }", output: "x => {\n x\n}" },
2816 { input: "(x) => { x }", output: "(x) => {\n x\n}" },
2817  
2818 {
2819 comment: 'a common snippet in jQuery plugins',
2820 input_: "settings = $.extend({},defaults,settings);",
2821 output: "settings = $.extend({}, defaults, settings);"
2822 },
2823  
2824 // reserved words used as property names
2825 { unchanged: "$http().then().finally().default()" },
2826 { input: "$http()\n.then()\n.finally()\n.default()", output: "$http()\n .then()\n .finally()\n .default()" },
2827 { unchanged: "$http().when.in.new.catch().throw()" },
2828 { input: "$http()\n.when\n.in\n.new\n.catch()\n.throw()", output: "$http()\n .when\n .in\n .new\n .catch()\n .throw()" },
2829  
2830 { input: '{xxx;}()', output: '{\n xxx;\n}()' },
2831  
2832 { unchanged: "a = \\'a\\'\nb = \\'b\\'" },
2833 { unchanged: "a = /reg/exp" },
2834 { unchanged: "a = /reg/" },
2835 { unchanged: '/abc/.test()' },
2836 { unchanged: '/abc/i.test()' },
2837 { input: "{/abc/i.test()}", output: "{\n /abc/i.test()\n}" },
2838 { input: 'var x=(a)/a;', output: 'var x = (a) / a;' },
2839  
2840 { unchanged: 'x != -1' },
2841  
2842 { input: 'for (; s-->0;)t', output: 'for (; s-- > 0;) t' },
2843 { input: 'for (; s++>0;)u', output: 'for (; s++ > 0;) u' },
2844 { input: 'a = s++>s--;', output: 'a = s++ > s--;' },
2845 { input: 'a = s++>--s;', output: 'a = s++ > --s;' },
2846  
2847 { input: '{x=#1=[]}', output: '{\n x = #1=[]\n}' },
2848 { input: '{a:#1={}}', output: '{\n a: #1={}\n}' },
2849 { input: '{a:#1#}', output: '{\n a: #1#\n}' },
2850  
2851 { fragment: true, unchanged: '"incomplete-string' },
2852 { fragment: true, unchanged: "\\'incomplete-string" },
2853 { fragment: true, unchanged: '/incomplete-regex' },
2854 { fragment: true, unchanged: '`incomplete-template-string' },
2855  
2856 { fragment: true, input: '{a:1},{a:2}', output: '{\n a: 1\n}, {\n a: 2\n}' },
2857 { fragment: true, input: 'var ary=[{a:1}, {a:2}];', output: 'var ary = [{\n a: 1\n}, {\n a: 2\n}];' },
2858  
2859 { comment: 'incomplete', fragment: true, input: '{a:#1', output: '{\n a: #1' },
2860 { comment: 'incomplete', fragment: true, input: '{a:#', output: '{\n a: #' },
2861  
2862 { comment: 'incomplete', fragment: true, input: '}}}', output: '}\n}\n}' },
2863  
2864 { fragment: true, unchanged: '<!--\nvoid();\n// -->' },
2865  
2866 { comment: 'incomplete regexp', fragment: true, input: 'a=/regexp', output: 'a = /regexp' },
2867  
2868 { input: '{a:#1=[],b:#1#,c:#999999#}', output: '{\n a: #1=[],\n b: #1#,\n c: #999999#\n}' },
2869  
2870 { input: "do{x()}while(a>1)", output: "do {\n x()\n} while (a > 1)" },
2871  
2872 { input: "x(); /reg/exp.match(something)", output: "x();\n/reg/exp.match(something)" },
2873  
2874 { fragment: true, input: "something();(", output: "something();\n(" },
2875 { fragment: true, input: "#!she/bangs, she bangs\nf=1", output: "#!she/bangs, she bangs\n\nf = 1" },
2876 { fragment: true, input: "#!she/bangs, she bangs\n\nf=1", output: "#!she/bangs, she bangs\n\nf = 1" },
2877 { fragment: true, unchanged: "#!she/bangs, she bangs\n\n/* comment */" },
2878 { fragment: true, unchanged: "#!she/bangs, she bangs\n\n\n/* comment */" },
2879 { fragment: true, unchanged: "#" },
2880 { fragment: true, unchanged: "#!" },
2881  
2882 { unchanged: "function namespace::something()" },
2883  
2884 { fragment: true, unchanged: "<!--\nsomething();\n-->" },
2885 { fragment: true, input: "<!--\nif(i<0){bla();}\n-->", output: "<!--\nif (i < 0) {\n bla();\n}\n-->" },
2886  
2887 { input: '{foo();--bar;}', output: '{\n foo();\n --bar;\n}' },
2888 { input: '{foo();++bar;}', output: '{\n foo();\n ++bar;\n}' },
2889 { input: '{--bar;}', output: '{\n --bar;\n}' },
2890 { input: '{++bar;}', output: '{\n ++bar;\n}' },
2891 { input: 'if(true)++a;', output: 'if (true) ++a;' },
2892 { input: 'if(true)\n++a;', output: 'if (true)\n ++a;' },
2893 { input: 'if(true)--a;', output: 'if (true) --a;' },
2894 { input: 'if(true)\n--a;', output: 'if (true)\n --a;' },
2895 { unchanged: 'elem[array]++;' },
2896 { unchanged: 'elem++ * elem[array]++;' },
2897 { unchanged: 'elem-- * -elem[array]++;' },
2898 { unchanged: 'elem-- + elem[array]++;' },
2899 { unchanged: 'elem-- - elem[array]++;' },
2900 { unchanged: 'elem-- - -elem[array]++;' },
2901 { unchanged: 'elem-- - +elem[array]++;' },
2902  
2903  
2904 {
2905 comment: 'Handling of newlines around unary ++ and -- operators',
2906 input: '{foo\n++bar;}',
2907 output: '{\n foo\n ++bar;\n}'
2908 },
2909 { input: '{foo++\nbar;}', output: '{\n foo++\n bar;\n}' },
2910  
2911 {
2912 comment: 'This is invalid, but harder to guard against. Issue #203.',
2913 input: '{foo\n++\nbar;}',
2914 output: '{\n foo\n ++\n bar;\n}'
2915 },
2916  
2917 {
2918 comment: 'regexps',
2919 input: 'a(/abc\\\\/\\\\/def/);b()',
2920 output: "a(/abc\\\\/\\\\/def/);\nb()"
2921 },
2922 { input: 'a(/a[b\\\\[\\\\]c]d/);b()', output: "a(/a[b\\\\[\\\\]c]d/);\nb()" },
2923 { comment: 'incomplete char class', fragment: true, unchanged: 'a(/a[b\\\\[' },
2924  
2925 {
2926 comment: 'allow unescaped / in char classes',
2927 input: 'a(/[a/b]/);b()',
2928 output: "a(/[a/b]/);\nb()"
2929 },
2930 { unchanged: 'typeof /foo\\\\//;' },
2931 { unchanged: 'throw /foo\\\\//;' },
2932 { unchanged: 'do /foo\\\\//;' },
2933 { unchanged: 'return /foo\\\\//;' },
2934 { unchanged: 'switch (a) {\n case /foo\\\\//:\n b\n}' },
2935 { unchanged: 'if (a) /foo\\\\//\nelse /foo\\\\//;' },
2936  
2937 { unchanged: 'if (foo) /regex/.test();' },
2938 { unchanged: "for (index in [1, 2, 3]) /^test$/i.test(s)" },
2939  
2940 { unchanged: 'function foo() {\n return [\n "one",\n "two"\n ];\n}' },
2941 { input: 'a=[[1,2],[4,5],[7,8]]', output: "a = [\n [1, 2],\n [4, 5],\n [7, 8]\n]" },
2942 {
2943 input: 'a=[[1,2],[4,5],function(){},[7,8]]',
2944 output: "a = [\n [1, 2],\n [4, 5],\n function() {},\n [7, 8]\n]"
2945 },
2946 {
2947 input: 'a=[[1,2],[4,5],function(){},function(){},[7,8]]',
2948 output: "a = [\n [1, 2],\n [4, 5],\n function() {},\n function() {},\n [7, 8]\n]"
2949 },
2950 {
2951 input: 'a=[[1,2],[4,5],function(){},[7,8]]',
2952 output: "a = [\n [1, 2],\n [4, 5],\n function() {},\n [7, 8]\n]"
2953 },
2954 {
2955 input: 'a=[b,c,function(){},function(){},d]',
2956 output: "a = [b, c, function() {}, function() {}, d]"
2957 },
2958 {
2959 input: 'a=[b,c,\nfunction(){},function(){},d]',
2960 output: "a = [b, c,\n function() {},\n function() {},\n d\n]"
2961 },
2962 { input: 'a=[a[1],b[4],c[d[7]]]', output: "a = [a[1], b[4], c[d[7]]]" },
2963 { input: '[1,2,[3,4,[5,6],7],8]', output: "[1, 2, [3, 4, [5, 6], 7], 8]" },
2964  
2965 {
2966 input: '[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]',
2967 output: '[\n [\n ["1", "2"],\n ["3", "4"]\n ],\n [\n ["5", "6", "7"],\n ["8", "9", "0"]\n ],\n [\n ["1", "2", "3"],\n ["4", "5", "6", "7"],\n ["8", "9", "0"]\n ]\n]'
2968 },
2969  
2970 { input: '{[x()[0]];indent;}', output: '{\n [x()[0]];\n indent;\n}' },
2971 { unchanged: '/*\n foo trailing space \n * bar trailing space \n**/' },
2972 { unchanged: '{\n /*\n foo \n * bar \n */\n}' },
2973  
2974 { unchanged: 'return ++i' },
2975 { unchanged: 'return !!x' },
2976 { unchanged: 'return !x' },
2977 { input: 'return [1,2]', output: 'return [1, 2]' },
2978 { unchanged: 'return;' },
2979 { unchanged: 'return\nfunc' },
2980 { input: 'catch(e)', output: 'catch (e)' },
2981  
2982 {
2983 input: 'var a=1,b={foo:2,bar:3},{baz:4,wham:5},c=4;',
2984 output: 'var a = 1,\n b = {\n foo: 2,\n bar: 3\n },\n {\n baz: 4,\n wham: 5\n }, c = 4;'
2985 },
2986 {
2987 input: 'var a=1,b={foo:2,bar:3},{baz:4,wham:5},\nc=4;',
2988 output: 'var a = 1,\n b = {\n foo: 2,\n bar: 3\n },\n {\n baz: 4,\n wham: 5\n },\n c = 4;'
2989 },
2990  
2991 {
2992 comment: 'inline comment',
2993 input_: 'function x(/*int*/ start, /*string*/ foo)',
2994 output: 'function x( /*int*/ start, /*string*/ foo)'
2995 },
2996  
2997 {
2998 comment: 'javadoc comment',
2999 input: '/**\n* foo\n*/',
3000 output: '/**\n * foo\n */'
3001 },
3002 { input: '{\n/**\n* foo\n*/\n}', output: '{\n /**\n * foo\n */\n}' },
3003  
3004 {
3005 comment: 'starless block comment',
3006 unchanged: '/**\nfoo\n*/'
3007 },
3008 { unchanged: '/**\nfoo\n**/' },
3009 { unchanged: '/**\nfoo\nbar\n**/' },
3010 { unchanged: '/**\nfoo\n\nbar\n**/' },
3011 { unchanged: '/**\nfoo\n bar\n**/' },
3012 { input: '{\n/**\nfoo\n*/\n}', output: '{\n /**\n foo\n */\n}' },
3013 { input: '{\n/**\nfoo\n**/\n}', output: '{\n /**\n foo\n **/\n}' },
3014 { input: '{\n/**\nfoo\nbar\n**/\n}', output: '{\n /**\n foo\n bar\n **/\n}' },
3015 { input: '{\n/**\nfoo\n\nbar\n**/\n}', output: '{\n /**\n foo\n\n bar\n **/\n}' },
3016 { input: '{\n/**\nfoo\n bar\n**/\n}', output: '{\n /**\n foo\n bar\n **/\n}' },
3017 { unchanged: '{\n /**\n foo\nbar\n **/\n}' },
3018  
3019 { input: 'var a,b,c=1,d,e,f=2;', output: 'var a, b, c = 1,\n d, e, f = 2;' },
3020 { input: 'var a,b,c=[],d,e,f=2;', output: 'var a, b, c = [],\n d, e, f = 2;' },
3021 { unchanged: 'function() {\n var a, b, c, d, e = [],\n f;\n}' },
3022  
3023 { input: 'do/regexp/;\nwhile(1);', output: 'do /regexp/;\nwhile (1);' },
3024 { input: 'var a = a,\na;\nb = {\nb\n}', output: 'var a = a,\n a;\nb = {\n b\n}' },
3025  
3026 { unchanged: 'var a = a,\n /* c */\n b;' },
3027 { unchanged: 'var a = a,\n // c\n b;' },
3028  
3029 {
3030 comment: 'weird element referencing',
3031 unchanged: 'foo.("bar");'
3032 },
3033  
3034  
3035 { unchanged: 'if (a) a()\nelse b()\nnewline()' },
3036 { unchanged: 'if (a) a()\nnewline()' },
3037 { input: 'a=typeof(x)', output: 'a = typeof(x)' },
3038  
3039 { unchanged: 'var a = function() {\n return null;\n },\n b = false;' },
3040  
3041 { unchanged: 'var a = function() {\n func1()\n}' },
3042 { unchanged: 'var a = function() {\n func1()\n}\nvar b = function() {\n func2()\n}' },
3043  
3044 {
3045 comment: 'code with and without semicolons',
3046 input_: 'var whatever = require("whatever");\nfunction() {\n a = 6;\n}',
3047 output: 'var whatever = require("whatever");\n\nfunction() {\n a = 6;\n}'
3048 },
3049 {
3050 input: 'var whatever = require("whatever")\nfunction() {\n a = 6\n}',
3051 output: 'var whatever = require("whatever")\n\nfunction() {\n a = 6\n}'
3052 },
3053  
3054 { input: '{"x":[{"a":1,"b":3},\n7,8,8,8,8,{"b":99},{"a":11}]}', output: '{\n "x": [{\n "a": 1,\n "b": 3\n },\n 7, 8, 8, 8, 8, {\n "b": 99\n }, {\n "a": 11\n }\n ]\n}' },
3055 { input: '{"x":[{"a":1,"b":3},7,8,8,8,8,{"b":99},{"a":11}]}', output: '{\n "x": [{\n "a": 1,\n "b": 3\n }, 7, 8, 8, 8, 8, {\n "b": 99\n }, {\n "a": 11\n }]\n}' },
3056  
3057 { input: '{"1":{"1a":"1b"},"2"}', output: '{\n "1": {\n "1a": "1b"\n },\n "2"\n}' },
3058 { input: '{a:{a:b},c}', output: '{\n a: {\n a: b\n },\n c\n}' },
3059  
3060 { input: '{[y[a]];keep_indent;}', output: '{\n [y[a]];\n keep_indent;\n}' },
3061  
3062 { input: 'if (x) {y} else { if (x) {y}}', output: 'if (x) {\n y\n} else {\n if (x) {\n y\n }\n}' },
3063  
3064 { unchanged: 'if (foo) one()\ntwo()\nthree()' },
3065 { unchanged: 'if (1 + foo() && bar(baz()) / 2) one()\ntwo()\nthree()' },
3066 { unchanged: 'if (1 + foo() && bar(baz()) / 2) one();\ntwo();\nthree();' },
3067  
3068 { input: 'var a=1,b={bang:2},c=3;', output: 'var a = 1,\n b = {\n bang: 2\n },\n c = 3;' },
3069 { input: 'var a={bing:1},b=2,c=3;', output: 'var a = {\n bing: 1\n },\n b = 2,\n c = 3;' },
3070  
3071 ],
3072 }],
3073 examples: [{
3074 // Example
3075 group_name: "one",
3076 description: "",
3077 options: [],
3078 values: [{
3079 source: "", //string or array of lines
3080 output: "" //string or array of lines
3081 }]
3082 }]
3083 };