diff options
| author | 2017-10-04 20:27:34 +0000 | |
|---|---|---|
| committer | 2017-10-04 20:27:34 +0000 | |
| commit | 31eb748944903b7f4f38afda9851951ca9dfc1ae (patch) | |
| tree | 9b95b6ea45d0874d75eb05b90c0840e191416439 /gnu/llvm/tools/clang/unittests/Format/FormatTestJS.cpp | |
| parent | Don't try to handle IPv4-compatible IPv6 addresses (diff) | |
| download | wireguard-openbsd-31eb748944903b7f4f38afda9851951ca9dfc1ae.tar.xz wireguard-openbsd-31eb748944903b7f4f38afda9851951ca9dfc1ae.zip | |
Import LLVM 5.0.0 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/clang/unittests/Format/FormatTestJS.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/unittests/Format/FormatTestJS.cpp | 403 |
1 files changed, 394 insertions, 9 deletions
diff --git a/gnu/llvm/tools/clang/unittests/Format/FormatTestJS.cpp b/gnu/llvm/tools/clang/unittests/Format/FormatTestJS.cpp index 230717fe47c..c256ebe4626 100644 --- a/gnu/llvm/tools/clang/unittests/Format/FormatTestJS.cpp +++ b/gnu/llvm/tools/clang/unittests/Format/FormatTestJS.cpp @@ -24,10 +24,10 @@ protected: DEBUG(llvm::errs() << "---\n"); DEBUG(llvm::errs() << Code << "\n\n"); std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length)); - bool IncompleteFormat = false; + FormattingAttemptStatus Status; tooling::Replacements Replaces = - reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat); - EXPECT_FALSE(IncompleteFormat); + reformat(Style, Code, Ranges, "<stdin>", &Status); + EXPECT_TRUE(Status.FormatComplete); auto Result = applyAllReplacements(Code, Replaces); EXPECT_TRUE(static_cast<bool>(Result)); DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); @@ -132,6 +132,8 @@ TEST_F(FormatTestJS, ReservedWords) { verifyFormat("x.interface = 1;"); verifyFormat("x.for = 1;"); verifyFormat("x.of() = 1;"); + verifyFormat("of(null);"); + verifyFormat("import {of} from 'x';"); verifyFormat("x.in() = 1;"); verifyFormat("x.let() = 1;"); verifyFormat("x.var() = 1;"); @@ -167,6 +169,8 @@ TEST_F(FormatTestJS, ReservedWordsMethods) { TEST_F(FormatTestJS, CppKeywords) { // Make sure we don't mess stuff up because of C++ keywords. verifyFormat("return operator && (aa);"); + // .. or QT ones. + verifyFormat("slots: Slot[];"); } TEST_F(FormatTestJS, ES6DestructuringAssignment) { @@ -240,6 +244,18 @@ TEST_F(FormatTestJS, ContainerLiterals) { "};"); verifyFormat("var x = {y: (a) => a};"); + // Methods in object literals. + verifyFormat("var x = {\n" + " y(a: string): number {\n" + " return a;\n" + " }\n" + "};"); + verifyFormat("var x = {\n" + " y(a: string) {\n" + " return a;\n" + " }\n" + "};"); + // Computed keys. verifyFormat("var x = {[a]: 1, b: 2, [c]: 3};"); verifyFormat("var x = {\n" @@ -266,6 +282,11 @@ TEST_F(FormatTestJS, ContainerLiterals) { " aaa,\n" " aaa,\n" "};"); + verifyFormat("return {\n" + " a,\n" + " b: 'b',\n" + " c,\n" + "};"); } TEST_F(FormatTestJS, MethodsInObjectLiterals) { @@ -297,6 +318,25 @@ TEST_F(FormatTestJS, MethodsInObjectLiterals) { "};"); } +TEST_F(FormatTestJS, GettersSettersVisibilityKeywords) { + // Don't break after "protected" + verifyFormat("class X {\n" + " protected get getter():\n" + " number {\n" + " return 1;\n" + " }\n" + "}", + getGoogleJSStyleWithColumns(12)); + // Don't break after "get" + verifyFormat("class X {\n" + " protected get someReallyLongGetterName():\n" + " number {\n" + " return 1;\n" + " }\n" + "}", + getGoogleJSStyleWithColumns(40)); +} + TEST_F(FormatTestJS, SpacesInContainerLiterals) { verifyFormat("var arr = [1, 2, 3];"); verifyFormat("f({a: 1, b: 2, c: 3});"); @@ -327,6 +367,25 @@ TEST_F(FormatTestJS, GoogScopes) { "});"); } +TEST_F(FormatTestJS, IIFEs) { + // Internal calling parens; no semi. + verifyFormat("(function() {\n" + "var a = 1;\n" + "}())"); + // External calling parens; no semi. + verifyFormat("(function() {\n" + "var b = 2;\n" + "})()"); + // Internal calling parens; with semi. + verifyFormat("(function() {\n" + "var c = 3;\n" + "}());"); + // External calling parens; with semi. + verifyFormat("(function() {\n" + "var d = 4;\n" + "})();"); +} + TEST_F(FormatTestJS, GoogModules) { verifyFormat("goog.module('this.is.really.absurdly.long');", getGoogleJSStyleWithColumns(40)); @@ -411,6 +470,15 @@ TEST_F(FormatTestJS, FormatsFreestandingFunctions) { " inner2(a, b);\n" "}"); verifyFormat("function f() {}"); + verifyFormat("function aFunction() {}\n" + "(function f() {\n" + " var x = 1;\n" + "}());\n"); + verifyFormat("function aFunction() {}\n" + "{\n" + " let x = 1;\n" + " console.log(x);\n" + "}\n"); } TEST_F(FormatTestJS, GeneratorFunctions) { @@ -445,12 +513,31 @@ TEST_F(FormatTestJS, AsyncFunctions) { " let x = 1;\n" " return fetch(x);\n" "}"); + verifyFormat("async function f() {\n" + " return 1;\n" + "}\n" + "\n" + "function a() {\n" + " return 1;\n" + "}\n", + " async function f() {\n" + " return 1;\n" + "}\n" + "\n" + " function a() {\n" + " return 1;\n" + "} \n"); verifyFormat("async function* f() {\n" " yield fetch(x);\n" "}"); verifyFormat("export async function f() {\n" " return fetch(x);\n" "}"); + verifyFormat("let x = async () => f();"); + verifyFormat("let x = async function() {\n" + " f();\n" + "};"); + verifyFormat("let x = async();"); verifyFormat("class X {\n" " async asyncMethod() {\n" " return fetch(1);\n" @@ -460,6 +547,38 @@ TEST_F(FormatTestJS, AsyncFunctions) { " // Comment.\n" " return async.then();\n" "}\n"); + verifyFormat("for await (const x of y) {\n" + " console.log(x);\n" + "}\n"); + verifyFormat("function asyncLoop() {\n" + " for await (const x of y) {\n" + " console.log(x);\n" + " }\n" + "}\n"); +} + +TEST_F(FormatTestJS, FunctionParametersTrailingComma) { + verifyFormat("function trailingComma(\n" + " p1,\n" + " p2,\n" + " p3,\n" + ") {\n" + " a; //\n" + "}\n", + "function trailingComma(p1, p2, p3,) {\n" + " a; //\n" + "}\n"); + verifyFormat("trailingComma(\n" + " p1,\n" + " p2,\n" + " p3,\n" + ");\n", + "trailingComma(p1, p2, p3,);\n"); + verifyFormat("trailingComma(\n" + " p1 // hello\n" + ");\n", + "trailingComma(p1 // hello\n" + ");\n"); } TEST_F(FormatTestJS, ArrayLiterals) { @@ -497,6 +616,11 @@ TEST_F(FormatTestJS, ArrayLiterals) { " [];"); verifyFormat("someFunction([], {a: a});"); + + verifyFormat("var string = [\n" + " 'aaaaaa',\n" + " 'bbbbbb',\n" + "].join('+');"); } TEST_F(FormatTestJS, ColumnLayoutForArrayLiterals) { @@ -587,13 +711,23 @@ TEST_F(FormatTestJS, FunctionLiterals) { " doSomething();\n" "}, this));"); + verifyFormat("SomeFunction(function() {\n" + " foo();\n" + " bar();\n" + "}.bind(this));"); + + verifyFormat("SomeFunction((function() {\n" + " foo();\n" + " bar();\n" + " }).bind(this));"); + // FIXME: This is bad, we should be wrapping before "function() {". verifyFormat("someFunction(function() {\n" " doSomething(); // break\n" "})\n" " .doSomethingElse(\n" " // break\n" - " );"); + " );"); Style.ColumnLimit = 33; verifyFormat("f({a: function() { return 1; }});", Style); @@ -760,7 +894,7 @@ TEST_F(FormatTestJS, ArrowFunctions) { "})\n" " .doSomethingElse(\n" " // break\n" - " );"); + " );"); } TEST_F(FormatTestJS, ReturnStatements) { @@ -796,6 +930,14 @@ TEST_F(FormatTestJS, WrapRespectsAutomaticSemicolonInsertion) { " aaa\n" "];", getGoogleJSStyleWithColumns(12)); + verifyFormat("class X {\n" + " readonly ratherLongField =\n" + " 1;\n" + "}", + "class X {\n" + " readonly ratherLongField = 1;\n" + "}", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, AutomaticSemicolonInsertionHeuristic) { @@ -858,13 +1000,25 @@ TEST_F(FormatTestJS, AutomaticSemicolonInsertionHeuristic) { "return 1", "a = null\n" " return 1"); + // Below "class Y {}" should ideally be on its own line. verifyFormat( "x = {\n" " a: 1\n" - "}\n" - "class Y {}", + "} class Y {}", " x = {a : 1}\n" " class Y { }"); + verifyFormat( + "if (x) {\n" + "}\n" + "return 1", + "if (x) {}\n" + " return 1"); + verifyFormat( + "if (x) {\n" + "}\n" + "class X {}", + "if (x) {}\n" + " class X {}"); } TEST_F(FormatTestJS, ImportExportASI) { @@ -873,11 +1027,17 @@ TEST_F(FormatTestJS, ImportExportASI) { "export function z() {}", "import {x} from 'y'\n" " export function z() {}"); + // Below "class Y {}" should ideally be on its own line. verifyFormat( - "export {x}\n" - "class Y {}", + "export {x} class Y {}", " export {x}\n" " class Y {\n}"); + verifyFormat( + "if (x) {\n" + "}\n" + "export class Y {}", + "if ( x ) { }\n" + " export class Y {}"); } TEST_F(FormatTestJS, ClosureStyleCasts) { @@ -913,6 +1073,7 @@ TEST_F(FormatTestJS, RegexLiteralClassification) { verifyFormat("var x = a ? /abc/ : /abc/;"); verifyFormat("for (var i = 0; /abc/.test(s[i]); i++) {\n}"); verifyFormat("var x = !/abc/.test(y);"); + verifyFormat("var x = foo()! / 10;"); verifyFormat("var x = a && /abc/.test(y);"); verifyFormat("var x = a || /abc/.test(y);"); verifyFormat("var x = a + /abc/.search(y);"); @@ -1018,6 +1179,15 @@ TEST_F(FormatTestJS, RegexLiteralExamples) { verifyFormat("var regex = search.match(/(?:\?|&)times=([^?&]+)/i);"); } +TEST_F(FormatTestJS, IgnoresMpegTS) { + std::string MpegTS(200, ' '); + MpegTS.replace(0, strlen("nearlyLooks + like + ts + code; "), + "nearlyLooks + like + ts + code; "); + MpegTS[0] = 0x47; + MpegTS[188] = 0x47; + verifyFormat(MpegTS, MpegTS); +} + TEST_F(FormatTestJS, TypeAnnotations) { verifyFormat("var x: string;"); verifyFormat("var x: {a: string; b: number;} = {};"); @@ -1045,6 +1215,9 @@ TEST_F(FormatTestJS, TypeAnnotations) { verifyFormat("function someFunc(args: string[]):\n" " {longReturnValue: string[]} {}", getGoogleJSStyleWithColumns(60)); + verifyFormat( + "var someValue = (v as aaaaaaaaaaaaaaaaaaaa<T>[])\n" + " .someFunction(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); } TEST_F(FormatTestJS, UnionIntersectionTypes) { @@ -1061,17 +1234,31 @@ TEST_F(FormatTestJS, UnionIntersectionTypes) { verifyFormat("let x: Bar|Baz;"); verifyFormat("let x: Bar<X>|Baz;"); verifyFormat("let x: (Foo|Bar)[];"); + verifyFormat("type X = {\n" + " a: Foo|Bar;\n" + "};"); + verifyFormat("export type X = {\n" + " a: Foo|Bar;\n" + "};"); } TEST_F(FormatTestJS, ClassDeclarations) { verifyFormat("class C {\n x: string = 12;\n}"); verifyFormat("class C {\n x(): string => 12;\n}"); verifyFormat("class C {\n ['x' + 2]: string = 12;\n}"); + verifyFormat("class C {\n" + " foo() {}\n" + " [bar]() {}\n" + "}\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 {\n return 'asd';\n }\n}"); verifyFormat("class C extends P implements I {}"); verifyFormat("class C extends p.P implements i.I {}"); + verifyFormat( + "x(class {\n" + " a(): A {}\n" + "});"); verifyFormat("class Test {\n" " aaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaa):\n" " aaaaaaaaaaaaaaaaaaaaaa {}\n" @@ -1152,6 +1339,9 @@ TEST_F(FormatTestJS, MetadataAnnotations) { "}"); verifyFormat("class X {}\n" "class Y {}"); + verifyFormat("class X {\n" + " @property() private isReply = false;\n" + "}\n"); } TEST_F(FormatTestJS, TypeAliases) { @@ -1164,6 +1354,20 @@ TEST_F(FormatTestJS, TypeAliases) { "class C {}"); } +TEST_F(FormatTestJS, TypeInterfaceLineWrapping) { + const FormatStyle &Style = getGoogleJSStyleWithColumns(20); + verifyFormat("type LongTypeIsReallyUnreasonablyLong =\n" + " string;\n", + "type LongTypeIsReallyUnreasonablyLong = string;\n", + Style); + verifyFormat( + "interface AbstractStrategyFactoryProvider {\n" + " a: number\n" + "}\n", + "interface AbstractStrategyFactoryProvider { a: number }\n", + Style); +} + TEST_F(FormatTestJS, Modules) { verifyFormat("import SomeThing from 'some/module.js';"); verifyFormat("import {X, Y} from 'some/module.js';"); @@ -1260,6 +1464,17 @@ TEST_F(FormatTestJS, ImportWrapping) { " A,\n" "} from 'some/module.js';", Style); + Style.ColumnLimit = 40; + // Using this version of verifyFormat because test::messUp hides the issue. + verifyFormat("import {\n" + " A,\n" + "} from\n" + " 'some/path/longer/than/column/limit/module.js';", + " import { \n" + " A, \n" + " } from\n" + " 'some/path/longer/than/column/limit/module.js' ; ", + Style); } TEST_F(FormatTestJS, TemplateStrings) { @@ -1351,6 +1566,62 @@ TEST_F(FormatTestJS, TemplateStrings) { "var y;"); // Escaped dollar. verifyFormat("var x = ` \\${foo}`;\n"); + + // The token stream can contain two string_literals in sequence, but that + // doesn't mean that they are implicitly concatenated in JavaScript. + verifyFormat("var f = `aaaa ${a ? 'a' : 'b'}`;"); + + // Ensure that scopes are appropriately set around evaluated expressions in + // template strings. + verifyFormat("var f = `aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa\n" + " aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa`;", + "var f = `aaaaaaaaaaaaa:${aaaaaaa. aaaaa} aaaaaaaa\n" + " aaaaaaaaaaaaa:${ aaaaaaa. aaaaa} aaaaaaaa`;"); + verifyFormat("var x = someFunction(`${})`) //\n" + " .oooooooooooooooooon();"); + verifyFormat("var x = someFunction(`${aaaa}${\n" + " aaaaa( //\n" + " aaaaa)\n" + " })`);"); +} + +TEST_F(FormatTestJS, TemplateStringMultiLineExpression) { + verifyFormat("var f = `aaaaaaaaaaaaaaaaaa: ${\n" + " aaaaa + //\n" + " bbbb\n" + " }`;", + "var f = `aaaaaaaaaaaaaaaaaa: ${aaaaa + //\n" + " bbbb}`;"); + verifyFormat("var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${\n" + " aaaaa + //\n" + " bbbb\n" + " }`;", + "var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${ aaaaa + //\n" + " bbbb }`;"); + verifyFormat("var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${\n" + " someFunction(\n" + " aaaaa + //\n" + " bbbb)\n" + " }`;", + "var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${someFunction (\n" + " aaaaa + //\n" + " bbbb)}`;"); + + // It might be preferable to wrap before "someFunction". + verifyFormat("var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${someFunction({\n" + " aaaa: aaaaa,\n" + " bbbb: bbbbb,\n" + " })}`;", + "var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${someFunction ({\n" + " aaaa: aaaaa,\n" + " bbbb: bbbbb,\n" + " })}`;"); } TEST_F(FormatTestJS, TemplateStringASI) { @@ -1370,6 +1641,7 @@ TEST_F(FormatTestJS, NestedTemplateStrings) { TEST_F(FormatTestJS, TaggedTemplateStrings) { verifyFormat("var x = html`<ul>`;"); + verifyFormat("yield `hello`;"); } TEST_F(FormatTestJS, CastSyntax) { @@ -1387,6 +1659,9 @@ TEST_F(FormatTestJS, CastSyntax) { verifyFormat("x = x as {a: string};"); verifyFormat("x = x as (string);"); verifyFormat("x = x! as (string);"); + verifyFormat("var x = something.someFunction() as\n" + " something;", + getGoogleJSStyleWithColumns(40)); } TEST_F(FormatTestJS, TypeArguments) { @@ -1460,6 +1735,58 @@ TEST_F(FormatTestJS, JSDocAnnotations) { " * @export {this.is.a.long.path.to.a.Type}\n" " */", getGoogleJSStyleWithColumns(20)); + verifyFormat("/**\n" + " * @mods {this.is.a.long.path.to.a.Type}\n" + " */", + "/**\n" + " * @mods {this.is.a.long.path.to.a.Type}\n" + " */", + getGoogleJSStyleWithColumns(20)); + verifyFormat("/**\n" + " * @param {this.is.a.long.path.to.a.Type}\n" + " */", + "/**\n" + " * @param {this.is.a.long.path.to.a.Type}\n" + " */", + getGoogleJSStyleWithColumns(20)); + verifyFormat("/**\n" + " * @see http://very/very/long/url/is/long\n" + " */", + "/**\n" + " * @see http://very/very/long/url/is/long\n" + " */", + getGoogleJSStyleWithColumns(20)); + verifyFormat( + "/**\n" + " * @param This is a\n" + " * long comment but\n" + " * no type\n" + " */", + "/**\n" + " * @param This is a long comment but no type\n" + " */", + getGoogleJSStyleWithColumns(20)); + // Don't break @param line, but reindent it and reflow unrelated lines. + verifyFormat("{\n" + " /**\n" + " * long long long\n" + " * long\n" + " * @param {this.is.a.long.path.to.a.Type} a\n" + " * long long long\n" + " * long long\n" + " */\n" + " function f(a) {}\n" + "}", + "{\n" + "/**\n" + " * long long long long\n" + " * @param {this.is.a.long.path.to.a.Type} a\n" + " * long long long long\n" + " * long\n" + " */\n" + " function f(a) {}\n" + "}", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, RequoteStringsSingle) { @@ -1530,8 +1857,21 @@ TEST_F(FormatTestJS, NonNullAssertionOperator) { verifyFormat("let x = !foo;\n"); verifyFormat("let x = foo[0]!;\n"); verifyFormat("let x = (foo)!;\n"); + verifyFormat("let x = x(foo!);\n"); + verifyFormat( + "a.aaaaaa(a.a!).then(\n" + " x => x(x));\n", + getGoogleJSStyleWithColumns(20)); verifyFormat("let x = foo! - 1;\n"); verifyFormat("let x = {foo: 1}!;\n"); + verifyFormat( + "let x = hello.foo()!\n" + " .foo()!\n" + " .foo()!\n" + " .foo()!;\n", + getGoogleJSStyleWithColumns(20)); + verifyFormat("let x = namespace!;\n"); + verifyFormat("return !!x;\n"); } TEST_F(FormatTestJS, Conditional) { @@ -1547,6 +1887,51 @@ TEST_F(FormatTestJS, ImportComments) { verifyFormat("import {x} from 'x'; // from some location", getGoogleJSStyleWithColumns(25)); verifyFormat("// taze: x from 'location'", getGoogleJSStyleWithColumns(10)); + verifyFormat("/// <reference path=\"some/location\" />", getGoogleJSStyleWithColumns(10)); +} + +TEST_F(FormatTestJS, Exponentiation) { + verifyFormat("squared = x ** 2;"); + verifyFormat("squared **= 2;"); +} + +TEST_F(FormatTestJS, NestedLiterals) { + FormatStyle FourSpaces = getGoogleJSStyleWithColumns(15); + FourSpaces.IndentWidth = 4; + verifyFormat("var l = [\n" + " [\n" + " 1,\n" + " ],\n" + "];", FourSpaces); + verifyFormat("var l = [\n" + " {\n" + " 1: 1,\n" + " },\n" + "];", FourSpaces); + verifyFormat("someFunction(\n" + " p1,\n" + " [\n" + " 1,\n" + " ],\n" + ");", FourSpaces); + verifyFormat("someFunction(\n" + " p1,\n" + " {\n" + " 1: 1,\n" + " },\n" + ");", FourSpaces); + verifyFormat("var o = {\n" + " 1: 1,\n" + " 2: {\n" + " 3: 3,\n" + " },\n" + "};", FourSpaces); + verifyFormat("var o = {\n" + " 1: 1,\n" + " 2: [\n" + " 3,\n" + " ],\n" + "};", FourSpaces); } } // end namespace tooling |
