diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:49:41 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:49:41 +0000 |
commit | 45b533945f0851ec234ca846e1af5ee1e4df0b6e (patch) | |
tree | 0a5b74c0b9ca73aded34df95c91fcaf3815230d8 /unittests/Format/FormatTestJS.cpp | |
parent | 7e86edd64bfae4e324224452e4ea879b3371a4bd (diff) |
Notes
Diffstat (limited to 'unittests/Format/FormatTestJS.cpp')
-rw-r--r-- | unittests/Format/FormatTestJS.cpp | 198 |
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 |