python-javascript.mustache 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import re
  4. import unittest
  5. import jsbeautifier
  6. import six
  7. class TestJSBeautifier(unittest.TestCase):
  8. def test_unescape(self):
  9. # Test cases contributed by <chrisjshull on GitHub.com>
  10. test_fragment = self.decodesto
  11. bt = self.bt
  12. bt('"\\\\s"') # == "\\s" in the js source
  13. bt("'\\\\s'") # == '\\s' in the js source
  14. bt("'\\\\\\s'") # == '\\\s' in the js source
  15. bt("'\\s'") # == '\s' in the js source
  16. bt('"•"')
  17. bt('"—"')
  18. bt('"\\x41\\x42\\x43\\x01"', '"\\x41\\x42\\x43\\x01"')
  19. bt('"\\u2022"', '"\\u2022"')
  20. bt('a = /\s+/')
  21. #bt('a = /\\x41/','a = /A/')
  22. bt('"\\u2022";a = /\s+/;"\\x41\\x42\\x43\\x01".match(/\\x41/);','"\\u2022";\na = /\s+/;\n"\\x41\\x42\\x43\\x01".match(/\\x41/);')
  23. bt('"\\x22\\x27",\'\\x22\\x27\',"\\x5c",\'\\x5c\',"\\xff and \\xzz","unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"', '"\\x22\\x27", \'\\x22\\x27\', "\\x5c", \'\\x5c\', "\\xff and \\xzz", "unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"')
  24. self.options.unescape_strings = True
  25. bt('"\\x41\\x42\\x43\\x01"', '"ABC\\x01"')
  26. bt('"\\u2022"', '"\\u2022"')
  27. bt('a = /\s+/')
  28. bt('"\\u2022";a = /\s+/;"\\x41\\x42\\x43\\x01".match(/\\x41/);','"\\u2022";\na = /\s+/;\n"ABC\\x01".match(/\\x41/);')
  29. bt('"\\x22\\x27",\'\\x22\\x27\',"\\x5c",\'\\x5c\',"\\xff and \\xzz","unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"', '"\\"\'", \'"\\\'\', "\\\\", \'\\\\\', "\\xff and \\xzz", "unicode \\u0000 \\" \' \\\\ \\uffff \\uzzzz"')
  30. self.options.unescape_strings = False
  31. def test_beautifier(self):
  32. test_fragment = self.decodesto
  33. bt = self.bt
  34. true = True
  35. false = False
  36. def unicode_char(value):
  37. return six.unichr(value)
  38. {{#default_options}} self.options.{{name}} = {{&value}}
  39. {{/default_options}}
  40. {{#groups}}
  41. {{^matrix}}
  42. # {{&name}}
  43. {{#options}}
  44. self.options.{{name}} = {{&value}}
  45. {{/options}}
  46. {{#tests}}
  47. {{#test_line}}.{{/test_line}}
  48. {{/tests}}
  49. {{/matrix}}
  50. {{#matrix}}
  51. # {{&name}} - ({{#matrix_context_string}}.{{/matrix_context_string}})
  52. {{#options}}
  53. self.options.{{name}} = {{&value}}
  54. {{/options}}
  55. {{#tests}}
  56. {{#test_line}}.{{/test_line}}
  57. {{/tests}}
  58. {{/matrix}}
  59. {{/groups}}
  60. {{=<% %>=}}
  61. bt('{{}/z/}', "{\n {}\n /z/\n}")
  62. <%={{ }}=%>
  63. self.options.indent_size = 1;
  64. self.options.indent_char = ' ';
  65. bt('{ one_char() }', "{\n one_char()\n}")
  66. bt('var a,b=1,c=2', 'var a, b = 1,\n c = 2')
  67. self.options.indent_size = 4;
  68. self.options.indent_char = ' ';
  69. bt('{ one_char() }', "{\n one_char()\n}")
  70. self.options.indent_size = 1;
  71. self.options.indent_char = "\t";
  72. bt('{ one_char() }', "{\n\tone_char()\n}")
  73. bt('x = a ? b : c; x;', 'x = a ? b : c;\nx;')
  74. #set to something else than it should change to, but with tabs on, should override
  75. self.options.indent_size = 5;
  76. self.options.indent_char = ' ';
  77. self.options.indent_with_tabs = True;
  78. bt('{ one_char() }', "{\n\tone_char()\n}")
  79. bt('x = a ? b : c; x;', 'x = a ? b : c;\nx;')
  80. self.options.indent_size = 4;
  81. self.options.indent_char = ' ';
  82. self.options.indent_with_tabs = False;
  83. self.options.preserve_newlines = False;
  84. bt('var\na=dont_preserve_newlines;', 'var a = dont_preserve_newlines;')
  85. # make sure the blank line between function definitions stays
  86. # even when preserve_newlines = False
  87. bt('function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}')
  88. bt('function foo() {\n return 1;\n}\nfunction foo() {\n return 1;\n}',
  89. 'function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}'
  90. )
  91. bt('function foo() {\n return 1;\n}\n\n\nfunction foo() {\n return 1;\n}',
  92. 'function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}'
  93. )
  94. self.options.preserve_newlines = True;
  95. bt('var\na=do_preserve_newlines;', 'var\n a = do_preserve_newlines;')
  96. bt('// a\n// b\n\n// c\n// d')
  97. bt('if (foo) // comment\n{\n bar();\n}')
  98. self.options.keep_array_indentation = False;
  99. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f']",
  100. "a = ['a', 'b', 'c',\n 'd', 'e', 'f'\n]")
  101. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']",
  102. "a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i'\n]")
  103. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']",
  104. "a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i'\n]")
  105. bt('var x = [{}\n]', 'var x = [{}]')
  106. bt('var x = [{foo:bar}\n]', 'var x = [{\n foo: bar\n}]')
  107. bt("a = ['something',\n 'completely',\n 'different'];\nif (x);",
  108. "a = ['something',\n 'completely',\n 'different'\n];\nif (x);")
  109. bt("a = ['a','b','c']", "a = ['a', 'b', 'c']")
  110. bt("a = ['a', 'b','c']", "a = ['a', 'b', 'c']")
  111. bt("x = [{'a':0}]",
  112. "x = [{\n 'a': 0\n}]")
  113. bt('{a([[a1]], {b;});}',
  114. '{\n a([\n [a1]\n ], {\n b;\n });\n}')
  115. bt("a();\n [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();",
  116. "a();\n[\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n].toString();")
  117. bt("a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();",
  118. "a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n].toString();")
  119. bt("function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}",
  120. "function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}")
  121. bt('function foo() {\n return [\n "one",\n "two"\n ];\n}')
  122. # 4 spaces per indent input, processed with 4-spaces per indent
  123. bt( "function foo() {\n" +
  124. " return [\n" +
  125. " {\n" +
  126. " one: 'x',\n" +
  127. " two: [\n" +
  128. " {\n" +
  129. " id: 'a',\n" +
  130. " name: 'apple'\n" +
  131. " }, {\n" +
  132. " id: 'b',\n" +
  133. " name: 'banana'\n" +
  134. " }\n" +
  135. " ]\n" +
  136. " }\n" +
  137. " ];\n" +
  138. "}",
  139. "function foo() {\n" +
  140. " return [{\n" +
  141. " one: 'x',\n" +
  142. " two: [{\n" +
  143. " id: 'a',\n" +
  144. " name: 'apple'\n" +
  145. " }, {\n" +
  146. " id: 'b',\n" +
  147. " name: 'banana'\n" +
  148. " }]\n" +
  149. " }];\n" +
  150. "}")
  151. # 3 spaces per indent input, processed with 4-spaces per indent
  152. bt( "function foo() {\n" +
  153. " return [\n" +
  154. " {\n" +
  155. " one: 'x',\n" +
  156. " two: [\n" +
  157. " {\n" +
  158. " id: 'a',\n" +
  159. " name: 'apple'\n" +
  160. " }, {\n" +
  161. " id: 'b',\n" +
  162. " name: 'banana'\n" +
  163. " }\n" +
  164. " ]\n" +
  165. " }\n" +
  166. " ];\n" +
  167. "}",
  168. "function foo() {\n" +
  169. " return [{\n" +
  170. " one: 'x',\n" +
  171. " two: [{\n" +
  172. " id: 'a',\n" +
  173. " name: 'apple'\n" +
  174. " }, {\n" +
  175. " id: 'b',\n" +
  176. " name: 'banana'\n" +
  177. " }]\n" +
  178. " }];\n" +
  179. "}")
  180. self.options.keep_array_indentation = True;
  181. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f']")
  182. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']")
  183. bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']")
  184. bt('var x = [{}\n]', 'var x = [{}\n]')
  185. bt('var x = [{foo:bar}\n]', 'var x = [{\n foo: bar\n }\n]')
  186. bt("a = ['something',\n 'completely',\n 'different'];\nif (x);")
  187. bt("a = ['a','b','c']", "a = ['a', 'b', 'c']")
  188. bt("a = ['a', 'b','c']", "a = ['a', 'b', 'c']")
  189. bt("x = [{'a':0}]",
  190. "x = [{\n 'a': 0\n}]")
  191. bt('{a([[a1]], {b;});}',
  192. '{\n a([[a1]], {\n b;\n });\n}')
  193. bt("a();\n [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();",
  194. "a();\n [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();")
  195. bt("a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();",
  196. "a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();")
  197. bt("function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}",
  198. "function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}")
  199. bt('function foo() {\n return [\n "one",\n "two"\n ];\n}')
  200. # 4 spaces per indent input, processed with 4-spaces per indent
  201. bt( "function foo() {\n" +
  202. " return [\n" +
  203. " {\n" +
  204. " one: 'x',\n" +
  205. " two: [\n" +
  206. " {\n" +
  207. " id: 'a',\n" +
  208. " name: 'apple'\n" +
  209. " }, {\n" +
  210. " id: 'b',\n" +
  211. " name: 'banana'\n" +
  212. " }\n" +
  213. " ]\n" +
  214. " }\n" +
  215. " ];\n" +
  216. "}")
  217. # 3 spaces per indent input, processed with 4-spaces per indent
  218. # Should be unchanged, but is not - #445
  219. # bt( "function foo() {\n" +
  220. # " return [\n" +
  221. # " {\n" +
  222. # " one: 'x',\n" +
  223. # " two: [\n" +
  224. # " {\n" +
  225. # " id: 'a',\n" +
  226. # " name: 'apple'\n" +
  227. # " }, {\n" +
  228. # " id: 'b',\n" +
  229. # " name: 'banana'\n" +
  230. # " }\n" +
  231. # " ]\n" +
  232. # " }\n" +
  233. # " ];\n" +
  234. # "}")
  235. self.options.keep_array_indentation = False;
  236. bt('a = //comment\n /regex/;')
  237. bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a) {\n b;\n} else {\n c;\n}')
  238. bt('var a = new function();')
  239. test_fragment('new function')
  240. # START tests for brace positioning
  241. # If this is ever supported, update tests for each brace style.
  242. # test_fragment('return\n{', 'return\n{') # can't support this?, but that's an improbable and extreme case anyway.
  243. self.options.brace_style = 'expand';
  244. bt('//case 1\nif (a == 1)\n{}\n//case 2\nelse if (a == 2)\n{}')
  245. bt('if(1){2}else{3}', "if (1)\n{\n 2\n}\nelse\n{\n 3\n}")
  246. bt('try{a();}catch(b){c();}catch(d){}finally{e();}',
  247. "try\n{\n a();\n}\ncatch (b)\n{\n c();\n}\ncatch (d)\n{}\nfinally\n{\n e();\n}")
  248. bt('if(a){b();}else if(c) foo();',
  249. "if (a)\n{\n b();\n}\nelse if (c) foo();")
  250. bt("if (a) {\n// comment\n}else{\n// comment\n}",
  251. "if (a)\n{\n // comment\n}\nelse\n{\n // comment\n}") # if/else statement with empty body
  252. bt('if (x) {y} else { if (x) {y}}',
  253. 'if (x)\n{\n y\n}\nelse\n{\n if (x)\n {\n y\n }\n}')
  254. bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}',
  255. 'if (a)\n{\n b;\n}\nelse\n{\n c;\n}')
  256. test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}',
  257. ' /*\n * xx\n */\n // xx\n if (foo)\n {\n bar();\n }')
  258. bt('if (foo)\n{}\nelse /regex/.test();')
  259. test_fragment('if (foo) {', 'if (foo)\n{')
  260. test_fragment('foo {', 'foo\n{')
  261. test_fragment('return {', 'return {') # return needs the brace.
  262. test_fragment('return /* inline */ {', 'return /* inline */ {')
  263. test_fragment('return;\n{', 'return;\n{')
  264. bt("throw {}")
  265. bt("throw {\n foo;\n}")
  266. bt('var foo = {}')
  267. bt('function x() {\n foo();\n}zzz', 'function x()\n{\n foo();\n}\nzzz')
  268. test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx')
  269. bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}')
  270. bt('var a = new function() {};')
  271. bt('var a = new function a() {};', 'var a = new function a()\n{};')
  272. bt('var a = new function()\n{};', 'var a = new function() {};')
  273. bt('var a = new function a()\n{};')
  274. bt('var a = new function a()\n {},\n b = new function b()\n {};')
  275. bt("foo({\n 'a': 1\n},\n10);",
  276. "foo(\n {\n 'a': 1\n },\n 10);")
  277. bt('(["foo","bar"]).each(function(i) {return i;});',
  278. '(["foo", "bar"]).each(function(i)\n{\n return i;\n});')
  279. bt('(function(i) {return i;})();',
  280. '(function(i)\n{\n return i;\n})();')
  281. bt( "test( /*Argument 1*/ {\n" +
  282. " 'Value1': '1'\n" +
  283. "}, /*Argument 2\n" +
  284. " */ {\n" +
  285. " 'Value2': '2'\n" +
  286. "});",
  287. # expected
  288. "test( /*Argument 1*/\n" +
  289. " {\n" +
  290. " 'Value1': '1'\n" +
  291. " },\n" +
  292. " /*Argument 2\n" +
  293. " */\n" +
  294. " {\n" +
  295. " 'Value2': '2'\n" +
  296. " });")
  297. bt( "test(\n" +
  298. "/*Argument 1*/ {\n" +
  299. " 'Value1': '1'\n" +
  300. "},\n" +
  301. "/*Argument 2\n" +
  302. " */ {\n" +
  303. " 'Value2': '2'\n" +
  304. "});",
  305. # expected
  306. "test(\n" +
  307. " /*Argument 1*/\n" +
  308. " {\n" +
  309. " 'Value1': '1'\n" +
  310. " },\n" +
  311. " /*Argument 2\n" +
  312. " */\n" +
  313. " {\n" +
  314. " 'Value2': '2'\n" +
  315. " });")
  316. bt( "test( /*Argument 1*/\n" +
  317. "{\n" +
  318. " 'Value1': '1'\n" +
  319. "}, /*Argument 2\n" +
  320. " */\n" +
  321. "{\n" +
  322. " 'Value2': '2'\n" +
  323. "});",
  324. # expected
  325. "test( /*Argument 1*/\n" +
  326. " {\n" +
  327. " 'Value1': '1'\n" +
  328. " },\n" +
  329. " /*Argument 2\n" +
  330. " */\n" +
  331. " {\n" +
  332. " 'Value2': '2'\n" +
  333. " });")
  334. self.options.brace_style = 'collapse';
  335. bt('//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}')
  336. bt('if(1){2}else{3}', "if (1) {\n 2\n} else {\n 3\n}")
  337. bt('try{a();}catch(b){c();}catch(d){}finally{e();}',
  338. "try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}")
  339. bt('if(a){b();}else if(c) foo();',
  340. "if (a) {\n b();\n} else if (c) foo();")
  341. bt("if (a) {\n// comment\n}else{\n// comment\n}",
  342. "if (a) {\n // comment\n} else {\n // comment\n}") # if/else statement with empty body
  343. bt('if (x) {y} else { if (x) {y}}',
  344. 'if (x) {\n y\n} else {\n if (x) {\n y\n }\n}')
  345. bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}',
  346. 'if (a) {\n b;\n} else {\n c;\n}')
  347. test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}',
  348. ' /*\n * xx\n */\n // xx\n if (foo) {\n bar();\n }')
  349. bt('if (foo) {} else /regex/.test();')
  350. test_fragment('if (foo) {', 'if (foo) {')
  351. test_fragment('foo {', 'foo {')
  352. test_fragment('return {', 'return {') # return needs the brace.
  353. test_fragment('return /* inline */ {', 'return /* inline */ {')
  354. test_fragment('return;\n{', 'return; {')
  355. bt("throw {}")
  356. bt("throw {\n foo;\n}")
  357. bt('var foo = {}')
  358. bt('function x() {\n foo();\n}zzz', 'function x() {\n foo();\n}\nzzz')
  359. test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx')
  360. bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}')
  361. bt('var a = new function() {};')
  362. bt('var a = new function a() {};')
  363. bt('var a = new function()\n{};', 'var a = new function() {};')
  364. bt('var a = new function a()\n{};', 'var a = new function a() {};')
  365. bt('var a = new function a()\n {},\n b = new function b()\n {};', 'var a = new function a() {},\n b = new function b() {};')
  366. bt("foo({\n 'a': 1\n},\n10);",
  367. "foo({\n 'a': 1\n },\n 10);")
  368. bt('(["foo","bar"]).each(function(i) {return i;});',
  369. '(["foo", "bar"]).each(function(i) {\n return i;\n});')
  370. bt('(function(i) {return i;})();',
  371. '(function(i) {\n return i;\n})();')
  372. bt( "test( /*Argument 1*/ {\n" +
  373. " 'Value1': '1'\n" +
  374. "}, /*Argument 2\n" +
  375. " */ {\n" +
  376. " 'Value2': '2'\n" +
  377. "});",
  378. # expected
  379. "test( /*Argument 1*/ {\n" +
  380. " 'Value1': '1'\n" +
  381. " },\n" +
  382. " /*Argument 2\n" +
  383. " */\n" +
  384. " {\n" +
  385. " 'Value2': '2'\n" +
  386. " });")
  387. bt( "test(\n" +
  388. "/*Argument 1*/ {\n" +
  389. " 'Value1': '1'\n" +
  390. "},\n" +
  391. "/*Argument 2\n" +
  392. " */ {\n" +
  393. " 'Value2': '2'\n" +
  394. "});",
  395. # expected
  396. "test(\n" +
  397. " /*Argument 1*/\n" +
  398. " {\n" +
  399. " 'Value1': '1'\n" +
  400. " },\n" +
  401. " /*Argument 2\n" +
  402. " */\n" +
  403. " {\n" +
  404. " 'Value2': '2'\n" +
  405. " });")
  406. bt( "test( /*Argument 1*/\n" +
  407. "{\n" +
  408. " 'Value1': '1'\n" +
  409. "}, /*Argument 2\n" +
  410. " */\n" +
  411. "{\n" +
  412. " 'Value2': '2'\n" +
  413. "});",
  414. # expected
  415. "test( /*Argument 1*/ {\n" +
  416. " 'Value1': '1'\n" +
  417. " },\n" +
  418. " /*Argument 2\n" +
  419. " */\n" +
  420. " {\n" +
  421. " 'Value2': '2'\n" +
  422. " });")
  423. self.options.brace_style = "end-expand";
  424. bt('//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}')
  425. bt('if(1){2}else{3}', "if (1) {\n 2\n}\nelse {\n 3\n}")
  426. bt('try{a();}catch(b){c();}catch(d){}finally{e();}',
  427. "try {\n a();\n}\ncatch (b) {\n c();\n}\ncatch (d) {}\nfinally {\n e();\n}")
  428. bt('if(a){b();}else if(c) foo();',
  429. "if (a) {\n b();\n}\nelse if (c) foo();")
  430. bt("if (a) {\n// comment\n}else{\n// comment\n}",
  431. "if (a) {\n // comment\n}\nelse {\n // comment\n}") # if/else statement with empty body
  432. bt('if (x) {y} else { if (x) {y}}',
  433. 'if (x) {\n y\n}\nelse {\n if (x) {\n y\n }\n}')
  434. bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}',
  435. 'if (a) {\n b;\n}\nelse {\n c;\n}')
  436. test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}',
  437. ' /*\n * xx\n */\n // xx\n if (foo) {\n bar();\n }')
  438. bt('if (foo) {}\nelse /regex/.test();')
  439. test_fragment('if (foo) {', 'if (foo) {')
  440. test_fragment('foo {', 'foo {')
  441. test_fragment('return {', 'return {') # return needs the brace.
  442. test_fragment('return /* inline */ {', 'return /* inline */ {')
  443. test_fragment('return;\n{', 'return; {')
  444. bt("throw {}")
  445. bt("throw {\n foo;\n}")
  446. bt('var foo = {}')
  447. bt('function x() {\n foo();\n}zzz', 'function x() {\n foo();\n}\nzzz')
  448. test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx')
  449. bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}')
  450. bt('var a = new function() {};')
  451. bt('var a = new function a() {};')
  452. bt('var a = new function()\n{};', 'var a = new function() {};')
  453. bt('var a = new function a()\n{};', 'var a = new function a() {};')
  454. bt('var a = new function a()\n {},\n b = new function b()\n {};', 'var a = new function a() {},\n b = new function b() {};')
  455. bt("foo({\n 'a': 1\n},\n10);",
  456. "foo({\n 'a': 1\n },\n 10);")
  457. bt('(["foo","bar"]).each(function(i) {return i;});',
  458. '(["foo", "bar"]).each(function(i) {\n return i;\n});')
  459. bt('(function(i) {return i;})();',
  460. '(function(i) {\n return i;\n})();')
  461. bt( "test( /*Argument 1*/ {\n" +
  462. " 'Value1': '1'\n" +
  463. "}, /*Argument 2\n" +
  464. " */ {\n" +
  465. " 'Value2': '2'\n" +
  466. "});",
  467. # expected
  468. "test( /*Argument 1*/ {\n" +
  469. " 'Value1': '1'\n" +
  470. " },\n" +
  471. " /*Argument 2\n" +
  472. " */\n" +
  473. " {\n" +
  474. " 'Value2': '2'\n" +
  475. " });")
  476. bt( "test(\n" +
  477. "/*Argument 1*/ {\n" +
  478. " 'Value1': '1'\n" +
  479. "},\n" +
  480. "/*Argument 2\n" +
  481. " */ {\n" +
  482. " 'Value2': '2'\n" +
  483. "});",
  484. # expected
  485. "test(\n" +
  486. " /*Argument 1*/\n" +
  487. " {\n" +
  488. " 'Value1': '1'\n" +
  489. " },\n" +
  490. " /*Argument 2\n" +
  491. " */\n" +
  492. " {\n" +
  493. " 'Value2': '2'\n" +
  494. " });")
  495. bt( "test( /*Argument 1*/\n" +
  496. "{\n" +
  497. " 'Value1': '1'\n" +
  498. "}, /*Argument 2\n" +
  499. " */\n" +
  500. "{\n" +
  501. " 'Value2': '2'\n" +
  502. "});",
  503. # expected
  504. "test( /*Argument 1*/ {\n" +
  505. " 'Value1': '1'\n" +
  506. " },\n" +
  507. " /*Argument 2\n" +
  508. " */\n" +
  509. " {\n" +
  510. " 'Value2': '2'\n" +
  511. " });")
  512. self.options.brace_style = 'none';
  513. bt('//case 1\nif (a == 1)\n{}\n//case 2\nelse if (a == 2)\n{}')
  514. bt('if(1){2}else{3}', "if (1) {\n 2\n} else {\n 3\n}")
  515. bt('try{a();}catch(b){c();}catch(d){}finally{e();}',
  516. "try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}")
  517. bt('if(a){b();}else if(c) foo();',
  518. "if (a) {\n b();\n} else if (c) foo();")
  519. bt("if (a) {\n// comment\n}else{\n// comment\n}",
  520. "if (a) {\n // comment\n} else {\n // comment\n}") # if/else statement with empty body
  521. bt('if (x) {y} else { if (x) {y}}',
  522. 'if (x) {\n y\n} else {\n if (x) {\n y\n }\n}')
  523. bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}',
  524. 'if (a)\n{\n b;\n}\nelse\n{\n c;\n}')
  525. test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}',
  526. ' /*\n * xx\n */\n // xx\n if (foo) {\n bar();\n }')
  527. bt('if (foo)\n{}\nelse /regex/.test();')
  528. test_fragment('if (foo) {')
  529. test_fragment('foo {')
  530. test_fragment('return {') # return needs the brace.
  531. test_fragment('return /* inline */ {')
  532. test_fragment('return;\n{')
  533. bt("throw {}")
  534. bt("throw {\n foo;\n}")
  535. bt('var foo = {}')
  536. bt('function x() {\n foo();\n}zzz', 'function x() {\n foo();\n}\nzzz')
  537. test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx')
  538. bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}')
  539. bt('var a = new function() {};')
  540. bt('var a = new function a() {};')
  541. bt('var a = new function()\n{};', 'var a = new function() {};')
  542. bt('var a = new function a()\n{};')
  543. bt('var a = new function a()\n {},\n b = new function b()\n {};')
  544. bt("foo({\n 'a': 1\n},\n10);",
  545. "foo({\n 'a': 1\n },\n 10);")
  546. bt('(["foo","bar"]).each(function(i) {return i;});',
  547. '(["foo", "bar"]).each(function(i) {\n return i;\n});')
  548. bt('(function(i) {return i;})();',
  549. '(function(i) {\n return i;\n})();')
  550. bt( "test( /*Argument 1*/ {\n" +
  551. " 'Value1': '1'\n" +
  552. "}, /*Argument 2\n" +
  553. " */ {\n" +
  554. " 'Value2': '2'\n" +
  555. "});",
  556. # expected
  557. "test( /*Argument 1*/ {\n" +
  558. " 'Value1': '1'\n" +
  559. " },\n" +
  560. " /*Argument 2\n" +
  561. " */\n" +
  562. " {\n" +
  563. " 'Value2': '2'\n" +
  564. " });")
  565. bt( "test(\n" +
  566. "/*Argument 1*/ {\n" +
  567. " 'Value1': '1'\n" +
  568. "},\n" +
  569. "/*Argument 2\n" +
  570. " */ {\n" +
  571. " 'Value2': '2'\n" +
  572. "});",
  573. # expected
  574. "test(\n" +
  575. " /*Argument 1*/\n" +
  576. " {\n" +
  577. " 'Value1': '1'\n" +
  578. " },\n" +
  579. " /*Argument 2\n" +
  580. " */\n" +
  581. " {\n" +
  582. " 'Value2': '2'\n" +
  583. " });")
  584. bt( "test( /*Argument 1*/\n" +
  585. "{\n" +
  586. " 'Value1': '1'\n" +
  587. "}, /*Argument 2\n" +
  588. " */\n" +
  589. "{\n" +
  590. " 'Value2': '2'\n" +
  591. "});",
  592. # expected
  593. "test( /*Argument 1*/\n" +
  594. " {\n" +
  595. " 'Value1': '1'\n" +
  596. " },\n" +
  597. " /*Argument 2\n" +
  598. " */\n" +
  599. " {\n" +
  600. " 'Value2': '2'\n" +
  601. " });")
  602. # END tests for brace position
  603. self.options.brace_style = 'collapse';
  604. test_fragment('roo = {\n /*\n ****\n FOO\n ****\n */\n BAR: 0\n};')
  605. test_fragment("if (zz) {\n // ....\n}\n(function")
  606. self.options.preserve_newlines = True;
  607. bt('var a = 42; // foo\n\nvar b;')
  608. bt('var a = 42; // foo\n\n\nvar b;')
  609. bt("var a = 'foo' +\n 'bar';")
  610. bt("var a = \"foo\" +\n \"bar\";")
  611. bt('"foo""bar""baz"', '"foo"\n"bar"\n"baz"')
  612. bt("'foo''bar''baz'", "'foo'\n'bar'\n'baz'")
  613. bt("{\n get foo() {}\n}")
  614. bt("{\n var a = get\n foo();\n}")
  615. bt("{\n set foo() {}\n}")
  616. bt("{\n var a = set\n foo();\n}")
  617. bt("var x = {\n get function()\n}")
  618. bt("var x = {\n set function()\n}")
  619. # According to my current research get/set have no special meaning outside of an object literal
  620. bt("var x = set\n\na() {}", "var x = set\n\na() {}")
  621. bt("var x = set\n\nfunction() {}", "var x = set\n\nfunction() {}")
  622. bt('<!-- foo\nbar();\n-->')
  623. bt('<!-- dont crash') # -->
  624. bt('for () /abc/.test()')
  625. bt('if (k) /aaa/m.test(v) && l();')
  626. bt('switch (true) {\n case /swf/i.test(foo):\n bar();\n}')
  627. bt('createdAt = {\n type: Date,\n default: Date.now\n}')
  628. bt('switch (createdAt) {\n case a:\n Date,\n default:\n Date.now\n}')
  629. bt('return function();')
  630. bt('var a = function();')
  631. bt('var a = 5 + function();')
  632. bt('{\n foo // something\n ,\n bar // something\n baz\n}')
  633. bt('function a(a) {} function b(b) {} function c(c) {}', 'function a(a) {}\n\nfunction b(b) {}\n\nfunction c(c) {}')
  634. bt('3.*7;', '3. * 7;')
  635. bt('a = 1.e-64 * 0.5e+4 / 6e-23;')
  636. bt('import foo.*;', 'import foo.*;') # actionscript's import
  637. test_fragment('function f(a: a, b: b)') # actionscript
  638. bt('foo(a, function() {})')
  639. bt('foo(a, /regex/)')
  640. bt('/* foo */\n"x"')
  641. self.options.break_chained_methods = False
  642. self.options.preserve_newlines = False
  643. bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo.bar().baz().cucumber(fat)')
  644. bt('foo\n.bar()\n.baz().cucumber(fat); foo.bar().baz().cucumber(fat)', 'foo.bar().baz().cucumber(fat);\nfoo.bar().baz().cucumber(fat)')
  645. bt('foo\n.bar()\n.baz().cucumber(fat)\n foo.bar().baz().cucumber(fat)', 'foo.bar().baz().cucumber(fat)\nfoo.bar().baz().cucumber(fat)')
  646. bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this.something = foo.bar().baz().cucumber(fat)')
  647. bt('this.something.xxx = foo.moo.bar()')
  648. bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this.something.xxx = foo.moo.bar()')
  649. self.options.break_chained_methods = False
  650. self.options.preserve_newlines = True
  651. bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo\n .bar()\n .baz().cucumber(fat)')
  652. 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)')
  653. 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)')
  654. bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this\n .something = foo.bar()\n .baz().cucumber(fat)')
  655. bt('this.something.xxx = foo.moo.bar()')
  656. bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this\n .something\n .xxx = foo.moo\n .bar()')
  657. self.options.break_chained_methods = True
  658. self.options.preserve_newlines = False
  659. bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo.bar()\n .baz()\n .cucumber(fat)')
  660. 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)')
  661. 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)')
  662. bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this.something = foo.bar()\n .baz()\n .cucumber(fat)')
  663. bt('this.something.xxx = foo.moo.bar()')
  664. bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this.something.xxx = foo.moo.bar()')
  665. self.options.break_chained_methods = True
  666. self.options.preserve_newlines = True
  667. bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo\n .bar()\n .baz()\n .cucumber(fat)')
  668. 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)')
  669. 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)')
  670. bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this\n .something = foo.bar()\n .baz()\n .cucumber(fat)')
  671. bt('this.something.xxx = foo.moo.bar()')
  672. bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this\n .something\n .xxx = foo.moo\n .bar()')
  673. self.options.break_chained_methods = False
  674. self.options.preserve_newlines = False
  675. # Line wrap test intputs
  676. #..............---------1---------2---------3---------4---------5---------6---------7
  677. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  678. wrap_input_1=('foo.bar().baz().cucumber((fat && "sassy") || (leans\n&& mean));\n' +
  679. 'Test_very_long_variable_name_this_should_never_wrap\n.but_this_can\n' +
  680. 'if (wraps_can_occur && inside_an_if_block) that_is_\n.okay();\n' +
  681. 'object_literal = {\n' +
  682. ' propertx: first_token + 12345678.99999E-6,\n' +
  683. ' property: first_token_should_never_wrap + but_this_can,\n' +
  684. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  685. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  686. '}')
  687. #..............---------1---------2---------3---------4---------5---------6---------7
  688. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  689. wrap_input_2=('{\n' +
  690. ' foo.bar().baz().cucumber((fat && "sassy") || (leans\n&& mean));\n' +
  691. ' Test_very_long_variable_name_this_should_never_wrap\n.but_this_can\n' +
  692. ' if (wraps_can_occur && inside_an_if_block) that_is_\n.okay();\n' +
  693. ' object_literal = {\n' +
  694. ' propertx: first_token + 12345678.99999E-6,\n' +
  695. ' property: first_token_should_never_wrap + but_this_can,\n' +
  696. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  697. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  698. ' }' +
  699. '}')
  700. self.options.preserve_newlines = False
  701. self.options.wrap_line_length = 0
  702. #..............---------1---------2---------3---------4---------5---------6---------7
  703. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  704. test_fragment(wrap_input_1,
  705. # expected #
  706. 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' +
  707. 'Test_very_long_variable_name_this_should_never_wrap.but_this_can\n' +
  708. 'if (wraps_can_occur && inside_an_if_block) that_is_.okay();\n' +
  709. 'object_literal = {\n' +
  710. ' propertx: first_token + 12345678.99999E-6,\n' +
  711. ' property: first_token_should_never_wrap + but_this_can,\n' +
  712. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  713. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  714. '}')
  715. self.options.wrap_line_length = 70
  716. #..............---------1---------2---------3---------4---------5---------6---------7
  717. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  718. test_fragment(wrap_input_1,
  719. # expected #
  720. 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' +
  721. 'Test_very_long_variable_name_this_should_never_wrap.but_this_can\n' +
  722. 'if (wraps_can_occur && inside_an_if_block) that_is_.okay();\n' +
  723. 'object_literal = {\n' +
  724. ' propertx: first_token + 12345678.99999E-6,\n' +
  725. ' property: first_token_should_never_wrap + but_this_can,\n' +
  726. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  727. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  728. '}')
  729. self.options.wrap_line_length = 40
  730. #..............---------1---------2---------3---------4---------5---------6---------7
  731. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  732. test_fragment(wrap_input_1,
  733. # expected #
  734. 'foo.bar().baz().cucumber((fat &&\n' +
  735. ' "sassy") || (leans && mean));\n' +
  736. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  737. ' .but_this_can\n' +
  738. 'if (wraps_can_occur &&\n' +
  739. ' inside_an_if_block) that_is_.okay();\n' +
  740. 'object_literal = {\n' +
  741. ' propertx: first_token +\n' +
  742. ' 12345678.99999E-6,\n' +
  743. ' property: first_token_should_never_wrap +\n' +
  744. ' but_this_can,\n' +
  745. ' propertz: first_token_should_never_wrap +\n' +
  746. ' !but_this_can,\n' +
  747. ' proper: "first_token_should_never_wrap" +\n' +
  748. ' "but_this_can"\n' +
  749. '}')
  750. self.options.wrap_line_length = 41
  751. # NOTE: wrap is only best effort - line continues until next wrap point is found.
  752. #..............---------1---------2---------3---------4---------5---------6---------7
  753. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  754. test_fragment(wrap_input_1,
  755. # expected #
  756. 'foo.bar().baz().cucumber((fat && "sassy") ||\n' +
  757. ' (leans && mean));\n' +
  758. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  759. ' .but_this_can\n' +
  760. 'if (wraps_can_occur &&\n' +
  761. ' inside_an_if_block) that_is_.okay();\n' +
  762. 'object_literal = {\n' +
  763. ' propertx: first_token +\n' +
  764. ' 12345678.99999E-6,\n' +
  765. ' property: first_token_should_never_wrap +\n' +
  766. ' but_this_can,\n' +
  767. ' propertz: first_token_should_never_wrap +\n' +
  768. ' !but_this_can,\n' +
  769. ' proper: "first_token_should_never_wrap" +\n' +
  770. ' "but_this_can"\n' +
  771. '}')
  772. self.options.wrap_line_length = 45
  773. # NOTE: wrap is only best effort - line continues until next wrap point is found.
  774. #..............---------1---------2---------3---------4---------5---------6---------7
  775. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  776. test_fragment(wrap_input_2,
  777. # expected #
  778. '{\n' +
  779. ' foo.bar().baz().cucumber((fat && "sassy") ||\n' +
  780. ' (leans && mean));\n' +
  781. ' Test_very_long_variable_name_this_should_never_wrap\n' +
  782. ' .but_this_can\n' +
  783. ' if (wraps_can_occur &&\n' +
  784. ' inside_an_if_block) that_is_.okay();\n' +
  785. ' object_literal = {\n' +
  786. ' propertx: first_token +\n' +
  787. ' 12345678.99999E-6,\n' +
  788. ' property: first_token_should_never_wrap +\n' +
  789. ' but_this_can,\n' +
  790. ' propertz: first_token_should_never_wrap +\n' +
  791. ' !but_this_can,\n' +
  792. ' proper: "first_token_should_never_wrap" +\n' +
  793. ' "but_this_can"\n' +
  794. ' }\n'+
  795. '}')
  796. self.options.preserve_newlines = True
  797. self.options.wrap_line_length = 0
  798. #..............---------1---------2---------3---------4---------5---------6---------7
  799. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  800. test_fragment(wrap_input_1,
  801. # expected #
  802. 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' +
  803. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  804. ' .but_this_can\n' +
  805. 'if (wraps_can_occur && inside_an_if_block) that_is_\n' +
  806. ' .okay();\n' +
  807. 'object_literal = {\n' +
  808. ' propertx: first_token + 12345678.99999E-6,\n' +
  809. ' property: first_token_should_never_wrap + but_this_can,\n' +
  810. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  811. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  812. '}')
  813. self.options.wrap_line_length = 70
  814. #..............---------1---------2---------3---------4---------5---------6---------7
  815. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  816. test_fragment(wrap_input_1,
  817. # expected #
  818. 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' +
  819. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  820. ' .but_this_can\n' +
  821. 'if (wraps_can_occur && inside_an_if_block) that_is_\n' +
  822. ' .okay();\n' +
  823. 'object_literal = {\n' +
  824. ' propertx: first_token + 12345678.99999E-6,\n' +
  825. ' property: first_token_should_never_wrap + but_this_can,\n' +
  826. ' propertz: first_token_should_never_wrap + !but_this_can,\n' +
  827. ' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
  828. '}')
  829. self.options.wrap_line_length = 40
  830. #..............---------1---------2---------3---------4---------5---------6---------7
  831. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  832. test_fragment(wrap_input_1,
  833. # expected #
  834. 'foo.bar().baz().cucumber((fat &&\n' +
  835. ' "sassy") || (leans && mean));\n' +
  836. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  837. ' .but_this_can\n' +
  838. 'if (wraps_can_occur &&\n' +
  839. ' inside_an_if_block) that_is_\n' +
  840. ' .okay();\n' +
  841. 'object_literal = {\n' +
  842. ' propertx: first_token +\n' +
  843. ' 12345678.99999E-6,\n' +
  844. ' property: first_token_should_never_wrap +\n' +
  845. ' but_this_can,\n' +
  846. ' propertz: first_token_should_never_wrap +\n' +
  847. ' !but_this_can,\n' +
  848. ' proper: "first_token_should_never_wrap" +\n' +
  849. ' "but_this_can"\n' +
  850. '}')
  851. self.options.wrap_line_length = 41
  852. # NOTE: wrap is only best effort - line continues until next wrap point is found.
  853. #..............---------1---------2---------3---------4---------5---------6---------7
  854. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  855. test_fragment(wrap_input_1,
  856. # expected #
  857. 'foo.bar().baz().cucumber((fat && "sassy") ||\n' +
  858. ' (leans && mean));\n' +
  859. 'Test_very_long_variable_name_this_should_never_wrap\n' +
  860. ' .but_this_can\n' +
  861. 'if (wraps_can_occur &&\n' +
  862. ' inside_an_if_block) that_is_\n' +
  863. ' .okay();\n' +
  864. 'object_literal = {\n' +
  865. ' propertx: first_token +\n' +
  866. ' 12345678.99999E-6,\n' +
  867. ' property: first_token_should_never_wrap +\n' +
  868. ' but_this_can,\n' +
  869. ' propertz: first_token_should_never_wrap +\n' +
  870. ' !but_this_can,\n' +
  871. ' proper: "first_token_should_never_wrap" +\n' +
  872. ' "but_this_can"\n' +
  873. '}')
  874. self.options.wrap_line_length = 45
  875. # NOTE: wrap is only best effort - line continues until next wrap point is found.
  876. #..............---------1---------2---------3---------4---------5---------6---------7
  877. #..............1234567890123456789012345678901234567890123456789012345678901234567890
  878. test_fragment(wrap_input_2,
  879. # expected #
  880. '{\n' +
  881. ' foo.bar().baz().cucumber((fat && "sassy") ||\n' +
  882. ' (leans && mean));\n' +
  883. ' Test_very_long_variable_name_this_should_never_wrap\n' +
  884. ' .but_this_can\n' +
  885. ' if (wraps_can_occur &&\n' +
  886. ' inside_an_if_block) that_is_\n' +
  887. ' .okay();\n' +
  888. ' object_literal = {\n' +
  889. ' propertx: first_token +\n' +
  890. ' 12345678.99999E-6,\n' +
  891. ' property: first_token_should_never_wrap +\n' +
  892. ' but_this_can,\n' +
  893. ' propertz: first_token_should_never_wrap +\n' +
  894. ' !but_this_can,\n' +
  895. ' proper: "first_token_should_never_wrap" +\n' +
  896. ' "but_this_can"\n' +
  897. ' }\n'+
  898. '}')
  899. self.options.wrap_line_length = 0
  900. self.options.preserve_newlines = False
  901. bt('if (foo) // comment\n bar();')
  902. bt('if (foo) // comment\n (bar());')
  903. bt('if (foo) // comment\n (bar());')
  904. bt('if (foo) // comment\n /asdf/;')
  905. bt('this.oa = new OAuth(\n' +
  906. ' _requestToken,\n' +
  907. ' _accessToken,\n' +
  908. ' consumer_key\n' +
  909. ');',
  910. 'this.oa = new OAuth(_requestToken, _accessToken, consumer_key);')
  911. bt('foo = {\n x: y, // #44\n w: z // #44\n}')
  912. bt('switch (x) {\n case "a":\n // comment on newline\n break;\n case "b": // comment on same line\n break;\n}')
  913. bt('this.type =\n this.options =\n // comment\n this.enabled null;',
  914. 'this.type = this.options =\n // comment\n this.enabled null;')
  915. bt('someObj\n .someFunc1()\n // This comment should not break the indent\n .someFunc2();',
  916. 'someObj.someFunc1()\n // This comment should not break the indent\n .someFunc2();')
  917. bt('if (true ||\n!true) return;', 'if (true || !true) return;')
  918. # these aren't ready yet.
  919. #bt('if (foo) // comment\n bar() /*i*/ + baz() /*j\n*/ + asdf();')
  920. bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\na();',
  921. 'if (foo)\n if (bar)\n if (baz) whee();\na();')
  922. bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\nelse\na();',
  923. 'if (foo)\n if (bar)\n if (baz) whee();\n else a();')
  924. bt('if (foo)\nbar();\nelse\ncar();',
  925. 'if (foo) bar();\nelse car();')
  926. bt('if (foo) if (bar) if (baz);\na();',
  927. 'if (foo)\n if (bar)\n if (baz);\na();')
  928. bt('if (foo) if (bar) if (baz) whee();\na();',
  929. 'if (foo)\n if (bar)\n if (baz) whee();\na();')
  930. bt('if (foo) a()\nif (bar) if (baz) whee();\na();',
  931. 'if (foo) a()\nif (bar)\n if (baz) whee();\na();')
  932. bt('if (foo);\nif (bar) if (baz) whee();\na();',
  933. 'if (foo);\nif (bar)\n if (baz) whee();\na();')
  934. bt('if (options)\n' +
  935. ' for (var p in options)\n' +
  936. ' this[p] = options[p];',
  937. 'if (options)\n'+
  938. ' for (var p in options) this[p] = options[p];')
  939. bt('if (options) for (var p in options) this[p] = options[p];',
  940. 'if (options)\n for (var p in options) this[p] = options[p];')
  941. bt('if (options) do q(); while (b());',
  942. 'if (options)\n do q(); while (b());')
  943. bt('if (options) while (b()) q();',
  944. 'if (options)\n while (b()) q();')
  945. bt('if (options) do while (b()) q(); while (a());',
  946. 'if (options)\n do\n while (b()) q(); while (a());')
  947. bt('function f(a, b, c,\nd, e) {}',
  948. 'function f(a, b, c, d, e) {}')
  949. bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
  950. 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}')
  951. bt('function f(a,b) {if(a) b()}\n\n\n\nfunction g(a,b) {if(!a) b()}',
  952. 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}')
  953. # This is not valid syntax, but still want to behave reasonably and not side-effect
  954. bt('(if(a) b())(if(a) b())',
  955. '(\n if (a) b())(\n if (a) b())')
  956. bt('(if(a) b())\n\n\n(if(a) b())',
  957. '(\n if (a) b())\n(\n if (a) b())')
  958. # space between functions
  959. bt('/*\n * foo\n */\nfunction foo() {}')
  960. bt('// a nice function\nfunction foo() {}')
  961. bt('function foo() {}\nfunction foo() {}',
  962. 'function foo() {}\n\nfunction foo() {}'
  963. )
  964. bt('[\n function() {}\n]')
  965. bt("if\n(a)\nb();", "if (a) b();")
  966. bt('var a =\nfoo', 'var a = foo')
  967. bt('var a = {\n"a":1,\n"b":2}', "var a = {\n \"a\": 1,\n \"b\": 2\n}")
  968. bt("var a = {\n'a':1,\n'b':2}", "var a = {\n 'a': 1,\n 'b': 2\n}")
  969. bt('var a = /*i*/ "b";')
  970. bt('var a = /*i*/\n"b";', 'var a = /*i*/ "b";')
  971. bt('var a = /*i*/\nb;', 'var a = /*i*/ b;')
  972. bt('{\n\n\n"x"\n}', '{\n "x"\n}')
  973. bt('if(a &&\nb\n||\nc\n||d\n&&\ne) e = f', 'if (a && b || c || d && e) e = f')
  974. bt('if(a &&\n(b\n||\nc\n||d)\n&&\ne) e = f', 'if (a && (b || c || d) && e) e = f')
  975. test_fragment('\n\n"x"', '"x"')
  976. 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;',
  977. 'a = 1;\nb = 2;')
  978. self.options.preserve_newlines = True
  979. bt('if (foo) // comment\n bar();')
  980. bt('if (foo) // comment\n (bar());')
  981. bt('if (foo) // comment\n (bar());')
  982. bt('if (foo) // comment\n /asdf/;')
  983. bt('this.oa = new OAuth(\n' +
  984. ' _requestToken,\n' +
  985. ' _accessToken,\n' +
  986. ' consumer_key\n' +
  987. ');')
  988. bt('foo = {\n x: y, // #44\n w: z // #44\n}')
  989. bt('switch (x) {\n case "a":\n // comment on newline\n break;\n case "b": // comment on same line\n break;\n}')
  990. bt('this.type =\n this.options =\n // comment\n this.enabled null;')
  991. bt('someObj\n .someFunc1()\n // This comment should not break the indent\n .someFunc2();')
  992. bt('if (true ||\n!true) return;', 'if (true ||\n !true) return;')
  993. # these aren't ready yet.
  994. # bt('if (foo) // comment\n bar() /*i*/ + baz() /*j\n*/ + asdf();')
  995. bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\na();',
  996. 'if (foo)\n if (bar)\n if (baz)\n whee();\na();')
  997. bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\nelse\na();',
  998. 'if (foo)\n if (bar)\n if (baz)\n whee();\n else\n a();')
  999. bt('if (foo) bar();\nelse\ncar();',
  1000. 'if (foo) bar();\nelse\n car();')
  1001. bt('if (foo) if (bar) if (baz);\na();',
  1002. 'if (foo)\n if (bar)\n if (baz);\na();')
  1003. bt('if (foo) if (bar) if (baz) whee();\na();',
  1004. 'if (foo)\n if (bar)\n if (baz) whee();\na();')
  1005. bt('if (foo) a()\nif (bar) if (baz) whee();\na();',
  1006. 'if (foo) a()\nif (bar)\n if (baz) whee();\na();')
  1007. bt('if (foo);\nif (bar) if (baz) whee();\na();',
  1008. 'if (foo);\nif (bar)\n if (baz) whee();\na();')
  1009. bt('if (options)\n' +
  1010. ' for (var p in options)\n' +
  1011. ' this[p] = options[p];')
  1012. bt('if (options) for (var p in options) this[p] = options[p];',
  1013. 'if (options)\n for (var p in options) this[p] = options[p];')
  1014. bt('if (options) do q(); while (b());',
  1015. 'if (options)\n do q(); while (b());')
  1016. bt('if (options) do; while (b());',
  1017. 'if (options)\n do; while (b());')
  1018. bt('if (options) while (b()) q();',
  1019. 'if (options)\n while (b()) q();')
  1020. bt('if (options) do while (b()) q(); while (a());',
  1021. 'if (options)\n do\n while (b()) q(); while (a());')
  1022. bt('function f(a, b, c,\nd, e) {}',
  1023. 'function f(a, b, c,\n d, e) {}')
  1024. bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
  1025. 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}')
  1026. bt('function f(a,b) {if(a) b()}\n\n\n\nfunction g(a,b) {if(!a) b()}',
  1027. 'function f(a, b) {\n if (a) b()\n}\n\n\n\nfunction g(a, b) {\n if (!a) b()\n}')
  1028. # This is not valid syntax, but still want to behave reasonably and not side-effect
  1029. bt('(if(a) b())(if(a) b())',
  1030. '(\n if (a) b())(\n if (a) b())')
  1031. bt('(if(a) b())\n\n\n(if(a) b())',
  1032. '(\n if (a) b())\n\n\n(\n if (a) b())')
  1033. bt("if\n(a)\nb();", "if (a)\n b();")
  1034. bt('var a =\nfoo', 'var a =\n foo')
  1035. bt('var a = {\n"a":1,\n"b":2}', "var a = {\n \"a\": 1,\n \"b\": 2\n}")
  1036. bt("var a = {\n'a':1,\n'b':2}", "var a = {\n 'a': 1,\n 'b': 2\n}")
  1037. bt('var a = /*i*/ "b";')
  1038. bt('var a = /*i*/\n"b";', 'var a = /*i*/\n "b";')
  1039. bt('var a = /*i*/\nb;', 'var a = /*i*/\n b;')
  1040. bt('{\n\n\n"x"\n}', '{\n\n\n "x"\n}')
  1041. bt('if(a &&\nb\n||\nc\n||d\n&&\ne) e = f', 'if (a &&\n b ||\n c || d &&\n e) e = f')
  1042. bt('if(a &&\n(b\n||\nc\n||d)\n&&\ne) e = f', 'if (a &&\n (b ||\n c || d) &&\n e) e = f')
  1043. test_fragment('\n\n"x"', '"x"')
  1044. # this beavior differs between js and python, defaults to unlimited in js, 10 in python
  1045. 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;',
  1046. 'a = 1;\n\n\n\n\n\n\n\n\n\nb = 2;')
  1047. self.options.max_preserve_newlines = 8;
  1048. 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;',
  1049. 'a = 1;\n\n\n\n\n\n\n\nb = 2;')
  1050. # Test the option to have spaces within parens
  1051. self.options.space_in_paren = False
  1052. self.options.space_in_empty_paren = False
  1053. bt('if(p) foo(a,b)', 'if (p) foo(a, b)')
  1054. bt('try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }',
  1055. 'try {\n while (true) {\n willThrow()\n }\n} catch (result) switch (result) {\n case 1:\n ++result\n}')
  1056. bt('((e/((a+(b)*c)-d))^2)*5;', '((e / ((a + (b) * c) - d)) ^ 2) * 5;')
  1057. bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
  1058. 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}')
  1059. bt('a=[];',
  1060. 'a = [];')
  1061. bt('a=[b,c,d];',
  1062. 'a = [b, c, d];')
  1063. bt('a= f[b];',
  1064. 'a = f[b];')
  1065. self.options.space_in_paren = True
  1066. bt('if(p) foo(a,b)', 'if ( p ) foo( a, b )')
  1067. bt('try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }',
  1068. 'try {\n while ( true ) {\n willThrow()\n }\n} catch ( result ) switch ( result ) {\n case 1:\n ++result\n}')
  1069. bt('((e/((a+(b)*c)-d))^2)*5;', '( ( e / ( ( a + ( b ) * c ) - d ) ) ^ 2 ) * 5;')
  1070. bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
  1071. 'function f( a, b ) {\n if ( a ) b()\n}\n\nfunction g( a, b ) {\n if ( !a ) b()\n}')
  1072. bt('a=[ ];',
  1073. 'a = [];')
  1074. bt('a=[b,c,d];',
  1075. 'a = [ b, c, d ];')
  1076. bt('a= f[b];',
  1077. 'a = f[ b ];')
  1078. self.options.space_in_empty_paren = True
  1079. bt('if(p) foo(a,b)', 'if ( p ) foo( a, b )')
  1080. bt('try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }',
  1081. 'try {\n while ( true ) {\n willThrow( )\n }\n} catch ( result ) switch ( result ) {\n case 1:\n ++result\n}')
  1082. bt('((e/((a+(b)*c)-d))^2)*5;', '( ( e / ( ( a + ( b ) * c ) - d ) ) ^ 2 ) * 5;')
  1083. bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
  1084. 'function f( a, b ) {\n if ( a ) b( )\n}\n\nfunction g( a, b ) {\n if ( !a ) b( )\n}')
  1085. bt('a=[ ];',
  1086. 'a = [ ];')
  1087. bt('a=[b,c,d];',
  1088. 'a = [ b, c, d ];')
  1089. bt('a= f[b];',
  1090. 'a = f[ b ];')
  1091. self.options.space_in_paren = False
  1092. self.options.space_in_empty_paren = False
  1093. # Test template strings
  1094. bt('`This is a ${template} string.`', '`This is a ${template} string.`')
  1095. bt('`This\n is\n a\n ${template}\n string.`', '`This\n is\n a\n ${template}\n string.`')
  1096. bt('a = `This is a continuation\\\nstring.`', 'a = `This is a continuation\\\nstring.`');
  1097. bt('a = "This is a continuation\\\nstring."', 'a = "This is a continuation\\\nstring."');
  1098. def decodesto(self, input, expectation=None):
  1099. if expectation == None:
  1100. expectation = input
  1101. self.assertMultiLineEqual(
  1102. jsbeautifier.beautify(input, self.options), expectation)
  1103. # if the expected is different from input, run it again
  1104. # expected output should be unchanged when run twice.
  1105. if not expectation == None:
  1106. self.assertMultiLineEqual(
  1107. jsbeautifier.beautify(expectation, self.options), expectation)
  1108. # Everywhere we do newlines, they should be replaced with opts.eol
  1109. self.options.eol = '\r\\n';
  1110. expectation = expectation.replace('\n', '\r\n')
  1111. self.assertMultiLineEqual(
  1112. jsbeautifier.beautify(input, self.options), expectation)
  1113. input = input.replace('\n', '\r\n')
  1114. self.assertMultiLineEqual(
  1115. jsbeautifier.beautify(input, self.options), expectation)
  1116. self.options.eol = '\n'
  1117. def wrap(self, text):
  1118. return self.wrapregex.sub(' \\1', text)
  1119. def bt(self, input, expectation=None):
  1120. if expectation == None:
  1121. expectation = input
  1122. self.decodesto(input, expectation)
  1123. # If we set raw, input should be unchanged
  1124. self.options.test_output_raw = True
  1125. if self.options.end_with_newline:
  1126. elf.decodesto(input, input)
  1127. self.options.test_output_raw = False
  1128. if self.options.indent_size == 4 and input:
  1129. wrapped_input = '{\n%s\n foo = bar;\n}' % self.wrap(input)
  1130. wrapped_expect = '{\n%s\n foo = bar;\n}' % self.wrap(expectation)
  1131. self.decodesto(wrapped_input, wrapped_expect)
  1132. # If we set raw, input should be unchanged
  1133. self.options.test_output_raw = True
  1134. if self.options.end_with_newline:
  1135. elf.decodesto(wrapped_input, wrapped_input)
  1136. self.options.test_output_raw = False
  1137. @classmethod
  1138. def setUpClass(cls):
  1139. options = jsbeautifier.default_options()
  1140. options.indent_size = 4
  1141. options.indent_char = ' '
  1142. options.preserve_newlines = True
  1143. options.jslint_happy = False
  1144. options.keep_array_indentation = False
  1145. options.brace_style = 'collapse'
  1146. options.indent_level = 0
  1147. options.break_chained_methods = False
  1148. options.eol = '\n'
  1149. cls.options = options
  1150. cls.wrapregex = re.compile('^(.+)$', re.MULTILINE)
  1151. if __name__ == '__main__':
  1152. unittest.main()