beautify-javascript-tests.js 109 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386
  1. /*global js_beautify: true */
  2. function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_beautify)
  3. {
  4. var opts = {
  5. indent_size: 4,
  6. indent_char: ' ',
  7. preserve_newlines: true,
  8. jslint_happy: false,
  9. keep_array_indentation: false,
  10. brace_style: 'collapse',
  11. space_before_conditional: true,
  12. break_chained_methods: false,
  13. selector_separator: '\n',
  14. end_with_newline: false
  15. };
  16. function test_js_beautifier(input)
  17. {
  18. return js_beautify(input, opts);
  19. }
  20. function test_html_beautifier(input)
  21. {
  22. return html_beautify(input, opts);
  23. }
  24. var sanitytest;
  25. // test the input on beautifier with the current flag settings
  26. // does not check the indentation / surroundings as bt() does
  27. function test_fragment(input, expected)
  28. {
  29. expected = expected || expected === '' ? expected : input;
  30. sanitytest.expect(input, expected);
  31. // if the expected is different from input, run it again
  32. // expected output should be unchanged when run twice.
  33. if (expected !== input) {
  34. sanitytest.expect(expected, expected);
  35. }
  36. // Everywhere we do newlines, they should be replaced with opts.eol
  37. opts.eol = '\r\\n';
  38. expected = expected.replace(/[\n]/g, '\r\n');
  39. sanitytest.expect(input, expected);
  40. input = input.replace(/[\n]/g, '\r\n');
  41. sanitytest.expect(input, expected);
  42. opts.eol = '\n';
  43. }
  44. // test the input on beautifier with the current flag settings
  45. // test both the input as well as { input } wrapping
  46. function bt(input, expectation)
  47. {
  48. var wrapped_input, wrapped_expectation;
  49. expectation = expectation || expectation === '' ? expectation : input;
  50. sanitytest.test_function(test_js_beautifier, 'js_beautify');
  51. test_fragment(input, expectation);
  52. // If we set raw, input should be unchanged
  53. opts.test_output_raw = true;
  54. if (!opts.end_with_newline) {
  55. test_fragment(input, input);
  56. }
  57. opts.test_output_raw = false;
  58. // test also the returned indentation
  59. // e.g if input = "asdf();"
  60. // then test that this remains properly formatted as well:
  61. // {
  62. // asdf();
  63. // indent;
  64. // }
  65. if (opts.indent_size === 4 && input) {
  66. wrapped_input = '{\n' + input.replace(/^(.+)$/mg, ' $1') + '\n foo = bar;\n}';
  67. wrapped_expectation = '{\n' + expectation.replace(/^(.+)$/mg, ' $1') + '\n foo = bar;\n}';
  68. test_fragment(wrapped_input, wrapped_expectation);
  69. // If we set raw, input should be unchanged
  70. opts.test_output_raw = true;
  71. if (!opts.end_with_newline) {
  72. test_fragment(wrapped_input, wrapped_input);
  73. }
  74. opts.test_output_raw = false;
  75. }
  76. }
  77. // run all tests for the given brace style ("collapse", "expand", "end-expand", or "none").
  78. // uses various whitespace combinations before and after opening and closing braces,
  79. // respectively, for most of the tests' inputs.
  80. function beautify_brace_tests(brace_style) {
  81. var ex_brace_style = opts.brace_style,
  82. indent_on_wrap_str = ' '; // could use Array(opts.indent_size + 1).join(' '); if we wanted to replace _all_ of the hardcoded 4-space in the test and expectation strings
  83. function permute_brace_tests(expect_open_white, expect_close_white) {
  84. // run the tests that need permutation against a specific combination of
  85. // pre-opening-brace and pre-closing-brace whitespace
  86. function run_brace_permutation(test_open_white, test_close_white) {
  87. var to = test_open_white,
  88. tc = test_close_white,
  89. eo = expect_open_white ? expect_open_white : to === '' ? ' ' : to,
  90. ec = expect_close_white ? expect_close_white : tc === '' ? ' ' : tc,
  91. i = eo === '\n' ? indent_on_wrap_str: '';
  92. bt( '//case 1\nif (a == 1)' + to + '{}\n//case 2\nelse if (a == 2)' + to + '{}',
  93. '//case 1\nif (a == 1)' + eo + '{}\n//case 2\nelse if (a == 2)' + eo + '{}');
  94. bt( 'if(1)' + to + '{2}' + tc + 'else' + to + '{3}',
  95. 'if (1)' + eo + '{\n 2\n}' + ec + 'else' + eo + '{\n 3\n}');
  96. bt( 'try' + to + '{a();}' + tc +
  97. 'catch(b)' + to + '{c();}' + tc +
  98. 'catch(d)' + to + '{}' + tc +
  99. 'finally' + to + '{e();}',
  100. // expected
  101. 'try' + eo + '{\n a();\n}' + ec +
  102. 'catch (b)' + eo + '{\n c();\n}' + ec +
  103. 'catch (d)' + eo + '{}' + ec +
  104. 'finally' + eo + '{\n e();\n}');
  105. bt( 'if(a)' + to + '{b();}' + tc + 'else if(c) foo();',
  106. 'if (a)' + eo + '{\n b();\n}' + ec + 'else if (c) foo();');
  107. // if/else statement with empty body
  108. bt( 'if (a)' + to + '{\n// comment\n}' + tc + 'else' + to + '{\n// comment\n}',
  109. 'if (a)' + eo + '{\n // comment\n}' + ec + 'else' + eo + '{\n // comment\n}');
  110. bt( 'if (x)' + to + '{y}' + tc + 'else' + to + '{ if (x)' + to + '{y}}',
  111. 'if (x)' + eo + '{\n y\n}' + ec + 'else' + eo + '{\n if (x)' + eo + i + '{\n y\n }\n}');
  112. bt( 'if (a)' + to + '{\nb;\n}' + tc + 'else' + to + '{\nc;\n}',
  113. 'if (a)' + eo + '{\n b;\n}' + ec + 'else' + eo + '{\n c;\n}');
  114. test_fragment(' /*\n* xx\n*/\n// xx\nif (foo)' + to + '{\n bar();\n}',
  115. ' /*\n * xx\n */\n // xx\n if (foo)' + eo + i + '{\n bar();\n }');
  116. bt( 'if (foo)' + to + '{}' + tc + 'else /regex/.test();',
  117. 'if (foo)' + eo + '{}' + ec + 'else /regex/.test();');
  118. test_fragment('if (foo)' + to + '{', 'if (foo)' + eo + '{');
  119. test_fragment('foo' + to + '{', 'foo' + eo + '{');
  120. test_fragment('return;' + to + '{', 'return;' + eo + '{');
  121. bt( 'function x()' + to + '{\n foo();\n}zzz', 'function x()' + eo +'{\n foo();\n}\nzzz');
  122. bt( 'var a = new function a()' + to + '{};', 'var a = new function a()' + eo + '{};');
  123. bt( 'var a = new function a()' + to + ' {},\n b = new function b()' + to + ' {};',
  124. 'var a = new function a()' + eo + i + '{},\n b = new function b()' + eo + i + '{};');
  125. bt("foo(" + to + "{\n 'a': 1\n},\n10);",
  126. "foo(" + (eo === ' ' ? '' : eo) + i + "{\n 'a': 1\n },\n 10);"); // "foo( {..." is a weird case
  127. bt('(["foo","bar"]).each(function(i)' + to + '{return i;});',
  128. '(["foo", "bar"]).each(function(i)' + eo + '{\n return i;\n});');
  129. bt('(function(i)' + to + '{return i;})();', '(function(i)' + eo + '{\n return i;\n})();');
  130. bt( "test( /*Argument 1*/" + to + "{\n" +
  131. " 'Value1': '1'\n" +
  132. "}, /*Argument 2\n" +
  133. " */ {\n" +
  134. " 'Value2': '2'\n" +
  135. "});",
  136. // expected
  137. "test( /*Argument 1*/" + eo + i + "{\n" +
  138. " 'Value1': '1'\n" +
  139. " },\n" +
  140. " /*Argument 2\n" +
  141. " */\n" +
  142. " {\n" +
  143. " 'Value2': '2'\n" +
  144. " });");
  145. bt( "test( /*Argument 1*/" + to + "{\n" +
  146. " 'Value1': '1'\n" +
  147. "}, /*Argument 2\n" +
  148. " */\n" +
  149. "{\n" +
  150. " 'Value2': '2'\n" +
  151. "});",
  152. // expected
  153. "test( /*Argument 1*/" + eo + i + "{\n" +
  154. " 'Value1': '1'\n" +
  155. " },\n" +
  156. " /*Argument 2\n" +
  157. " */\n" +
  158. " {\n" +
  159. " 'Value2': '2'\n" +
  160. " });");
  161. }
  162. run_brace_permutation('\n', '\n');
  163. run_brace_permutation('\n', ' ');
  164. run_brace_permutation(' ', ' ');
  165. run_brace_permutation(' ', '\n');
  166. run_brace_permutation('','');
  167. // brace tests that don't make sense to permutate
  168. test_fragment('return {'); // return needs the brace.
  169. test_fragment('return /* inline */ {');
  170. bt('throw {}');
  171. bt('throw {\n foo;\n}');
  172. bt( 'var foo = {}');
  173. test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx');
  174. bt( '{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}');
  175. bt( 'var a = new function() {};');
  176. bt( 'var a = new function()\n{};', 'var a = new function() {};');
  177. bt( "test(\n" +
  178. "/*Argument 1*/ {\n" +
  179. " 'Value1': '1'\n" +
  180. "},\n" +
  181. "/*Argument 2\n" +
  182. " */ {\n" +
  183. " 'Value2': '2'\n" +
  184. "});",
  185. // expected
  186. "test(\n" +
  187. " /*Argument 1*/\n" +
  188. " {\n" +
  189. " 'Value1': '1'\n" +
  190. " },\n" +
  191. " /*Argument 2\n" +
  192. " */\n" +
  193. " {\n" +
  194. " 'Value2': '2'\n" +
  195. " });");
  196. }
  197. opts.brace_style = brace_style;
  198. switch(opts.brace_style) {
  199. case 'collapse':
  200. permute_brace_tests(' ', ' ');
  201. break;
  202. case 'expand':
  203. permute_brace_tests('\n', '\n');
  204. break;
  205. case 'end-expand':
  206. permute_brace_tests(' ', '\n');
  207. break;
  208. case 'none':
  209. permute_brace_tests();
  210. break;
  211. }
  212. opts.brace_style = ex_brace_style;
  213. }
  214. function unicode_char(value) {
  215. return String.fromCharCode(value)
  216. }
  217. function beautifier_tests()
  218. {
  219. sanitytest = test_obj;
  220. opts.indent_size = 4;
  221. opts.indent_char = ' ';
  222. opts.preserve_newlines = true;
  223. opts.jslint_happy = false;
  224. opts.keep_array_indentation = false;
  225. opts.brace_style = 'collapse';
  226. // Unicode Support
  227. bt('var ' + unicode_char(3232) + '_' + unicode_char(3232) + ' = "hi";');
  228. bt(
  229. 'var ' + unicode_char(228) + 'x = {\n' +
  230. ' ' + unicode_char(228) + 'rgerlich: true\n' +
  231. '};');
  232. // End With Newline - (eof = "\n")
  233. opts.end_with_newline = true;
  234. test_fragment('', '\n');
  235. test_fragment(' return .5', ' return .5\n');
  236. test_fragment(' \n\nreturn .5\n\n\n\n', ' return .5\n');
  237. test_fragment('\n');
  238. // End With Newline - (eof = "")
  239. opts.end_with_newline = false;
  240. test_fragment('');
  241. test_fragment(' return .5');
  242. test_fragment(' \n\nreturn .5\n\n\n\n', ' return .5');
  243. test_fragment('\n', '');
  244. // Comma-first option - (c0 = "\n, ", c1 = "\n , ", c2 = "\n , ", c3 = "\n , ")
  245. opts.comma_first = true;
  246. bt('{a:1, b:2}', '{\n a: 1\n , b: 2\n}');
  247. bt('var a=1, b=c[d], e=6;', 'var a = 1\n , b = c[d]\n , e = 6;');
  248. bt('for(var a=1,b=2,c=3;d<3;d++)\ne', 'for (var a = 1, b = 2, c = 3; d < 3; d++)\n e');
  249. bt('for(var a=1,b=2,\nc=3;d<3;d++)\ne', 'for (var a = 1, b = 2\n , c = 3; d < 3; d++)\n e');
  250. bt('function foo() {\n return [\n "one"\n , "two"\n ];\n}');
  251. bt('a=[[1,2],[4,5],[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , [7, 8]\n]');
  252. bt('a=[[1,2],[4,5],[7,8],]', 'a = [\n [1, 2]\n , [4, 5]\n , [7, 8]\n, ]');
  253. bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , function() {}\n , [7, 8]\n]');
  254. bt('a=[[1,2],[4,5],function(){},function(){},[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , function() {}\n , function() {}\n , [7, 8]\n]');
  255. bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , function() {}\n , [7, 8]\n]');
  256. bt('a=[b,c,function(){},function(){},d]', 'a = [b, c, function() {}, function() {}, d]');
  257. bt('a=[b,c,\nfunction(){},function(){},d]', 'a = [b, c\n , function() {}\n , function() {}\n , d\n]');
  258. bt('a=[a[1],b[4],c[d[7]]]', 'a = [a[1], b[4], c[d[7]]]');
  259. bt('[1,2,[3,4,[5,6],7],8]', '[1, 2, [3, 4, [5, 6], 7], 8]');
  260. bt('[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]', '[\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]');
  261. // Comma-first option - (c0 = ",\n", c1 = ",\n ", c2 = ",\n ", c3 = ",\n ")
  262. opts.comma_first = false;
  263. bt('{a:1, b:2}', '{\n a: 1,\n b: 2\n}');
  264. bt('var a=1, b=c[d], e=6;', 'var a = 1,\n b = c[d],\n e = 6;');
  265. bt('for(var a=1,b=2,c=3;d<3;d++)\ne', 'for (var a = 1, b = 2, c = 3; d < 3; d++)\n e');
  266. bt('for(var a=1,b=2,\nc=3;d<3;d++)\ne', 'for (var a = 1, b = 2,\n c = 3; d < 3; d++)\n e');
  267. bt('function foo() {\n return [\n "one",\n "two"\n ];\n}');
  268. bt('a=[[1,2],[4,5],[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n [7, 8]\n]');
  269. bt('a=[[1,2],[4,5],[7,8],]', 'a = [\n [1, 2],\n [4, 5],\n [7, 8],\n]');
  270. bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n [7, 8]\n]');
  271. bt('a=[[1,2],[4,5],function(){},function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n function() {},\n [7, 8]\n]');
  272. bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n [7, 8]\n]');
  273. bt('a=[b,c,function(){},function(){},d]', 'a = [b, c, function() {}, function() {}, d]');
  274. bt('a=[b,c,\nfunction(){},function(){},d]', 'a = [b, c,\n function() {},\n function() {},\n d\n]');
  275. bt('a=[a[1],b[4],c[d[7]]]', 'a = [a[1], b[4], c[d[7]]]');
  276. bt('[1,2,[3,4,[5,6],7],8]', '[1, 2, [3, 4, [5, 6], 7], 8]');
  277. bt('[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]', '[\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]');
  278. // New Test Suite
  279. // Async / await tests
  280. bt('async function foo() {}');
  281. bt('let w = async function foo() {}');
  282. bt('async function foo() {}\nvar x = await foo();');
  283. // async function as an input to another function
  284. bt('wrapper(async function foo() {})');
  285. // await on inline anonymous function. should have a space after await
  286. bt(
  287. 'async function() {\n var w = await(async function() {\n return await foo();\n })();\n}',
  288. 'async function() {\n var w = await (async function() {\n return await foo();\n })();\n}');
  289. // ensure that this doesn't break anyone with the async library
  290. bt('async.map(function(t) {})');
  291. // e4x - Test that e4x literals passed through when e4x-option is enabled
  292. opts.e4x = true;
  293. bt('xml=<a b="c"><d/><e>\n foo</e>x</a>;', 'xml = <a b="c"><d/><e>\n foo</e>x</a>;');
  294. bt('<a b=\'This is a quoted "c".\'/>');
  295. bt('<a b="This is a quoted \'c\'."/>');
  296. bt('<a b="A quote \' inside string."/>');
  297. bt('<a b=\'A quote " inside string.\'/>');
  298. bt('<a b=\'Some """ quotes "" inside string.\'/>');
  299. // Handles inline expressions
  300. bt('xml=<{a} b="c"><d/><e v={z}>\n foo</e>x</{a}>;', 'xml = <{a} b="c"><d/><e v={z}>\n foo</e>x</{a}>;');
  301. bt('xml=<{a} b="c">\n <e v={z}>\n foo</e>x</{a}>;', 'xml = <{a} b="c">\n <e v={z}>\n foo</e>x</{a}>;');
  302. // xml literals with special characters in elem names - see http://www.w3.org/TR/REC-xml/#NT-NameChar
  303. bt('xml = <_:.valid.xml- _:.valid.xml-="123"/>;');
  304. // Handles CDATA
  305. bt('xml=<![CDATA[ b="c"><d/><e v={z}>\n foo</e>x/]]>;', 'xml = <![CDATA[ b="c"><d/><e v={z}>\n foo</e>x/]]>;');
  306. bt('xml=<![CDATA[]]>;', 'xml = <![CDATA[]]>;');
  307. bt('xml=<a b="c"><![CDATA[d/></a></{}]]></a>;', 'xml = <a b="c"><![CDATA[d/></a></{}]]></a>;');
  308. // JSX - working jsx from http://prettydiff.com/unit_tests/beautification_javascript_jsx.txt
  309. bt(
  310. 'var ListItem = React.createClass({\n' +
  311. ' render: function() {\n' +
  312. ' return (\n' +
  313. ' <li className="ListItem">\n' +
  314. ' <a href={ "/items/" + this.props.item.id }>\n' +
  315. ' this.props.item.name\n' +
  316. ' </a>\n' +
  317. ' </li>\n' +
  318. ' );\n' +
  319. ' }\n' +
  320. '});');
  321. bt(
  322. 'var List = React.createClass({\n' +
  323. ' renderList: function() {\n' +
  324. ' return this.props.items.map(function(item) {\n' +
  325. ' return <ListItem item={item} key={item.id} />;\n' +
  326. ' });\n' +
  327. ' },\n' +
  328. '\n' +
  329. ' render: function() {\n' +
  330. ' return <ul className="List">\n' +
  331. ' this.renderList()\n' +
  332. ' </ul>\n' +
  333. ' }\n' +
  334. '});');
  335. bt(
  336. 'var Mist = React.createClass({\n' +
  337. ' renderList: function() {\n' +
  338. ' return this.props.items.map(function(item) {\n' +
  339. ' return <ListItem item={return <tag>{item}</tag>} key={item.id} />;\n' +
  340. ' });\n' +
  341. ' }\n' +
  342. '});');
  343. bt(
  344. '// JSX\n' +
  345. 'var box = <Box>\n' +
  346. ' {shouldShowAnswer(user) ?\n' +
  347. ' <Answer value={false}>no</Answer> : <Box.Comment>\n' +
  348. ' Text Content\n' +
  349. ' </Box.Comment>}\n' +
  350. ' </Box>;\n' +
  351. 'var a = function() {\n' +
  352. ' return <tsdf>asdf</tsdf>;\n' +
  353. '};\n' +
  354. '\n' +
  355. 'var HelloMessage = React.createClass({\n' +
  356. ' render: function() {\n' +
  357. ' return <div>Hello {this.props.name}</div>;\n' +
  358. ' }\n' +
  359. '});\n' +
  360. 'React.render(<HelloMessage name="John" />, mountNode);');
  361. bt(
  362. 'var Timer = React.createClass({\n' +
  363. ' getInitialState: function() {\n' +
  364. ' return {\n' +
  365. ' secondsElapsed: 0\n' +
  366. ' };\n' +
  367. ' },\n' +
  368. ' tick: function() {\n' +
  369. ' this.setState({\n' +
  370. ' secondsElapsed: this.state.secondsElapsed + 1\n' +
  371. ' });\n' +
  372. ' },\n' +
  373. ' componentDidMount: function() {\n' +
  374. ' this.interval = setInterval(this.tick, 1000);\n' +
  375. ' },\n' +
  376. ' componentWillUnmount: function() {\n' +
  377. ' clearInterval(this.interval);\n' +
  378. ' },\n' +
  379. ' render: function() {\n' +
  380. ' return (\n' +
  381. ' <div>Seconds Elapsed: {this.state.secondsElapsed}</div>\n' +
  382. ' );\n' +
  383. ' }\n' +
  384. '});\n' +
  385. 'React.render(<Timer />, mountNode);');
  386. bt(
  387. 'var TodoList = React.createClass({\n' +
  388. ' render: function() {\n' +
  389. ' var createItem = function(itemText) {\n' +
  390. ' return <li>{itemText}</li>;\n' +
  391. ' };\n' +
  392. ' return <ul>{this.props.items.map(createItem)}</ul>;\n' +
  393. ' }\n' +
  394. '});');
  395. bt(
  396. 'var TodoApp = React.createClass({\n' +
  397. ' getInitialState: function() {\n' +
  398. ' return {\n' +
  399. ' items: [],\n' +
  400. ' text: \'\'\n' +
  401. ' };\n' +
  402. ' },\n' +
  403. ' onChange: function(e) {\n' +
  404. ' this.setState({\n' +
  405. ' text: e.target.value\n' +
  406. ' });\n' +
  407. ' },\n' +
  408. ' handleSubmit: function(e) {\n' +
  409. ' e.preventDefault();\n' +
  410. ' var nextItems = this.state.items.concat([this.state.text]);\n' +
  411. ' var nextText = \'\';\n' +
  412. ' this.setState({\n' +
  413. ' items: nextItems,\n' +
  414. ' text: nextText\n' +
  415. ' });\n' +
  416. ' },\n' +
  417. ' render: function() {\n' +
  418. ' return (\n' +
  419. ' <div>\n' +
  420. ' <h3>TODO</h3>\n' +
  421. ' <TodoList items={this.state.items} />\n' +
  422. ' <form onSubmit={this.handleSubmit}>\n' +
  423. ' <input onChange={this.onChange} value={this.state.text} />\n' +
  424. ' <button>{\'Add #\' + (this.state.items.length + 1)}</button>\n' +
  425. ' </form>\n' +
  426. ' </div>\n' +
  427. ' );\n' +
  428. ' }\n' +
  429. '});\n' +
  430. 'React.render(<TodoApp />, mountNode);');
  431. bt(
  432. 'var converter = new Showdown.converter();\n' +
  433. 'var MarkdownEditor = React.createClass({\n' +
  434. ' getInitialState: function() {\n' +
  435. ' return {value: \'Type some *markdown* here!\'};\n' +
  436. ' },\n' +
  437. ' handleChange: function() {\n' +
  438. ' this.setState({value: this.refs.textarea.getDOMNode().value});\n' +
  439. ' },\n' +
  440. ' render: function() {\n' +
  441. ' return (\n' +
  442. ' <div className="MarkdownEditor">\n' +
  443. ' <h3>Input</h3>\n' +
  444. ' <textarea\n' +
  445. ' onChange={this.handleChange}\n' +
  446. ' ref="textarea"\n' +
  447. ' defaultValue={this.state.value} />\n' +
  448. ' <h3>Output</h3>\n' +
  449. ' <div\n' +
  450. ' className="content"\n' +
  451. ' dangerouslySetInnerHTML=\n' +
  452. ' />\n' +
  453. ' </div>\n' +
  454. ' );\n' +
  455. ' }\n' +
  456. '});\n' +
  457. 'React.render(<MarkdownEditor />, mountNode);',
  458. 'var converter = new Showdown.converter();\n' +
  459. 'var MarkdownEditor = React.createClass({\n' +
  460. ' getInitialState: function() {\n' +
  461. ' return {\n' +
  462. ' value: \'Type some *markdown* here!\'\n' +
  463. ' };\n' +
  464. ' },\n' +
  465. ' handleChange: function() {\n' +
  466. ' this.setState({\n' +
  467. ' value: this.refs.textarea.getDOMNode().value\n' +
  468. ' });\n' +
  469. ' },\n' +
  470. ' render: function() {\n' +
  471. ' return (\n' +
  472. ' <div className="MarkdownEditor">\n' +
  473. ' <h3>Input</h3>\n' +
  474. ' <textarea\n' +
  475. ' onChange={this.handleChange}\n' +
  476. ' ref="textarea"\n' +
  477. ' defaultValue={this.state.value} />\n' +
  478. ' <h3>Output</h3>\n' +
  479. ' <div\n' +
  480. ' className="content"\n' +
  481. ' dangerouslySetInnerHTML=\n' +
  482. ' />\n' +
  483. ' </div>\n' +
  484. ' );\n' +
  485. ' }\n' +
  486. '});\n' +
  487. 'React.render(<MarkdownEditor />, mountNode);');
  488. // JSX - Not quite correct jsx formatting that still works
  489. bt(
  490. 'var content = (\n' +
  491. ' <Nav>\n' +
  492. ' {/* child comment, put {} around */}\n' +
  493. ' <Person\n' +
  494. ' /* multi\n' +
  495. ' line\n' +
  496. ' comment */\n' +
  497. ' //attr="test"\n' +
  498. ' name={window.isLoggedIn ? window.name : \'\'} // end of line comment\n' +
  499. ' />\n' +
  500. ' </Nav>\n' +
  501. ' );\n' +
  502. 'var qwer = <DropDown> A dropdown list <Menu> <MenuItem>Do Something</MenuItem> <MenuItem>Do Something Fun!</MenuItem> <MenuItem>Do Something Else</MenuItem> </Menu> </DropDown>;\n' +
  503. 'render(dropdown);',
  504. 'var content = (\n' +
  505. ' <Nav>\n' +
  506. ' {/* child comment, put {} around */}\n' +
  507. ' <Person\n' +
  508. ' /* multi\n' +
  509. ' line\n' +
  510. ' comment */\n' +
  511. ' //attr="test"\n' +
  512. ' name={window.isLoggedIn ? window.name : \'\'} // end of line comment\n' +
  513. ' />\n' +
  514. ' </Nav>\n' +
  515. ');\n' +
  516. 'var qwer = <DropDown> A dropdown list <Menu> <MenuItem>Do Something</MenuItem> <MenuItem>Do Something Fun!</MenuItem> <MenuItem>Do Something Else</MenuItem> </Menu> </DropDown>;\n' +
  517. 'render(dropdown);');
  518. // Handles messed up tags, as long as it isn't the same name
  519. // as the root tag. Also handles tags of same name as root tag
  520. // as long as nesting matches.
  521. bt(
  522. 'xml=<a x="jn"><c></b></f><a><d jnj="jnn"><f></a ></nj></a>;',
  523. 'xml = <a x="jn"><c></b></f><a><d jnj="jnn"><f></a ></nj></a>;');
  524. // If xml is not terminated, the remainder of the file is treated
  525. // as part of the xml-literal (passed through unaltered)
  526. test_fragment(
  527. 'xml=<a></b>\nc<b;',
  528. 'xml = <a></b>\nc<b;');
  529. // Issue #646 = whitespace is allowed in attribute declarations
  530. bt(
  531. 'let a = React.createClass({\n' +
  532. ' render() {\n' +
  533. ' return (\n' +
  534. ' <p className=\'a\'>\n' +
  535. ' <span>c</span>\n' +
  536. ' </p>\n' +
  537. ' );\n' +
  538. ' }\n' +
  539. '});');
  540. bt(
  541. 'let a = React.createClass({\n' +
  542. ' render() {\n' +
  543. ' return (\n' +
  544. ' <p className = \'b\'>\n' +
  545. ' <span>c</span>\n' +
  546. ' </p>\n' +
  547. ' );\n' +
  548. ' }\n' +
  549. '});');
  550. bt(
  551. 'let a = React.createClass({\n' +
  552. ' render() {\n' +
  553. ' return (\n' +
  554. ' <p className = "c">\n' +
  555. ' <span>c</span>\n' +
  556. ' </p>\n' +
  557. ' );\n' +
  558. ' }\n' +
  559. '});');
  560. bt(
  561. 'let a = React.createClass({\n' +
  562. ' render() {\n' +
  563. ' return (\n' +
  564. ' <{e} className = {d}>\n' +
  565. ' <span>c</span>\n' +
  566. ' </{e}>\n' +
  567. ' );\n' +
  568. ' }\n' +
  569. '});');
  570. // e4x disabled
  571. opts.e4x = false;
  572. bt(
  573. 'xml=<a b="c"><d/><e>\n foo</e>x</a>;',
  574. 'xml = < a b = "c" > < d / > < e >\n foo < /e>x</a > ;');
  575. // Multiple braces
  576. bt('{{}/z/}', '{\n {}\n /z/\n}');
  577. // Beautify preserve formatting
  578. bt('/* beautify preserve:start */\n/* beautify preserve:end */');
  579. bt('/* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */');
  580. bt('var a = 1;\n/* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */');
  581. bt('/* beautify preserve:start */ {asdklgh;y;;{}dd2d}/* beautify preserve:end */');
  582. bt(
  583. 'var a = 1;\n/* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */',
  584. 'var a = 1;\n/* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */');
  585. bt(
  586. 'var a = 1;\n /* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */',
  587. 'var a = 1;\n/* beautify preserve:start */\n var a = 1;\n/* beautify preserve:end */');
  588. bt(
  589. 'var a = {\n' +
  590. ' /* beautify preserve:start */\n' +
  591. ' one : 1\n' +
  592. ' two : 2,\n' +
  593. ' three : 3,\n' +
  594. ' ten : 10\n' +
  595. ' /* beautify preserve:end */\n' +
  596. '};');
  597. bt(
  598. 'var a = {\n' +
  599. '/* beautify preserve:start */\n' +
  600. ' one : 1,\n' +
  601. ' two : 2,\n' +
  602. ' three : 3,\n' +
  603. ' ten : 10\n' +
  604. '/* beautify preserve:end */\n' +
  605. '};',
  606. 'var a = {\n' +
  607. ' /* beautify preserve:start */\n' +
  608. ' one : 1,\n' +
  609. ' two : 2,\n' +
  610. ' three : 3,\n' +
  611. ' ten : 10\n' +
  612. '/* beautify preserve:end */\n' +
  613. '};');
  614. // one space before and after required, only single spaces inside.
  615. bt(
  616. 'var a = {\n' +
  617. '/* beautify preserve:start */\n' +
  618. ' one : 1,\n' +
  619. ' two : 2,\n' +
  620. ' three : 3,\n' +
  621. ' ten : 10\n' +
  622. '};',
  623. 'var a = {\n' +
  624. ' /* beautify preserve:start */\n' +
  625. ' one: 1,\n' +
  626. ' two: 2,\n' +
  627. ' three: 3,\n' +
  628. ' ten: 10\n' +
  629. '};');
  630. bt(
  631. 'var a = {\n' +
  632. '/*beautify preserve:start*/\n' +
  633. ' one : 1,\n' +
  634. ' two : 2,\n' +
  635. ' three : 3,\n' +
  636. ' ten : 10\n' +
  637. '};',
  638. 'var a = {\n' +
  639. ' /*beautify preserve:start*/\n' +
  640. ' one: 1,\n' +
  641. ' two: 2,\n' +
  642. ' three: 3,\n' +
  643. ' ten: 10\n' +
  644. '};');
  645. bt(
  646. 'var a = {\n' +
  647. '/*beautify preserve:start*/\n' +
  648. ' one : 1,\n' +
  649. ' two : 2,\n' +
  650. ' three : 3,\n' +
  651. ' ten : 10\n' +
  652. '};',
  653. 'var a = {\n' +
  654. ' /*beautify preserve:start*/\n' +
  655. ' one: 1,\n' +
  656. ' two: 2,\n' +
  657. ' three: 3,\n' +
  658. ' ten: 10\n' +
  659. '};');
  660. // Directive: ignore
  661. bt('/* beautify ignore:start */\n/* beautify ignore:end */');
  662. bt('/* beautify ignore:start */\n var a,,,{ 1;\n/* beautify ignore:end */');
  663. bt('var a = 1;\n/* beautify ignore:start */\n var a = 1;\n/* beautify ignore:end */');
  664. bt('/* beautify ignore:start */ {asdklgh;y;+++;dd2d}/* beautify ignore:end */');
  665. bt(
  666. 'var a = 1;\n/* beautify ignore:start */\n var a,,,{ 1;\n/* beautify ignore:end */',
  667. 'var a = 1;\n/* beautify ignore:start */\n var a,,,{ 1;\n/* beautify ignore:end */');
  668. bt(
  669. 'var a = 1;\n /* beautify ignore:start */\n var a,,,{ 1;\n/* beautify ignore:end */',
  670. 'var a = 1;\n/* beautify ignore:start */\n var a,,,{ 1;\n/* beautify ignore:end */');
  671. bt(
  672. 'var a = {\n' +
  673. ' /* beautify ignore:start */\n' +
  674. ' one : 1\n' +
  675. ' two : 2,\n' +
  676. ' three : {\n' +
  677. ' ten : 10\n' +
  678. ' /* beautify ignore:end */\n' +
  679. '};');
  680. bt(
  681. 'var a = {\n' +
  682. '/* beautify ignore:start */\n' +
  683. ' one : 1\n' +
  684. ' two : 2,\n' +
  685. ' three : {\n' +
  686. ' ten : 10\n' +
  687. '/* beautify ignore:end */\n' +
  688. '};',
  689. 'var a = {\n' +
  690. ' /* beautify ignore:start */\n' +
  691. ' one : 1\n' +
  692. ' two : 2,\n' +
  693. ' three : {\n' +
  694. ' ten : 10\n' +
  695. '/* beautify ignore:end */\n' +
  696. '};');
  697. // Directives - multiple and interacting
  698. bt(
  699. 'var a = {\n' +
  700. '/* beautify preserve:start */\n' +
  701. '/* beautify preserve:start */\n' +
  702. ' one : 1,\n' +
  703. ' /* beautify preserve:end */\n' +
  704. ' two : 2,\n' +
  705. ' three : 3,\n' +
  706. '/* beautify preserve:start */\n' +
  707. ' ten : 10\n' +
  708. '/* beautify preserve:end */\n' +
  709. '};',
  710. 'var a = {\n' +
  711. ' /* beautify preserve:start */\n' +
  712. '/* beautify preserve:start */\n' +
  713. ' one : 1,\n' +
  714. ' /* beautify preserve:end */\n' +
  715. ' two: 2,\n' +
  716. ' three: 3,\n' +
  717. ' /* beautify preserve:start */\n' +
  718. ' ten : 10\n' +
  719. '/* beautify preserve:end */\n' +
  720. '};');
  721. bt(
  722. 'var a = {\n' +
  723. '/* beautify ignore:start */\n' +
  724. ' one : 1\n' +
  725. ' /* beautify ignore:end */\n' +
  726. ' two : 2,\n' +
  727. '/* beautify ignore:start */\n' +
  728. ' three : {\n' +
  729. ' ten : 10\n' +
  730. '/* beautify ignore:end */\n' +
  731. '};',
  732. 'var a = {\n' +
  733. ' /* beautify ignore:start */\n' +
  734. ' one : 1\n' +
  735. ' /* beautify ignore:end */\n' +
  736. ' two: 2,\n' +
  737. ' /* beautify ignore:start */\n' +
  738. ' three : {\n' +
  739. ' ten : 10\n' +
  740. '/* beautify ignore:end */\n' +
  741. '};');
  742. // Starts can occur together, ignore:end must occur alone.
  743. bt(
  744. 'var a = {\n' +
  745. '/* beautify ignore:start */\n' +
  746. ' one : 1\n' +
  747. ' NOTE: ignore end block does not support starting other directives\n' +
  748. ' This does not match the ending the ignore...\n' +
  749. ' /* beautify ignore:end preserve:start */\n' +
  750. ' two : 2,\n' +
  751. '/* beautify ignore:start */\n' +
  752. ' three : {\n' +
  753. ' ten : 10\n' +
  754. ' ==The next comment ends the starting ignore==\n' +
  755. '/* beautify ignore:end */\n' +
  756. '};',
  757. 'var a = {\n' +
  758. ' /* beautify ignore:start */\n' +
  759. ' one : 1\n' +
  760. ' NOTE: ignore end block does not support starting other directives\n' +
  761. ' This does not match the ending the ignore...\n' +
  762. ' /* beautify ignore:end preserve:start */\n' +
  763. ' two : 2,\n' +
  764. '/* beautify ignore:start */\n' +
  765. ' three : {\n' +
  766. ' ten : 10\n' +
  767. ' ==The next comment ends the starting ignore==\n' +
  768. '/* beautify ignore:end */\n' +
  769. '};');
  770. bt(
  771. 'var a = {\n' +
  772. '/* beautify ignore:start preserve:start */\n' +
  773. ' one : {\n' +
  774. ' /* beautify ignore:end */\n' +
  775. ' two : 2,\n' +
  776. ' /* beautify ignore:start */\n' +
  777. ' three : {\n' +
  778. '/* beautify ignore:end */\n' +
  779. ' ten : 10\n' +
  780. ' // This is all preserved\n' +
  781. '};',
  782. 'var a = {\n' +
  783. ' /* beautify ignore:start preserve:start */\n' +
  784. ' one : {\n' +
  785. ' /* beautify ignore:end */\n' +
  786. ' two : 2,\n' +
  787. ' /* beautify ignore:start */\n' +
  788. ' three : {\n' +
  789. '/* beautify ignore:end */\n' +
  790. ' ten : 10\n' +
  791. ' // This is all preserved\n' +
  792. '};');
  793. bt(
  794. 'var a = {\n' +
  795. '/* beautify ignore:start preserve:start */\n' +
  796. ' one : {\n' +
  797. ' /* beautify ignore:end */\n' +
  798. ' two : 2,\n' +
  799. ' /* beautify ignore:start */\n' +
  800. ' three : {\n' +
  801. '/* beautify ignore:end */\n' +
  802. ' ten : 10,\n' +
  803. '/* beautify preserve:end */\n' +
  804. ' eleven: 11\n' +
  805. '};',
  806. 'var a = {\n' +
  807. ' /* beautify ignore:start preserve:start */\n' +
  808. ' one : {\n' +
  809. ' /* beautify ignore:end */\n' +
  810. ' two : 2,\n' +
  811. ' /* beautify ignore:start */\n' +
  812. ' three : {\n' +
  813. '/* beautify ignore:end */\n' +
  814. ' ten : 10,\n' +
  815. '/* beautify preserve:end */\n' +
  816. ' eleven: 11\n' +
  817. '};');
  818. // Template Formatting
  819. bt('<?=$view["name"]; ?>');
  820. bt('a = <?= external() ?>;');
  821. bt(
  822. '<?php\n' +
  823. 'for($i = 1; $i <= 100; $i++;) {\n' +
  824. ' #count to 100!\n' +
  825. ' echo($i . "</br>");\n' +
  826. '}\n' +
  827. '?>');
  828. bt('a = <%= external() %>;');
  829. // jslint and space after anon function - (f = " ", c = "")
  830. opts.jslint_happy = true;
  831. opts.space_after_anon_function = true;
  832. bt(
  833. 'a=typeof(x)',
  834. 'a = typeof (x)');
  835. bt(
  836. 'x();\n\nfunction(){}',
  837. 'x();\n\nfunction () {}');
  838. bt(
  839. 'function () {\n var a, b, c, d, e = [],\n f;\n}');
  840. bt(
  841. 'switch(x) {case 0: case 1: a(); break; default: break}',
  842. 'switch (x) {\ncase 0:\ncase 1:\n a();\n break;\ndefault:\n break\n}');
  843. bt('switch(x){case -1:break;case !y:break;}', 'switch (x) {\ncase -1:\n break;\ncase !y:\n break;\n}');
  844. // typical greasemonkey start
  845. test_fragment('// comment 2\n(function ()');
  846. bt(
  847. 'var a2, b2, c2, d2 = 0, c = function() {}, d = \'\';',
  848. 'var a2, b2, c2, d2 = 0,\n c = function () {},\n d = \'\';');
  849. bt(
  850. 'var a2, b2, c2, d2 = 0, c = function() {},\nd = \'\';',
  851. 'var a2, b2, c2, d2 = 0,\n c = function () {},\n d = \'\';');
  852. bt(
  853. 'var o2=$.extend(a);function(){alert(x);}',
  854. 'var o2 = $.extend(a);\n\nfunction () {\n alert(x);\n}');
  855. bt('function*() {\n yield 1;\n}', 'function* () {\n yield 1;\n}');
  856. bt('function* x() {\n yield 1;\n}');
  857. // jslint and space after anon function - (f = " ", c = "")
  858. opts.jslint_happy = true;
  859. opts.space_after_anon_function = false;
  860. bt(
  861. 'a=typeof(x)',
  862. 'a = typeof (x)');
  863. bt(
  864. 'x();\n\nfunction(){}',
  865. 'x();\n\nfunction () {}');
  866. bt(
  867. 'function () {\n var a, b, c, d, e = [],\n f;\n}');
  868. bt(
  869. 'switch(x) {case 0: case 1: a(); break; default: break}',
  870. 'switch (x) {\ncase 0:\ncase 1:\n a();\n break;\ndefault:\n break\n}');
  871. bt('switch(x){case -1:break;case !y:break;}', 'switch (x) {\ncase -1:\n break;\ncase !y:\n break;\n}');
  872. // typical greasemonkey start
  873. test_fragment('// comment 2\n(function ()');
  874. bt(
  875. 'var a2, b2, c2, d2 = 0, c = function() {}, d = \'\';',
  876. 'var a2, b2, c2, d2 = 0,\n c = function () {},\n d = \'\';');
  877. bt(
  878. 'var a2, b2, c2, d2 = 0, c = function() {},\nd = \'\';',
  879. 'var a2, b2, c2, d2 = 0,\n c = function () {},\n d = \'\';');
  880. bt(
  881. 'var o2=$.extend(a);function(){alert(x);}',
  882. 'var o2 = $.extend(a);\n\nfunction () {\n alert(x);\n}');
  883. bt('function*() {\n yield 1;\n}', 'function* () {\n yield 1;\n}');
  884. bt('function* x() {\n yield 1;\n}');
  885. // jslint and space after anon function - (f = " ", c = " ")
  886. opts.jslint_happy = false;
  887. opts.space_after_anon_function = true;
  888. bt(
  889. 'a=typeof(x)',
  890. 'a = typeof (x)');
  891. bt(
  892. 'x();\n\nfunction(){}',
  893. 'x();\n\nfunction () {}');
  894. bt(
  895. 'function () {\n var a, b, c, d, e = [],\n f;\n}');
  896. bt(
  897. 'switch(x) {case 0: case 1: a(); break; default: break}',
  898. 'switch (x) {\n case 0:\n case 1:\n a();\n break;\n default:\n break\n}');
  899. bt('switch(x){case -1:break;case !y:break;}', 'switch (x) {\n case -1:\n break;\n case !y:\n break;\n}');
  900. // typical greasemonkey start
  901. test_fragment('// comment 2\n(function ()');
  902. bt(
  903. 'var a2, b2, c2, d2 = 0, c = function() {}, d = \'\';',
  904. 'var a2, b2, c2, d2 = 0,\n c = function () {},\n d = \'\';');
  905. bt(
  906. 'var a2, b2, c2, d2 = 0, c = function() {},\nd = \'\';',
  907. 'var a2, b2, c2, d2 = 0,\n c = function () {},\n d = \'\';');
  908. bt(
  909. 'var o2=$.extend(a);function(){alert(x);}',
  910. 'var o2 = $.extend(a);\n\nfunction () {\n alert(x);\n}');
  911. bt('function*() {\n yield 1;\n}', 'function* () {\n yield 1;\n}');
  912. bt('function* x() {\n yield 1;\n}');
  913. // jslint and space after anon function - (f = "", c = " ")
  914. opts.jslint_happy = false;
  915. opts.space_after_anon_function = false;
  916. bt(
  917. 'a=typeof(x)',
  918. 'a = typeof(x)');
  919. bt(
  920. 'x();\n\nfunction(){}',
  921. 'x();\n\nfunction() {}');
  922. bt(
  923. 'function () {\n var a, b, c, d, e = [],\n f;\n}',
  924. 'function() {\n var a, b, c, d, e = [],\n f;\n}');
  925. bt(
  926. 'switch(x) {case 0: case 1: a(); break; default: break}',
  927. 'switch (x) {\n case 0:\n case 1:\n a();\n break;\n default:\n break\n}');
  928. bt('switch(x){case -1:break;case !y:break;}', 'switch (x) {\n case -1:\n break;\n case !y:\n break;\n}');
  929. // typical greasemonkey start
  930. test_fragment('// comment 2\n(function()');
  931. bt(
  932. 'var a2, b2, c2, d2 = 0, c = function() {}, d = \'\';',
  933. 'var a2, b2, c2, d2 = 0,\n c = function() {},\n d = \'\';');
  934. bt(
  935. 'var a2, b2, c2, d2 = 0, c = function() {},\nd = \'\';',
  936. 'var a2, b2, c2, d2 = 0,\n c = function() {},\n d = \'\';');
  937. bt(
  938. 'var o2=$.extend(a);function(){alert(x);}',
  939. 'var o2 = $.extend(a);\n\nfunction() {\n alert(x);\n}');
  940. bt('function*() {\n yield 1;\n}');
  941. bt('function* x() {\n yield 1;\n}');
  942. // Regression tests
  943. // Issue 241
  944. bt(
  945. 'obj\n' +
  946. ' .last({\n' +
  947. ' foo: 1,\n' +
  948. ' bar: 2\n' +
  949. ' });\n' +
  950. 'var test = 1;');
  951. bt(
  952. 'obj\n' +
  953. ' .last(a, function() {\n' +
  954. ' var test;\n' +
  955. ' });\n' +
  956. 'var test = 1;');
  957. bt(
  958. 'obj.first()\n' +
  959. ' .second()\n' +
  960. ' .last(function(err, response) {\n' +
  961. ' console.log(err);\n' +
  962. ' });');
  963. // Issue 268 and 275
  964. bt(
  965. 'obj.last(a, function() {\n' +
  966. ' var test;\n' +
  967. '});\n' +
  968. 'var test = 1;');
  969. bt(
  970. 'obj.last(a,\n' +
  971. ' function() {\n' +
  972. ' var test;\n' +
  973. ' });\n' +
  974. 'var test = 1;');
  975. bt(
  976. '(function() {if (!window.FOO) window.FOO || (window.FOO = function() {var b = {bar: "zort"};});})();',
  977. '(function() {\n' +
  978. ' if (!window.FOO) window.FOO || (window.FOO = function() {\n' +
  979. ' var b = {\n' +
  980. ' bar: "zort"\n' +
  981. ' };\n' +
  982. ' });\n' +
  983. '})();');
  984. // Issue 281
  985. bt(
  986. 'define(["dojo/_base/declare", "my/Employee", "dijit/form/Button",\n' +
  987. ' "dojo/_base/lang", "dojo/Deferred"\n' +
  988. '], function(declare, Employee, Button, lang, Deferred) {\n' +
  989. ' return declare(Employee, {\n' +
  990. ' constructor: function() {\n' +
  991. ' new Button({\n' +
  992. ' onClick: lang.hitch(this, function() {\n' +
  993. ' new Deferred().then(lang.hitch(this, function() {\n' +
  994. ' this.salary * 0.25;\n' +
  995. ' }));\n' +
  996. ' })\n' +
  997. ' });\n' +
  998. ' }\n' +
  999. ' });\n' +
  1000. '});');
  1001. bt(
  1002. 'define(["dojo/_base/declare", "my/Employee", "dijit/form/Button",\n' +
  1003. ' "dojo/_base/lang", "dojo/Deferred"\n' +
  1004. ' ],\n' +
  1005. ' function(declare, Employee, Button, lang, Deferred) {\n' +
  1006. ' return declare(Employee, {\n' +
  1007. ' constructor: function() {\n' +
  1008. ' new Button({\n' +
  1009. ' onClick: lang.hitch(this, function() {\n' +
  1010. ' new Deferred().then(lang.hitch(this, function() {\n' +
  1011. ' this.salary * 0.25;\n' +
  1012. ' }));\n' +
  1013. ' })\n' +
  1014. ' });\n' +
  1015. ' }\n' +
  1016. ' });\n' +
  1017. ' });');
  1018. // Issue 459
  1019. bt(
  1020. '(function() {\n' +
  1021. ' return {\n' +
  1022. ' foo: function() {\n' +
  1023. ' return "bar";\n' +
  1024. ' },\n' +
  1025. ' bar: ["bar"]\n' +
  1026. ' };\n' +
  1027. '}());');
  1028. // Issue 505 - strings should end at newline unless continued by backslash
  1029. bt(
  1030. 'var name = "a;\n' +
  1031. 'name = "b";');
  1032. bt(
  1033. 'var name = "a;\\\n' +
  1034. ' name = b";');
  1035. // Issue 514 - some operators require spaces to distinguish them
  1036. bt('var c = "_ACTION_TO_NATIVEAPI_" + ++g++ + +new Date;');
  1037. bt('var c = "_ACTION_TO_NATIVEAPI_" - --g-- - -new Date;');
  1038. // Issue 440 - reserved words can be used as object property names
  1039. bt(
  1040. 'a = {\n' +
  1041. ' function: {},\n' +
  1042. ' "function": {},\n' +
  1043. ' throw: {},\n' +
  1044. ' "throw": {},\n' +
  1045. ' var: {},\n' +
  1046. ' "var": {},\n' +
  1047. ' set: {},\n' +
  1048. ' "set": {},\n' +
  1049. ' get: {},\n' +
  1050. ' "get": {},\n' +
  1051. ' if: {},\n' +
  1052. ' "if": {},\n' +
  1053. ' then: {},\n' +
  1054. ' "then": {},\n' +
  1055. ' else: {},\n' +
  1056. ' "else": {},\n' +
  1057. ' yay: {}\n' +
  1058. '};');
  1059. // Issue 331 - if-else with braces edge case
  1060. bt(
  1061. 'if(x){a();}else{b();}if(y){c();}',
  1062. 'if (x) {\n' +
  1063. ' a();\n' +
  1064. '} else {\n' +
  1065. ' b();\n' +
  1066. '}\n' +
  1067. 'if (y) {\n' +
  1068. ' c();\n' +
  1069. '}');
  1070. // Issue 485 - ensure function declarations behave the same in arrays as elsewhere
  1071. bt(
  1072. 'var v = ["a",\n' +
  1073. ' function() {\n' +
  1074. ' return;\n' +
  1075. ' }, {\n' +
  1076. ' id: 1\n' +
  1077. ' }\n' +
  1078. '];');
  1079. bt(
  1080. 'var v = ["a", function() {\n' +
  1081. ' return;\n' +
  1082. '}, {\n' +
  1083. ' id: 1\n' +
  1084. '}];');
  1085. // Issue 382 - initial totally cursory support for es6 module export
  1086. bt(
  1087. 'module "Even" {\n' +
  1088. ' import odd from "Odd";\n' +
  1089. ' export function sum(x, y) {\n' +
  1090. ' return x + y;\n' +
  1091. ' }\n' +
  1092. ' export var pi = 3.141593;\n' +
  1093. ' export default moduleName;\n' +
  1094. '}');
  1095. bt(
  1096. 'module "Even" {\n' +
  1097. ' export default function div(x, y) {}\n' +
  1098. '}');
  1099. // Issue 508
  1100. bt('set["name"]');
  1101. bt('get["name"]');
  1102. bt(
  1103. 'a = {\n' +
  1104. ' set b(x) {},\n' +
  1105. ' c: 1,\n' +
  1106. ' d: function() {}\n' +
  1107. '};');
  1108. bt(
  1109. 'a = {\n' +
  1110. ' get b() {\n' +
  1111. ' retun 0;\n' +
  1112. ' },\n' +
  1113. ' c: 1,\n' +
  1114. ' d: function() {}\n' +
  1115. '};');
  1116. // Issue 298 - do not under indent if/while/for condtionals experesions
  1117. bt(
  1118. '\'use strict\';\n' +
  1119. 'if ([].some(function() {\n' +
  1120. ' return false;\n' +
  1121. ' })) {\n' +
  1122. ' console.log("hello");\n' +
  1123. '}');
  1124. // Issue 298 - do not under indent if/while/for condtionals experesions
  1125. bt(
  1126. '\'use strict\';\n' +
  1127. 'if ([].some(function() {\n' +
  1128. ' return false;\n' +
  1129. ' })) {\n' +
  1130. ' console.log("hello");\n' +
  1131. '}');
  1132. // Issue 552 - Typescript? Okay... we didn't break it before, so try not to break it now.
  1133. bt(
  1134. 'class Test {\n' +
  1135. ' blah: string[];\n' +
  1136. ' foo(): number {\n' +
  1137. ' return 0;\n' +
  1138. ' }\n' +
  1139. ' bar(): number {\n' +
  1140. ' return 0;\n' +
  1141. ' }\n' +
  1142. '}');
  1143. bt(
  1144. 'interface Test {\n' +
  1145. ' blah: string[];\n' +
  1146. ' foo(): number {\n' +
  1147. ' return 0;\n' +
  1148. ' }\n' +
  1149. ' bar(): number {\n' +
  1150. ' return 0;\n' +
  1151. ' }\n' +
  1152. '}');
  1153. // Issue 583 - Functions with comments after them should still indent correctly.
  1154. bt(
  1155. 'function exit(code) {\n' +
  1156. ' setTimeout(function() {\n' +
  1157. ' phantom.exit(code);\n' +
  1158. ' }, 0);\n' +
  1159. ' phantom.onError = function() {};\n' +
  1160. '}\n' +
  1161. '// Comment');
  1162. // Old tests
  1163. bt('');
  1164. test_fragment(' return .5');
  1165. test_fragment(' return .5;\n a();');
  1166. test_fragment(' return .5;\n a();');
  1167. test_fragment(' return .5;\n a();');
  1168. test_fragment(' < div');
  1169. bt('a = 1', 'a = 1');
  1170. bt('a=1', 'a = 1');
  1171. bt('(3) / 2');
  1172. bt('["a", "b"].join("")');
  1173. bt('a();\n\nb();');
  1174. bt('var a = 1 var b = 2', 'var a = 1\nvar b = 2');
  1175. bt('var a=1, b=c[d], e=6;', 'var a = 1,\n b = c[d],\n e = 6;');
  1176. bt('var a,\n b,\n c;');
  1177. bt('let a = 1 let b = 2', 'let a = 1\nlet b = 2');
  1178. bt('let a=1, b=c[d], e=6;', 'let a = 1,\n b = c[d],\n e = 6;');
  1179. bt('let a,\n b,\n c;');
  1180. bt('const a = 1 const b = 2', 'const a = 1\nconst b = 2');
  1181. bt('const a=1, b=c[d], e=6;', 'const a = 1,\n b = c[d],\n e = 6;');
  1182. bt('const a,\n b,\n c;');
  1183. bt('a = " 12345 "');
  1184. bt('a = \' 12345 \'');
  1185. bt('if (a == 1) b = 2;');
  1186. bt('if(1){2}else{3}', 'if (1) {\n 2\n} else {\n 3\n}');
  1187. bt('if(1||2);', 'if (1 || 2);');
  1188. bt('(a==1)||(b==2)', '(a == 1) || (b == 2)');
  1189. bt('var a = 1 if (2) 3;', 'var a = 1\nif (2) 3;');
  1190. bt('a = a + 1');
  1191. bt('a = a == 1');
  1192. bt('/12345[^678]*9+/.match(a)');
  1193. bt('a /= 5');
  1194. bt('a = 0.5 * 3');
  1195. bt('a *= 10.55');
  1196. bt('a < .5');
  1197. bt('a <= .5');
  1198. bt('a<.5', 'a < .5');
  1199. bt('a<=.5', 'a <= .5');
  1200. bt('a = 0xff;');
  1201. bt('a=0xff+4', 'a = 0xff + 4');
  1202. bt('a = [1, 2, 3, 4]');
  1203. bt('F*(g/=f)*g+b', 'F * (g /= f) * g + b');
  1204. bt('a.b({c:d})', 'a.b({\n c: d\n})');
  1205. bt('a.b\n(\n{\nc:\nd\n}\n)', 'a.b({\n c: d\n})');
  1206. bt('a.b({c:"d"})', 'a.b({\n c: "d"\n})');
  1207. bt('a.b\n(\n{\nc:\n"d"\n}\n)', 'a.b({\n c: "d"\n})');
  1208. bt('a=!b', 'a = !b');
  1209. bt('a=!!b', 'a = !!b');
  1210. bt('a?b:c', 'a ? b : c');
  1211. bt('a?1:2', 'a ? 1 : 2');
  1212. bt('a?(b):c', 'a ? (b) : c');
  1213. bt('x={a:1,b:w=="foo"?x:y,c:z}', 'x = {\n a: 1,\n b: w == "foo" ? x : y,\n c: z\n}');
  1214. bt('x=a?b?c?d:e:f:g;', 'x = a ? b ? c ? d : e : f : g;');
  1215. bt('x=a?b?c?d:{e1:1,e2:2}:f:g;', 'x = a ? b ? c ? d : {\n e1: 1,\n e2: 2\n} : f : g;');
  1216. bt('function void(void) {}');
  1217. bt('if(!a)foo();', 'if (!a) foo();');
  1218. bt('a=~a', 'a = ~a');
  1219. bt('a;/*comment*/b;', 'a; /*comment*/\nb;');
  1220. bt('a;/* comment */b;', 'a; /* comment */\nb;');
  1221. // simple comments don't get touched at all
  1222. test_fragment('a;/*\ncomment\n*/b;', 'a;\n/*\ncomment\n*/\nb;');
  1223. bt('a;/**\n* javadoc\n*/b;', 'a;\n/**\n * javadoc\n */\nb;');
  1224. test_fragment('a;/**\n\nno javadoc\n*/b;', 'a;\n/**\n\nno javadoc\n*/\nb;');
  1225. // comment blocks detected and reindented even w/o javadoc starter
  1226. bt('a;/*\n* javadoc\n*/b;', 'a;\n/*\n * javadoc\n */\nb;');
  1227. bt('if(a)break;', 'if (a) break;');
  1228. bt('if(a){break}', 'if (a) {\n break\n}');
  1229. bt('if((a))foo();', 'if ((a)) foo();');
  1230. bt('for(var i=0;;) a', 'for (var i = 0;;) a');
  1231. bt('for(var i=0;;)\na', 'for (var i = 0;;)\n a');
  1232. bt('a++;');
  1233. bt('for(;;i++)a()', 'for (;; i++) a()');
  1234. bt('for(;;i++)\na()', 'for (;; i++)\n a()');
  1235. bt('for(;;++i)a', 'for (;; ++i) a');
  1236. bt('return(1)', 'return (1)');
  1237. bt('try{a();}catch(b){c();}finally{d();}', 'try {\n a();\n} catch (b) {\n c();\n} finally {\n d();\n}');
  1238. // magic function call
  1239. bt('(xx)()');
  1240. // another magic function call
  1241. bt('a[1]()');
  1242. bt('if(a){b();}else if(c) foo();', 'if (a) {\n b();\n} else if (c) foo();');
  1243. bt('switch(x) {case 0: case 1: a(); break; default: break}', 'switch (x) {\n case 0:\n case 1:\n a();\n break;\n default:\n break\n}');
  1244. bt('switch(x){case -1:break;case !y:break;}', 'switch (x) {\n case -1:\n break;\n case !y:\n break;\n}');
  1245. bt('a !== b');
  1246. bt('if (a) b(); else c();', 'if (a) b();\nelse c();');
  1247. // typical greasemonkey start
  1248. bt('// comment\n(function something() {})');
  1249. // duplicating newlines
  1250. bt('{\n\n x();\n\n}');
  1251. bt('if (a in b) foo();');
  1252. bt('if(X)if(Y)a();else b();else c();', 'if (X)\n if (Y) a();\n else b();\nelse c();');
  1253. bt('if (foo) bar();\nelse break');
  1254. bt('var a, b;');
  1255. bt('var a = new function();');
  1256. test_fragment('new function');
  1257. bt('var a, b');
  1258. bt('{a:1, b:2}', '{\n a: 1,\n b: 2\n}');
  1259. bt('a={1:[-1],2:[+1]}', 'a = {\n 1: [-1],\n 2: [+1]\n}');
  1260. bt('var l = {\'a\':\'1\', \'b\':\'2\'}', 'var l = {\n \'a\': \'1\',\n \'b\': \'2\'\n}');
  1261. bt('if (template.user[n] in bk) foo();');
  1262. bt('return 45');
  1263. bt('return this.prevObject ||\n\n this.constructor(null);');
  1264. bt('If[1]');
  1265. bt('Then[1]');
  1266. bt('a = 1e10');
  1267. bt('a = 1.3e10');
  1268. bt('a = 1.3e-10');
  1269. bt('a = -1.3e-10');
  1270. bt('a = 1e-10');
  1271. bt('a = e - 10');
  1272. bt('a = 11-10', 'a = 11 - 10');
  1273. bt('a = 1;// comment', 'a = 1; // comment');
  1274. bt('a = 1; // comment');
  1275. bt('a = 1;\n // comment', 'a = 1;\n// comment');
  1276. bt('a = [-1, -1, -1]');
  1277. // The exact formatting these should have is open for discussion, but they are at least reasonable
  1278. bt('a = [ // comment\n -1, -1, -1\n]');
  1279. bt('var a = [ // comment\n -1, -1, -1\n]');
  1280. bt('a = [ // comment\n -1, // comment\n -1, -1\n]');
  1281. bt('var a = [ // comment\n -1, // comment\n -1, -1\n]');
  1282. bt('o = [{a:b},{c:d}]', 'o = [{\n a: b\n}, {\n c: d\n}]');
  1283. // was: extra space appended
  1284. bt('if (a) {\n do();\n}');
  1285. // if/else statement with empty body
  1286. bt('if (a) {\n// comment\n}else{\n// comment\n}', 'if (a) {\n // comment\n} else {\n // comment\n}');
  1287. // multiple comments indentation
  1288. bt('if (a) {\n// comment\n// comment\n}', 'if (a) {\n // comment\n // comment\n}');
  1289. bt('if (a) b() else c();', 'if (a) b()\nelse c();');
  1290. bt('if (a) b() else if c() d();', 'if (a) b()\nelse if c() d();');
  1291. bt('{}');
  1292. bt('{\n\n}');
  1293. bt('do { a(); } while ( 1 );', 'do {\n a();\n} while (1);');
  1294. bt('do {} while (1);');
  1295. bt('do {\n} while (1);', 'do {} while (1);');
  1296. bt('do {\n\n} while (1);');
  1297. bt('var a = x(a, b, c)');
  1298. bt('delete x if (a) b();', 'delete x\nif (a) b();');
  1299. bt('delete x[x] if (a) b();', 'delete x[x]\nif (a) b();');
  1300. bt('for(var a=1,b=2)d', 'for (var a = 1, b = 2) d');
  1301. bt('for(var a=1,b=2,c=3) d', 'for (var a = 1, b = 2, c = 3) d');
  1302. bt('for(var a=1,b=2,c=3;d<3;d++)\ne', 'for (var a = 1, b = 2, c = 3; d < 3; d++)\n e');
  1303. bt('function x(){(a||b).c()}', 'function x() {\n (a || b).c()\n}');
  1304. bt('function x(){return - 1}', 'function x() {\n return -1\n}');
  1305. bt('function x(){return ! a}', 'function x() {\n return !a\n}');
  1306. bt('x => x');
  1307. bt('(x) => x');
  1308. bt('x => { x }', 'x => {\n x\n}');
  1309. bt('(x) => { x }', '(x) => {\n x\n}');
  1310. // a common snippet in jQuery plugins
  1311. bt(
  1312. 'settings = $.extend({},defaults,settings);',
  1313. 'settings = $.extend({}, defaults, settings);');
  1314. bt('$http().then().finally().default()');
  1315. bt('$http()\n.then()\n.finally()\n.default()', '$http()\n .then()\n .finally()\n .default()');
  1316. bt('$http().when.in.new.catch().throw()');
  1317. bt('$http()\n.when\n.in\n.new\n.catch()\n.throw()', '$http()\n .when\n .in\n .new\n .catch()\n .throw()');
  1318. bt('{xxx;}()', '{\n xxx;\n}()');
  1319. bt('a = \'a\'\nb = \'b\'');
  1320. bt('a = /reg/exp');
  1321. bt('a = /reg/');
  1322. bt('/abc/.test()');
  1323. bt('/abc/i.test()');
  1324. bt('{/abc/i.test()}', '{\n /abc/i.test()\n}');
  1325. bt('var x=(a)/a;', 'var x = (a) / a;');
  1326. bt('x != -1');
  1327. bt('for (; s-->0;)t', 'for (; s-- > 0;) t');
  1328. bt('for (; s++>0;)u', 'for (; s++ > 0;) u');
  1329. bt('a = s++>s--;', 'a = s++ > s--;');
  1330. bt('a = s++>--s;', 'a = s++ > --s;');
  1331. bt('{x=#1=[]}', '{\n x = #1=[]\n}');
  1332. bt('{a:#1={}}', '{\n a: #1={}\n}');
  1333. bt('{a:#1#}', '{\n a: #1#\n}');
  1334. test_fragment('"incomplete-string');
  1335. test_fragment('\'incomplete-string');
  1336. test_fragment('/incomplete-regex');
  1337. test_fragment('`incomplete-template-string');
  1338. test_fragment('{a:1},{a:2}', '{\n a: 1\n}, {\n a: 2\n}');
  1339. test_fragment('var ary=[{a:1}, {a:2}];', 'var ary = [{\n a: 1\n}, {\n a: 2\n}];');
  1340. // incomplete
  1341. test_fragment('{a:#1', '{\n a: #1');
  1342. // incomplete
  1343. test_fragment('{a:#', '{\n a: #');
  1344. // incomplete
  1345. test_fragment('}}}', '}\n}\n}');
  1346. test_fragment('<!--\nvoid();\n// -->');
  1347. // incomplete regexp
  1348. test_fragment('a=/regexp', 'a = /regexp');
  1349. bt('{a:#1=[],b:#1#,c:#999999#}', '{\n a: #1=[],\n b: #1#,\n c: #999999#\n}');
  1350. bt('a = 1e+2');
  1351. bt('a = 1e-2');
  1352. bt('do{x()}while(a>1)', 'do {\n x()\n} while (a > 1)');
  1353. bt('x(); /reg/exp.match(something)', 'x();\n/reg/exp.match(something)');
  1354. test_fragment('something();(', 'something();\n(');
  1355. test_fragment('#!she/bangs, she bangs\nf=1', '#!she/bangs, she bangs\n\nf = 1');
  1356. test_fragment('#!she/bangs, she bangs\n\nf=1', '#!she/bangs, she bangs\n\nf = 1');
  1357. test_fragment('#!she/bangs, she bangs\n\n/* comment */');
  1358. test_fragment('#!she/bangs, she bangs\n\n\n/* comment */');
  1359. test_fragment('#');
  1360. test_fragment('#!');
  1361. bt('function namespace::something()');
  1362. test_fragment('<!--\nsomething();\n-->');
  1363. test_fragment('<!--\nif(i<0){bla();}\n-->', '<!--\nif (i < 0) {\n bla();\n}\n-->');
  1364. bt('{foo();--bar;}', '{\n foo();\n --bar;\n}');
  1365. bt('{foo();++bar;}', '{\n foo();\n ++bar;\n}');
  1366. bt('{--bar;}', '{\n --bar;\n}');
  1367. bt('{++bar;}', '{\n ++bar;\n}');
  1368. bt('if(true)++a;', 'if (true) ++a;');
  1369. bt('if(true)\n++a;', 'if (true)\n ++a;');
  1370. bt('if(true)--a;', 'if (true) --a;');
  1371. bt('if(true)\n--a;', 'if (true)\n --a;');
  1372. bt('elem[array]++;');
  1373. bt('elem++ * elem[array]++;');
  1374. bt('elem-- * -elem[array]++;');
  1375. bt('elem-- + elem[array]++;');
  1376. bt('elem-- - elem[array]++;');
  1377. bt('elem-- - -elem[array]++;');
  1378. bt('elem-- - +elem[array]++;');
  1379. // Handling of newlines around unary ++ and -- operators
  1380. bt('{foo\n++bar;}', '{\n foo\n ++bar;\n}');
  1381. bt('{foo++\nbar;}', '{\n foo++\n bar;\n}');
  1382. // This is invalid, but harder to guard against. Issue #203.
  1383. bt('{foo\n++\nbar;}', '{\n foo\n ++\n bar;\n}');
  1384. // regexps
  1385. bt('a(/abc\\/\\/def/);b()', 'a(/abc\\/\\/def/);\nb()');
  1386. bt('a(/a[b\\[\\]c]d/);b()', 'a(/a[b\\[\\]c]d/);\nb()');
  1387. // incomplete char class
  1388. test_fragment('a(/a[b\\[');
  1389. // allow unescaped / in char classes
  1390. bt('a(/[a/b]/);b()', 'a(/[a/b]/);\nb()');
  1391. bt('typeof /foo\\//;');
  1392. bt('yield /foo\\//;');
  1393. bt('throw /foo\\//;');
  1394. bt('do /foo\\//;');
  1395. bt('return /foo\\//;');
  1396. bt('switch (a) {\n case /foo\\//:\n b\n}');
  1397. bt('if (a) /foo\\//\nelse /foo\\//;');
  1398. bt('if (foo) /regex/.test();');
  1399. bt('for (index in [1, 2, 3]) /^test$/i.test(s)');
  1400. bt('result = yield pgClient.query_(queryString);');
  1401. bt('function foo() {\n return [\n "one",\n "two"\n ];\n}');
  1402. bt('a=[[1,2],[4,5],[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n [7, 8]\n]');
  1403. bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n [7, 8]\n]');
  1404. bt('a=[[1,2],[4,5],function(){},function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n function() {},\n [7, 8]\n]');
  1405. bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n [7, 8]\n]');
  1406. bt('a=[b,c,function(){},function(){},d]', 'a = [b, c, function() {}, function() {}, d]');
  1407. bt('a=[b,c,\nfunction(){},function(){},d]', 'a = [b, c,\n function() {},\n function() {},\n d\n]');
  1408. bt('a=[a[1],b[4],c[d[7]]]', 'a = [a[1], b[4], c[d[7]]]');
  1409. bt('[1,2,[3,4,[5,6],7],8]', '[1, 2, [3, 4, [5, 6], 7], 8]');
  1410. bt('[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]', '[\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]');
  1411. bt('{[x()[0]];indent;}', '{\n [x()[0]];\n indent;\n}');
  1412. bt('/*\n foo trailing space \n * bar trailing space \n**/');
  1413. bt('{\n /*\n foo \n * bar \n */\n}');
  1414. bt('return ++i');
  1415. bt('return !!x');
  1416. bt('return !x');
  1417. bt('return [1,2]', 'return [1, 2]');
  1418. bt('return;');
  1419. bt('return\nfunc');
  1420. bt('catch(e)', 'catch (e)');
  1421. bt('yield [1, 2]');
  1422. bt('var a=1,b={foo:2,bar:3},{baz:4,wham:5},c=4;', 'var a = 1,\n b = {\n foo: 2,\n bar: 3\n },\n {\n baz: 4,\n wham: 5\n }, c = 4;');
  1423. bt('var a=1,b={foo:2,bar:3},{baz:4,wham:5},\nc=4;', 'var a = 1,\n b = {\n foo: 2,\n bar: 3\n },\n {\n baz: 4,\n wham: 5\n },\n c = 4;');
  1424. // inline comment
  1425. bt(
  1426. 'function x(/*int*/ start, /*string*/ foo)',
  1427. 'function x( /*int*/ start, /*string*/ foo)');
  1428. // javadoc comment
  1429. bt('/**\n* foo\n*/', '/**\n * foo\n */');
  1430. bt('{\n/**\n* foo\n*/\n}', '{\n /**\n * foo\n */\n}');
  1431. // starless block comment
  1432. bt('/**\nfoo\n*/');
  1433. bt('/**\nfoo\n**/');
  1434. bt('/**\nfoo\nbar\n**/');
  1435. bt('/**\nfoo\n\nbar\n**/');
  1436. bt('/**\nfoo\n bar\n**/');
  1437. bt('{\n/**\nfoo\n*/\n}', '{\n /**\n foo\n */\n}');
  1438. bt('{\n/**\nfoo\n**/\n}', '{\n /**\n foo\n **/\n}');
  1439. bt('{\n/**\nfoo\nbar\n**/\n}', '{\n /**\n foo\n bar\n **/\n}');
  1440. bt('{\n/**\nfoo\n\nbar\n**/\n}', '{\n /**\n foo\n\n bar\n **/\n}');
  1441. bt('{\n/**\nfoo\n bar\n**/\n}', '{\n /**\n foo\n bar\n **/\n}');
  1442. bt('{\n /**\n foo\nbar\n **/\n}');
  1443. bt('var a,b,c=1,d,e,f=2;', 'var a, b, c = 1,\n d, e, f = 2;');
  1444. bt('var a,b,c=[],d,e,f=2;', 'var a, b, c = [],\n d, e, f = 2;');
  1445. bt('function() {\n var a, b, c, d, e = [],\n f;\n}');
  1446. bt('do/regexp/;\nwhile(1);', 'do /regexp/;\nwhile (1);');
  1447. bt('var a = a,\na;\nb = {\nb\n}', 'var a = a,\n a;\nb = {\n b\n}');
  1448. bt('var a = a,\n /* c */\n b;');
  1449. bt('var a = a,\n // c\n b;');
  1450. // weird element referencing
  1451. bt('foo.("bar");');
  1452. bt('if (a) a()\nelse b()\nnewline()');
  1453. bt('if (a) a()\nnewline()');
  1454. bt('a=typeof(x)', 'a = typeof(x)');
  1455. bt('var a = function() {\n return null;\n },\n b = false;');
  1456. bt('var a = function() {\n func1()\n}');
  1457. bt('var a = function() {\n func1()\n}\nvar b = function() {\n func2()\n}');
  1458. // code with and without semicolons
  1459. bt(
  1460. 'var whatever = require("whatever");\nfunction() {\n a = 6;\n}',
  1461. 'var whatever = require("whatever");\n\nfunction() {\n a = 6;\n}');
  1462. bt('var whatever = require("whatever")\nfunction() {\n a = 6\n}', 'var whatever = require("whatever")\n\nfunction() {\n a = 6\n}');
  1463. bt('{"x":[{"a":1,"b":3},\n7,8,8,8,8,{"b":99},{"a":11}]}', '{\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}');
  1464. bt('{"x":[{"a":1,"b":3},7,8,8,8,8,{"b":99},{"a":11}]}', '{\n "x": [{\n "a": 1,\n "b": 3\n }, 7, 8, 8, 8, 8, {\n "b": 99\n }, {\n "a": 11\n }]\n}');
  1465. bt('{"1":{"1a":"1b"},"2"}', '{\n "1": {\n "1a": "1b"\n },\n "2"\n}');
  1466. bt('{a:{a:b},c}', '{\n a: {\n a: b\n },\n c\n}');
  1467. bt('{[y[a]];keep_indent;}', '{\n [y[a]];\n keep_indent;\n}');
  1468. bt('if (x) {y} else { if (x) {y}}', 'if (x) {\n y\n} else {\n if (x) {\n y\n }\n}');
  1469. bt('if (foo) one()\ntwo()\nthree()');
  1470. bt('if (1 + foo() && bar(baz()) / 2) one()\ntwo()\nthree()');
  1471. bt('if (1 + foo() && bar(baz()) / 2) one();\ntwo();\nthree();');
  1472. bt('var a=1,b={bang:2},c=3;', 'var a = 1,\n b = {\n bang: 2\n },\n c = 3;');
  1473. bt('var a={bing:1},b=2,c=3;', 'var a = {\n bing: 1\n },\n b = 2,\n c = 3;');
  1474. opts.indent_size = 1;
  1475. opts.indent_char = ' ';
  1476. bt('{ one_char() }', "{\n one_char()\n}");
  1477. bt('var a,b=1,c=2', 'var a, b = 1,\n c = 2');
  1478. opts.indent_size = 4;
  1479. opts.indent_char = ' ';
  1480. bt('{ one_char() }', "{\n one_char()\n}");
  1481. opts.indent_size = 1;
  1482. opts.indent_char = "\t";
  1483. bt('{ one_char() }', "{\n\tone_char()\n}");
  1484. bt('x = a ? b : c; x;', 'x = a ? b : c;\nx;');
  1485. //set to something else than it should change to, but with tabs on, should override
  1486. opts.indent_size = 5;
  1487. opts.indent_char = ' ';
  1488. opts.indent_with_tabs = true;
  1489. bt('{ one_char() }', "{\n\tone_char()\n}");
  1490. bt('x = a ? b : c; x;', 'x = a ? b : c;\nx;');
  1491. opts.indent_size = 4;
  1492. opts.indent_char = ' ';
  1493. opts.indent_with_tabs = false;
  1494. opts.preserve_newlines = false;
  1495. bt('var\na=dont_preserve_newlines;', 'var a = dont_preserve_newlines;');
  1496. // make sure the blank line between function definitions stays
  1497. // even when preserve_newlines = false
  1498. bt('function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}');
  1499. bt('function foo() {\n return 1;\n}\nfunction foo() {\n return 1;\n}',
  1500. 'function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}'
  1501. );
  1502. bt('function foo() {\n return 1;\n}\n\n\nfunction foo() {\n return 1;\n}',
  1503. 'function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}'
  1504. );
  1505. opts.preserve_newlines = true;
  1506. bt('var\na=do_preserve_newlines;', 'var\n a = do_preserve_newlines;');
  1507. bt('// a\n// b\n\n// c\n// d');
  1508. bt('if (foo) // comment\n{\n bar();\n}');
  1509. opts.keep_array_indentation = false;
  1510. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f']",
  1511. "a = ['a', 'b', 'c',\n 'd', 'e', 'f'\n]");
  1512. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']",
  1513. "a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i'\n]");
  1514. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']",
  1515. "a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i'\n]");
  1516. bt('var x = [{}\n]', 'var x = [{}]');
  1517. bt('var x = [{foo:bar}\n]', 'var x = [{\n foo: bar\n}]');
  1518. bt("a = ['something',\n 'completely',\n 'different'];\nif (x);",
  1519. "a = ['something',\n 'completely',\n 'different'\n];\nif (x);");
  1520. bt("a = ['a','b','c']", "a = ['a', 'b', 'c']");
  1521. bt("a = ['a', 'b','c']", "a = ['a', 'b', 'c']");
  1522. bt("x = [{'a':0}]",
  1523. "x = [{\n 'a': 0\n}]");
  1524. bt('{a([[a1]], {b;});}',
  1525. '{\n a([\n [a1]\n ], {\n b;\n });\n}');
  1526. bt("a();\n [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();",
  1527. "a();\n[\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n].toString();");
  1528. bt("a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();",
  1529. "a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n].toString();");
  1530. bt("function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}",
  1531. "function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}");
  1532. bt('function foo() {\n return [\n "one",\n "two"\n ];\n}');
  1533. // 4 spaces per indent input, processed with 4-spaces per indent
  1534. bt( "function foo() {\n" +
  1535. " return [\n" +
  1536. " {\n" +
  1537. " one: 'x',\n" +
  1538. " two: [\n" +
  1539. " {\n" +
  1540. " id: 'a',\n" +
  1541. " name: 'apple'\n" +
  1542. " }, {\n" +
  1543. " id: 'b',\n" +
  1544. " name: 'banana'\n" +
  1545. " }\n" +
  1546. " ]\n" +
  1547. " }\n" +
  1548. " ];\n" +
  1549. "}",
  1550. "function foo() {\n" +
  1551. " return [{\n" +
  1552. " one: 'x',\n" +
  1553. " two: [{\n" +
  1554. " id: 'a',\n" +
  1555. " name: 'apple'\n" +
  1556. " }, {\n" +
  1557. " id: 'b',\n" +
  1558. " name: 'banana'\n" +
  1559. " }]\n" +
  1560. " }];\n" +
  1561. "}");
  1562. // 3 spaces per indent input, processed with 4-spaces per indent
  1563. bt( "function foo() {\n" +
  1564. " return [\n" +
  1565. " {\n" +
  1566. " one: 'x',\n" +
  1567. " two: [\n" +
  1568. " {\n" +
  1569. " id: 'a',\n" +
  1570. " name: 'apple'\n" +
  1571. " }, {\n" +
  1572. " id: 'b',\n" +
  1573. " name: 'banana'\n" +
  1574. " }\n" +
  1575. " ]\n" +
  1576. " }\n" +
  1577. " ];\n" +
  1578. "}",
  1579. "function foo() {\n" +
  1580. " return [{\n" +
  1581. " one: 'x',\n" +
  1582. " two: [{\n" +
  1583. " id: 'a',\n" +
  1584. " name: 'apple'\n" +
  1585. " }, {\n" +
  1586. " id: 'b',\n" +
  1587. " name: 'banana'\n" +
  1588. " }]\n" +
  1589. " }];\n" +
  1590. "}");
  1591. opts.keep_array_indentation = true;
  1592. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f']");
  1593. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']");
  1594. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']");
  1595. bt('var x = [{}\n]', 'var x = [{}\n]');
  1596. bt('var x = [{foo:bar}\n]', 'var x = [{\n foo: bar\n }\n]');
  1597. bt("a = ['something',\n 'completely',\n 'different'];\nif (x);");
  1598. bt("a = ['a','b','c']", "a = ['a', 'b', 'c']");
  1599. bt("a = ['a', 'b','c']", "a = ['a', 'b', 'c']");
  1600. bt("x = [{'a':0}]",
  1601. "x = [{\n 'a': 0\n}]");
  1602. bt('{a([[a1]], {b;});}',
  1603. '{\n a([[a1]], {\n b;\n });\n}');
  1604. bt("a();\n [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();",
  1605. "a();\n [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();");
  1606. bt("a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();",
  1607. "a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();");
  1608. bt("function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}",
  1609. "function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}");
  1610. bt('function foo() {\n return [\n "one",\n "two"\n ];\n}');
  1611. // 4 spaces per indent input, processed with 4-spaces per indent
  1612. bt( "function foo() {\n" +
  1613. " return [\n" +
  1614. " {\n" +
  1615. " one: 'x',\n" +
  1616. " two: [\n" +
  1617. " {\n" +
  1618. " id: 'a',\n" +
  1619. " name: 'apple'\n" +
  1620. " }, {\n" +
  1621. " id: 'b',\n" +
  1622. " name: 'banana'\n" +
  1623. " }\n" +
  1624. " ]\n" +
  1625. " }\n" +
  1626. " ];\n" +
  1627. "}");
  1628. // 3 spaces per indent input, processed with 4-spaces per indent
  1629. // Should be unchanged, but is not - #445
  1630. // bt( "function foo() {\n" +
  1631. // " return [\n" +
  1632. // " {\n" +
  1633. // " one: 'x',\n" +
  1634. // " two: [\n" +
  1635. // " {\n" +
  1636. // " id: 'a',\n" +
  1637. // " name: 'apple'\n" +
  1638. // " }, {\n" +
  1639. // " id: 'b',\n" +
  1640. // " name: 'banana'\n" +
  1641. // " }\n" +
  1642. // " ]\n" +
  1643. // " }\n" +
  1644. // " ];\n" +
  1645. // "}");
  1646. opts.keep_array_indentation = false;
  1647. bt('a = //comment\n /regex/;');
  1648. bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a) {\n b;\n} else {\n c;\n}');
  1649. // tests for brace positioning
  1650. beautify_brace_tests('expand');
  1651. beautify_brace_tests('collapse');
  1652. beautify_brace_tests('end-expand');
  1653. beautify_brace_tests('none');
  1654. bt('// func-comment\n\nfunction foo() {}\n\n// end-func-comment');
  1655. test_fragment('roo = {\n /*\n ****\n FOO\n ****\n */\n BAR: 0\n};');
  1656. bt('"foo""bar""baz"', '"foo"\n"bar"\n"baz"');
  1657. bt("'foo''bar''baz'", "'foo'\n'bar'\n'baz'");
  1658. test_fragment("if (zz) {\n // ....\n}\n(function");
  1659. bt("{\n get foo() {}\n}");
  1660. bt("{\n var a = get\n foo();\n}");
  1661. bt("{\n set foo() {}\n}");
  1662. bt("{\n var a = set\n foo();\n}");
  1663. bt("var x = {\n get function()\n}");
  1664. bt("var x = {\n set function()\n}");
  1665. // According to my current research get/set have no special meaning outside of an object literal
  1666. bt("var x = set\n\na() {}", "var x = set\n\na() {}");
  1667. bt("var x = set\n\nfunction() {}", "var x = set\n\nfunction() {}");
  1668. bt('<!-- foo\nbar();\n-->');
  1669. bt('<!-- dont crash'); // -->
  1670. bt('for () /abc/.test()');
  1671. bt('if (k) /aaa/m.test(v) && l();');
  1672. bt('switch (true) {\n case /swf/i.test(foo):\n bar();\n}');
  1673. bt('createdAt = {\n type: Date,\n default: Date.now\n}');
  1674. bt('switch (createdAt) {\n case a:\n Date,\n default:\n Date.now\n}');
  1675. opts.space_before_conditional = false;
  1676. bt('if(a) b()');
  1677. opts.space_before_conditional = true;
  1678. opts.preserve_newlines = true;
  1679. bt('var a = 42; // foo\n\nvar b;');
  1680. bt('var a = 42; // foo\n\n\nvar b;');
  1681. bt("var a = 'foo' +\n 'bar';");
  1682. bt("var a = \"foo\" +\n \"bar\";");
  1683. bt('this.oa = new OAuth(\n' +
  1684. ' _requestToken,\n' +
  1685. ' _accessToken,\n' +
  1686. ' consumer_key\n' +
  1687. ');');
  1688. opts.unescape_strings = false;
  1689. test_fragment('"\\x22\\x27", \'\\x22\\x27\', "\\x5c", \'\\x5c\', "\\xff and \\xzz", "unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"');
  1690. opts.unescape_strings = true;
  1691. test_fragment('"\\x20\\x40\\x4a"', '" @J"');
  1692. test_fragment('"\\xff\\x40\\x4a"');
  1693. test_fragment('"\\u0072\\u016B\\u0137\\u012B\\u0074\\u0069\\u0073"', '"rūķītis"');
  1694. test_fragment('"Google Chrome est\\u00E1 actualizado."', '"Google Chrome está actualizado."');
  1695. /*
  1696. bt('"\\x22\\x27",\'\\x22\\x27\',"\\x5c",\'\\x5c\',"\\xff and \\xzz","unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"',
  1697. '"\\"\'", \'"\\\'\', "\\\\", \'\\\\\', "\\xff and \\xzz", "unicode \\u0000 \\" \' \\\\ \\uffff \\uzzzz"');
  1698. */
  1699. opts.unescape_strings = false;
  1700. bt('return function();');
  1701. bt('var a = function();');
  1702. bt('var a = 5 + function();');
  1703. bt('3.*7;', '3. * 7;');
  1704. bt('a = 1.e-64 * 0.5e+4 / 6e-23;');
  1705. bt('import foo.*;', 'import foo.*;'); // actionscript's import
  1706. test_fragment('function f(a: a, b: b)'); // actionscript
  1707. bt('{\n foo // something\n ,\n bar // something\n baz\n}');
  1708. bt('function a(a) {} function b(b) {} function c(c) {}', 'function a(a) {}\n\nfunction b(b) {}\n\nfunction c(c) {}');
  1709. bt('foo(a, function() {})');
  1710. bt('foo(a, /regex/)');
  1711. bt('/* foo */\n"x"');
  1712. opts.break_chained_methods = false;
  1713. opts.preserve_newlines = false;
  1714. bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo.bar().baz().cucumber(fat)');
  1715. bt('foo\n.bar()\n.baz().cucumber(fat); foo.bar().baz().cucumber(fat)', 'foo.bar().baz().cucumber(fat);\nfoo.bar().baz().cucumber(fat)');
  1716. bt('foo\n.bar()\n.baz().cucumber(fat)\n foo.bar().baz().cucumber(fat)', 'foo.bar().baz().cucumber(fat)\nfoo.bar().baz().cucumber(fat)');
  1717. bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this.something = foo.bar().baz().cucumber(fat)');
  1718. bt('this.something.xxx = foo.moo.bar()');
  1719. bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this.something.xxx = foo.moo.bar()');
  1720. opts.break_chained_methods = false;
  1721. opts.preserve_newlines = true;
  1722. bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo\n .bar()\n .baz().cucumber(fat)');
  1723. bt('foo\n.bar()\n.baz().cucumber(fat); foo.bar().baz().cucumber(fat)', 'foo\n .bar()\n .baz().cucumber(fat);\nfoo.bar().baz().cucumber(fat)');
  1724. bt('foo\n.bar()\n.baz().cucumber(fat)\n foo.bar().baz().cucumber(fat)', 'foo\n .bar()\n .baz().cucumber(fat)\nfoo.bar().baz().cucumber(fat)');
  1725. bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this\n .something = foo.bar()\n .baz().cucumber(fat)');
  1726. bt('this.something.xxx = foo.moo.bar()');
  1727. bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this\n .something\n .xxx = foo.moo\n .bar()');
  1728. opts.break_chained_methods = true;
  1729. opts.preserve_newlines = false;
  1730. bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo.bar()\n .baz()\n .cucumber(fat)');
  1731. bt('foo\n.bar()\n.baz().cucumber(fat); foo.bar().baz().cucumber(fat)', 'foo.bar()\n .baz()\n .cucumber(fat);\nfoo.bar()\n .baz()\n .cucumber(fat)');
  1732. bt('foo\n.bar()\n.baz().cucumber(fat)\n foo.bar().baz().cucumber(fat)', 'foo.bar()\n .baz()\n .cucumber(fat)\nfoo.bar()\n .baz()\n .cucumber(fat)');
  1733. bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this.something = foo.bar()\n .baz()\n .cucumber(fat)');
  1734. bt('this.something.xxx = foo.moo.bar()');
  1735. bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this.something.xxx = foo.moo.bar()');
  1736. opts.break_chained_methods = true;
  1737. opts.preserve_newlines = true;
  1738. bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo\n .bar()\n .baz()\n .cucumber(fat)');
  1739. bt('foo\n.bar()\n.baz().cucumber(fat); foo.bar().baz().cucumber(fat)', 'foo\n .bar()\n .baz()\n .cucumber(fat);\nfoo.bar()\n .baz()\n .cucumber(fat)');
  1740. bt('foo\n.bar()\n.baz().cucumber(fat)\n foo.bar().baz().cucumber(fat)', 'foo\n .bar()\n .baz()\n .cucumber(fat)\nfoo.bar()\n .baz()\n .cucumber(fat)');
  1741. bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this\n .something = foo.bar()\n .baz()\n .cucumber(fat)');
  1742. bt('this.something.xxx = foo.moo.bar()');
  1743. bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this\n .something\n .xxx = foo.moo\n .bar()');
  1744. opts.break_chained_methods = false;
  1745. // Line wrap test intputs
  1746. //.............---------1---------2---------3---------4---------5---------6---------7
  1747. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1748. wrap_input_1=('foo.bar().baz().cucumber((fat && "sassy") || (leans\n&& mean));\n' +
  1749. 'Test_very_long_variable_name_this_should_never_wrap\n.but_this_can\n' +
  1750. 'if (wraps_can_occur && inside_an_if_block) that_is_\n.okay();\n' +
  1751. 'object_literal = {\n' +
  1752. ' propertx: first_token + 12345678.99999E-6,\n' +
  1753. ' property: first_token_should_never_wrap + but_this_can,\n' +
  1754. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  1755. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  1756. '}');
  1757. //.............---------1---------2---------3---------4---------5---------6---------7
  1758. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1759. wrap_input_2=('{\n' +
  1760. ' foo.bar().baz().cucumber((fat && "sassy") || (leans\n&& mean));\n' +
  1761. ' Test_very_long_variable_name_this_should_never_wrap\n.but_this_can\n' +
  1762. ' if (wraps_can_occur && inside_an_if_block) that_is_\n.okay();\n' +
  1763. ' object_literal = {\n' +
  1764. ' propertx: first_token + 12345678.99999E-6,\n' +
  1765. ' property: first_token_should_never_wrap + but_this_can,\n' +
  1766. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  1767. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  1768. ' }' +
  1769. '}');
  1770. opts.preserve_newlines = false;
  1771. opts.wrap_line_length = 0;
  1772. //.............---------1---------2---------3---------4---------5---------6---------7
  1773. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1774. test_fragment(wrap_input_1,
  1775. /* expected */
  1776. 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' +
  1777. 'Test_very_long_variable_name_this_should_never_wrap.but_this_can\n' +
  1778. 'if (wraps_can_occur && inside_an_if_block) that_is_.okay();\n' +
  1779. 'object_literal = {\n' +
  1780. ' propertx: first_token + 12345678.99999E-6,\n' +
  1781. ' property: first_token_should_never_wrap + but_this_can,\n' +
  1782. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  1783. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  1784. '}');
  1785. opts.wrap_line_length = 70;
  1786. //.............---------1---------2---------3---------4---------5---------6---------7
  1787. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1788. test_fragment(wrap_input_1,
  1789. /* expected */
  1790. 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' +
  1791. 'Test_very_long_variable_name_this_should_never_wrap.but_this_can\n' +
  1792. 'if (wraps_can_occur && inside_an_if_block) that_is_.okay();\n' +
  1793. 'object_literal = {\n' +
  1794. ' propertx: first_token + 12345678.99999E-6,\n' +
  1795. ' property: first_token_should_never_wrap + but_this_can,\n' +
  1796. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  1797. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  1798. '}');
  1799. opts.wrap_line_length = 40;
  1800. //.............---------1---------2---------3---------4---------5---------6---------7
  1801. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1802. test_fragment(wrap_input_1,
  1803. /* expected */
  1804. 'foo.bar().baz().cucumber((fat &&\n' +
  1805. ' "sassy") || (leans && mean));\n' +
  1806. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  1807. ' .but_this_can\n' +
  1808. 'if (wraps_can_occur &&\n' +
  1809. ' inside_an_if_block) that_is_.okay();\n' +
  1810. 'object_literal = {\n' +
  1811. ' propertx: first_token +\n' +
  1812. ' 12345678.99999E-6,\n' +
  1813. ' property: first_token_should_never_wrap +\n' +
  1814. ' but_this_can,\n' +
  1815. ' propertz: first_token_should_never_wrap +\n' +
  1816. ' !but_this_can,\n' +
  1817. ' proper: "first_token_should_never_wrap" +\n' +
  1818. ' "but_this_can"\n' +
  1819. '}');
  1820. opts.wrap_line_length = 41;
  1821. // NOTE: wrap is only best effort - line continues until next wrap point is found.
  1822. //.............---------1---------2---------3---------4---------5---------6---------7
  1823. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1824. test_fragment(wrap_input_1,
  1825. /* expected */
  1826. 'foo.bar().baz().cucumber((fat && "sassy") ||\n' +
  1827. ' (leans && mean));\n' +
  1828. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  1829. ' .but_this_can\n' +
  1830. 'if (wraps_can_occur &&\n' +
  1831. ' inside_an_if_block) that_is_.okay();\n' +
  1832. 'object_literal = {\n' +
  1833. ' propertx: first_token +\n' +
  1834. ' 12345678.99999E-6,\n' +
  1835. ' property: first_token_should_never_wrap +\n' +
  1836. ' but_this_can,\n' +
  1837. ' propertz: first_token_should_never_wrap +\n' +
  1838. ' !but_this_can,\n' +
  1839. ' proper: "first_token_should_never_wrap" +\n' +
  1840. ' "but_this_can"\n' +
  1841. '}');
  1842. opts.wrap_line_length = 45;
  1843. // NOTE: wrap is only best effort - line continues until next wrap point is found.
  1844. //.............---------1---------2---------3---------4---------5---------6---------7
  1845. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1846. test_fragment(wrap_input_2,
  1847. /* expected */
  1848. '{\n' +
  1849. ' foo.bar().baz().cucumber((fat && "sassy") ||\n' +
  1850. ' (leans && mean));\n' +
  1851. ' Test_very_long_variable_name_this_should_never_wrap\n' +
  1852. ' .but_this_can\n' +
  1853. ' if (wraps_can_occur &&\n' +
  1854. ' inside_an_if_block) that_is_.okay();\n' +
  1855. ' object_literal = {\n' +
  1856. ' propertx: first_token +\n' +
  1857. ' 12345678.99999E-6,\n' +
  1858. ' property: first_token_should_never_wrap +\n' +
  1859. ' but_this_can,\n' +
  1860. ' propertz: first_token_should_never_wrap +\n' +
  1861. ' !but_this_can,\n' +
  1862. ' proper: "first_token_should_never_wrap" +\n' +
  1863. ' "but_this_can"\n' +
  1864. ' }\n'+
  1865. '}');
  1866. opts.preserve_newlines = true;
  1867. opts.wrap_line_length = 0;
  1868. //.............---------1---------2---------3---------4---------5---------6---------7
  1869. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1870. test_fragment(wrap_input_1,
  1871. /* expected */
  1872. 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' +
  1873. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  1874. ' .but_this_can\n' +
  1875. 'if (wraps_can_occur && inside_an_if_block) that_is_\n' +
  1876. ' .okay();\n' +
  1877. 'object_literal = {\n' +
  1878. ' propertx: first_token + 12345678.99999E-6,\n' +
  1879. ' property: first_token_should_never_wrap + but_this_can,\n' +
  1880. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  1881. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  1882. '}');
  1883. opts.wrap_line_length = 70;
  1884. //.............---------1---------2---------3---------4---------5---------6---------7
  1885. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1886. test_fragment(wrap_input_1,
  1887. /* expected */
  1888. 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' +
  1889. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  1890. ' .but_this_can\n' +
  1891. 'if (wraps_can_occur && inside_an_if_block) that_is_\n' +
  1892. ' .okay();\n' +
  1893. 'object_literal = {\n' +
  1894. ' propertx: first_token + 12345678.99999E-6,\n' +
  1895. ' property: first_token_should_never_wrap + but_this_can,\n' +
  1896. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  1897. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  1898. '}');
  1899. opts.wrap_line_length = 40;
  1900. //.............---------1---------2---------3---------4---------5---------6---------7
  1901. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1902. test_fragment(wrap_input_1,
  1903. /* expected */
  1904. 'foo.bar().baz().cucumber((fat &&\n' +
  1905. ' "sassy") || (leans && mean));\n' +
  1906. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  1907. ' .but_this_can\n' +
  1908. 'if (wraps_can_occur &&\n' +
  1909. ' inside_an_if_block) that_is_\n' +
  1910. ' .okay();\n' +
  1911. 'object_literal = {\n' +
  1912. ' propertx: first_token +\n' +
  1913. ' 12345678.99999E-6,\n' +
  1914. ' property: first_token_should_never_wrap +\n' +
  1915. ' but_this_can,\n' +
  1916. ' propertz: first_token_should_never_wrap +\n' +
  1917. ' !but_this_can,\n' +
  1918. ' proper: "first_token_should_never_wrap" +\n' +
  1919. ' "but_this_can"\n' +
  1920. '}');
  1921. opts.wrap_line_length = 41;
  1922. // NOTE: wrap is only best effort - line continues until next wrap point is found.
  1923. //.............---------1---------2---------3---------4---------5---------6---------7
  1924. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1925. test_fragment(wrap_input_1,
  1926. /* expected */
  1927. 'foo.bar().baz().cucumber((fat && "sassy") ||\n' +
  1928. ' (leans && mean));\n' +
  1929. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  1930. ' .but_this_can\n' +
  1931. 'if (wraps_can_occur &&\n' +
  1932. ' inside_an_if_block) that_is_\n' +
  1933. ' .okay();\n' +
  1934. 'object_literal = {\n' +
  1935. ' propertx: first_token +\n' +
  1936. ' 12345678.99999E-6,\n' +
  1937. ' property: first_token_should_never_wrap +\n' +
  1938. ' but_this_can,\n' +
  1939. ' propertz: first_token_should_never_wrap +\n' +
  1940. ' !but_this_can,\n' +
  1941. ' proper: "first_token_should_never_wrap" +\n' +
  1942. ' "but_this_can"\n' +
  1943. '}');
  1944. opts.wrap_line_length = 45;
  1945. // NOTE: wrap is only best effort - line continues until next wrap point is found.
  1946. //.............---------1---------2---------3---------4---------5---------6---------7
  1947. //.............1234567890123456789012345678901234567890123456789012345678901234567890
  1948. test_fragment(wrap_input_2,
  1949. /* expected */
  1950. '{\n' +
  1951. ' foo.bar().baz().cucumber((fat && "sassy") ||\n' +
  1952. ' (leans && mean));\n' +
  1953. ' Test_very_long_variable_name_this_should_never_wrap\n' +
  1954. ' .but_this_can\n' +
  1955. ' if (wraps_can_occur &&\n' +
  1956. ' inside_an_if_block) that_is_\n' +
  1957. ' .okay();\n' +
  1958. ' object_literal = {\n' +
  1959. ' propertx: first_token +\n' +
  1960. ' 12345678.99999E-6,\n' +
  1961. ' property: first_token_should_never_wrap +\n' +
  1962. ' but_this_can,\n' +
  1963. ' propertz: first_token_should_never_wrap +\n' +
  1964. ' !but_this_can,\n' +
  1965. ' proper: "first_token_should_never_wrap" +\n' +
  1966. ' "but_this_can"\n' +
  1967. ' }\n'+
  1968. '}');
  1969. opts.wrap_line_length = 0;
  1970. opts.preserve_newlines = false;
  1971. bt('if (foo) // comment\n bar();');
  1972. bt('if (foo) // comment\n (bar());');
  1973. bt('if (foo) // comment\n (bar());');
  1974. bt('if (foo) // comment\n /asdf/;');
  1975. bt('this.oa = new OAuth(\n' +
  1976. ' _requestToken,\n' +
  1977. ' _accessToken,\n' +
  1978. ' consumer_key\n' +
  1979. ');',
  1980. 'this.oa = new OAuth(_requestToken, _accessToken, consumer_key);');
  1981. bt('foo = {\n x: y, // #44\n w: z // #44\n}');
  1982. bt('switch (x) {\n case "a":\n // comment on newline\n break;\n case "b": // comment on same line\n break;\n}');
  1983. bt('this.type =\n this.options =\n // comment\n this.enabled null;',
  1984. 'this.type = this.options =\n // comment\n this.enabled null;');
  1985. bt('someObj\n .someFunc1()\n // This comment should not break the indent\n .someFunc2();',
  1986. 'someObj.someFunc1()\n // This comment should not break the indent\n .someFunc2();');
  1987. bt('if (true ||\n!true) return;', 'if (true || !true) return;');
  1988. // these aren't ready yet.
  1989. //bt('if (foo) // comment\n bar() /*i*/ + baz() /*j\n*/ + asdf();');
  1990. bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\na();',
  1991. 'if (foo)\n if (bar)\n if (baz) whee();\na();');
  1992. bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\nelse\na();',
  1993. 'if (foo)\n if (bar)\n if (baz) whee();\n else a();');
  1994. bt('if (foo)\nbar();\nelse\ncar();',
  1995. 'if (foo) bar();\nelse car();');
  1996. bt('if (foo) if (bar) if (baz);\na();',
  1997. 'if (foo)\n if (bar)\n if (baz);\na();');
  1998. bt('if (foo) if (bar) if (baz) whee();\na();',
  1999. 'if (foo)\n if (bar)\n if (baz) whee();\na();');
  2000. bt('if (foo) a()\nif (bar) if (baz) whee();\na();',
  2001. 'if (foo) a()\nif (bar)\n if (baz) whee();\na();');
  2002. bt('if (foo);\nif (bar) if (baz) whee();\na();',
  2003. 'if (foo);\nif (bar)\n if (baz) whee();\na();');
  2004. bt('if (options)\n' +
  2005. ' for (var p in options)\n' +
  2006. ' this[p] = options[p];',
  2007. 'if (options)\n'+
  2008. ' for (var p in options) this[p] = options[p];');
  2009. bt('if (options) for (var p in options) this[p] = options[p];',
  2010. 'if (options)\n for (var p in options) this[p] = options[p];');
  2011. bt('if (options) do q(); while (b());',
  2012. 'if (options)\n do q(); while (b());');
  2013. bt('if (options) while (b()) q();',
  2014. 'if (options)\n while (b()) q();');
  2015. bt('if (options) do while (b()) q(); while (a());',
  2016. 'if (options)\n do\n while (b()) q(); while (a());');
  2017. bt('function f(a, b, c,\nd, e) {}',
  2018. 'function f(a, b, c, d, e) {}');
  2019. bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
  2020. 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}');
  2021. bt('function f(a,b) {if(a) b()}\n\n\n\nfunction g(a,b) {if(!a) b()}',
  2022. 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}');
  2023. // This is not valid syntax, but still want to behave reasonably and not side-effect
  2024. bt('(if(a) b())(if(a) b())',
  2025. '(\n if (a) b())(\n if (a) b())');
  2026. bt('(if(a) b())\n\n\n(if(a) b())',
  2027. '(\n if (a) b())\n(\n if (a) b())');
  2028. bt("if\n(a)\nb();", "if (a) b();");
  2029. bt('var a =\nfoo', 'var a = foo');
  2030. bt('var a = {\n"a":1,\n"b":2}', "var a = {\n \"a\": 1,\n \"b\": 2\n}");
  2031. bt("var a = {\n'a':1,\n'b':2}", "var a = {\n 'a': 1,\n 'b': 2\n}");
  2032. bt('var a = /*i*/ "b";');
  2033. bt('var a = /*i*/\n"b";', 'var a = /*i*/ "b";');
  2034. bt('var a = /*i*/\nb;', 'var a = /*i*/ b;');
  2035. bt('{\n\n\n"x"\n}', '{\n "x"\n}');
  2036. bt('if(a &&\nb\n||\nc\n||d\n&&\ne) e = f', 'if (a && b || c || d && e) e = f');
  2037. bt('if(a &&\n(b\n||\nc\n||d)\n&&\ne) e = f', 'if (a && (b || c || d) && e) e = f');
  2038. test_fragment('\n\n"x"', '"x"');
  2039. bt('a = 1;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nb = 2;',
  2040. 'a = 1;\nb = 2;');
  2041. opts.preserve_newlines = true;
  2042. bt('if (foo) // comment\n bar();');
  2043. bt('if (foo) // comment\n (bar());');
  2044. bt('if (foo) // comment\n (bar());');
  2045. bt('if (foo) // comment\n /asdf/;');
  2046. bt('foo = {\n x: y, // #44\n w: z // #44\n}');
  2047. bt('switch (x) {\n case "a":\n // comment on newline\n break;\n case "b": // comment on same line\n break;\n}');
  2048. bt('this.type =\n this.options =\n // comment\n this.enabled null;');
  2049. bt('someObj\n .someFunc1()\n // This comment should not break the indent\n .someFunc2();');
  2050. bt('if (true ||\n!true) return;', 'if (true ||\n !true) return;');
  2051. // these aren't ready yet.
  2052. // bt('if (foo) // comment\n bar() /*i*/ + baz() /*j\n*/ + asdf();');
  2053. bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\na();',
  2054. 'if (foo)\n if (bar)\n if (baz)\n whee();\na();');
  2055. bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\nelse\na();',
  2056. 'if (foo)\n if (bar)\n if (baz)\n whee();\n else\n a();');
  2057. bt('if (foo) bar();\nelse\ncar();',
  2058. 'if (foo) bar();\nelse\n car();');
  2059. bt('if (foo) if (bar) if (baz);\na();',
  2060. 'if (foo)\n if (bar)\n if (baz);\na();');
  2061. bt('if (foo) if (bar) if (baz) whee();\na();',
  2062. 'if (foo)\n if (bar)\n if (baz) whee();\na();');
  2063. bt('if (foo) a()\nif (bar) if (baz) whee();\na();',
  2064. 'if (foo) a()\nif (bar)\n if (baz) whee();\na();');
  2065. bt('if (foo);\nif (bar) if (baz) whee();\na();',
  2066. 'if (foo);\nif (bar)\n if (baz) whee();\na();');
  2067. bt('if (options)\n' +
  2068. ' for (var p in options)\n' +
  2069. ' this[p] = options[p];');
  2070. bt('if (options) for (var p in options) this[p] = options[p];',
  2071. 'if (options)\n for (var p in options) this[p] = options[p];');
  2072. bt('if (options) do q(); while (b());',
  2073. 'if (options)\n do q(); while (b());');
  2074. bt('if (options) do; while (b());',
  2075. 'if (options)\n do; while (b());');
  2076. bt('if (options) while (b()) q();',
  2077. 'if (options)\n while (b()) q();');
  2078. bt('if (options) do while (b()) q(); while (a());',
  2079. 'if (options)\n do\n while (b()) q(); while (a());');
  2080. bt('function f(a, b, c,\nd, e) {}',
  2081. 'function f(a, b, c,\n d, e) {}');
  2082. bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
  2083. 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}');
  2084. bt('function f(a,b) {if(a) b()}\n\n\n\nfunction g(a,b) {if(!a) b()}',
  2085. 'function f(a, b) {\n if (a) b()\n}\n\n\n\nfunction g(a, b) {\n if (!a) b()\n}');
  2086. // This is not valid syntax, but still want to behave reasonably and not side-effect
  2087. bt('(if(a) b())(if(a) b())',
  2088. '(\n if (a) b())(\n if (a) b())');
  2089. bt('(if(a) b())\n\n\n(if(a) b())',
  2090. '(\n if (a) b())\n\n\n(\n if (a) b())');
  2091. // space between functions
  2092. bt('/*\n * foo\n */\nfunction foo() {}');
  2093. bt('// a nice function\nfunction foo() {}');
  2094. bt('function foo() {}\nfunction foo() {}',
  2095. 'function foo() {}\n\nfunction foo() {}'
  2096. );
  2097. bt('[\n function() {}\n]');
  2098. bt("if\n(a)\nb();", "if (a)\n b();");
  2099. bt('var a =\nfoo', 'var a =\n foo');
  2100. bt('var a = {\n"a":1,\n"b":2}', "var a = {\n \"a\": 1,\n \"b\": 2\n}");
  2101. bt("var a = {\n'a':1,\n'b':2}", "var a = {\n 'a': 1,\n 'b': 2\n}");
  2102. bt('var a = /*i*/ "b";');
  2103. bt('var a = /*i*/\n"b";', 'var a = /*i*/\n "b";');
  2104. bt('var a = /*i*/\nb;', 'var a = /*i*/\n b;');
  2105. bt('{\n\n\n"x"\n}', '{\n\n\n "x"\n}');
  2106. bt('if(a &&\nb\n||\nc\n||d\n&&\ne) e = f', 'if (a &&\n b ||\n c || d &&\n e) e = f');
  2107. bt('if(a &&\n(b\n||\nc\n||d)\n&&\ne) e = f', 'if (a &&\n (b ||\n c || d) &&\n e) e = f');
  2108. test_fragment('\n\n"x"', '"x"');
  2109. // this beavior differs between js and python, defaults to unlimited in js, 10 in python
  2110. bt('a = 1;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nb = 2;',
  2111. 'a = 1;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nb = 2;');
  2112. opts.max_preserve_newlines = 8;
  2113. bt('a = 1;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nb = 2;',
  2114. 'a = 1;\n\n\n\n\n\n\n\nb = 2;');
  2115. // Test the option to have spaces within parens
  2116. opts.space_in_paren = false;
  2117. bt('if(p) foo(a,b)', 'if (p) foo(a, b)');
  2118. bt('try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }',
  2119. 'try {\n while (true) {\n willThrow()\n }\n} catch (result) switch (result) {\n case 1:\n ++result\n}');
  2120. bt('((e/((a+(b)*c)-d))^2)*5;', '((e / ((a + (b) * c) - d)) ^ 2) * 5;');
  2121. bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
  2122. 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}');
  2123. bt('a=[];',
  2124. 'a = [];');
  2125. bt('a=[b,c,d];',
  2126. 'a = [b, c, d];');
  2127. bt('a= f[b];',
  2128. 'a = f[b];');
  2129. opts.space_in_paren = true;
  2130. bt('if(p) foo(a,b)', 'if ( p ) foo( a, b )');
  2131. bt('try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }',
  2132. 'try {\n while ( true ) {\n willThrow()\n }\n} catch ( result ) switch ( result ) {\n case 1:\n ++result\n}');
  2133. bt('((e/((a+(b)*c)-d))^2)*5;', '( ( e / ( ( a + ( b ) * c ) - d ) ) ^ 2 ) * 5;');
  2134. bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
  2135. 'function f( a, b ) {\n if ( a ) b()\n}\n\nfunction g( a, b ) {\n if ( !a ) b()\n}');
  2136. bt('a=[];',
  2137. 'a = [];');
  2138. bt('a=[b,c,d];',
  2139. 'a = [ b, c, d ];');
  2140. bt('a= f[b];',
  2141. 'a = f[ b ];');
  2142. opts.space_in_empty_paren = true;
  2143. bt('if(p) foo(a,b)', 'if ( p ) foo( a, b )');
  2144. bt('try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }',
  2145. 'try {\n while ( true ) {\n willThrow( )\n }\n} catch ( result ) switch ( result ) {\n case 1:\n ++result\n}');
  2146. bt('((e/((a+(b)*c)-d))^2)*5;', '( ( e / ( ( a + ( b ) * c ) - d ) ) ^ 2 ) * 5;');
  2147. bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
  2148. 'function f( a, b ) {\n if ( a ) b( )\n}\n\nfunction g( a, b ) {\n if ( !a ) b( )\n}');
  2149. bt('a=[];',
  2150. 'a = [ ];');
  2151. bt('a=[b,c,d];',
  2152. 'a = [ b, c, d ];');
  2153. bt('a= f[b];',
  2154. 'a = f[ b ];');
  2155. opts.space_in_empty_paren = false;
  2156. opts.space_in_paren = false;
  2157. // Test template strings
  2158. bt('`This is a ${template} string.`', '`This is a ${template} string.`');
  2159. bt('`This\n is\n a\n ${template}\n string.`', '`This\n is\n a\n ${template}\n string.`');
  2160. bt('a = `This is a continuation\\\nstring.`', 'a = `This is a continuation\\\nstring.`');
  2161. bt('a = "This is a continuation\\\nstring."', 'a = "This is a continuation\\\nstring."');
  2162. Urlencoded.run_tests(sanitytest);
  2163. }
  2164. beautifier_tests();
  2165. }
  2166. if (typeof exports !== "undefined") {
  2167. exports.run_javascript_tests = run_javascript_tests;
  2168. }