diff options
Diffstat (limited to 'unittests/Format/FormatTestJS.cpp')
-rw-r--r-- | unittests/Format/FormatTestJS.cpp | 207 |
1 files changed, 184 insertions, 23 deletions
diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index 2819383a3585..6f494db71d15 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/unittests/Format/FormatTestJS.cpp @@ -135,6 +135,8 @@ TEST_F(FormatTestJS, ReservedWords) { verifyFormat("x.in() = 1;"); verifyFormat("x.let() = 1;"); verifyFormat("x.var() = 1;"); + verifyFormat("x.for() = 1;"); + verifyFormat("x.as() = 1;"); verifyFormat("x = {\n" " a: 12,\n" " interface: 1,\n" @@ -147,6 +149,21 @@ TEST_F(FormatTestJS, ReservedWords) { verifyFormat("x = interface instanceof y;"); } +TEST_F(FormatTestJS, ReservedWordsMethods) { + verifyFormat( + "class X {\n" + " delete() {\n" + " x();\n" + " }\n" + " interface() {\n" + " x();\n" + " }\n" + " let() {\n" + " x();\n" + " }\n" + "}\n"); +} + TEST_F(FormatTestJS, CppKeywords) { // Make sure we don't mess stuff up because of C++ keywords. verifyFormat("return operator && (aa);"); @@ -161,7 +178,11 @@ TEST_F(FormatTestJS, ES6DestructuringAssignment) { } TEST_F(FormatTestJS, ContainerLiterals) { - verifyFormat("var x = {y: function(a) { return a; }};"); + verifyFormat("var x = {\n" + " y: function(a) {\n" + " return a;\n" + " }\n" + "};"); verifyFormat("return {\n" " link: function() {\n" " f(); //\n" @@ -212,7 +233,11 @@ TEST_F(FormatTestJS, ContainerLiterals) { verifyFormat("x = foo && {a: 123};"); // Arrow functions in object literals. - verifyFormat("var x = {y: (a) => { return a; }};"); + verifyFormat("var x = {\n" + " y: (a) => {\n" + " return a;\n" + " }\n" + "};"); verifyFormat("var x = {y: (a) => a};"); // Computed keys. @@ -234,6 +259,13 @@ TEST_F(FormatTestJS, ContainerLiterals) { " b: b,\n" " 'c': c,\n" "};"); + + // Dict literals can skip the label names. + verifyFormat("var x = {\n" + " aaa,\n" + " aaa,\n" + " aaa,\n" + "};"); } TEST_F(FormatTestJS, MethodsInObjectLiterals) { @@ -324,13 +356,48 @@ TEST_F(FormatTestJS, FormatsNamespaces) { "}\n"); } +TEST_F(FormatTestJS, NamespacesMayNotWrap) { + verifyFormat("declare namespace foobarbaz {\n" + "}\n", getGoogleJSStyleWithColumns(18)); + verifyFormat("declare module foobarbaz {\n" + "}\n", getGoogleJSStyleWithColumns(15)); + verifyFormat("namespace foobarbaz {\n" + "}\n", getGoogleJSStyleWithColumns(10)); + verifyFormat("module foobarbaz {\n" + "}\n", getGoogleJSStyleWithColumns(7)); +} + +TEST_F(FormatTestJS, AmbientDeclarations) { + FormatStyle NineCols = getGoogleJSStyleWithColumns(9); + verifyFormat( + "declare class\n" + " X {}", + NineCols); + verifyFormat( + "declare function\n" + "x();", // TODO(martinprobst): should ideally be indented. + NineCols); + verifyFormat( + "declare enum X {\n" + "}", + NineCols); + verifyFormat( + "declare let\n" + " x: number;", + NineCols); +} + TEST_F(FormatTestJS, FormatsFreestandingFunctions) { verifyFormat("function outer1(a, b) {\n" - " function inner1(a, b) { return a; }\n" + " function inner1(a, b) {\n" + " return a;\n" + " }\n" " inner1(a, b);\n" "}\n" "function outer2(a, b) {\n" - " function inner2(a, b) { return a; }\n" + " function inner2(a, b) {\n" + " return a;\n" + " }\n" " inner2(a, b);\n" "}"); verifyFormat("function f() {}"); @@ -341,6 +408,8 @@ TEST_F(FormatTestJS, GeneratorFunctions) { " let x = 1;\n" " yield x;\n" " yield* something();\n" + " yield [1, 2];\n" + " yield {a: 1};\n" "}"); verifyFormat("function*\n" " f() {\n" @@ -350,8 +419,15 @@ TEST_F(FormatTestJS, GeneratorFunctions) { " yield 1;\n" "}\n"); verifyFormat("class X {\n" - " * generatorMethod() { yield x; }\n" + " * generatorMethod() {\n" + " yield x;\n" + " }\n" "}"); + verifyFormat("var x = {\n" + " a: function*() {\n" + " //\n" + " }\n" + "}\n"); } TEST_F(FormatTestJS, AsyncFunctions) { @@ -366,7 +442,9 @@ TEST_F(FormatTestJS, AsyncFunctions) { " return fetch(x);\n" "}"); verifyFormat("class X {\n" - " async asyncMethod() { return fetch(1); }\n" + " async asyncMethod() {\n" + " return fetch(1);\n" + " }\n" "}"); verifyFormat("function initialize() {\n" " // Comment.\n" @@ -423,8 +501,10 @@ TEST_F(FormatTestJS, ColumnLayoutForArrayLiterals) { } TEST_F(FormatTestJS, FunctionLiterals) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript); + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; verifyFormat("doFoo(function() {});"); - verifyFormat("doFoo(function() { return 1; });"); + verifyFormat("doFoo(function() { return 1; });", Style); verifyFormat("var func = function() {\n" " return 1;\n" "};"); @@ -438,7 +518,8 @@ TEST_F(FormatTestJS, FunctionLiterals) { " getAttribute: function(key) { return this[key]; },\n" " style: {direction: ''}\n" " }\n" - "};"); + "};", + Style); verifyFormat("abc = xyz ? function() {\n" " return 1;\n" "} : function() {\n" @@ -476,13 +557,6 @@ TEST_F(FormatTestJS, FunctionLiterals) { " // code\n" " });"); - verifyFormat("f({a: function() { return 1; }});", - getGoogleJSStyleWithColumns(33)); - verifyFormat("f({\n" - " a: function() { return 1; }\n" - "});", - getGoogleJSStyleWithColumns(32)); - verifyFormat("return {\n" " a: function SomeFunction() {\n" " // ...\n" @@ -510,6 +584,15 @@ TEST_F(FormatTestJS, FunctionLiterals) { " .doSomethingElse(\n" " // break\n" " );"); + + Style.ColumnLimit = 33; + verifyFormat("f({a: function() { return 1; }});", Style); + Style.ColumnLimit = 32; + verifyFormat("f({\n" + " a: function() { return 1; }\n" + "});", + Style); + } TEST_F(FormatTestJS, InliningFunctionLiterals) { @@ -570,6 +653,8 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) { } TEST_F(FormatTestJS, MultipleFunctionLiterals) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript); + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; verifyFormat("promise.then(\n" " function success() {\n" " doFoo();\n" @@ -606,7 +691,8 @@ TEST_F(FormatTestJS, MultipleFunctionLiterals) { " .thenCatch(function(error) {\n" " body();\n" " body();\n" - " });"); + " });", + Style); verifyFormat("getSomeLongPromise()\n" " .then(function(value) {\n" " body();\n" @@ -619,7 +705,8 @@ TEST_F(FormatTestJS, MultipleFunctionLiterals) { verifyFormat("getSomeLongPromise()\n" " .then(function(value) { body(); })\n" - " .thenCatch(function(error) { body(); });"); + " .thenCatch(function(error) { body(); });", + Style); verifyFormat("return [aaaaaaaaaaaaaaaaaaaaaa]\n" " .aaaaaaa(function() {\n" @@ -633,7 +720,9 @@ TEST_F(FormatTestJS, ArrowFunctions) { " return a;\n" "};"); verifyFormat("var x = (a) => {\n" - " function y() { return 42; }\n" + " function y() {\n" + " return 42;\n" + " }\n" " return a;\n" "};"); verifyFormat("var x = (a: type): {some: type} => {\n" @@ -686,7 +775,9 @@ TEST_F(FormatTestJS, WrapRespectsAutomaticSemicolonInsertion) { // would change due to automatic semicolon insertion. // See http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1. verifyFormat("return aaaaa;", getGoogleJSStyleWithColumns(10)); + verifyFormat("return /* hello! */ aaaaa;", getGoogleJSStyleWithColumns(10)); verifyFormat("continue aaaaa;", getGoogleJSStyleWithColumns(10)); + verifyFormat("continue /* hello! */ aaaaa;", getGoogleJSStyleWithColumns(10)); verifyFormat("break aaaaa;", getGoogleJSStyleWithColumns(10)); verifyFormat("throw aaaaa;", getGoogleJSStyleWithColumns(10)); verifyFormat("aaaaaaaaa++;", getGoogleJSStyleWithColumns(10)); @@ -745,6 +836,18 @@ TEST_F(FormatTestJS, AutomaticSemicolonInsertionHeuristic) { "String"); verifyFormat("function f(@Foo bar) {}", "function f(@Foo\n" " bar) {}"); + verifyFormat("a = true\n" + "return 1", + "a = true\n" + " return 1"); + verifyFormat("a = 's'\n" + "return 1", + "a = 's'\n" + " return 1"); + verifyFormat("a = null\n" + "return 1", + "a = null\n" + " return 1"); } TEST_F(FormatTestJS, ClosureStyleCasts) { @@ -899,8 +1002,16 @@ TEST_F(FormatTestJS, TypeAnnotations) { verifyFormat("((a: string, b: number): string => a + b);"); verifyFormat("var x: (y: number) => string;"); verifyFormat("var x: P<string, (a: number) => string>;"); - verifyFormat("var x = {y: function(): z { return 1; }};"); - verifyFormat("var x = {y: function(): {a: number} { return 1; }};"); + verifyFormat("var x = {\n" + " y: function(): z {\n" + " return 1;\n" + " }\n" + "};"); + verifyFormat("var x = {\n" + " y: function(): {a: number} {\n" + " return 1;\n" + " }\n" + "};"); verifyFormat("function someFunc(args: string[]):\n" " {longReturnValue: string[]} {}", getGoogleJSStyleWithColumns(60)); @@ -928,7 +1039,7 @@ TEST_F(FormatTestJS, ClassDeclarations) { verifyFormat("class C {\n ['x' + 2]: string = 12;\n}"); verifyFormat("class C {\n private x: string = 12;\n}"); verifyFormat("class C {\n private static x: string = 12;\n}"); - verifyFormat("class C {\n static x(): string { return 'asd'; }\n}"); + verifyFormat("class C {\n static x(): string {\n return 'asd';\n }\n}"); verifyFormat("class C extends P implements I {}"); verifyFormat("class C extends p.P implements i.I {}"); verifyFormat("class Test {\n" @@ -1091,7 +1202,9 @@ TEST_F(FormatTestJS, Modules) { verifyFormat("export default () => {};"); verifyFormat("export interface Foo { foo: number; }\n" "export class Bar {\n" - " blah(): string { return this.blah; };\n" + " blah(): string {\n" + " return this.blah;\n" + " };\n" "}"); } @@ -1122,7 +1235,7 @@ TEST_F(FormatTestJS, ImportWrapping) { TEST_F(FormatTestJS, TemplateStrings) { // Keeps any whitespace/indentation within the template string. verifyFormat("var x = `hello\n" - " ${ name }\n" + " ${name}\n" " !`;", "var x = `hello\n" " ${ name }\n" @@ -1206,6 +1319,27 @@ TEST_F(FormatTestJS, TemplateStrings) { "var y;", "var x = ` \\` a`;\n" "var y;"); + // Escaped dollar. + verifyFormat("var x = ` \\${foo}`;\n"); +} + +TEST_F(FormatTestJS, TemplateStringASI) { + verifyFormat("var x = `hello${world}`;", "var x = `hello${\n" + " world\n" + "}`;"); +} + +TEST_F(FormatTestJS, NestedTemplateStrings) { + verifyFormat( + "var x = `<ul>${xs.map(x => `<li>${x}</li>`).join('\\n')}</ul>`;"); + verifyFormat("var x = `he${({text: 'll'}.text)}o`;"); + + // Crashed at some point. + verifyFormat("}"); +} + +TEST_F(FormatTestJS, TaggedTemplateStrings) { + verifyFormat("var x = html`<ul>`;"); } TEST_F(FormatTestJS, CastSyntax) { @@ -1218,6 +1352,11 @@ TEST_F(FormatTestJS, CastSyntax) { " 1, //\n" " 2\n" "];"); + verifyFormat("var x = [{x: 1} as type];"); + verifyFormat("x = x as [a, b];"); + verifyFormat("x = x as {a: string};"); + verifyFormat("x = x as (string);"); + verifyFormat("x = x! as (string);"); } TEST_F(FormatTestJS, TypeArguments) { @@ -1318,6 +1457,21 @@ TEST_F(FormatTestJS, RequoteStringsSingle) { "let x = \"single\";\n"); } +TEST_F(FormatTestJS, RequoteAndIndent) { + verifyFormat("let x = someVeryLongFunctionThatGoesOnAndOn(\n" + " 'double quoted string that needs wrapping');", + "let x = someVeryLongFunctionThatGoesOnAndOn(" + "\"double quoted string that needs wrapping\");"); + + verifyFormat("let x =\n" + " 'foo\\'oo';\n" + "let x =\n" + " 'foo\\'oo';", + "let x=\"foo'oo\";\n" + "let x=\"foo'oo\";", + getGoogleJSStyleWithColumns(15)); +} + TEST_F(FormatTestJS, RequoteStringsDouble) { FormatStyle DoubleQuotes = getGoogleStyle(FormatStyle::LK_JavaScript); DoubleQuotes.JavaScriptQuotes = FormatStyle::JSQS_Double; @@ -1346,6 +1500,7 @@ TEST_F(FormatTestJS, NonNullAssertionOperator) { verifyFormat("let x = !foo;\n"); verifyFormat("let x = foo[0]!;\n"); verifyFormat("let x = (foo)!;\n"); + verifyFormat("let x = foo! - 1;\n"); verifyFormat("let x = {foo: 1}!;\n"); } @@ -1358,5 +1513,11 @@ TEST_F(FormatTestJS, Conditional) { "}"); } +TEST_F(FormatTestJS, ImportComments) { + verifyFormat("import {x} from 'x'; // from some location", + getGoogleJSStyleWithColumns(25)); + verifyFormat("// taze: x from 'location'", getGoogleJSStyleWithColumns(10)); +} + } // end namespace tooling } // end namespace clang |