aboutsummaryrefslogtreecommitdiff
path: root/unittests/Format/FormatTestJS.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Format/FormatTestJS.cpp')
-rw-r--r--unittests/Format/FormatTestJS.cpp207
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