/*global js_beautify: true */ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_beautify) { var opts = { indent_size: 4, indent_char: ' ', preserve_newlines: true, jslint_happy: false, keep_array_indentation: false, brace_style: 'collapse', space_before_conditional: true, break_chained_methods: false, selector_separator: '\n', end_with_newline: false }; function test_js_beautifier(input) { return js_beautify(input, opts); } function test_html_beautifier(input) { return html_beautify(input, opts); } var sanitytest; // test the input on beautifier with the current flag settings // does not check the indentation / surroundings as bt() does function test_fragment(input, expected) { expected = expected || expected === '' ? expected : input; sanitytest.expect(input, expected); // if the expected is different from input, run it again // expected output should be unchanged when run twice. if (expected !== input) { sanitytest.expect(expected, expected); } // Everywhere we do newlines, they should be replaced with opts.eol opts.eol = '\r\\n'; expected = expected.replace(/[\n]/g, '\r\n'); sanitytest.expect(input, expected); input = input.replace(/[\n]/g, '\r\n'); sanitytest.expect(input, expected); opts.eol = '\n'; } // test the input on beautifier with the current flag settings // test both the input as well as { input } wrapping function bt(input, expectation) { var wrapped_input, wrapped_expectation; expectation = expectation || expectation === '' ? expectation : input; sanitytest.test_function(test_js_beautifier, 'js_beautify'); test_fragment(input, expectation); // If we set raw, input should be unchanged opts.test_output_raw = true; if (!opts.end_with_newline) { test_fragment(input, input); } opts.test_output_raw = false; // test also the returned indentation // e.g if input = "asdf();" // then test that this remains properly formatted as well: // { // asdf(); // indent; // } if (opts.indent_size === 4 && input) { wrapped_input = '{\n' + input.replace(/^(.+)$/mg, ' $1') + '\n foo = bar;\n}'; wrapped_expectation = '{\n' + expectation.replace(/^(.+)$/mg, ' $1') + '\n foo = bar;\n}'; test_fragment(wrapped_input, wrapped_expectation); // If we set raw, input should be unchanged opts.test_output_raw = true; if (!opts.end_with_newline) { test_fragment(wrapped_input, wrapped_input); } opts.test_output_raw = false; } } // run all tests for the given brace style ("collapse", "expand", "end-expand", or "none"). // uses various whitespace combinations before and after opening and closing braces, // respectively, for most of the tests' inputs. function beautify_brace_tests(brace_style) { var ex_brace_style = opts.brace_style, indent_on_wrap_str = ' '; // could use Array(opts.indent_size + 1).join(' '); if we wanted to replace _all_ of the hardcoded 4-space in the test and expectation strings function permute_brace_tests(expect_open_white, expect_close_white) { // run the tests that need permutation against a specific combination of // pre-opening-brace and pre-closing-brace whitespace function run_brace_permutation(test_open_white, test_close_white) { var to = test_open_white, tc = test_close_white, eo = expect_open_white ? expect_open_white : to === '' ? ' ' : to, ec = expect_close_white ? expect_close_white : tc === '' ? ' ' : tc, i = eo === '\n' ? indent_on_wrap_str: ''; bt( '//case 1\nif (a == 1)' + to + '{}\n//case 2\nelse if (a == 2)' + to + '{}', '//case 1\nif (a == 1)' + eo + '{}\n//case 2\nelse if (a == 2)' + eo + '{}'); bt( 'if(1)' + to + '{2}' + tc + 'else' + to + '{3}', 'if (1)' + eo + '{\n 2\n}' + ec + 'else' + eo + '{\n 3\n}'); bt( 'try' + to + '{a();}' + tc + 'catch(b)' + to + '{c();}' + tc + 'catch(d)' + to + '{}' + tc + 'finally' + to + '{e();}', // expected 'try' + eo + '{\n a();\n}' + ec + 'catch (b)' + eo + '{\n c();\n}' + ec + 'catch (d)' + eo + '{}' + ec + 'finally' + eo + '{\n e();\n}'); bt( 'if(a)' + to + '{b();}' + tc + 'else if(c) foo();', 'if (a)' + eo + '{\n b();\n}' + ec + 'else if (c) foo();'); // if/else statement with empty body bt( 'if (a)' + to + '{\n// comment\n}' + tc + 'else' + to + '{\n// comment\n}', 'if (a)' + eo + '{\n // comment\n}' + ec + 'else' + eo + '{\n // comment\n}'); bt( 'if (x)' + to + '{y}' + tc + 'else' + to + '{ if (x)' + to + '{y}}', 'if (x)' + eo + '{\n y\n}' + ec + 'else' + eo + '{\n if (x)' + eo + i + '{\n y\n }\n}'); bt( 'if (a)' + to + '{\nb;\n}' + tc + 'else' + to + '{\nc;\n}', 'if (a)' + eo + '{\n b;\n}' + ec + 'else' + eo + '{\n c;\n}'); test_fragment(' /*\n* xx\n*/\n// xx\nif (foo)' + to + '{\n bar();\n}', ' /*\n * xx\n */\n // xx\n if (foo)' + eo + i + '{\n bar();\n }'); bt( 'if (foo)' + to + '{}' + tc + 'else /regex/.test();', 'if (foo)' + eo + '{}' + ec + 'else /regex/.test();'); test_fragment('if (foo)' + to + '{', 'if (foo)' + eo + '{'); test_fragment('foo' + to + '{', 'foo' + eo + '{'); test_fragment('return;' + to + '{', 'return;' + eo + '{'); bt( 'function x()' + to + '{\n foo();\n}zzz', 'function x()' + eo +'{\n foo();\n}\nzzz'); bt( 'var a = new function a()' + to + '{};', 'var a = new function a()' + eo + '{};'); bt( 'var a = new function a()' + to + ' {},\n b = new function b()' + to + ' {};', 'var a = new function a()' + eo + i + '{},\n b = new function b()' + eo + i + '{};'); bt("foo(" + to + "{\n 'a': 1\n},\n10);", "foo(" + (eo === ' ' ? '' : eo) + i + "{\n 'a': 1\n },\n 10);"); // "foo( {..." is a weird case bt('(["foo","bar"]).each(function(i)' + to + '{return i;});', '(["foo", "bar"]).each(function(i)' + eo + '{\n return i;\n});'); bt('(function(i)' + to + '{return i;})();', '(function(i)' + eo + '{\n return i;\n})();'); bt( "test( /*Argument 1*/" + to + "{\n" + " 'Value1': '1'\n" + "}, /*Argument 2\n" + " */ {\n" + " 'Value2': '2'\n" + "});", // expected "test( /*Argument 1*/" + eo + i + "{\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });"); bt( "test( /*Argument 1*/" + to + "{\n" + " 'Value1': '1'\n" + "}, /*Argument 2\n" + " */\n" + "{\n" + " 'Value2': '2'\n" + "});", // expected "test( /*Argument 1*/" + eo + i + "{\n" + " 'Value1': '1'\n" + " },\n" + " /*Argument 2\n" + " */\n" + " {\n" + " 'Value2': '2'\n" + " });"); } run_brace_permutation('\n', '\n'); run_brace_permutation('\n', ' '); run_brace_permutation(' ', ' '); run_brace_permutation(' ', '\n'); run_brace_permutation('',''); // brace tests that don't make sense to permutate test_fragment('return {'); // return needs the brace. test_fragment('return /* inline */ {'); bt('throw {}'); bt('throw {\n foo;\n}'); bt( 'var foo = {}'); 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()\n{};', 'var a = new function() {};'); 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" + " });"); } opts.brace_style = brace_style; switch(opts.brace_style) { case 'collapse': permute_brace_tests(' ', ' '); break; case 'expand': permute_brace_tests('\n', '\n'); break; case 'end-expand': permute_brace_tests(' ', '\n'); break; case 'none': permute_brace_tests(); break; } opts.brace_style = ex_brace_style; } function unicode_char(value) { return String.fromCharCode(value) } function beautifier_tests() { sanitytest = test_obj; {{#default_options}} opts.{{name}} = {{&value}}; {{/default_options}} {{#groups}}{{#set_mustache_tags}}.{{/set_mustache_tags}}{{^matrix}} // {{&name}} {{#options}} opts.{{name}} = {{&value}}; {{/options}} {{#tests}} {{#test_line}}.{{/test_line}}; {{/tests}} {{/matrix}}{{#matrix}} // {{&name}} - ({{#matrix_context_string}}.{{/matrix_context_string}}) {{#options}} opts.{{name}} = {{&value}}; {{/options}} {{#tests}} {{#test_line}}.{{/test_line}}; {{/tests}} {{/matrix}}{{#unset_mustache_tags}}.{{/unset_mustache_tags}} {{/groups}} opts.indent_size = 1; opts.indent_char = ' '; bt('{ one_char() }', "{\n one_char()\n}"); bt('var a,b=1,c=2', 'var a, b = 1,\n c = 2'); opts.indent_size = 4; opts.indent_char = ' '; bt('{ one_char() }', "{\n one_char()\n}"); opts.indent_size = 1; opts.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 opts.indent_size = 5; opts.indent_char = ' '; opts.indent_with_tabs = true; bt('{ one_char() }', "{\n\tone_char()\n}"); bt('x = a ? b : c; x;', 'x = a ? b : c;\nx;'); opts.indent_size = 4; opts.indent_char = ' '; opts.indent_with_tabs = false; opts.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}' ); opts.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}'); opts.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" + "}"); opts.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" + // "}"); opts.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}'); // tests for brace positioning beautify_brace_tests('expand'); beautify_brace_tests('collapse'); beautify_brace_tests('end-expand'); beautify_brace_tests('none'); bt('// func-comment\n\nfunction foo() {}\n\n// end-func-comment'); test_fragment('roo = {\n /*\n ****\n FOO\n ****\n */\n BAR: 0\n};'); bt('"foo""bar""baz"', '"foo"\n"bar"\n"baz"'); bt("'foo''bar''baz'", "'foo'\n'bar'\n'baz'"); test_fragment("if (zz) {\n // ....\n}\n(function"); 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}'); opts.space_before_conditional = false; bt('if(a) b()'); opts.space_before_conditional = true; opts.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('this.oa = new OAuth(\n' + ' _requestToken,\n' + ' _accessToken,\n' + ' consumer_key\n' + ');'); opts.unescape_strings = false; test_fragment('"\\x22\\x27", \'\\x22\\x27\', "\\x5c", \'\\x5c\', "\\xff and \\xzz", "unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"'); opts.unescape_strings = true; test_fragment('"\\x20\\x40\\x4a"', '" @J"'); test_fragment('"\\xff\\x40\\x4a"'); test_fragment('"\\u0072\\u016B\\u0137\\u012B\\u0074\\u0069\\u0073"', '"rūķītis"'); test_fragment('"Google Chrome est\\u00E1 actualizado."', '"Google Chrome está actualizado."'); /* bt('"\\x22\\x27",\'\\x22\\x27\',"\\x5c",\'\\x5c\',"\\xff and \\xzz","unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"', '"\\"\'", \'"\\\'\', "\\\\", \'\\\\\', "\\xff and \\xzz", "unicode \\u0000 \\" \' \\\\ \\uffff \\uzzzz"'); */ opts.unescape_strings = false; bt('return function();'); bt('var a = function();'); bt('var a = 5 + function();'); 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('{\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('foo(a, function() {})'); bt('foo(a, /regex/)'); bt('/* foo */\n"x"'); opts.break_chained_methods = false; opts.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()'); opts.break_chained_methods = false; opts.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()'); opts.break_chained_methods = true; opts.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()'); opts.break_chained_methods = true; opts.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()'); opts.break_chained_methods = 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' + ' }' + '}'); opts.preserve_newlines = false; opts.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' + '}'); opts.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' + '}'); opts.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' + '}'); opts.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' + '}'); opts.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'+ '}'); opts.preserve_newlines = true; opts.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' + '}'); opts.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' + '}'); opts.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' + '}'); opts.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' + '}'); opts.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'+ '}'); opts.wrap_line_length = 0; opts.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())'); 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;'); opts.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('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())'); // 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)\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\n\n\n\n\n\n\n\n\n\n\n\n\nb = 2;'); opts.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 opts.space_in_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];'); opts.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 ];'); opts.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 ];'); opts.space_in_empty_paren = false; opts.space_in_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."'); Urlencoded.run_tests(sanitytest); } beautifier_tests(); } if (typeof exports !== "undefined") { exports.run_javascript_tests = run_javascript_tests; }