aboutsummaryrefslogtreecommitdiff
path: root/unittests/Format/FormatTestJS.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-12-30 11:49:41 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-12-30 11:49:41 +0000
commit45b533945f0851ec234ca846e1af5ee1e4df0b6e (patch)
tree0a5b74c0b9ca73aded34df95c91fcaf3815230d8 /unittests/Format/FormatTestJS.cpp
parent7e86edd64bfae4e324224452e4ea879b3371a4bd (diff)
Notes
Diffstat (limited to 'unittests/Format/FormatTestJS.cpp')
-rw-r--r--unittests/Format/FormatTestJS.cpp198
1 files changed, 144 insertions, 54 deletions
diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp
index d068d35d7d39..cba2ce3370c9 100644
--- a/unittests/Format/FormatTestJS.cpp
+++ b/unittests/Format/FormatTestJS.cpp
@@ -49,7 +49,8 @@ protected:
static void verifyFormat(
llvm::StringRef Code,
const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_JavaScript)) {
- EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
+ std::string result = format(test::messUp(Code), Style);
+ EXPECT_EQ(Code.str(), result) << "Formatted:\n" << result;
}
};
@@ -79,8 +80,8 @@ TEST_F(FormatTestJS, UnderstandsJavaScriptOperators) {
" q();",
getGoogleJSStyleWithColumns(20));
verifyFormat("var x = aaaaaaaaaa ?\n"
- " bbbbbb :\n"
- " ccc;",
+ " bbbbbb :\n"
+ " ccc;",
getGoogleJSStyleWithColumns(20));
verifyFormat("var b = a.map((x) => x + 1);");
@@ -99,9 +100,31 @@ TEST_F(FormatTestJS, LiteralOperatorsCanBeKeywords) {
verifyFormat("not.and.or.not_eq = 1;");
}
+TEST_F(FormatTestJS, ReservedWords) {
+ // JavaScript reserved words (aka keywords) are only illegal when used as
+ // Identifiers, but are legal as IdentifierNames.
+ verifyFormat("x.class.struct = 1;");
+ verifyFormat("x.case = 1;");
+ verifyFormat("x.interface = 1;");
+ verifyFormat("x = {\n"
+ " a: 12,\n"
+ " interface: 1,\n"
+ " switch: 1,\n"
+ "};");
+ verifyFormat("var struct = 2;");
+ verifyFormat("var union = 2;");
+}
+
+TEST_F(FormatTestJS, CppKeywords) {
+ // Make sure we don't mess stuff up because of C++ keywords.
+ verifyFormat("return operator && (aa);");
+}
+
TEST_F(FormatTestJS, ES6DestructuringAssignment) {
verifyFormat("var [a, b, c] = [1, 2, 3];");
+ verifyFormat("let [a, b, c] = [1, 2, 3];");
verifyFormat("var {a, b} = {a: 1, b: 2};");
+ verifyFormat("let {a, b} = {a: 1, b: 2};");
}
TEST_F(FormatTestJS, ContainerLiterals) {
@@ -236,6 +259,8 @@ TEST_F(FormatTestJS, GoogModules) {
getGoogleJSStyleWithColumns(40));
verifyFormat("var long = goog.require('this.is.really.absurdly.long');",
getGoogleJSStyleWithColumns(40));
+ verifyFormat("goog.setTestOnly('this.is.really.absurdly.long');",
+ getGoogleJSStyleWithColumns(40));
// These should be wrapped normally.
verifyFormat(
@@ -263,31 +288,43 @@ TEST_F(FormatTestJS, ArrayLiterals) {
" bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
" ccccccccccccccccccccccccccc\n"
"];");
- verifyFormat("var someVariable = SomeFuntion([\n"
+ verifyFormat("var someVariable = SomeFunction([\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
" bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
" ccccccccccccccccccccccccccc\n"
"]);");
- verifyFormat("var someVariable = SomeFuntion([\n"
+ verifyFormat("var someVariable = SomeFunction([\n"
" [aaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbb],\n"
"]);",
getGoogleJSStyleWithColumns(51));
- verifyFormat("var someVariable = SomeFuntion(aaaa, [\n"
+ verifyFormat("var someVariable = SomeFunction(aaaa, [\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
" bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
" ccccccccccccccccccccccccccc\n"
"]);");
- verifyFormat("var someVariable = SomeFuntion(aaaa,\n"
- " [\n"
- " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
- " bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
- " ccccccccccccccccccccccccccc\n"
- " ],\n"
- " aaaa);");
+ verifyFormat("var someVariable = SomeFunction(\n"
+ " aaaa,\n"
+ " [\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
+ " ccccccccccccccccccccccccccc\n"
+ " ],\n"
+ " aaaa);");
verifyFormat("someFunction([], {a: a});");
}
+TEST_F(FormatTestJS, ColumnLayoutForArrayLiterals) {
+ verifyFormat("var array = [\n"
+ " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
+ " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
+ "];");
+ verifyFormat("var array = someFunction([\n"
+ " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
+ " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
+ "]);");
+}
+
TEST_F(FormatTestJS, FunctionLiterals) {
verifyFormat("doFoo(function() {});");
verifyFormat("doFoo(function() { return 1; });");
@@ -305,14 +342,11 @@ TEST_F(FormatTestJS, FunctionLiterals) {
" style: {direction: ''}\n"
" }\n"
"};");
- EXPECT_EQ("abc = xyz ?\n"
- " function() {\n"
- " return 1;\n"
- " } :\n"
- " function() {\n"
- " return -1;\n"
- " };",
- format("abc=xyz?function(){return 1;}:function(){return -1;};"));
+ verifyFormat("abc = xyz ? function() {\n"
+ " return 1;\n"
+ "} : function() {\n"
+ " return -1;\n"
+ "};");
verifyFormat("var closure = goog.bind(\n"
" function() { // comment\n"
@@ -364,17 +398,13 @@ TEST_F(FormatTestJS, FunctionLiterals) {
" someFunction();\n"
" }, this), aaaaaaaaaaaaaaaaa);");
- // FIXME: This is not ideal yet.
- verifyFormat("someFunction(goog.bind(\n"
- " function() {\n"
- " doSomething();\n"
- " doSomething();\n"
- " },\n"
- " this),\n"
- " goog.bind(function() {\n"
- " doSomething();\n"
- " doSomething();\n"
- " }, this));");
+ verifyFormat("someFunction(goog.bind(function() {\n"
+ " doSomething();\n"
+ " doSomething();\n"
+ "}, this), goog.bind(function() {\n"
+ " doSomething();\n"
+ " doSomething();\n"
+ "}, this));");
// FIXME: This is bad, we should be wrapping before "function() {".
verifyFormat("someFunction(function() {\n"
@@ -434,6 +464,12 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
" }\n"
"}",
Style);
+
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+ verifyFormat("var func = function() {\n"
+ " return 1;\n"
+ "};",
+ Style);
}
TEST_F(FormatTestJS, MultipleFunctionLiterals) {
@@ -457,16 +493,16 @@ TEST_F(FormatTestJS, MultipleFunctionLiterals) {
" doFoo();\n"
" doBaz();\n"
" });\n");
- // FIXME: Here, we should probably break right after the "(" for consistency.
- verifyFormat("promise.then([],\n"
- " function success() {\n"
- " doFoo();\n"
- " doBar();\n"
- " },\n"
- " function error() {\n"
- " doFoo();\n"
- " doBaz();\n"
- " });\n");
+ verifyFormat("promise.then(\n"
+ " [],\n"
+ " function success() {\n"
+ " doFoo();\n"
+ " doBar();\n"
+ " },\n"
+ " function error() {\n"
+ " doFoo();\n"
+ " doBaz();\n"
+ " });\n");
verifyFormat("getSomeLongPromise()\n"
" .then(function(value) { body(); })\n"
@@ -508,13 +544,13 @@ TEST_F(FormatTestJS, ArrowFunctions) {
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) =>\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
"};");
- verifyFormat(
- "var a = a.aaaaaaa((a: a) => aaaaaaaaaaaaaaaaaaaaa(bbbbbbbbb) &&\n"
- " aaaaaaaaaaaaaaaaaaaaa(bbbbbbb));");
- verifyFormat(
- "var a = a.aaaaaaa((a: a) => aaaaaaaaaaaaaaaaaaaaa(bbbbbbbbb) ?\n"
- " aaaaaaaaaaaaaaaaaaaaa(bbbbbbb) :\n"
- " aaaaaaaaaaaaaaaaaaaaa(bbbbbbb));");
+ verifyFormat("var a = a.aaaaaaa(\n"
+ " (a: a) => aaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbb) &&\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbb));");
+ verifyFormat("var a = a.aaaaaaa(\n"
+ " (a: a) => aaaaaaaaaaaaaaaaaaaaa(bbbbbbbbb) ?\n"
+ " aaaaaaaaaaaaaaaaaaaaa(bbbbbbb) :\n"
+ " aaaaaaaaaaaaaaaaaaaaa(bbbbbbb));");
// FIXME: This is bad, we should be wrapping before "() => {".
verifyFormat("someFunction(() => {\n"
@@ -531,6 +567,11 @@ TEST_F(FormatTestJS, ReturnStatements) {
"}");
}
+TEST_F(FormatTestJS, ForLoops) {
+ verifyFormat("for (var i in [2, 3]) {\n"
+ "}");
+}
+
TEST_F(FormatTestJS, AutomaticSemicolonInsertion) {
// The following statements must not wrap, as otherwise the program meaning
// would change due to automatic semicolon insertion.
@@ -564,7 +605,7 @@ TEST_F(FormatTestJS, TryCatch) {
TEST_F(FormatTestJS, StringLiteralConcatenation) {
verifyFormat("var literal = 'hello ' +\n"
- " 'world';");
+ " 'world';");
}
TEST_F(FormatTestJS, RegexLiteralClassification) {
@@ -585,6 +626,13 @@ TEST_F(FormatTestJS, RegexLiteralClassification) {
// Not regex literals.
verifyFormat("var a = a / 2 + b / 3;");
+ verifyFormat("var a = a++ / 2;");
+ // Prefix unary can operate on regex literals, not that it makes sense.
+ verifyFormat("var a = ++/a/;");
+
+ // This is a known issue, regular expressions are incorrectly detected if
+ // directly following a closing parenthesis.
+ verifyFormat("if (foo) / bar /.exec(baz);");
}
TEST_F(FormatTestJS, RegexLiteralSpecialCharacters) {
@@ -602,9 +650,18 @@ TEST_F(FormatTestJS, RegexLiteralSpecialCharacters) {
verifyFormat("var regex = /x|y/;");
verifyFormat("var regex = /a{2}/;");
verifyFormat("var regex = /a{1,3}/;");
+
verifyFormat("var regex = /[abc]/;");
verifyFormat("var regex = /[^abc]/;");
verifyFormat("var regex = /[\\b]/;");
+ verifyFormat("var regex = /[/]/;");
+ verifyFormat("var regex = /[\\/]/;");
+ verifyFormat("var regex = /\\[/;");
+ verifyFormat("var regex = /\\\\[/]/;");
+ verifyFormat("var regex = /}[\"]/;");
+ verifyFormat("var regex = /}[/\"]/;");
+ verifyFormat("var regex = /}[\"/]/;");
+
verifyFormat("var regex = /\\b/;");
verifyFormat("var regex = /\\B/;");
verifyFormat("var regex = /\\d/;");
@@ -705,12 +762,18 @@ TEST_F(FormatTestJS, ClassDeclarations) {
TEST_F(FormatTestJS, InterfaceDeclarations) {
verifyFormat("interface I {\n"
" x: string;\n"
+ " enum: string[];\n"
"}\n"
"var y;");
// Ensure that state is reset after parsing the interface.
verifyFormat("interface a {}\n"
"export function b() {}\n"
"var x;");
+
+ // Arrays of object type literals.
+ verifyFormat("interface I {\n"
+ " o: {}[];\n"
+ "}");
}
TEST_F(FormatTestJS, EnumDeclarations) {
@@ -818,7 +881,7 @@ TEST_F(FormatTestJS, TemplateStrings) {
getGoogleJSStyleWithColumns(35)); // Barely fits.
EXPECT_EQ("var x = `hello\n"
" ${world}` >=\n"
- " some();",
+ " some();",
format("var x =\n"
" `hello\n"
" ${world}` >= some();",
@@ -843,7 +906,7 @@ TEST_F(FormatTestJS, TemplateStrings) {
// are first token in line.
verifyFormat(
"var a = aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
- " `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`;");
+ " `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`;");
// Two template strings.
verifyFormat("var x = `hello` == `hello`;");
@@ -893,11 +956,20 @@ TEST_F(FormatTestJS, TypeArguments) {
verifyFormat("function f(): List<any> {}");
verifyFormat("function aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa():\n"
" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {}");
- verifyFormat("function aaaaaaaaaa(aaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaa,\n"
- " aaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaa):\n"
+ verifyFormat("function aaaaaaaaaa(\n"
+ " aaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaa,\n"
+ " aaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaa):\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {}");
}
+TEST_F(FormatTestJS, UserDefinedTypeGuards) {
+ verifyFormat(
+ "function foo(check: Object):\n"
+ " check is {foo: string, bar: string, baz: string, foobar: string} {\n"
+ " return 'bar' in check;\n"
+ "}\n");
+}
+
TEST_F(FormatTestJS, OptionalTypes) {
verifyFormat("function x(a?: b, c?, d?) {}");
verifyFormat("class X {\n"
@@ -920,5 +992,23 @@ TEST_F(FormatTestJS, IndexSignature) {
verifyFormat("var x: {[k: string]: v};");
}
+TEST_F(FormatTestJS, WrapAfterParen) {
+ verifyFormat("xxxxxxxxxxx(\n"
+ " aaa, aaa);",
+ getGoogleJSStyleWithColumns(20));
+ verifyFormat("xxxxxxxxxxx(\n"
+ " aaa, aaa, aaa,\n"
+ " aaa, aaa, aaa);",
+ getGoogleJSStyleWithColumns(20));
+ verifyFormat("xxxxxxxxxxx(\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " function(x) {\n"
+ " y(); //\n"
+ " });",
+ getGoogleJSStyleWithColumns(40));
+ verifyFormat("while (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&\n"
+ " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}");
+}
+
} // end namespace tooling
} // end namespace clang