#!/usr/bin/env python # -*- coding: utf-8 -*- import re import unittest import jsbeautifier import six class TestJSBeautifier(unittest.TestCase): def test_unescape(self): # Test cases contributed by test_fragment = self.decodesto bt = self.bt bt('"\\\\s"') # == "\\s" in the js source bt("'\\\\s'") # == '\\s' in the js source bt("'\\\\\\s'") # == '\\\s' in the js source bt("'\\s'") # == '\s' in the js source bt('"•"') bt('"—"') bt('"\\x41\\x42\\x43\\x01"', '"\\x41\\x42\\x43\\x01"') bt('"\\u2022"', '"\\u2022"') bt('a = /\s+/') #bt('a = /\\x41/','a = /A/') bt('"\\u2022";a = /\s+/;"\\x41\\x42\\x43\\x01".match(/\\x41/);','"\\u2022";\na = /\s+/;\n"\\x41\\x42\\x43\\x01".match(/\\x41/);') 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"') self.options.unescape_strings = True bt('"\\x41\\x42\\x43\\x01"', '"ABC\\x01"') bt('"\\u2022"', '"\\u2022"') bt('a = /\s+/') bt('"\\u2022";a = /\s+/;"\\x41\\x42\\x43\\x01".match(/\\x41/);','"\\u2022";\na = /\s+/;\n"ABC\\x01".match(/\\x41/);') bt('"\\x22\\x27",\'\\x22\\x27\',"\\x5c",\'\\x5c\',"\\xff and \\xzz","unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"', '"\\"\'", \'"\\\'\', "\\\\", \'\\\\\', "\\xff and \\xzz", "unicode \\u0000 \\" \' \\\\ \\uffff \\uzzzz"') self.options.unescape_strings = False def test_beautifier(self): test_fragment = self.decodesto bt = self.bt true = True false = False def unicode_char(value): return six.unichr(value) {{#default_options}} self.options.{{name}} = {{&value}} {{/default_options}} {{#groups}} {{^matrix}} # {{&name}} {{#options}} self.options.{{name}} = {{&value}} {{/options}} {{#tests}} {{#test_line}}.{{/test_line}} {{/tests}} {{/matrix}} {{#matrix}} # {{&name}} - ({{#matrix_context_string}}.{{/matrix_context_string}}) {{#options}} self.options.{{name}} = {{&value}} {{/options}} {{#tests}} {{#test_line}}.{{/test_line}} {{/tests}} {{/matrix}} {{/groups}} {{=<% %>=}} bt('{{}/z/}', "{\n {}\n /z/\n}") <%={{ }}=%> self.options.indent_size = 1; self.options.indent_char = ' '; bt('{ one_char() }', "{\n one_char()\n}") bt('var a,b=1,c=2', 'var a, b = 1,\n c = 2') self.options.indent_size = 4; self.options.indent_char = ' '; bt('{ one_char() }', "{\n one_char()\n}") self.options.indent_size = 1; self.options.indent_char = "\t"; bt('{ one_char() }', "{\n\tone_char()\n}") bt('x = a ? b : c; x;', 'x = a ? b : c;\nx;') #set to something else than it should change to, but with tabs on, should override self.options.indent_size = 5; self.options.indent_char = ' '; self.options.indent_with_tabs = True; bt('{ one_char() }', "{\n\tone_char()\n}") bt('x = a ? b : c; x;', 'x = a ? b : c;\nx;') self.options.indent_size = 4; self.options.indent_char = ' '; self.options.indent_with_tabs = False; self.options.preserve_newlines = False; bt('var\na=dont_preserve_newlines;', 'var a = dont_preserve_newlines;') # make sure the blank line between function definitions stays # even when preserve_newlines = False bt('function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}') bt('function foo() {\n return 1;\n}\nfunction foo() {\n return 1;\n}', 'function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}' ) bt('function foo() {\n return 1;\n}\n\n\nfunction foo() {\n return 1;\n}', 'function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}' ) self.options.preserve_newlines = True; bt('var\na=do_preserve_newlines;', 'var\n a = do_preserve_newlines;') bt('// a\n// b\n\n// c\n// d') bt('if (foo) // comment\n{\n bar();\n}') self.options.keep_array_indentation = False; bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f']", "a = ['a', 'b', 'c',\n 'd', 'e', 'f'\n]") bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']", "a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i'\n]") bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']", "a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i'\n]") bt('var x = [{}\n]', 'var x = [{}]') bt('var x = [{foo:bar}\n]', 'var x = [{\n foo: bar\n}]') bt("a = ['something',\n 'completely',\n 'different'];\nif (x);", "a = ['something',\n 'completely',\n 'different'\n];\nif (x);") bt("a = ['a','b','c']", "a = ['a', 'b', 'c']") bt("a = ['a', 'b','c']", "a = ['a', 'b', 'c']") bt("x = [{'a':0}]", "x = [{\n 'a': 0\n}]") bt('{a([[a1]], {b;});}', '{\n a([\n [a1]\n ], {\n b;\n });\n}') bt("a();\n [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();", "a();\n[\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n].toString();") bt("a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();", "a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n].toString();") bt("function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}", "function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}") bt('function foo() {\n return [\n "one",\n "two"\n ];\n}') # 4 spaces per indent input, processed with 4-spaces per indent bt( "function foo() {\n" + " return [\n" + " {\n" + " one: 'x',\n" + " two: [\n" + " {\n" + " id: 'a',\n" + " name: 'apple'\n" + " }, {\n" + " id: 'b',\n" + " name: 'banana'\n" + " }\n" + " ]\n" + " }\n" + " ];\n" + "}", "function foo() {\n" + " return [{\n" + " one: 'x',\n" + " two: [{\n" + " id: 'a',\n" + " name: 'apple'\n" + " }, {\n" + " id: 'b',\n" + " name: 'banana'\n" + " }]\n" + " }];\n" + "}") # 3 spaces per indent input, processed with 4-spaces per indent bt( "function foo() {\n" + " return [\n" + " {\n" + " one: 'x',\n" + " two: [\n" + " {\n" + " id: 'a',\n" + " name: 'apple'\n" + " }, {\n" + " id: 'b',\n" + " name: 'banana'\n" + " }\n" + " ]\n" + " }\n" + " ];\n" + "}", "function foo() {\n" + " return [{\n" + " one: 'x',\n" + " two: [{\n" + " id: 'a',\n" + " name: 'apple'\n" + " }, {\n" + " id: 'b',\n" + " name: 'banana'\n" + " }]\n" + " }];\n" + "}") self.options.keep_array_indentation = True; bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f']") bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']") bt("a = ['a', 'b', 'c',\n 'd', 'e', 'f',\n 'g', 'h', 'i']") bt('var x = [{}\n]', 'var x = [{}\n]') bt('var x = [{foo:bar}\n]', 'var x = [{\n foo: bar\n }\n]') bt("a = ['something',\n 'completely',\n 'different'];\nif (x);") bt("a = ['a','b','c']", "a = ['a', 'b', 'c']") bt("a = ['a', 'b','c']", "a = ['a', 'b', 'c']") bt("x = [{'a':0}]", "x = [{\n 'a': 0\n}]") bt('{a([[a1]], {b;});}', '{\n a([[a1]], {\n b;\n });\n}') bt("a();\n [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();", "a();\n [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();") bt("a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();", "a();\na = [\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ].toString();") bt("function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}", "function() {\n Foo([\n ['sdfsdfsd'],\n ['sdfsdfsdf']\n ]);\n}") bt('function foo() {\n return [\n "one",\n "two"\n ];\n}') # 4 spaces per indent input, processed with 4-spaces per indent bt( "function foo() {\n" + " return [\n" + " {\n" + " one: 'x',\n" + " two: [\n" + " {\n" + " id: 'a',\n" + " name: 'apple'\n" + " }, {\n" + " id: 'b',\n" + " name: 'banana'\n" + " }\n" + " ]\n" + " }\n" + " ];\n" + "}") # 3 spaces per indent input, processed with 4-spaces per indent # Should be unchanged, but is not - #445 # bt( "function foo() {\n" + # " return [\n" + # " {\n" + # " one: 'x',\n" + # " two: [\n" + # " {\n" + # " id: 'a',\n" + # " name: 'apple'\n" + # " }, {\n" + # " id: 'b',\n" + # " name: 'banana'\n" + # " }\n" + # " ]\n" + # " }\n" + # " ];\n" + # "}") self.options.keep_array_indentation = False; bt('a = //comment\n /regex/;') bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a) {\n b;\n} else {\n c;\n}') bt('var a = new function();') test_fragment('new function') # START tests for brace positioning # If this is ever supported, update tests for each brace style. # test_fragment('return\n{', 'return\n{') # can't support this?, but that's an improbable and extreme case anyway. self.options.brace_style = 'expand'; bt('//case 1\nif (a == 1)\n{}\n//case 2\nelse if (a == 2)\n{}') bt('if(1){2}else{3}', "if (1)\n{\n 2\n}\nelse\n{\n 3\n}") bt('try{a();}catch(b){c();}catch(d){}finally{e();}', "try\n{\n a();\n}\ncatch (b)\n{\n c();\n}\ncatch (d)\n{}\nfinally\n{\n e();\n}") bt('if(a){b();}else if(c) foo();', "if (a)\n{\n b();\n}\nelse if (c) foo();") bt("if (a) {\n// comment\n}else{\n// comment\n}", "if (a)\n{\n // comment\n}\nelse\n{\n // comment\n}") # if/else statement with empty body bt('if (x) {y} else { if (x) {y}}', 'if (x)\n{\n y\n}\nelse\n{\n if (x)\n {\n y\n }\n}') bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a)\n{\n b;\n}\nelse\n{\n c;\n}') test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}', ' /*\n * xx\n */\n // xx\n if (foo)\n {\n bar();\n }') bt('if (foo)\n{}\nelse /regex/.test();') test_fragment('if (foo) {', 'if (foo)\n{') test_fragment('foo {', 'foo\n{') test_fragment('return {', 'return {') # return needs the brace. test_fragment('return /* inline */ {', 'return /* inline */ {') test_fragment('return;\n{', 'return;\n{') bt("throw {}") bt("throw {\n foo;\n}") bt('var foo = {}') bt('function x() {\n foo();\n}zzz', 'function x()\n{\n foo();\n}\nzzz') test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx') bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}') bt('var a = new function() {};') bt('var a = new function a() {};', 'var a = new function a()\n{};') bt('var a = new function()\n{};', 'var a = new function() {};') bt('var a = new function a()\n{};') bt('var a = new function a()\n {},\n b = new function b()\n {};') bt("foo({\n 'a': 1\n},\n10);", "foo(\n {\n 'a': 1\n },\n 10);") bt('(["foo","bar"]).each(function(i) {return i;});', '(["foo", "bar"]).each(function(i)\n{\n return i;\n});') bt('(function(i) {return i;})();', '(function(i)\n{\n return i;\n})();') bt( "test( /*Argument 1*/ {\n" + " 'Value1': '1'\n" + "}, /*Argument 2\n" + " */ {\n" + " 'Value2': '2'\n" + "});", # expected "test( /*Argument 1*/\n" + " {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") bt( "test(\n" + "/*Argument 1*/ {\n" + " 'Value1': '1'\n" + "},\n" + "/*Argument 2\n" + " */ {\n" + " 'Value2': '2'\n" + "});", # expected "test(\n" + " /*Argument 1*/\n" + " {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") bt( "test( /*Argument 1*/\n" + "{\n" + " 'Value1': '1'\n" + "}, /*Argument 2\n" + " */\n" + "{\n" + " 'Value2': '2'\n" + "});", # expected "test( /*Argument 1*/\n" + " {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") self.options.brace_style = 'collapse'; bt('//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}') bt('if(1){2}else{3}', "if (1) {\n 2\n} else {\n 3\n}") bt('try{a();}catch(b){c();}catch(d){}finally{e();}', "try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}") bt('if(a){b();}else if(c) foo();', "if (a) {\n b();\n} else if (c) foo();") bt("if (a) {\n// comment\n}else{\n// comment\n}", "if (a) {\n // comment\n} else {\n // comment\n}") # if/else statement with empty body bt('if (x) {y} else { if (x) {y}}', 'if (x) {\n y\n} else {\n if (x) {\n y\n }\n}') bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a) {\n b;\n} else {\n c;\n}') test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}', ' /*\n * xx\n */\n // xx\n if (foo) {\n bar();\n }') bt('if (foo) {} else /regex/.test();') test_fragment('if (foo) {', 'if (foo) {') test_fragment('foo {', 'foo {') test_fragment('return {', 'return {') # return needs the brace. test_fragment('return /* inline */ {', 'return /* inline */ {') test_fragment('return;\n{', 'return; {') bt("throw {}") bt("throw {\n foo;\n}") bt('var foo = {}') bt('function x() {\n foo();\n}zzz', 'function x() {\n foo();\n}\nzzz') test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx') bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}') bt('var a = new function() {};') bt('var a = new function a() {};') bt('var a = new function()\n{};', 'var a = new function() {};') bt('var a = new function a()\n{};', 'var a = new function a() {};') bt('var a = new function a()\n {},\n b = new function b()\n {};', 'var a = new function a() {},\n b = new function b() {};') bt("foo({\n 'a': 1\n},\n10);", "foo({\n 'a': 1\n },\n 10);") bt('(["foo","bar"]).each(function(i) {return i;});', '(["foo", "bar"]).each(function(i) {\n return i;\n});') bt('(function(i) {return i;})();', '(function(i) {\n return i;\n})();') bt( "test( /*Argument 1*/ {\n" + " 'Value1': '1'\n" + "}, /*Argument 2\n" + " */ {\n" + " 'Value2': '2'\n" + "});", # expected "test( /*Argument 1*/ {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") bt( "test(\n" + "/*Argument 1*/ {\n" + " 'Value1': '1'\n" + "},\n" + "/*Argument 2\n" + " */ {\n" + " 'Value2': '2'\n" + "});", # expected "test(\n" + " /*Argument 1*/\n" + " {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") bt( "test( /*Argument 1*/\n" + "{\n" + " 'Value1': '1'\n" + "}, /*Argument 2\n" + " */\n" + "{\n" + " 'Value2': '2'\n" + "});", # expected "test( /*Argument 1*/ {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") self.options.brace_style = "end-expand"; bt('//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}') bt('if(1){2}else{3}', "if (1) {\n 2\n}\nelse {\n 3\n}") bt('try{a();}catch(b){c();}catch(d){}finally{e();}', "try {\n a();\n}\ncatch (b) {\n c();\n}\ncatch (d) {}\nfinally {\n e();\n}") bt('if(a){b();}else if(c) foo();', "if (a) {\n b();\n}\nelse if (c) foo();") bt("if (a) {\n// comment\n}else{\n// comment\n}", "if (a) {\n // comment\n}\nelse {\n // comment\n}") # if/else statement with empty body bt('if (x) {y} else { if (x) {y}}', 'if (x) {\n y\n}\nelse {\n if (x) {\n y\n }\n}') bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a) {\n b;\n}\nelse {\n c;\n}') test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}', ' /*\n * xx\n */\n // xx\n if (foo) {\n bar();\n }') bt('if (foo) {}\nelse /regex/.test();') test_fragment('if (foo) {', 'if (foo) {') test_fragment('foo {', 'foo {') test_fragment('return {', 'return {') # return needs the brace. test_fragment('return /* inline */ {', 'return /* inline */ {') test_fragment('return;\n{', 'return; {') bt("throw {}") bt("throw {\n foo;\n}") bt('var foo = {}') bt('function x() {\n foo();\n}zzz', 'function x() {\n foo();\n}\nzzz') test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx') bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}') bt('var a = new function() {};') bt('var a = new function a() {};') bt('var a = new function()\n{};', 'var a = new function() {};') bt('var a = new function a()\n{};', 'var a = new function a() {};') bt('var a = new function a()\n {},\n b = new function b()\n {};', 'var a = new function a() {},\n b = new function b() {};') bt("foo({\n 'a': 1\n},\n10);", "foo({\n 'a': 1\n },\n 10);") bt('(["foo","bar"]).each(function(i) {return i;});', '(["foo", "bar"]).each(function(i) {\n return i;\n});') bt('(function(i) {return i;})();', '(function(i) {\n return i;\n})();') bt( "test( /*Argument 1*/ {\n" + " 'Value1': '1'\n" + "}, /*Argument 2\n" + " */ {\n" + " 'Value2': '2'\n" + "});", # expected "test( /*Argument 1*/ {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") bt( "test(\n" + "/*Argument 1*/ {\n" + " 'Value1': '1'\n" + "},\n" + "/*Argument 2\n" + " */ {\n" + " 'Value2': '2'\n" + "});", # expected "test(\n" + " /*Argument 1*/\n" + " {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") bt( "test( /*Argument 1*/\n" + "{\n" + " 'Value1': '1'\n" + "}, /*Argument 2\n" + " */\n" + "{\n" + " 'Value2': '2'\n" + "});", # expected "test( /*Argument 1*/ {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") self.options.brace_style = 'none'; bt('//case 1\nif (a == 1)\n{}\n//case 2\nelse if (a == 2)\n{}') bt('if(1){2}else{3}', "if (1) {\n 2\n} else {\n 3\n}") bt('try{a();}catch(b){c();}catch(d){}finally{e();}', "try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}") bt('if(a){b();}else if(c) foo();', "if (a) {\n b();\n} else if (c) foo();") bt("if (a) {\n// comment\n}else{\n// comment\n}", "if (a) {\n // comment\n} else {\n // comment\n}") # if/else statement with empty body bt('if (x) {y} else { if (x) {y}}', 'if (x) {\n y\n} else {\n if (x) {\n y\n }\n}') bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a)\n{\n b;\n}\nelse\n{\n c;\n}') test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}', ' /*\n * xx\n */\n // xx\n if (foo) {\n bar();\n }') bt('if (foo)\n{}\nelse /regex/.test();') test_fragment('if (foo) {') test_fragment('foo {') test_fragment('return {') # return needs the brace. test_fragment('return /* inline */ {') test_fragment('return;\n{') bt("throw {}") bt("throw {\n foo;\n}") bt('var foo = {}') bt('function x() {\n foo();\n}zzz', 'function x() {\n foo();\n}\nzzz') test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx') bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}') bt('var a = new function() {};') bt('var a = new function a() {};') bt('var a = new function()\n{};', 'var a = new function() {};') bt('var a = new function a()\n{};') bt('var a = new function a()\n {},\n b = new function b()\n {};') bt("foo({\n 'a': 1\n},\n10);", "foo({\n 'a': 1\n },\n 10);") bt('(["foo","bar"]).each(function(i) {return i;});', '(["foo", "bar"]).each(function(i) {\n return i;\n});') bt('(function(i) {return i;})();', '(function(i) {\n return i;\n})();') bt( "test( /*Argument 1*/ {\n" + " 'Value1': '1'\n" + "}, /*Argument 2\n" + " */ {\n" + " 'Value2': '2'\n" + "});", # expected "test( /*Argument 1*/ {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") bt( "test(\n" + "/*Argument 1*/ {\n" + " 'Value1': '1'\n" + "},\n" + "/*Argument 2\n" + " */ {\n" + " 'Value2': '2'\n" + "});", # expected "test(\n" + " /*Argument 1*/\n" + " {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") bt( "test( /*Argument 1*/\n" + "{\n" + " 'Value1': '1'\n" + "}, /*Argument 2\n" + " */\n" + "{\n" + " 'Value2': '2'\n" + "});", # expected "test( /*Argument 1*/\n" + " {\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });") # END tests for brace position self.options.brace_style = 'collapse'; test_fragment('roo = {\n /*\n ****\n FOO\n ****\n */\n BAR: 0\n};') test_fragment("if (zz) {\n // ....\n}\n(function") self.options.preserve_newlines = True; bt('var a = 42; // foo\n\nvar b;') bt('var a = 42; // foo\n\n\nvar b;') bt("var a = 'foo' +\n 'bar';") bt("var a = \"foo\" +\n \"bar\";") bt('"foo""bar""baz"', '"foo"\n"bar"\n"baz"') bt("'foo''bar''baz'", "'foo'\n'bar'\n'baz'") bt("{\n get foo() {}\n}") bt("{\n var a = get\n foo();\n}") bt("{\n set foo() {}\n}") bt("{\n var a = set\n foo();\n}") bt("var x = {\n get function()\n}") bt("var x = {\n set function()\n}") # According to my current research get/set have no special meaning outside of an object literal bt("var x = set\n\na() {}", "var x = set\n\na() {}") bt("var x = set\n\nfunction() {}", "var x = set\n\nfunction() {}") bt('') bt(' bt('for () /abc/.test()') bt('if (k) /aaa/m.test(v) && l();') bt('switch (true) {\n case /swf/i.test(foo):\n bar();\n}') bt('createdAt = {\n type: Date,\n default: Date.now\n}') bt('switch (createdAt) {\n case a:\n Date,\n default:\n Date.now\n}') bt('return function();') bt('var a = function();') bt('var a = 5 + function();') bt('{\n foo // something\n ,\n bar // something\n baz\n}') bt('function a(a) {} function b(b) {} function c(c) {}', 'function a(a) {}\n\nfunction b(b) {}\n\nfunction c(c) {}') bt('3.*7;', '3. * 7;') bt('a = 1.e-64 * 0.5e+4 / 6e-23;') bt('import foo.*;', 'import foo.*;') # actionscript's import test_fragment('function f(a: a, b: b)') # actionscript bt('foo(a, function() {})') bt('foo(a, /regex/)') bt('/* foo */\n"x"') self.options.break_chained_methods = False self.options.preserve_newlines = False bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo.bar().baz().cucumber(fat)') bt('foo\n.bar()\n.baz().cucumber(fat); foo.bar().baz().cucumber(fat)', 'foo.bar().baz().cucumber(fat);\nfoo.bar().baz().cucumber(fat)') bt('foo\n.bar()\n.baz().cucumber(fat)\n foo.bar().baz().cucumber(fat)', 'foo.bar().baz().cucumber(fat)\nfoo.bar().baz().cucumber(fat)') bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this.something = foo.bar().baz().cucumber(fat)') bt('this.something.xxx = foo.moo.bar()') bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this.something.xxx = foo.moo.bar()') self.options.break_chained_methods = False self.options.preserve_newlines = True bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo\n .bar()\n .baz().cucumber(fat)') 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)') 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)') bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this\n .something = foo.bar()\n .baz().cucumber(fat)') bt('this.something.xxx = foo.moo.bar()') bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this\n .something\n .xxx = foo.moo\n .bar()') self.options.break_chained_methods = True self.options.preserve_newlines = False bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo.bar()\n .baz()\n .cucumber(fat)') 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)') 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)') bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this.something = foo.bar()\n .baz()\n .cucumber(fat)') bt('this.something.xxx = foo.moo.bar()') bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this.something.xxx = foo.moo.bar()') self.options.break_chained_methods = True self.options.preserve_newlines = True bt('foo\n.bar()\n.baz().cucumber(fat)', 'foo\n .bar()\n .baz()\n .cucumber(fat)') 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)') 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)') bt('this\n.something = foo.bar()\n.baz().cucumber(fat)', 'this\n .something = foo.bar()\n .baz()\n .cucumber(fat)') bt('this.something.xxx = foo.moo.bar()') bt('this\n.something\n.xxx = foo.moo\n.bar()', 'this\n .something\n .xxx = foo.moo\n .bar()') self.options.break_chained_methods = False self.options.preserve_newlines = False # Line wrap test intputs #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 wrap_input_1=('foo.bar().baz().cucumber((fat && "sassy") || (leans\n&& mean));\n' + 'Test_very_long_variable_name_this_should_never_wrap\n.but_this_can\n' + 'if (wraps_can_occur && inside_an_if_block) that_is_\n.okay();\n' + 'object_literal = {\n' + ' propertx: first_token + 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap + but_this_can,\n' + ' propertz: first_token_should_never_wrap + !but_this_can,\n' + ' proper: "first_token_should_never_wrap" + "but_this_can"\n' + '}') #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 wrap_input_2=('{\n' + ' foo.bar().baz().cucumber((fat && "sassy") || (leans\n&& mean));\n' + ' Test_very_long_variable_name_this_should_never_wrap\n.but_this_can\n' + ' if (wraps_can_occur && inside_an_if_block) that_is_\n.okay();\n' + ' object_literal = {\n' + ' propertx: first_token + 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap + but_this_can,\n' + ' propertz: first_token_should_never_wrap + !but_this_can,\n' + ' proper: "first_token_should_never_wrap" + "but_this_can"\n' + ' }' + '}') self.options.preserve_newlines = False self.options.wrap_line_length = 0 #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 test_fragment(wrap_input_1, # expected # 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' + 'Test_very_long_variable_name_this_should_never_wrap.but_this_can\n' + 'if (wraps_can_occur && inside_an_if_block) that_is_.okay();\n' + 'object_literal = {\n' + ' propertx: first_token + 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap + but_this_can,\n' + ' propertz: first_token_should_never_wrap + !but_this_can,\n' + ' proper: "first_token_should_never_wrap" + "but_this_can"\n' + '}') self.options.wrap_line_length = 70 #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 test_fragment(wrap_input_1, # expected # 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' + 'Test_very_long_variable_name_this_should_never_wrap.but_this_can\n' + 'if (wraps_can_occur && inside_an_if_block) that_is_.okay();\n' + 'object_literal = {\n' + ' propertx: first_token + 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap + but_this_can,\n' + ' propertz: first_token_should_never_wrap + !but_this_can,\n' + ' proper: "first_token_should_never_wrap" + "but_this_can"\n' + '}') self.options.wrap_line_length = 40 #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 test_fragment(wrap_input_1, # expected # 'foo.bar().baz().cucumber((fat &&\n' + ' "sassy") || (leans && mean));\n' + 'Test_very_long_variable_name_this_should_never_wrap\n' + ' .but_this_can\n' + 'if (wraps_can_occur &&\n' + ' inside_an_if_block) that_is_.okay();\n' + 'object_literal = {\n' + ' propertx: first_token +\n' + ' 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap +\n' + ' but_this_can,\n' + ' propertz: first_token_should_never_wrap +\n' + ' !but_this_can,\n' + ' proper: "first_token_should_never_wrap" +\n' + ' "but_this_can"\n' + '}') self.options.wrap_line_length = 41 # NOTE: wrap is only best effort - line continues until next wrap point is found. #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 test_fragment(wrap_input_1, # expected # 'foo.bar().baz().cucumber((fat && "sassy") ||\n' + ' (leans && mean));\n' + 'Test_very_long_variable_name_this_should_never_wrap\n' + ' .but_this_can\n' + 'if (wraps_can_occur &&\n' + ' inside_an_if_block) that_is_.okay();\n' + 'object_literal = {\n' + ' propertx: first_token +\n' + ' 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap +\n' + ' but_this_can,\n' + ' propertz: first_token_should_never_wrap +\n' + ' !but_this_can,\n' + ' proper: "first_token_should_never_wrap" +\n' + ' "but_this_can"\n' + '}') self.options.wrap_line_length = 45 # NOTE: wrap is only best effort - line continues until next wrap point is found. #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 test_fragment(wrap_input_2, # expected # '{\n' + ' foo.bar().baz().cucumber((fat && "sassy") ||\n' + ' (leans && mean));\n' + ' Test_very_long_variable_name_this_should_never_wrap\n' + ' .but_this_can\n' + ' if (wraps_can_occur &&\n' + ' inside_an_if_block) that_is_.okay();\n' + ' object_literal = {\n' + ' propertx: first_token +\n' + ' 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap +\n' + ' but_this_can,\n' + ' propertz: first_token_should_never_wrap +\n' + ' !but_this_can,\n' + ' proper: "first_token_should_never_wrap" +\n' + ' "but_this_can"\n' + ' }\n'+ '}') self.options.preserve_newlines = True self.options.wrap_line_length = 0 #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 test_fragment(wrap_input_1, # expected # 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' + 'Test_very_long_variable_name_this_should_never_wrap\n' + ' .but_this_can\n' + 'if (wraps_can_occur && inside_an_if_block) that_is_\n' + ' .okay();\n' + 'object_literal = {\n' + ' propertx: first_token + 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap + but_this_can,\n' + ' propertz: first_token_should_never_wrap + !but_this_can,\n' + ' proper: "first_token_should_never_wrap" + "but_this_can"\n' + '}') self.options.wrap_line_length = 70 #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 test_fragment(wrap_input_1, # expected # 'foo.bar().baz().cucumber((fat && "sassy") || (leans && mean));\n' + 'Test_very_long_variable_name_this_should_never_wrap\n' + ' .but_this_can\n' + 'if (wraps_can_occur && inside_an_if_block) that_is_\n' + ' .okay();\n' + 'object_literal = {\n' + ' propertx: first_token + 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap + but_this_can,\n' + ' propertz: first_token_should_never_wrap + !but_this_can,\n' + ' proper: "first_token_should_never_wrap" + "but_this_can"\n' + '}') self.options.wrap_line_length = 40 #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 test_fragment(wrap_input_1, # expected # 'foo.bar().baz().cucumber((fat &&\n' + ' "sassy") || (leans && mean));\n' + 'Test_very_long_variable_name_this_should_never_wrap\n' + ' .but_this_can\n' + 'if (wraps_can_occur &&\n' + ' inside_an_if_block) that_is_\n' + ' .okay();\n' + 'object_literal = {\n' + ' propertx: first_token +\n' + ' 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap +\n' + ' but_this_can,\n' + ' propertz: first_token_should_never_wrap +\n' + ' !but_this_can,\n' + ' proper: "first_token_should_never_wrap" +\n' + ' "but_this_can"\n' + '}') self.options.wrap_line_length = 41 # NOTE: wrap is only best effort - line continues until next wrap point is found. #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 test_fragment(wrap_input_1, # expected # 'foo.bar().baz().cucumber((fat && "sassy") ||\n' + ' (leans && mean));\n' + 'Test_very_long_variable_name_this_should_never_wrap\n' + ' .but_this_can\n' + 'if (wraps_can_occur &&\n' + ' inside_an_if_block) that_is_\n' + ' .okay();\n' + 'object_literal = {\n' + ' propertx: first_token +\n' + ' 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap +\n' + ' but_this_can,\n' + ' propertz: first_token_should_never_wrap +\n' + ' !but_this_can,\n' + ' proper: "first_token_should_never_wrap" +\n' + ' "but_this_can"\n' + '}') self.options.wrap_line_length = 45 # NOTE: wrap is only best effort - line continues until next wrap point is found. #..............---------1---------2---------3---------4---------5---------6---------7 #..............1234567890123456789012345678901234567890123456789012345678901234567890 test_fragment(wrap_input_2, # expected # '{\n' + ' foo.bar().baz().cucumber((fat && "sassy") ||\n' + ' (leans && mean));\n' + ' Test_very_long_variable_name_this_should_never_wrap\n' + ' .but_this_can\n' + ' if (wraps_can_occur &&\n' + ' inside_an_if_block) that_is_\n' + ' .okay();\n' + ' object_literal = {\n' + ' propertx: first_token +\n' + ' 12345678.99999E-6,\n' + ' property: first_token_should_never_wrap +\n' + ' but_this_can,\n' + ' propertz: first_token_should_never_wrap +\n' + ' !but_this_can,\n' + ' proper: "first_token_should_never_wrap" +\n' + ' "but_this_can"\n' + ' }\n'+ '}') self.options.wrap_line_length = 0 self.options.preserve_newlines = False bt('if (foo) // comment\n bar();') bt('if (foo) // comment\n (bar());') bt('if (foo) // comment\n (bar());') bt('if (foo) // comment\n /asdf/;') bt('this.oa = new OAuth(\n' + ' _requestToken,\n' + ' _accessToken,\n' + ' consumer_key\n' + ');', 'this.oa = new OAuth(_requestToken, _accessToken, consumer_key);') bt('foo = {\n x: y, // #44\n w: z // #44\n}') bt('switch (x) {\n case "a":\n // comment on newline\n break;\n case "b": // comment on same line\n break;\n}') bt('this.type =\n this.options =\n // comment\n this.enabled null;', 'this.type = this.options =\n // comment\n this.enabled null;') bt('someObj\n .someFunc1()\n // This comment should not break the indent\n .someFunc2();', 'someObj.someFunc1()\n // This comment should not break the indent\n .someFunc2();') bt('if (true ||\n!true) return;', 'if (true || !true) return;') # these aren't ready yet. #bt('if (foo) // comment\n bar() /*i*/ + baz() /*j\n*/ + asdf();') bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\na();', 'if (foo)\n if (bar)\n if (baz) whee();\na();') bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\nelse\na();', 'if (foo)\n if (bar)\n if (baz) whee();\n else a();') bt('if (foo)\nbar();\nelse\ncar();', 'if (foo) bar();\nelse car();') bt('if (foo) if (bar) if (baz);\na();', 'if (foo)\n if (bar)\n if (baz);\na();') bt('if (foo) if (bar) if (baz) whee();\na();', 'if (foo)\n if (bar)\n if (baz) whee();\na();') bt('if (foo) a()\nif (bar) if (baz) whee();\na();', 'if (foo) a()\nif (bar)\n if (baz) whee();\na();') bt('if (foo);\nif (bar) if (baz) whee();\na();', 'if (foo);\nif (bar)\n if (baz) whee();\na();') bt('if (options)\n' + ' for (var p in options)\n' + ' this[p] = options[p];', 'if (options)\n'+ ' for (var p in options) this[p] = options[p];') bt('if (options) for (var p in options) this[p] = options[p];', 'if (options)\n for (var p in options) this[p] = options[p];') bt('if (options) do q(); while (b());', 'if (options)\n do q(); while (b());') bt('if (options) while (b()) q();', 'if (options)\n while (b()) q();') bt('if (options) do while (b()) q(); while (a());', 'if (options)\n do\n while (b()) q(); while (a());') bt('function f(a, b, c,\nd, e) {}', 'function f(a, b, c, d, e) {}') bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}', 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}') bt('function f(a,b) {if(a) b()}\n\n\n\nfunction g(a,b) {if(!a) b()}', 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}') # This is not valid syntax, but still want to behave reasonably and not side-effect bt('(if(a) b())(if(a) b())', '(\n if (a) b())(\n if (a) b())') bt('(if(a) b())\n\n\n(if(a) b())', '(\n if (a) b())\n(\n if (a) b())') # space between functions bt('/*\n * foo\n */\nfunction foo() {}') bt('// a nice function\nfunction foo() {}') bt('function foo() {}\nfunction foo() {}', 'function foo() {}\n\nfunction foo() {}' ) bt('[\n function() {}\n]') bt("if\n(a)\nb();", "if (a) b();") bt('var a =\nfoo', 'var a = foo') bt('var a = {\n"a":1,\n"b":2}', "var a = {\n \"a\": 1,\n \"b\": 2\n}") bt("var a = {\n'a':1,\n'b':2}", "var a = {\n 'a': 1,\n 'b': 2\n}") bt('var a = /*i*/ "b";') bt('var a = /*i*/\n"b";', 'var a = /*i*/ "b";') bt('var a = /*i*/\nb;', 'var a = /*i*/ b;') bt('{\n\n\n"x"\n}', '{\n "x"\n}') bt('if(a &&\nb\n||\nc\n||d\n&&\ne) e = f', 'if (a && b || c || d && e) e = f') bt('if(a &&\n(b\n||\nc\n||d)\n&&\ne) e = f', 'if (a && (b || c || d) && e) e = f') test_fragment('\n\n"x"', '"x"') 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;', 'a = 1;\nb = 2;') self.options.preserve_newlines = True bt('if (foo) // comment\n bar();') bt('if (foo) // comment\n (bar());') bt('if (foo) // comment\n (bar());') bt('if (foo) // comment\n /asdf/;') bt('this.oa = new OAuth(\n' + ' _requestToken,\n' + ' _accessToken,\n' + ' consumer_key\n' + ');') bt('foo = {\n x: y, // #44\n w: z // #44\n}') bt('switch (x) {\n case "a":\n // comment on newline\n break;\n case "b": // comment on same line\n break;\n}') bt('this.type =\n this.options =\n // comment\n this.enabled null;') bt('someObj\n .someFunc1()\n // This comment should not break the indent\n .someFunc2();') bt('if (true ||\n!true) return;', 'if (true ||\n !true) return;') # these aren't ready yet. # bt('if (foo) // comment\n bar() /*i*/ + baz() /*j\n*/ + asdf();') bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\na();', 'if (foo)\n if (bar)\n if (baz)\n whee();\na();') bt('if\n(foo)\nif\n(bar)\nif\n(baz)\nwhee();\nelse\na();', 'if (foo)\n if (bar)\n if (baz)\n whee();\n else\n a();') bt('if (foo) bar();\nelse\ncar();', 'if (foo) bar();\nelse\n car();') bt('if (foo) if (bar) if (baz);\na();', 'if (foo)\n if (bar)\n if (baz);\na();') bt('if (foo) if (bar) if (baz) whee();\na();', 'if (foo)\n if (bar)\n if (baz) whee();\na();') bt('if (foo) a()\nif (bar) if (baz) whee();\na();', 'if (foo) a()\nif (bar)\n if (baz) whee();\na();') bt('if (foo);\nif (bar) if (baz) whee();\na();', 'if (foo);\nif (bar)\n if (baz) whee();\na();') bt('if (options)\n' + ' for (var p in options)\n' + ' this[p] = options[p];') bt('if (options) for (var p in options) this[p] = options[p];', 'if (options)\n for (var p in options) this[p] = options[p];') bt('if (options) do q(); while (b());', 'if (options)\n do q(); while (b());') bt('if (options) do; while (b());', 'if (options)\n do; while (b());') bt('if (options) while (b()) q();', 'if (options)\n while (b()) q();') bt('if (options) do while (b()) q(); while (a());', 'if (options)\n do\n while (b()) q(); while (a());') bt('function f(a, b, c,\nd, e) {}', 'function f(a, b, c,\n d, e) {}') bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}', 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}') bt('function f(a,b) {if(a) b()}\n\n\n\nfunction g(a,b) {if(!a) b()}', 'function f(a, b) {\n if (a) b()\n}\n\n\n\nfunction g(a, b) {\n if (!a) b()\n}') # This is not valid syntax, but still want to behave reasonably and not side-effect bt('(if(a) b())(if(a) b())', '(\n if (a) b())(\n if (a) b())') bt('(if(a) b())\n\n\n(if(a) b())', '(\n if (a) b())\n\n\n(\n if (a) b())') bt("if\n(a)\nb();", "if (a)\n b();") bt('var a =\nfoo', 'var a =\n foo') bt('var a = {\n"a":1,\n"b":2}', "var a = {\n \"a\": 1,\n \"b\": 2\n}") bt("var a = {\n'a':1,\n'b':2}", "var a = {\n 'a': 1,\n 'b': 2\n}") bt('var a = /*i*/ "b";') bt('var a = /*i*/\n"b";', 'var a = /*i*/\n "b";') bt('var a = /*i*/\nb;', 'var a = /*i*/\n b;') bt('{\n\n\n"x"\n}', '{\n\n\n "x"\n}') bt('if(a &&\nb\n||\nc\n||d\n&&\ne) e = f', 'if (a &&\n b ||\n c || d &&\n e) e = f') bt('if(a &&\n(b\n||\nc\n||d)\n&&\ne) e = f', 'if (a &&\n (b ||\n c || d) &&\n e) e = f') test_fragment('\n\n"x"', '"x"') # this beavior differs between js and python, defaults to unlimited in js, 10 in python 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;', 'a = 1;\n\n\n\n\n\n\n\n\n\nb = 2;') self.options.max_preserve_newlines = 8; 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;', 'a = 1;\n\n\n\n\n\n\n\nb = 2;') # Test the option to have spaces within parens self.options.space_in_paren = False self.options.space_in_empty_paren = False bt('if(p) foo(a,b)', 'if (p) foo(a, b)') bt('try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }', 'try {\n while (true) {\n willThrow()\n }\n} catch (result) switch (result) {\n case 1:\n ++result\n}') bt('((e/((a+(b)*c)-d))^2)*5;', '((e / ((a + (b) * c) - d)) ^ 2) * 5;') bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}', 'function f(a, b) {\n if (a) b()\n}\n\nfunction g(a, b) {\n if (!a) b()\n}') bt('a=[];', 'a = [];') bt('a=[b,c,d];', 'a = [b, c, d];') bt('a= f[b];', 'a = f[b];') self.options.space_in_paren = True bt('if(p) foo(a,b)', 'if ( p ) foo( a, b )') bt('try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }', 'try {\n while ( true ) {\n willThrow()\n }\n} catch ( result ) switch ( result ) {\n case 1:\n ++result\n}') bt('((e/((a+(b)*c)-d))^2)*5;', '( ( e / ( ( a + ( b ) * c ) - d ) ) ^ 2 ) * 5;') bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}', 'function f( a, b ) {\n if ( a ) b()\n}\n\nfunction g( a, b ) {\n if ( !a ) b()\n}') bt('a=[ ];', 'a = [];') bt('a=[b,c,d];', 'a = [ b, c, d ];') bt('a= f[b];', 'a = f[ b ];') self.options.space_in_empty_paren = True bt('if(p) foo(a,b)', 'if ( p ) foo( a, b )') bt('try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }', 'try {\n while ( true ) {\n willThrow( )\n }\n} catch ( result ) switch ( result ) {\n case 1:\n ++result\n}') bt('((e/((a+(b)*c)-d))^2)*5;', '( ( e / ( ( a + ( b ) * c ) - d ) ) ^ 2 ) * 5;') bt('function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}', 'function f( a, b ) {\n if ( a ) b( )\n}\n\nfunction g( a, b ) {\n if ( !a ) b( )\n}') bt('a=[ ];', 'a = [ ];') bt('a=[b,c,d];', 'a = [ b, c, d ];') bt('a= f[b];', 'a = f[ b ];') self.options.space_in_paren = False self.options.space_in_empty_paren = False # Test template strings bt('`This is a ${template} string.`', '`This is a ${template} string.`') bt('`This\n is\n a\n ${template}\n string.`', '`This\n is\n a\n ${template}\n string.`') bt('a = `This is a continuation\\\nstring.`', 'a = `This is a continuation\\\nstring.`'); bt('a = "This is a continuation\\\nstring."', 'a = "This is a continuation\\\nstring."'); def decodesto(self, input, expectation=None): if expectation == None: expectation = input self.assertMultiLineEqual( jsbeautifier.beautify(input, self.options), expectation) # if the expected is different from input, run it again # expected output should be unchanged when run twice. if not expectation == None: self.assertMultiLineEqual( jsbeautifier.beautify(expectation, self.options), expectation) # Everywhere we do newlines, they should be replaced with opts.eol self.options.eol = '\r\\n'; expectation = expectation.replace('\n', '\r\n') self.assertMultiLineEqual( jsbeautifier.beautify(input, self.options), expectation) input = input.replace('\n', '\r\n') self.assertMultiLineEqual( jsbeautifier.beautify(input, self.options), expectation) self.options.eol = '\n' def wrap(self, text): return self.wrapregex.sub(' \\1', text) def bt(self, input, expectation=None): if expectation == None: expectation = input self.decodesto(input, expectation) # If we set raw, input should be unchanged self.options.test_output_raw = True if self.options.end_with_newline: elf.decodesto(input, input) self.options.test_output_raw = False if self.options.indent_size == 4 and input: wrapped_input = '{\n%s\n foo = bar;\n}' % self.wrap(input) wrapped_expect = '{\n%s\n foo = bar;\n}' % self.wrap(expectation) self.decodesto(wrapped_input, wrapped_expect) # If we set raw, input should be unchanged self.options.test_output_raw = True if self.options.end_with_newline: elf.decodesto(wrapped_input, wrapped_input) self.options.test_output_raw = False @classmethod def setUpClass(cls): options = jsbeautifier.default_options() options.indent_size = 4 options.indent_char = ' ' options.preserve_newlines = True options.jslint_happy = False options.keep_array_indentation = False options.brace_style = 'collapse' options.indent_level = 0 options.break_chained_methods = False options.eol = '\n' cls.options = options cls.wrapregex = re.compile('^(.+)$', re.MULTILINE) if __name__ == '__main__': unittest.main()