2013-12-03 18:50:16 +08:00
|
|
|
//===- unittest/Format/FormatTestJS.cpp - Formatting unit tests for JS ----===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "FormatTestUtils.h"
|
|
|
|
#include "clang/Format/Format.h"
|
|
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
2014-04-22 11:17:02 +08:00
|
|
|
#define DEBUG_TYPE "format-test"
|
|
|
|
|
2013-12-03 18:50:16 +08:00
|
|
|
namespace clang {
|
|
|
|
namespace format {
|
|
|
|
|
|
|
|
class FormatTestJS : public ::testing::Test {
|
|
|
|
protected:
|
|
|
|
static std::string format(llvm::StringRef Code, unsigned Offset,
|
|
|
|
unsigned Length, const FormatStyle &Style) {
|
|
|
|
DEBUG(llvm::errs() << "---\n");
|
|
|
|
DEBUG(llvm::errs() << Code << "\n\n");
|
|
|
|
std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
|
2015-06-11 21:29:20 +08:00
|
|
|
bool IncompleteFormat = false;
|
|
|
|
tooling::Replacements Replaces =
|
|
|
|
reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat);
|
|
|
|
EXPECT_FALSE(IncompleteFormat);
|
2013-12-03 18:50:16 +08:00
|
|
|
std::string Result = applyAllReplacements(Code, Replaces);
|
|
|
|
EXPECT_NE("", Result);
|
|
|
|
DEBUG(llvm::errs() << "\n" << Result << "\n\n");
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2014-05-20 19:14:57 +08:00
|
|
|
static std::string format(
|
|
|
|
llvm::StringRef Code,
|
|
|
|
const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_JavaScript)) {
|
2013-12-03 18:50:16 +08:00
|
|
|
return format(Code, 0, Code.size(), Style);
|
|
|
|
}
|
|
|
|
|
2013-12-10 19:28:13 +08:00
|
|
|
static FormatStyle getGoogleJSStyleWithColumns(unsigned ColumnLimit) {
|
2014-02-03 04:50:45 +08:00
|
|
|
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
|
2013-12-03 18:50:16 +08:00
|
|
|
Style.ColumnLimit = ColumnLimit;
|
|
|
|
return Style;
|
|
|
|
}
|
|
|
|
|
2014-02-03 04:50:45 +08:00
|
|
|
static void verifyFormat(
|
|
|
|
llvm::StringRef Code,
|
|
|
|
const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_JavaScript)) {
|
2016-03-15 03:21:36 +08:00
|
|
|
std::string Result = format(test::messUp(Code), Style);
|
|
|
|
EXPECT_EQ(Code.str(), Result) << "Formatted:\n" << Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void verifyFormat(
|
|
|
|
llvm::StringRef Expected,
|
|
|
|
llvm::StringRef Code,
|
|
|
|
const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_JavaScript)) {
|
|
|
|
std::string Result = format(Code, Style);
|
|
|
|
EXPECT_EQ(Expected.str(), Result) << "Formatted:\n" << Result;
|
2013-12-03 18:50:16 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(FormatTestJS, UnderstandsJavaScriptOperators) {
|
|
|
|
verifyFormat("a == = b;");
|
|
|
|
verifyFormat("a != = b;");
|
|
|
|
|
|
|
|
verifyFormat("a === b;");
|
2014-11-06 01:22:31 +08:00
|
|
|
verifyFormat("aaaaaaa ===\n b;", getGoogleJSStyleWithColumns(10));
|
2013-12-03 18:50:16 +08:00
|
|
|
verifyFormat("a !== b;");
|
2014-11-06 01:22:31 +08:00
|
|
|
verifyFormat("aaaaaaa !==\n b;", getGoogleJSStyleWithColumns(10));
|
|
|
|
verifyFormat("if (a + b + c +\n"
|
|
|
|
" d !==\n"
|
|
|
|
" e + f + g)\n"
|
2013-12-03 18:50:16 +08:00
|
|
|
" q();",
|
2013-12-10 19:28:13 +08:00
|
|
|
getGoogleJSStyleWithColumns(20));
|
2013-12-03 18:50:16 +08:00
|
|
|
|
|
|
|
verifyFormat("a >> >= b;");
|
|
|
|
|
|
|
|
verifyFormat("a >>> b;");
|
2014-11-06 01:22:31 +08:00
|
|
|
verifyFormat("aaaaaaa >>>\n b;", getGoogleJSStyleWithColumns(10));
|
2013-12-03 18:50:16 +08:00
|
|
|
verifyFormat("a >>>= b;");
|
2014-11-06 01:22:31 +08:00
|
|
|
verifyFormat("aaaaaaa >>>=\n b;", getGoogleJSStyleWithColumns(10));
|
|
|
|
verifyFormat("if (a + b + c +\n"
|
|
|
|
" d >>>\n"
|
|
|
|
" e + f + g)\n"
|
2013-12-03 18:50:16 +08:00
|
|
|
" q();",
|
2013-12-10 19:28:13 +08:00
|
|
|
getGoogleJSStyleWithColumns(20));
|
2014-11-06 01:22:31 +08:00
|
|
|
verifyFormat("var x = aaaaaaaaaa ?\n"
|
2015-12-21 21:52:19 +08:00
|
|
|
" bbbbbb :\n"
|
|
|
|
" ccc;",
|
2013-12-10 19:28:13 +08:00
|
|
|
getGoogleJSStyleWithColumns(20));
|
2014-05-19 15:27:02 +08:00
|
|
|
|
|
|
|
verifyFormat("var b = a.map((x) => x + 1);");
|
2014-09-19 18:48:15 +08:00
|
|
|
verifyFormat("return ('aaa') in bbbb;");
|
2016-02-01 19:20:47 +08:00
|
|
|
verifyFormat("var x = aaaaaaaaaaaaaaaaaaaaaaaaa() in\n"
|
|
|
|
" aaaa.aaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
|
|
|
|
FormatStyle Style = getGoogleJSStyleWithColumns(80);
|
|
|
|
Style.AlignOperands = true;
|
|
|
|
verifyFormat("var x = aaaaaaaaaaaaaaaaaaaaaaaaa() in\n"
|
|
|
|
" aaaa.aaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
|
|
|
|
Style);
|
|
|
|
Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
|
|
|
|
verifyFormat("var x = aaaaaaaaaaaaaaaaaaaaaaaaa()\n"
|
|
|
|
" in aaaa.aaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
|
|
|
|
Style);
|
2015-05-26 15:18:56 +08:00
|
|
|
|
|
|
|
// ES6 spread operator.
|
|
|
|
verifyFormat("someFunction(...a);");
|
|
|
|
verifyFormat("var x = [1, ...a, 2];");
|
2013-12-03 18:50:16 +08:00
|
|
|
}
|
|
|
|
|
2014-09-05 16:53:45 +08:00
|
|
|
TEST_F(FormatTestJS, UnderstandsAmpAmp) {
|
|
|
|
verifyFormat("e && e.SomeFunction();");
|
|
|
|
}
|
|
|
|
|
2014-09-05 02:23:42 +08:00
|
|
|
TEST_F(FormatTestJS, LiteralOperatorsCanBeKeywords) {
|
|
|
|
verifyFormat("not.and.or.not_eq = 1;");
|
|
|
|
}
|
|
|
|
|
2015-09-28 22:29:45 +08:00
|
|
|
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;");
|
2016-03-17 20:17:59 +08:00
|
|
|
verifyFormat("x.of() = 1;");
|
|
|
|
verifyFormat("x.in() = 1;");
|
|
|
|
verifyFormat("x.let() = 1;");
|
|
|
|
verifyFormat("x.var() = 1;");
|
2015-09-28 22:29:45 +08:00
|
|
|
verifyFormat("x = {\n"
|
|
|
|
" a: 12,\n"
|
|
|
|
" interface: 1,\n"
|
|
|
|
" switch: 1,\n"
|
|
|
|
"};");
|
2015-11-20 23:58:50 +08:00
|
|
|
verifyFormat("var struct = 2;");
|
|
|
|
verifyFormat("var union = 2;");
|
2016-04-20 02:18:59 +08:00
|
|
|
verifyFormat("var interface = 2;");
|
|
|
|
verifyFormat("interface = 2;");
|
|
|
|
verifyFormat("x = interface instanceof y;");
|
2015-09-28 22:29:45 +08:00
|
|
|
}
|
|
|
|
|
2015-12-22 23:47:56 +08:00
|
|
|
TEST_F(FormatTestJS, CppKeywords) {
|
|
|
|
// Make sure we don't mess stuff up because of C++ keywords.
|
|
|
|
verifyFormat("return operator && (aa);");
|
|
|
|
}
|
|
|
|
|
2014-05-19 15:37:07 +08:00
|
|
|
TEST_F(FormatTestJS, ES6DestructuringAssignment) {
|
|
|
|
verifyFormat("var [a, b, c] = [1, 2, 3];");
|
2015-09-28 22:28:08 +08:00
|
|
|
verifyFormat("let [a, b, c] = [1, 2, 3];");
|
2015-03-15 21:55:54 +08:00
|
|
|
verifyFormat("var {a, b} = {a: 1, b: 2};");
|
2015-09-28 22:28:08 +08:00
|
|
|
verifyFormat("let {a, b} = {a: 1, b: 2};");
|
2014-05-19 15:37:07 +08:00
|
|
|
}
|
|
|
|
|
2014-06-10 22:44:02 +08:00
|
|
|
TEST_F(FormatTestJS, ContainerLiterals) {
|
2015-05-21 20:23:34 +08:00
|
|
|
verifyFormat("var x = {y: function(a) { return a; }};");
|
2014-06-10 22:44:02 +08:00
|
|
|
verifyFormat("return {\n"
|
|
|
|
" link: function() {\n"
|
|
|
|
" f(); //\n"
|
|
|
|
" }\n"
|
|
|
|
"};");
|
|
|
|
verifyFormat("return {\n"
|
|
|
|
" a: a,\n"
|
|
|
|
" link: function() {\n"
|
|
|
|
" f(); //\n"
|
|
|
|
" }\n"
|
|
|
|
"};");
|
|
|
|
verifyFormat("return {\n"
|
|
|
|
" a: a,\n"
|
2014-09-05 17:27:38 +08:00
|
|
|
" link: function() {\n"
|
|
|
|
" f(); //\n"
|
|
|
|
" },\n"
|
|
|
|
" link: function() {\n"
|
|
|
|
" f(); //\n"
|
|
|
|
" }\n"
|
2014-06-10 22:44:02 +08:00
|
|
|
"};");
|
2014-09-04 22:58:30 +08:00
|
|
|
verifyFormat("var stuff = {\n"
|
|
|
|
" // comment for update\n"
|
|
|
|
" update: false,\n"
|
|
|
|
" // comment for modules\n"
|
|
|
|
" modules: false,\n"
|
|
|
|
" // comment for tasks\n"
|
|
|
|
" tasks: false\n"
|
|
|
|
"};");
|
2014-09-05 16:29:31 +08:00
|
|
|
verifyFormat("return {\n"
|
|
|
|
" 'finish':\n"
|
|
|
|
" //\n"
|
|
|
|
" a\n"
|
|
|
|
"};");
|
2014-11-27 23:24:48 +08:00
|
|
|
verifyFormat("var obj = {\n"
|
|
|
|
" fooooooooo: function(x) {\n"
|
|
|
|
" return x.zIsTooLongForOneLineWithTheDeclarationLine();\n"
|
|
|
|
" }\n"
|
|
|
|
"};");
|
2015-03-15 21:55:54 +08:00
|
|
|
// Simple object literal, as opposed to enum style below.
|
|
|
|
verifyFormat("var obj = {a: 123};");
|
|
|
|
// Enum style top level assignment.
|
|
|
|
verifyFormat("X = {\n a: 123\n};");
|
|
|
|
verifyFormat("X.Y = {\n a: 123\n};");
|
2015-06-10 17:21:09 +08:00
|
|
|
// But only on the top level, otherwise its a plain object literal assignment.
|
|
|
|
verifyFormat("function x() {\n"
|
|
|
|
" y = {z: 1};\n"
|
|
|
|
"}");
|
2015-03-15 21:55:54 +08:00
|
|
|
verifyFormat("x = foo && {a: 123};");
|
2015-05-21 20:23:34 +08:00
|
|
|
|
|
|
|
// Arrow functions in object literals.
|
|
|
|
verifyFormat("var x = {y: (a) => { return a; }};");
|
|
|
|
verifyFormat("var x = {y: (a) => a};");
|
2015-05-29 14:19:49 +08:00
|
|
|
|
|
|
|
// Computed keys.
|
2015-05-31 16:40:37 +08:00
|
|
|
verifyFormat("var x = {[a]: 1, b: 2, [c]: 3};");
|
2015-05-29 14:19:49 +08:00
|
|
|
verifyFormat("var x = {\n"
|
|
|
|
" [a]: 1,\n"
|
2015-05-31 16:40:37 +08:00
|
|
|
" b: 2,\n"
|
|
|
|
" [c]: 3,\n"
|
2015-05-29 14:19:49 +08:00
|
|
|
"};");
|
2016-02-08 06:17:13 +08:00
|
|
|
|
|
|
|
// Object literals can leave out labels.
|
|
|
|
verifyFormat("f({a}, () => {\n"
|
|
|
|
" g(); //\n"
|
|
|
|
"});");
|
2016-03-01 12:19:47 +08:00
|
|
|
|
|
|
|
// Keys can be quoted.
|
|
|
|
verifyFormat("var x = {\n"
|
|
|
|
" a: a,\n"
|
|
|
|
" b: b,\n"
|
|
|
|
" 'c': c,\n"
|
|
|
|
"};");
|
2014-06-10 22:44:02 +08:00
|
|
|
}
|
|
|
|
|
2015-03-31 22:34:15 +08:00
|
|
|
TEST_F(FormatTestJS, MethodsInObjectLiterals) {
|
|
|
|
verifyFormat("var o = {\n"
|
|
|
|
" value: 'test',\n"
|
|
|
|
" get value() { // getter\n"
|
|
|
|
" return this.value;\n"
|
|
|
|
" }\n"
|
|
|
|
"};");
|
|
|
|
verifyFormat("var o = {\n"
|
|
|
|
" value: 'test',\n"
|
|
|
|
" set value(val) { // setter\n"
|
|
|
|
" this.value = val;\n"
|
|
|
|
" }\n"
|
|
|
|
"};");
|
|
|
|
verifyFormat("var o = {\n"
|
|
|
|
" value: 'test',\n"
|
|
|
|
" someMethod(val) { // method\n"
|
|
|
|
" doSomething(this.value + val);\n"
|
|
|
|
" }\n"
|
|
|
|
"};");
|
2015-04-04 15:56:55 +08:00
|
|
|
verifyFormat("var o = {\n"
|
|
|
|
" someMethod(val) { // method\n"
|
|
|
|
" doSomething(this.value + val);\n"
|
|
|
|
" },\n"
|
|
|
|
" someOtherMethod(val) { // method\n"
|
|
|
|
" doSomething(this.value + val);\n"
|
|
|
|
" }\n"
|
|
|
|
"};");
|
2015-03-31 22:34:15 +08:00
|
|
|
}
|
|
|
|
|
2014-01-15 23:09:08 +08:00
|
|
|
TEST_F(FormatTestJS, SpacesInContainerLiterals) {
|
|
|
|
verifyFormat("var arr = [1, 2, 3];");
|
2014-12-05 00:07:17 +08:00
|
|
|
verifyFormat("f({a: 1, b: 2, c: 3});");
|
2014-02-03 04:50:45 +08:00
|
|
|
|
2014-05-21 21:26:58 +08:00
|
|
|
verifyFormat("var object_literal_with_long_name = {\n"
|
|
|
|
" a: 'aaaaaaaaaaaaaaaaaa',\n"
|
|
|
|
" b: 'bbbbbbbbbbbbbbbbbb'\n"
|
|
|
|
"};");
|
|
|
|
|
2014-12-05 00:07:17 +08:00
|
|
|
verifyFormat("f({a: 1, b: 2, c: 3});",
|
2014-02-03 04:50:45 +08:00
|
|
|
getChromiumStyle(FormatStyle::LK_JavaScript));
|
2014-12-05 00:07:17 +08:00
|
|
|
verifyFormat("f({'a': [{}]});");
|
2014-01-15 23:09:08 +08:00
|
|
|
}
|
|
|
|
|
2016-03-03 06:44:03 +08:00
|
|
|
TEST_F(FormatTestJS, SingleQuotedStrings) {
|
2014-01-31 20:49:42 +08:00
|
|
|
verifyFormat("this.function('', true);");
|
|
|
|
}
|
|
|
|
|
2014-05-06 21:54:10 +08:00
|
|
|
TEST_F(FormatTestJS, GoogScopes) {
|
|
|
|
verifyFormat("goog.scope(function() {\n"
|
|
|
|
"var x = a.b;\n"
|
|
|
|
"var y = c.d;\n"
|
|
|
|
"}); // goog.scope");
|
2015-03-30 17:56:50 +08:00
|
|
|
verifyFormat("goog.scope(function() {\n"
|
|
|
|
"// test\n"
|
|
|
|
"var x = 0;\n"
|
|
|
|
"// test\n"
|
|
|
|
"});");
|
2014-05-06 21:54:10 +08:00
|
|
|
}
|
|
|
|
|
2014-11-24 00:46:28 +08:00
|
|
|
TEST_F(FormatTestJS, GoogModules) {
|
|
|
|
verifyFormat("goog.module('this.is.really.absurdly.long');",
|
|
|
|
getGoogleJSStyleWithColumns(40));
|
|
|
|
verifyFormat("goog.require('this.is.really.absurdly.long');",
|
|
|
|
getGoogleJSStyleWithColumns(40));
|
|
|
|
verifyFormat("goog.provide('this.is.really.absurdly.long');",
|
|
|
|
getGoogleJSStyleWithColumns(40));
|
|
|
|
verifyFormat("var long = goog.require('this.is.really.absurdly.long');",
|
|
|
|
getGoogleJSStyleWithColumns(40));
|
2015-10-30 03:05:20 +08:00
|
|
|
verifyFormat("goog.setTestOnly('this.is.really.absurdly.long');",
|
|
|
|
getGoogleJSStyleWithColumns(40));
|
2016-02-22 23:06:53 +08:00
|
|
|
verifyFormat("goog.forwardDeclare('this.is.really.absurdly.long');",
|
|
|
|
getGoogleJSStyleWithColumns(40));
|
2014-11-27 22:46:03 +08:00
|
|
|
|
|
|
|
// These should be wrapped normally.
|
|
|
|
verifyFormat(
|
|
|
|
"var MyLongClassName =\n"
|
|
|
|
" goog.module.get('my.long.module.name.followedBy.MyLongClassName');");
|
2014-11-24 00:46:28 +08:00
|
|
|
}
|
|
|
|
|
clang-format: [JS] support free-standing functions again.
This worked initially but was broken by r210887.
Before:
function outer1(a, b) {
function inner1(a, b) { return a; } inner1(a, b);
} function outer2(a, b) { function inner2(a, b) { return a; } inner2(a, b); }
After:
function outer1(a, b) {
function inner1(a, b) { return a; }
inner1(a, b);
}
function outer2(a, b) {
function inner2(a, b) { return a; }
inner2(a, b);
}
Thanks to Adam Strzelecki for working on this.
llvm-svn: 212038
2014-06-30 21:24:54 +08:00
|
|
|
TEST_F(FormatTestJS, FormatsFreestandingFunctions) {
|
|
|
|
verifyFormat("function outer1(a, b) {\n"
|
|
|
|
" function inner1(a, b) { return a; }\n"
|
|
|
|
" inner1(a, b);\n"
|
|
|
|
"}\n"
|
|
|
|
"function outer2(a, b) {\n"
|
|
|
|
" function inner2(a, b) { return a; }\n"
|
|
|
|
" inner2(a, b);\n"
|
|
|
|
"}");
|
2015-06-11 21:31:45 +08:00
|
|
|
verifyFormat("function f() {}");
|
clang-format: [JS] support free-standing functions again.
This worked initially but was broken by r210887.
Before:
function outer1(a, b) {
function inner1(a, b) { return a; } inner1(a, b);
} function outer2(a, b) { function inner2(a, b) { return a; } inner2(a, b); }
After:
function outer1(a, b) {
function inner1(a, b) { return a; }
inner1(a, b);
}
function outer2(a, b) {
function inner2(a, b) { return a; }
inner2(a, b);
}
Thanks to Adam Strzelecki for working on this.
llvm-svn: 212038
2014-06-30 21:24:54 +08:00
|
|
|
}
|
|
|
|
|
2016-04-25 06:05:09 +08:00
|
|
|
TEST_F(FormatTestJS, GeneratorFunctions) {
|
|
|
|
verifyFormat("function* f() {\n"
|
|
|
|
" let x = 1;\n"
|
|
|
|
" yield x;\n"
|
|
|
|
" yield* something();\n"
|
|
|
|
"}");
|
|
|
|
verifyFormat("function*\n"
|
|
|
|
" f() {\n"
|
|
|
|
"}",
|
|
|
|
getGoogleJSStyleWithColumns(8));
|
|
|
|
verifyFormat("export function* f() {\n"
|
|
|
|
" yield 1;\n"
|
|
|
|
"}\n");
|
|
|
|
verifyFormat("class X {\n"
|
|
|
|
" * generatorMethod() { yield x; }\n"
|
|
|
|
"}");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FormatTestJS, AsyncFunctions) {
|
|
|
|
verifyFormat("async function f() {\n"
|
|
|
|
" let x = 1;\n"
|
|
|
|
" return fetch(x);\n"
|
|
|
|
"}");
|
|
|
|
verifyFormat("async function* f() {\n"
|
|
|
|
" yield fetch(x);\n"
|
|
|
|
"}");
|
|
|
|
verifyFormat("export async function f() {\n"
|
|
|
|
" return fetch(x);\n"
|
|
|
|
"}");
|
|
|
|
verifyFormat("class X {\n"
|
|
|
|
" async asyncMethod() { return fetch(1); }\n"
|
|
|
|
"}");
|
|
|
|
}
|
|
|
|
|
2015-05-28 15:21:50 +08:00
|
|
|
TEST_F(FormatTestJS, ArrayLiterals) {
|
2015-06-17 21:08:06 +08:00
|
|
|
verifyFormat("var aaaaa: List<SomeThing> =\n"
|
|
|
|
" [new SomeThingAAAAAAAAAAAA(), new SomeThingBBBBBBBBB()];");
|
2015-06-03 05:57:51 +08:00
|
|
|
verifyFormat("return [\n"
|
clang-format: [ObjC+JS] Allow bin-packing of array literals.
After reading the style guides again, they don't actually say how to
pack or not pack array literals. Based on some user reports, array
initializers can unnecessarily get quite long if they contain many
small elements. Array literals with trailing commas are still formatted
one per line so that users have a way to opt out of the packing.
Before:
var array = [
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa
];
After:
var array = [
aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa,
aaaaaa, aaaaaa
];
llvm-svn: 257615
2016-01-14 00:41:34 +08:00
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
|
2015-06-03 05:57:51 +08:00
|
|
|
" ccccccccccccccccccccccccccc\n"
|
|
|
|
"];");
|
2016-01-08 02:11:54 +08:00
|
|
|
verifyFormat("return [\n"
|
|
|
|
" aaaa().bbbbbbbb('A'),\n"
|
|
|
|
" aaaa().bbbbbbbb('B'),\n"
|
|
|
|
" aaaa().bbbbbbbb('C'),\n"
|
|
|
|
"];");
|
2015-10-27 20:38:37 +08:00
|
|
|
verifyFormat("var someVariable = SomeFunction([\n"
|
clang-format: [ObjC+JS] Allow bin-packing of array literals.
After reading the style guides again, they don't actually say how to
pack or not pack array literals. Based on some user reports, array
initializers can unnecessarily get quite long if they contain many
small elements. Array literals with trailing commas are still formatted
one per line so that users have a way to opt out of the packing.
Before:
var array = [
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa
];
After:
var array = [
aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa,
aaaaaa, aaaaaa
];
llvm-svn: 257615
2016-01-14 00:41:34 +08:00
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
|
2015-06-02 21:56:43 +08:00
|
|
|
" ccccccccccccccccccccccccccc\n"
|
2015-06-02 22:20:08 +08:00
|
|
|
"]);");
|
2015-10-27 20:38:37 +08:00
|
|
|
verifyFormat("var someVariable = SomeFunction([\n"
|
2015-06-02 23:04:29 +08:00
|
|
|
" [aaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbb],\n"
|
2015-06-02 23:14:21 +08:00
|
|
|
"]);",
|
|
|
|
getGoogleJSStyleWithColumns(51));
|
2015-10-27 20:38:37 +08:00
|
|
|
verifyFormat("var someVariable = SomeFunction(aaaa, [\n"
|
clang-format: [ObjC+JS] Allow bin-packing of array literals.
After reading the style guides again, they don't actually say how to
pack or not pack array literals. Based on some user reports, array
initializers can unnecessarily get quite long if they contain many
small elements. Array literals with trailing commas are still formatted
one per line so that users have a way to opt out of the packing.
Before:
var array = [
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa
];
After:
var array = [
aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa,
aaaaaa, aaaaaa
];
llvm-svn: 257615
2016-01-14 00:41:34 +08:00
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
|
2015-06-02 22:20:08 +08:00
|
|
|
" ccccccccccccccccccccccccccc\n"
|
2015-06-02 21:56:43 +08:00
|
|
|
"]);");
|
2015-10-27 20:38:37 +08:00
|
|
|
verifyFormat("var someVariable = SomeFunction(\n"
|
|
|
|
" aaaa,\n"
|
|
|
|
" [\n"
|
clang-format: [ObjC+JS] Allow bin-packing of array literals.
After reading the style guides again, they don't actually say how to
pack or not pack array literals. Based on some user reports, array
initializers can unnecessarily get quite long if they contain many
small elements. Array literals with trailing commas are still formatted
one per line so that users have a way to opt out of the packing.
Before:
var array = [
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa,
aaaaaa
];
After:
var array = [
aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa, aaaaaa,
aaaaaa, aaaaaa
];
llvm-svn: 257615
2016-01-14 00:41:34 +08:00
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
|
|
|
|
" cccccccccccccccccccccccccc\n"
|
2015-10-27 20:38:37 +08:00
|
|
|
" ],\n"
|
|
|
|
" aaaa);");
|
2016-01-04 21:11:41 +08:00
|
|
|
verifyFormat("var aaaa = aaaaa || // wrap\n"
|
|
|
|
" [];");
|
2015-06-02 23:31:37 +08:00
|
|
|
|
|
|
|
verifyFormat("someFunction([], {a: a});");
|
2015-05-28 15:21:50 +08:00
|
|
|
}
|
|
|
|
|
2015-12-22 23:48:15 +08:00
|
|
|
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"
|
|
|
|
"]);");
|
|
|
|
}
|
|
|
|
|
2014-06-13 15:02:04 +08:00
|
|
|
TEST_F(FormatTestJS, FunctionLiterals) {
|
2014-09-05 16:42:27 +08:00
|
|
|
verifyFormat("doFoo(function() {});");
|
2014-05-07 17:48:30 +08:00
|
|
|
verifyFormat("doFoo(function() { return 1; });");
|
2014-10-01 01:57:06 +08:00
|
|
|
verifyFormat("var func = function() {\n"
|
|
|
|
" return 1;\n"
|
|
|
|
"};");
|
2015-06-18 20:32:59 +08:00
|
|
|
verifyFormat("var func = //\n"
|
|
|
|
" function() {\n"
|
|
|
|
" return 1;\n"
|
|
|
|
"};");
|
2014-05-08 17:25:39 +08:00
|
|
|
verifyFormat("return {\n"
|
|
|
|
" body: {\n"
|
|
|
|
" setAttribute: function(key, val) { this[key] = val; },\n"
|
|
|
|
" getAttribute: function(key) { return this[key]; },\n"
|
|
|
|
" style: {direction: ''}\n"
|
|
|
|
" }\n"
|
|
|
|
"};");
|
2015-10-27 20:38:37 +08:00
|
|
|
verifyFormat("abc = xyz ? function() {\n"
|
|
|
|
" return 1;\n"
|
|
|
|
"} : function() {\n"
|
|
|
|
" return -1;\n"
|
|
|
|
"};");
|
2014-05-21 20:51:23 +08:00
|
|
|
|
|
|
|
verifyFormat("var closure = goog.bind(\n"
|
|
|
|
" function() { // comment\n"
|
|
|
|
" foo();\n"
|
|
|
|
" bar();\n"
|
|
|
|
" },\n"
|
|
|
|
" this, arg1IsReallyLongAndNeeedsLineBreaks,\n"
|
|
|
|
" arg3IsReallyLongAndNeeedsLineBreaks);");
|
|
|
|
verifyFormat("var closure = goog.bind(function() { // comment\n"
|
|
|
|
" foo();\n"
|
|
|
|
" bar();\n"
|
|
|
|
"}, this);");
|
2014-06-06 21:49:04 +08:00
|
|
|
verifyFormat("return {\n"
|
|
|
|
" a: 'E',\n"
|
|
|
|
" b: function() {\n"
|
|
|
|
" return function() {\n"
|
|
|
|
" f(); //\n"
|
|
|
|
" };\n"
|
|
|
|
" }\n"
|
|
|
|
"};");
|
2014-11-27 23:37:42 +08:00
|
|
|
verifyFormat("{\n"
|
|
|
|
" var someVariable = function(x) {\n"
|
|
|
|
" return x.zIsTooLongForOneLineWithTheDeclarationLine();\n"
|
|
|
|
" };\n"
|
|
|
|
"}");
|
2015-05-08 16:38:52 +08:00
|
|
|
verifyFormat("someLooooooooongFunction(\n"
|
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
|
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
|
|
|
|
" function(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n"
|
|
|
|
" // code\n"
|
|
|
|
" });");
|
2014-05-22 16:36:53 +08:00
|
|
|
|
2014-12-05 00:07:17 +08:00
|
|
|
verifyFormat("f({a: function() { return 1; }});",
|
|
|
|
getGoogleJSStyleWithColumns(33));
|
|
|
|
verifyFormat("f({\n"
|
2014-05-22 16:36:53 +08:00
|
|
|
" a: function() { return 1; }\n"
|
2014-12-05 00:07:17 +08:00
|
|
|
"});",
|
|
|
|
getGoogleJSStyleWithColumns(32));
|
2014-06-13 15:02:04 +08:00
|
|
|
|
|
|
|
verifyFormat("return {\n"
|
|
|
|
" a: function SomeFunction() {\n"
|
|
|
|
" // ...\n"
|
|
|
|
" return 1;\n"
|
|
|
|
" }\n"
|
|
|
|
"};");
|
2014-12-12 17:40:58 +08:00
|
|
|
verifyFormat("this.someObject.doSomething(aaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
|
|
|
|
" .then(goog.bind(function(aaaaaaaaaaa) {\n"
|
|
|
|
" someFunction();\n"
|
|
|
|
" someFunction();\n"
|
|
|
|
" }, this), aaaaaaaaaaaaaaaaa);");
|
|
|
|
|
2015-10-27 20:38:37 +08:00
|
|
|
verifyFormat("someFunction(goog.bind(function() {\n"
|
|
|
|
" doSomething();\n"
|
|
|
|
" doSomething();\n"
|
|
|
|
"}, this), goog.bind(function() {\n"
|
|
|
|
" doSomething();\n"
|
|
|
|
" doSomething();\n"
|
|
|
|
"}, this));");
|
2015-06-01 17:56:32 +08:00
|
|
|
|
|
|
|
// FIXME: This is bad, we should be wrapping before "function() {".
|
|
|
|
verifyFormat("someFunction(function() {\n"
|
|
|
|
" doSomething(); // break\n"
|
|
|
|
"})\n"
|
|
|
|
" .doSomethingElse(\n"
|
|
|
|
" // break\n"
|
|
|
|
" );");
|
2014-05-07 17:48:30 +08:00
|
|
|
}
|
|
|
|
|
2014-10-01 01:57:06 +08:00
|
|
|
TEST_F(FormatTestJS, InliningFunctionLiterals) {
|
|
|
|
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
|
|
|
|
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
|
|
|
|
verifyFormat("var func = function() {\n"
|
|
|
|
" return 1;\n"
|
|
|
|
"};",
|
|
|
|
Style);
|
|
|
|
verifyFormat("var func = doSomething(function() { return 1; });", Style);
|
|
|
|
verifyFormat("var outer = function() {\n"
|
|
|
|
" var inner = function() { return 1; }\n"
|
|
|
|
"};",
|
|
|
|
Style);
|
|
|
|
verifyFormat("function outer1(a, b) {\n"
|
|
|
|
" function inner1(a, b) { return a; }\n"
|
|
|
|
"}",
|
|
|
|
Style);
|
|
|
|
|
|
|
|
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
|
|
|
|
verifyFormat("var func = function() { return 1; };", Style);
|
|
|
|
verifyFormat("var func = doSomething(function() { return 1; });", Style);
|
|
|
|
verifyFormat(
|
|
|
|
"var outer = function() { var inner = function() { return 1; } };",
|
|
|
|
Style);
|
|
|
|
verifyFormat("function outer1(a, b) {\n"
|
|
|
|
" function inner1(a, b) { return a; }\n"
|
|
|
|
"}",
|
|
|
|
Style);
|
|
|
|
|
|
|
|
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
|
|
|
|
verifyFormat("var func = function() {\n"
|
|
|
|
" return 1;\n"
|
|
|
|
"};",
|
|
|
|
Style);
|
|
|
|
verifyFormat("var func = doSomething(function() {\n"
|
|
|
|
" return 1;\n"
|
|
|
|
"});",
|
|
|
|
Style);
|
|
|
|
verifyFormat("var outer = function() {\n"
|
|
|
|
" var inner = function() {\n"
|
|
|
|
" return 1;\n"
|
|
|
|
" }\n"
|
|
|
|
"};",
|
|
|
|
Style);
|
|
|
|
verifyFormat("function outer1(a, b) {\n"
|
|
|
|
" function inner1(a, b) {\n"
|
|
|
|
" return a;\n"
|
|
|
|
" }\n"
|
|
|
|
"}",
|
|
|
|
Style);
|
2015-11-21 00:44:28 +08:00
|
|
|
|
|
|
|
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
|
|
|
|
verifyFormat("var func = function() {\n"
|
|
|
|
" return 1;\n"
|
|
|
|
"};",
|
|
|
|
Style);
|
2014-10-01 01:57:06 +08:00
|
|
|
}
|
|
|
|
|
2014-06-03 20:02:45 +08:00
|
|
|
TEST_F(FormatTestJS, MultipleFunctionLiterals) {
|
|
|
|
verifyFormat("promise.then(\n"
|
|
|
|
" function success() {\n"
|
|
|
|
" doFoo();\n"
|
|
|
|
" doBar();\n"
|
|
|
|
" },\n"
|
|
|
|
" function error() {\n"
|
|
|
|
" doFoo();\n"
|
|
|
|
" doBaz();\n"
|
|
|
|
" },\n"
|
|
|
|
" []);\n");
|
|
|
|
verifyFormat("promise.then(\n"
|
|
|
|
" function success() {\n"
|
|
|
|
" doFoo();\n"
|
|
|
|
" doBar();\n"
|
|
|
|
" },\n"
|
|
|
|
" [],\n"
|
|
|
|
" function error() {\n"
|
|
|
|
" doFoo();\n"
|
|
|
|
" doBaz();\n"
|
|
|
|
" });\n");
|
2015-10-27 20:38:37 +08:00
|
|
|
verifyFormat("promise.then(\n"
|
|
|
|
" [],\n"
|
|
|
|
" function success() {\n"
|
|
|
|
" doFoo();\n"
|
|
|
|
" doBar();\n"
|
|
|
|
" },\n"
|
|
|
|
" function error() {\n"
|
|
|
|
" doFoo();\n"
|
|
|
|
" doBaz();\n"
|
|
|
|
" });\n");
|
2014-09-29 15:54:54 +08:00
|
|
|
|
|
|
|
verifyFormat("getSomeLongPromise()\n"
|
|
|
|
" .then(function(value) { body(); })\n"
|
2014-12-12 17:40:58 +08:00
|
|
|
" .thenCatch(function(error) {\n"
|
|
|
|
" body();\n"
|
|
|
|
" body();\n"
|
|
|
|
" });");
|
2014-09-29 15:54:54 +08:00
|
|
|
verifyFormat("getSomeLongPromise()\n"
|
|
|
|
" .then(function(value) {\n"
|
|
|
|
" body();\n"
|
|
|
|
" body();\n"
|
|
|
|
" })\n"
|
|
|
|
" .thenCatch(function(error) {\n"
|
|
|
|
" body();\n"
|
|
|
|
" body();\n"
|
|
|
|
" });");
|
2014-12-12 17:40:58 +08:00
|
|
|
|
2015-04-07 16:20:35 +08:00
|
|
|
verifyFormat("getSomeLongPromise()\n"
|
|
|
|
" .then(function(value) { body(); })\n"
|
|
|
|
" .thenCatch(function(error) { body(); });");
|
2016-01-11 19:00:58 +08:00
|
|
|
|
|
|
|
verifyFormat("return [aaaaaaaaaaaaaaaaaaaaaa]\n"
|
|
|
|
" .aaaaaaa(function() {\n"
|
|
|
|
" //\n"
|
|
|
|
" })\n"
|
|
|
|
" .bbbbbb();");
|
2014-06-03 20:02:45 +08:00
|
|
|
}
|
|
|
|
|
2015-05-21 20:23:34 +08:00
|
|
|
TEST_F(FormatTestJS, ArrowFunctions) {
|
|
|
|
verifyFormat("var x = (a) => {\n"
|
|
|
|
" return a;\n"
|
|
|
|
"};");
|
|
|
|
verifyFormat("var x = (a) => {\n"
|
|
|
|
" function y() { return 42; }\n"
|
|
|
|
" return a;\n"
|
|
|
|
"};");
|
|
|
|
verifyFormat("var x = (a: type): {some: type} => {\n"
|
|
|
|
" return a;\n"
|
|
|
|
"};");
|
|
|
|
verifyFormat("var x = (a) => a;");
|
2015-06-03 06:06:07 +08:00
|
|
|
verifyFormat("return () => [];");
|
2015-06-04 01:08:40 +08:00
|
|
|
verifyFormat("var aaaaaaaaaaaaaaaaaaaa = {\n"
|
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n"
|
|
|
|
" (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
|
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) =>\n"
|
2015-06-05 16:25:37 +08:00
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
|
2015-06-04 01:08:40 +08:00
|
|
|
"};");
|
2015-10-27 20:38:37 +08:00
|
|
|
verifyFormat("var a = a.aaaaaaa(\n"
|
|
|
|
" (a: a) => aaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbb) &&\n"
|
2015-12-21 21:52:19 +08:00
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbb));");
|
2015-10-27 20:38:37 +08:00
|
|
|
verifyFormat("var a = a.aaaaaaa(\n"
|
|
|
|
" (a: a) => aaaaaaaaaaaaaaaaaaaaa(bbbbbbbbb) ?\n"
|
2015-12-21 21:52:19 +08:00
|
|
|
" aaaaaaaaaaaaaaaaaaaaa(bbbbbbb) :\n"
|
|
|
|
" aaaaaaaaaaaaaaaaaaaaa(bbbbbbb));");
|
2015-06-01 17:56:32 +08:00
|
|
|
|
|
|
|
// FIXME: This is bad, we should be wrapping before "() => {".
|
|
|
|
verifyFormat("someFunction(() => {\n"
|
|
|
|
" doSomething(); // break\n"
|
|
|
|
"})\n"
|
|
|
|
" .doSomethingElse(\n"
|
|
|
|
" // break\n"
|
|
|
|
" );");
|
2015-05-21 20:23:34 +08:00
|
|
|
}
|
|
|
|
|
2014-05-06 22:12:21 +08:00
|
|
|
TEST_F(FormatTestJS, ReturnStatements) {
|
2014-10-01 01:57:06 +08:00
|
|
|
verifyFormat("function() {\n"
|
|
|
|
" return [hello, world];\n"
|
|
|
|
"}");
|
2014-05-06 22:12:21 +08:00
|
|
|
}
|
|
|
|
|
2015-11-21 00:18:42 +08:00
|
|
|
TEST_F(FormatTestJS, ForLoops) {
|
|
|
|
verifyFormat("for (var i in [2, 3]) {\n"
|
|
|
|
"}");
|
2016-02-11 21:24:15 +08:00
|
|
|
verifyFormat("for (var i of [2, 3]) {\n"
|
|
|
|
"}");
|
2016-03-06 02:34:26 +08:00
|
|
|
verifyFormat("for (let {a, b} of x) {\n"
|
|
|
|
"}");
|
|
|
|
verifyFormat("for (let {a, b} in x) {\n"
|
|
|
|
"}");
|
2015-11-21 00:18:42 +08:00
|
|
|
}
|
|
|
|
|
2016-03-15 03:21:36 +08:00
|
|
|
TEST_F(FormatTestJS, WrapRespectsAutomaticSemicolonInsertion) {
|
2015-06-12 12:58:27 +08:00
|
|
|
// The following statements must not wrap, as otherwise the program meaning
|
|
|
|
// 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("continue aaaaa;", getGoogleJSStyleWithColumns(10));
|
|
|
|
verifyFormat("break aaaaa;", getGoogleJSStyleWithColumns(10));
|
|
|
|
verifyFormat("throw aaaaa;", getGoogleJSStyleWithColumns(10));
|
|
|
|
verifyFormat("aaaaaaaaa++;", getGoogleJSStyleWithColumns(10));
|
|
|
|
verifyFormat("aaaaaaaaa--;", getGoogleJSStyleWithColumns(10));
|
2016-01-14 13:37:52 +08:00
|
|
|
verifyFormat("return [\n"
|
|
|
|
" aaa\n"
|
|
|
|
"];",
|
|
|
|
getGoogleJSStyleWithColumns(12));
|
2015-06-12 12:58:27 +08:00
|
|
|
}
|
|
|
|
|
2016-03-15 03:21:36 +08:00
|
|
|
TEST_F(FormatTestJS, AutomaticSemicolonInsertionHeuristic) {
|
|
|
|
verifyFormat("a\n"
|
|
|
|
"b;",
|
|
|
|
" a \n"
|
|
|
|
" b ;");
|
|
|
|
verifyFormat("a()\n"
|
|
|
|
"b;",
|
|
|
|
" a ()\n"
|
|
|
|
" b ;");
|
|
|
|
verifyFormat("a[b]\n"
|
|
|
|
"c;",
|
|
|
|
"a [b]\n"
|
|
|
|
"c ;");
|
|
|
|
verifyFormat("1\n"
|
|
|
|
"a;",
|
|
|
|
"1 \n"
|
|
|
|
"a ;");
|
|
|
|
verifyFormat("a\n"
|
|
|
|
"1;",
|
|
|
|
"a \n"
|
|
|
|
"1 ;");
|
|
|
|
verifyFormat("a\n"
|
|
|
|
"'x';",
|
|
|
|
"a \n"
|
|
|
|
" 'x';");
|
|
|
|
verifyFormat("a++\n"
|
|
|
|
"b;",
|
|
|
|
"a ++\n"
|
|
|
|
"b ;");
|
|
|
|
verifyFormat("a\n"
|
|
|
|
"!b && c;",
|
|
|
|
"a \n"
|
|
|
|
" ! b && c;");
|
|
|
|
verifyFormat("a\n"
|
|
|
|
"if (1) f();",
|
|
|
|
" a\n"
|
|
|
|
" if (1) f();");
|
|
|
|
verifyFormat("a\n"
|
|
|
|
"class X {}",
|
|
|
|
" a\n"
|
|
|
|
" class X {}");
|
|
|
|
verifyFormat("var a", "var\n"
|
|
|
|
"a");
|
|
|
|
verifyFormat("x instanceof String", "x\n"
|
|
|
|
"instanceof\n"
|
|
|
|
"String");
|
2016-04-11 15:35:57 +08:00
|
|
|
verifyFormat("function f(@Foo bar) {}", "function f(@Foo\n"
|
|
|
|
" bar) {}");
|
2016-03-15 03:21:36 +08:00
|
|
|
}
|
|
|
|
|
2015-05-21 20:23:34 +08:00
|
|
|
TEST_F(FormatTestJS, ClosureStyleCasts) {
|
2014-05-06 22:41:29 +08:00
|
|
|
verifyFormat("var x = /** @type {foo} */ (bar);");
|
|
|
|
}
|
|
|
|
|
2014-05-08 19:58:24 +08:00
|
|
|
TEST_F(FormatTestJS, TryCatch) {
|
|
|
|
verifyFormat("try {\n"
|
|
|
|
" f();\n"
|
|
|
|
"} catch (e) {\n"
|
|
|
|
" g();\n"
|
|
|
|
"} finally {\n"
|
|
|
|
" h();\n"
|
|
|
|
"}");
|
2014-09-04 23:03:34 +08:00
|
|
|
|
|
|
|
// But, of course, "catch" is a perfectly fine function name in JavaScript.
|
|
|
|
verifyFormat("someObject.catch();");
|
2014-11-27 22:55:17 +08:00
|
|
|
verifyFormat("someObject.new();");
|
|
|
|
verifyFormat("someObject.delete();");
|
2014-05-08 19:58:24 +08:00
|
|
|
}
|
|
|
|
|
2014-05-22 17:10:04 +08:00
|
|
|
TEST_F(FormatTestJS, StringLiteralConcatenation) {
|
|
|
|
verifyFormat("var literal = 'hello ' +\n"
|
2015-12-21 21:52:19 +08:00
|
|
|
" 'world';");
|
2014-05-22 17:10:04 +08:00
|
|
|
}
|
|
|
|
|
2014-05-08 15:01:45 +08:00
|
|
|
TEST_F(FormatTestJS, RegexLiteralClassification) {
|
|
|
|
// Regex literals.
|
|
|
|
verifyFormat("var regex = /abc/;");
|
|
|
|
verifyFormat("f(/abc/);");
|
|
|
|
verifyFormat("f(abc, /abc/);");
|
|
|
|
verifyFormat("some_map[/abc/];");
|
|
|
|
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 = a && /abc/.test(y);");
|
|
|
|
verifyFormat("var x = a || /abc/.test(y);");
|
|
|
|
verifyFormat("var x = a + /abc/.search(y);");
|
2015-07-02 21:20:45 +08:00
|
|
|
verifyFormat("/abc/.search(y);");
|
2014-05-08 15:45:18 +08:00
|
|
|
verifyFormat("var regexs = {/abc/, /abc/};");
|
|
|
|
verifyFormat("return /abc/;");
|
2014-05-08 15:01:45 +08:00
|
|
|
|
|
|
|
// Not regex literals.
|
|
|
|
verifyFormat("var a = a / 2 + b / 3;");
|
2015-10-18 15:02:28 +08:00
|
|
|
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);");
|
2014-05-08 15:01:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FormatTestJS, RegexLiteralSpecialCharacters) {
|
2015-05-08 15:55:13 +08:00
|
|
|
verifyFormat("var regex = /=/;");
|
2014-05-08 15:01:45 +08:00
|
|
|
verifyFormat("var regex = /a*/;");
|
|
|
|
verifyFormat("var regex = /a+/;");
|
|
|
|
verifyFormat("var regex = /a?/;");
|
|
|
|
verifyFormat("var regex = /.a./;");
|
|
|
|
verifyFormat("var regex = /a\\*/;");
|
|
|
|
verifyFormat("var regex = /^a$/;");
|
|
|
|
verifyFormat("var regex = /\\/a/;");
|
|
|
|
verifyFormat("var regex = /(?:x)/;");
|
|
|
|
verifyFormat("var regex = /x(?=y)/;");
|
|
|
|
verifyFormat("var regex = /x(?!y)/;");
|
|
|
|
verifyFormat("var regex = /x|y/;");
|
|
|
|
verifyFormat("var regex = /a{2}/;");
|
|
|
|
verifyFormat("var regex = /a{1,3}/;");
|
2015-10-12 11:13:48 +08:00
|
|
|
|
2014-05-08 15:01:45 +08:00
|
|
|
verifyFormat("var regex = /[abc]/;");
|
|
|
|
verifyFormat("var regex = /[^abc]/;");
|
|
|
|
verifyFormat("var regex = /[\\b]/;");
|
2015-10-12 11:13:48 +08:00
|
|
|
verifyFormat("var regex = /[/]/;");
|
|
|
|
verifyFormat("var regex = /[\\/]/;");
|
|
|
|
verifyFormat("var regex = /\\[/;");
|
|
|
|
verifyFormat("var regex = /\\\\[/]/;");
|
2015-10-18 15:02:28 +08:00
|
|
|
verifyFormat("var regex = /}[\"]/;");
|
|
|
|
verifyFormat("var regex = /}[/\"]/;");
|
|
|
|
verifyFormat("var regex = /}[\"/]/;");
|
2015-10-12 11:13:48 +08:00
|
|
|
|
2014-05-08 15:01:45 +08:00
|
|
|
verifyFormat("var regex = /\\b/;");
|
|
|
|
verifyFormat("var regex = /\\B/;");
|
|
|
|
verifyFormat("var regex = /\\d/;");
|
|
|
|
verifyFormat("var regex = /\\D/;");
|
|
|
|
verifyFormat("var regex = /\\f/;");
|
|
|
|
verifyFormat("var regex = /\\n/;");
|
|
|
|
verifyFormat("var regex = /\\r/;");
|
|
|
|
verifyFormat("var regex = /\\s/;");
|
|
|
|
verifyFormat("var regex = /\\S/;");
|
|
|
|
verifyFormat("var regex = /\\t/;");
|
|
|
|
verifyFormat("var regex = /\\v/;");
|
|
|
|
verifyFormat("var regex = /\\w/;");
|
|
|
|
verifyFormat("var regex = /\\W/;");
|
|
|
|
verifyFormat("var regex = /a(a)\\1/;");
|
|
|
|
verifyFormat("var regex = /\\0/;");
|
2014-05-12 19:29:50 +08:00
|
|
|
verifyFormat("var regex = /\\\\/g;");
|
|
|
|
verifyFormat("var regex = /\\a\\\\/g;");
|
|
|
|
verifyFormat("var regex = /\a\\//g;");
|
2014-09-09 22:37:39 +08:00
|
|
|
verifyFormat("var regex = /a\\//;\n"
|
|
|
|
"var x = 0;");
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var regex = /'/g;", "var regex = /'/g ;");
|
|
|
|
verifyFormat("var regex = /'/g; //'", "var regex = /'/g ; //'");
|
|
|
|
verifyFormat("var regex = /\\/*/;\n"
|
|
|
|
"var x = 0;",
|
|
|
|
"var regex = /\\/*/;\n"
|
|
|
|
"var x=0;");
|
|
|
|
verifyFormat("var x = /a\\//;", "var x = /a\\// \n;");
|
2015-06-25 00:01:02 +08:00
|
|
|
verifyFormat("var regex = /\"/;", getGoogleJSStyleWithColumns(16));
|
|
|
|
verifyFormat("var regex =\n"
|
|
|
|
" /\"/;",
|
|
|
|
getGoogleJSStyleWithColumns(15));
|
2015-07-02 22:14:04 +08:00
|
|
|
verifyFormat("var regex = //\n"
|
|
|
|
" /a/;");
|
2015-07-02 23:00:44 +08:00
|
|
|
verifyFormat("var regexs = [\n"
|
|
|
|
" /d/, //\n"
|
|
|
|
" /aa/, //\n"
|
|
|
|
"];");
|
2014-05-08 15:01:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FormatTestJS, RegexLiteralModifiers) {
|
|
|
|
verifyFormat("var regex = /abc/g;");
|
|
|
|
verifyFormat("var regex = /abc/i;");
|
|
|
|
verifyFormat("var regex = /abc/m;");
|
|
|
|
verifyFormat("var regex = /abc/y;");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FormatTestJS, RegexLiteralLength) {
|
|
|
|
verifyFormat("var regex = /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
|
|
|
|
getGoogleJSStyleWithColumns(60));
|
|
|
|
verifyFormat("var regex =\n"
|
|
|
|
" /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
|
|
|
|
getGoogleJSStyleWithColumns(60));
|
2014-12-17 17:11:08 +08:00
|
|
|
verifyFormat("var regex = /\\xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
|
|
|
|
getGoogleJSStyleWithColumns(50));
|
2014-05-08 15:01:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FormatTestJS, RegexLiteralExamples) {
|
|
|
|
verifyFormat("var regex = search.match(/(?:\?|&)times=([^?&]+)/i);");
|
|
|
|
}
|
|
|
|
|
2015-02-19 01:09:53 +08:00
|
|
|
TEST_F(FormatTestJS, TypeAnnotations) {
|
|
|
|
verifyFormat("var x: string;");
|
2016-01-09 23:56:28 +08:00
|
|
|
verifyFormat("var x: {a: string; b: number;} = {};");
|
2015-02-19 01:09:53 +08:00
|
|
|
verifyFormat("function x(): string {\n return 'x';\n}");
|
2015-05-21 20:23:34 +08:00
|
|
|
verifyFormat("function x(): {x: string} {\n return {x: 'x'};\n}");
|
2015-02-19 01:09:53 +08:00
|
|
|
verifyFormat("function x(y: string): string {\n return 'x';\n}");
|
|
|
|
verifyFormat("for (var y: string in x) {\n x();\n}");
|
2016-02-11 21:24:15 +08:00
|
|
|
verifyFormat("for (var y: string of x) {\n x();\n}");
|
2016-01-09 23:56:28 +08:00
|
|
|
verifyFormat("function x(y: {a?: number;} = {}): number {\n"
|
|
|
|
" return 12;\n"
|
|
|
|
"}");
|
2015-02-19 01:09:53 +08:00
|
|
|
verifyFormat("((a: string, b: number): string => a + b);");
|
|
|
|
verifyFormat("var x: (y: number) => string;");
|
|
|
|
verifyFormat("var x: P<string, (a: number) => string>;");
|
2015-05-21 20:23:34 +08:00
|
|
|
verifyFormat("var x = {y: function(): z { return 1; }};");
|
|
|
|
verifyFormat("var x = {y: function(): {a: number} { return 1; }};");
|
2016-01-08 18:51:24 +08:00
|
|
|
verifyFormat("function someFunc(args: string[]):\n"
|
|
|
|
" {longReturnValue: string[]} {}",
|
|
|
|
getGoogleJSStyleWithColumns(60));
|
2015-02-19 01:09:53 +08:00
|
|
|
}
|
|
|
|
|
2016-03-22 01:57:31 +08:00
|
|
|
TEST_F(FormatTestJS, UnionIntersectionTypes) {
|
|
|
|
verifyFormat("let x: A|B = A | B;");
|
|
|
|
verifyFormat("let x: A&B|C = A & B;");
|
|
|
|
verifyFormat("let x: Foo<A|B> = new Foo<A|B>();");
|
|
|
|
verifyFormat("function(x: A|B): C&D {}");
|
|
|
|
verifyFormat("function(x: A|B = A | B): C&D {}");
|
|
|
|
}
|
|
|
|
|
2015-02-19 01:14:05 +08:00
|
|
|
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 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 extends P implements I {}");
|
2015-04-13 22:56:54 +08:00
|
|
|
verifyFormat("class C extends p.P implements i.I {}");
|
2015-07-10 21:39:26 +08:00
|
|
|
verifyFormat("class Test {\n"
|
|
|
|
" aaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaa):\n"
|
|
|
|
" aaaaaaaaaaaaaaaaaaaaaa {}\n"
|
|
|
|
"}");
|
2016-01-08 15:06:07 +08:00
|
|
|
verifyFormat("foo = class Name {\n"
|
|
|
|
" constructor() {}\n"
|
|
|
|
"};");
|
|
|
|
verifyFormat("foo = class {\n"
|
|
|
|
" constructor() {}\n"
|
|
|
|
"};");
|
2016-01-09 23:56:28 +08:00
|
|
|
verifyFormat("class C {\n"
|
|
|
|
" x: {y: Z;} = {};\n"
|
|
|
|
" private y: {y: Z;} = {};\n"
|
|
|
|
"}");
|
2015-06-03 16:43:18 +08:00
|
|
|
|
|
|
|
// ':' is not a type declaration here.
|
|
|
|
verifyFormat("class X {\n"
|
|
|
|
" subs = {\n"
|
|
|
|
" 'b': {\n"
|
|
|
|
" 'c': 1,\n"
|
|
|
|
" },\n"
|
|
|
|
" };\n"
|
|
|
|
"}");
|
2015-02-19 01:14:05 +08:00
|
|
|
}
|
|
|
|
|
2015-05-05 16:12:50 +08:00
|
|
|
TEST_F(FormatTestJS, InterfaceDeclarations) {
|
|
|
|
verifyFormat("interface I {\n"
|
|
|
|
" x: string;\n"
|
2015-12-29 16:54:23 +08:00
|
|
|
" enum: string[];\n"
|
2016-02-03 13:33:44 +08:00
|
|
|
" enum?: string[];\n"
|
2015-06-12 12:56:34 +08:00
|
|
|
"}\n"
|
|
|
|
"var y;");
|
2015-07-06 22:26:04 +08:00
|
|
|
// Ensure that state is reset after parsing the interface.
|
|
|
|
verifyFormat("interface a {}\n"
|
|
|
|
"export function b() {}\n"
|
|
|
|
"var x;");
|
2015-12-22 23:48:35 +08:00
|
|
|
|
|
|
|
// Arrays of object type literals.
|
|
|
|
verifyFormat("interface I {\n"
|
|
|
|
" o: {}[];\n"
|
|
|
|
"}");
|
2015-05-05 16:12:50 +08:00
|
|
|
}
|
|
|
|
|
2015-06-17 17:44:02 +08:00
|
|
|
TEST_F(FormatTestJS, EnumDeclarations) {
|
2015-06-17 17:44:07 +08:00
|
|
|
verifyFormat("enum Foo {\n"
|
|
|
|
" A = 1,\n"
|
|
|
|
" B\n"
|
|
|
|
"}");
|
|
|
|
verifyFormat("export /* somecomment*/ enum Foo {\n"
|
|
|
|
" A = 1,\n"
|
|
|
|
" B\n"
|
|
|
|
"}");
|
2015-06-17 17:44:02 +08:00
|
|
|
verifyFormat("enum Foo {\n"
|
|
|
|
" A = 1, // comment\n"
|
|
|
|
" B\n"
|
|
|
|
"}\n"
|
|
|
|
"var x = 1;");
|
|
|
|
}
|
|
|
|
|
2015-02-19 01:17:15 +08:00
|
|
|
TEST_F(FormatTestJS, MetadataAnnotations) {
|
|
|
|
verifyFormat("@A\nclass C {\n}");
|
|
|
|
verifyFormat("@A({arg: 'value'})\nclass C {\n}");
|
|
|
|
verifyFormat("@A\n@B\nclass C {\n}");
|
|
|
|
verifyFormat("class C {\n @A x: string;\n}");
|
|
|
|
verifyFormat("class C {\n"
|
|
|
|
" @A\n"
|
|
|
|
" private x(): string {\n"
|
|
|
|
" return 'y';\n"
|
|
|
|
" }\n"
|
|
|
|
"}");
|
2016-04-11 17:17:57 +08:00
|
|
|
verifyFormat("class C {\n"
|
|
|
|
" private x(@A x: string) {}\n"
|
|
|
|
"}");
|
2015-02-20 00:03:16 +08:00
|
|
|
verifyFormat("class X {}\n"
|
|
|
|
"class Y {}");
|
2015-02-19 01:17:15 +08:00
|
|
|
}
|
|
|
|
|
2016-04-19 22:59:16 +08:00
|
|
|
TEST_F(FormatTestJS, TypeAliases) {
|
|
|
|
verifyFormat("type X = number;\n"
|
|
|
|
"class C {}");
|
|
|
|
verifyFormat("type X<Y> = Z<Y>;");
|
|
|
|
verifyFormat("type X = {\n"
|
|
|
|
" y: number\n"
|
|
|
|
"};\n"
|
|
|
|
"class C {}");
|
|
|
|
}
|
|
|
|
|
2015-02-20 00:07:32 +08:00
|
|
|
TEST_F(FormatTestJS, Modules) {
|
|
|
|
verifyFormat("import SomeThing from 'some/module.js';");
|
|
|
|
verifyFormat("import {X, Y} from 'some/module.js';");
|
2016-01-07 16:53:35 +08:00
|
|
|
verifyFormat("import a, {X, Y} from 'some/module.js';");
|
2016-03-22 22:32:20 +08:00
|
|
|
verifyFormat("import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,"
|
|
|
|
" VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying"
|
2015-02-20 00:07:32 +08:00
|
|
|
"} from 'some/module.js';");
|
2016-03-22 22:32:20 +08:00
|
|
|
verifyFormat("import {X, Y,} from 'some/module.js';");
|
2015-02-20 00:07:32 +08:00
|
|
|
verifyFormat("import {X as myLocalX, Y as myLocalY} from 'some/module.js';");
|
|
|
|
verifyFormat("import * as lib from 'some/module.js';");
|
2015-03-15 21:55:54 +08:00
|
|
|
verifyFormat("var x = {import: 1};\nx.import = 2;");
|
2015-02-20 00:14:18 +08:00
|
|
|
|
|
|
|
verifyFormat("export function fn() {\n"
|
|
|
|
" return 'fn';\n"
|
|
|
|
"}");
|
2015-06-11 21:31:45 +08:00
|
|
|
verifyFormat("export function A() {}\n"
|
|
|
|
"export default function B() {}\n"
|
|
|
|
"export function C() {}");
|
2016-04-19 22:55:37 +08:00
|
|
|
verifyFormat("export default () => {\n"
|
|
|
|
" let x = 1;\n"
|
|
|
|
" return x;\n"
|
|
|
|
"}");
|
2015-02-20 00:07:32 +08:00
|
|
|
verifyFormat("export const x = 12;");
|
|
|
|
verifyFormat("export default class X {}");
|
2015-02-20 00:14:18 +08:00
|
|
|
verifyFormat("export {X, Y} from 'some/module.js';");
|
2016-03-22 22:32:20 +08:00
|
|
|
verifyFormat("export {X, Y,} from 'some/module.js';");
|
|
|
|
verifyFormat("export {SomeVeryLongExport as X, "
|
|
|
|
"SomeOtherVeryLongExport as Y} from 'some/module.js';");
|
|
|
|
// export without 'from' is wrapped.
|
|
|
|
verifyFormat("export let someRatherLongVariableName =\n"
|
|
|
|
" someSurprisinglyLongVariable + someOtherRatherLongVar;");
|
|
|
|
// ... but not if from is just an identifier.
|
2015-02-20 00:14:18 +08:00
|
|
|
verifyFormat("export {\n"
|
2016-03-22 22:32:20 +08:00
|
|
|
" from as from,\n"
|
|
|
|
" someSurprisinglyLongVariable\n"
|
|
|
|
" as from\n"
|
|
|
|
"};",
|
|
|
|
getGoogleJSStyleWithColumns(20));
|
2015-02-20 00:14:18 +08:00
|
|
|
verifyFormat("export class C {\n"
|
|
|
|
" x: number;\n"
|
|
|
|
" y: string;\n"
|
|
|
|
"}");
|
|
|
|
verifyFormat("export class X { y: number; }");
|
2016-01-12 14:24:38 +08:00
|
|
|
verifyFormat("export abstract class X { y: number; }");
|
2015-02-20 00:14:18 +08:00
|
|
|
verifyFormat("export default class X { y: number }");
|
|
|
|
verifyFormat("export default function() {\n return 1;\n}");
|
|
|
|
verifyFormat("export var x = 12;");
|
2015-06-12 12:52:02 +08:00
|
|
|
verifyFormat("class C {}\n"
|
|
|
|
"export function f() {}\n"
|
|
|
|
"var v;");
|
2015-02-20 00:14:18 +08:00
|
|
|
verifyFormat("export var x: number = 12;");
|
|
|
|
verifyFormat("export const y = {\n"
|
|
|
|
" a: 1,\n"
|
|
|
|
" b: 2\n"
|
|
|
|
"};");
|
2015-06-12 13:08:18 +08:00
|
|
|
verifyFormat("export enum Foo {\n"
|
|
|
|
" BAR,\n"
|
|
|
|
" // adsdasd\n"
|
|
|
|
" BAZ\n"
|
|
|
|
"}");
|
2016-01-04 23:51:56 +08:00
|
|
|
verifyFormat("export default [\n"
|
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
|
|
|
|
" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
|
|
|
|
"];");
|
|
|
|
verifyFormat("export default [];");
|
2016-01-05 00:10:36 +08:00
|
|
|
verifyFormat("export default () => {};");
|
2016-01-12 06:57:40 +08:00
|
|
|
verifyFormat("export interface Foo { foo: number; }\n"
|
|
|
|
"export class Bar {\n"
|
|
|
|
" blah(): string { return this.blah; };\n"
|
|
|
|
"}");
|
2015-02-20 00:07:32 +08:00
|
|
|
}
|
|
|
|
|
2015-02-20 21:47:38 +08:00
|
|
|
TEST_F(FormatTestJS, TemplateStrings) {
|
|
|
|
// Keeps any whitespace/indentation within the template string.
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var x = `hello\n"
|
2015-02-20 21:47:38 +08:00
|
|
|
" ${ name }\n"
|
|
|
|
" !`;",
|
2016-03-15 03:21:36 +08:00
|
|
|
"var x = `hello\n"
|
2015-02-20 21:47:38 +08:00
|
|
|
" ${ name }\n"
|
2016-03-15 03:21:36 +08:00
|
|
|
" !`;");
|
2015-02-20 21:47:38 +08:00
|
|
|
|
|
|
|
verifyFormat("var x =\n"
|
|
|
|
" `hello ${world}` >= some();",
|
|
|
|
getGoogleJSStyleWithColumns(34)); // Barely doesn't fit.
|
|
|
|
verifyFormat("var x = `hello ${world}` >= some();",
|
2015-07-02 21:08:28 +08:00
|
|
|
getGoogleJSStyleWithColumns(35)); // Barely fits.
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var x = `hello\n"
|
2015-02-20 21:47:38 +08:00
|
|
|
" ${world}` >=\n"
|
2015-12-21 21:52:19 +08:00
|
|
|
" some();",
|
2016-03-15 03:21:36 +08:00
|
|
|
"var x =\n"
|
2015-02-20 21:47:38 +08:00
|
|
|
" `hello\n"
|
|
|
|
" ${world}` >= some();",
|
2016-03-15 03:21:36 +08:00
|
|
|
getGoogleJSStyleWithColumns(21)); // Barely doesn't fit.
|
|
|
|
verifyFormat("var x = `hello\n"
|
2015-02-20 21:47:38 +08:00
|
|
|
" ${world}` >= some();",
|
2016-03-15 03:21:36 +08:00
|
|
|
"var x =\n"
|
2015-02-20 21:47:38 +08:00
|
|
|
" `hello\n"
|
|
|
|
" ${world}` >= some();",
|
2016-03-15 03:21:36 +08:00
|
|
|
getGoogleJSStyleWithColumns(22)); // Barely fits.
|
2015-02-20 21:47:38 +08:00
|
|
|
|
2015-07-02 21:08:28 +08:00
|
|
|
verifyFormat("var x =\n"
|
|
|
|
" `h`;",
|
|
|
|
getGoogleJSStyleWithColumns(11));
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var x =\n `multi\n line`;", "var x = `multi\n line`;",
|
|
|
|
getGoogleJSStyleWithColumns(13));
|
2015-07-02 21:08:28 +08:00
|
|
|
verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
|
|
|
|
" `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`);");
|
2015-02-20 21:47:38 +08:00
|
|
|
|
2015-05-02 16:05:38 +08:00
|
|
|
// Make sure template strings get a proper ColumnWidth assigned, even if they
|
|
|
|
// are first token in line.
|
|
|
|
verifyFormat(
|
|
|
|
"var a = aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
|
2015-12-21 21:52:19 +08:00
|
|
|
" `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`;");
|
2015-05-02 16:05:38 +08:00
|
|
|
|
2015-02-20 21:47:38 +08:00
|
|
|
// Two template strings.
|
|
|
|
verifyFormat("var x = `hello` == `hello`;");
|
2015-04-16 16:20:51 +08:00
|
|
|
|
|
|
|
// Comments in template strings.
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var x = `//a`;\n"
|
2015-04-16 16:20:51 +08:00
|
|
|
"var y;",
|
2016-03-15 03:21:36 +08:00
|
|
|
"var x =\n `//a`;\n"
|
|
|
|
"var y ;");
|
|
|
|
verifyFormat("var x = `/*a`;\n"
|
|
|
|
"var y;",
|
|
|
|
"var x =\n `/*a`;\n"
|
|
|
|
"var y;");
|
2015-06-14 15:16:57 +08:00
|
|
|
// Unterminated string literals in a template string.
|
|
|
|
verifyFormat("var x = `'`; // comment with matching quote '\n"
|
|
|
|
"var y;");
|
|
|
|
verifyFormat("var x = `\"`; // comment with matching quote \"\n"
|
|
|
|
"var y;");
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("it(`'aaaaaaaaaaaaaaa `, aaaaaaaaa);",
|
|
|
|
"it(`'aaaaaaaaaaaaaaa `, aaaaaaaaa) ;",
|
|
|
|
getGoogleJSStyleWithColumns(40));
|
2015-04-16 16:20:51 +08:00
|
|
|
// Backticks in a comment - not a template string.
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var x = 1 // `/*a`;\n"
|
|
|
|
" ;",
|
|
|
|
"var x =\n 1 // `/*a`;\n"
|
|
|
|
" ;");
|
|
|
|
verifyFormat("/* ` */ var x = 1; /* ` */", "/* ` */ var x\n= 1; /* ` */");
|
2015-04-16 16:20:51 +08:00
|
|
|
// Comment spans multiple template strings.
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var x = `/*a`;\n"
|
|
|
|
"var y = ` */ `;",
|
|
|
|
"var x =\n `/*a`;\n"
|
|
|
|
"var y =\n ` */ `;");
|
2015-04-16 16:20:51 +08:00
|
|
|
// Escaped backtick.
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var x = ` \\` a`;\n"
|
|
|
|
"var y;",
|
|
|
|
"var x = ` \\` a`;\n"
|
|
|
|
"var y;");
|
2015-02-20 21:47:38 +08:00
|
|
|
}
|
|
|
|
|
2016-04-19 22:59:16 +08:00
|
|
|
TEST_F(FormatTestJS, CastSyntax) {
|
|
|
|
verifyFormat("var x = <type>foo;");
|
|
|
|
verifyFormat("var x = foo as type;");
|
|
|
|
}
|
2015-03-15 21:59:51 +08:00
|
|
|
|
|
|
|
TEST_F(FormatTestJS, TypeArguments) {
|
|
|
|
verifyFormat("class X<Y> {}");
|
|
|
|
verifyFormat("new X<Y>();");
|
|
|
|
verifyFormat("foo<Y>(a);");
|
|
|
|
verifyFormat("var x: X<Y>[];");
|
|
|
|
verifyFormat("class C extends D<E> implements F<G>, H<I> {}");
|
2015-06-11 21:31:45 +08:00
|
|
|
verifyFormat("function f(a: List<any> = null) {}");
|
|
|
|
verifyFormat("function f(): List<any> {}");
|
2015-07-03 18:37:23 +08:00
|
|
|
verifyFormat("function aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa():\n"
|
|
|
|
" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {}");
|
2015-10-27 20:38:37 +08:00
|
|
|
verifyFormat("function aaaaaaaaaa(\n"
|
|
|
|
" aaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaa,\n"
|
|
|
|
" aaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaa):\n"
|
2015-07-06 22:07:51 +08:00
|
|
|
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {}");
|
2015-03-15 21:59:51 +08:00
|
|
|
}
|
|
|
|
|
2015-12-30 16:00:58 +08:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2015-04-13 23:01:40 +08:00
|
|
|
TEST_F(FormatTestJS, OptionalTypes) {
|
2015-06-11 21:31:45 +08:00
|
|
|
verifyFormat("function x(a?: b, c?, d?) {}");
|
2015-04-13 23:01:40 +08:00
|
|
|
verifyFormat("class X {\n"
|
|
|
|
" y?: z;\n"
|
|
|
|
" z?;\n"
|
|
|
|
"}");
|
2015-05-05 16:40:32 +08:00
|
|
|
verifyFormat("interface X {\n"
|
|
|
|
" y?(): z;\n"
|
|
|
|
"}");
|
|
|
|
verifyFormat("x ? 1 : 2;");
|
2015-05-27 13:37:40 +08:00
|
|
|
verifyFormat("constructor({aa}: {\n"
|
|
|
|
" aa?: string,\n"
|
|
|
|
" aaaaaaaa?: string,\n"
|
|
|
|
" aaaaaaaaaaaaaaa?: boolean,\n"
|
|
|
|
" aaaaaa?: List<string>\n"
|
2015-06-11 21:31:45 +08:00
|
|
|
"}) {}");
|
2015-04-13 23:01:40 +08:00
|
|
|
}
|
|
|
|
|
2015-04-13 23:03:30 +08:00
|
|
|
TEST_F(FormatTestJS, IndexSignature) {
|
|
|
|
verifyFormat("var x: {[k: string]: v};");
|
|
|
|
}
|
|
|
|
|
2015-10-27 20:38:37 +08:00
|
|
|
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}");
|
|
|
|
}
|
|
|
|
|
2016-01-08 16:14:58 +08:00
|
|
|
TEST_F(FormatTestJS, JSDocAnnotations) {
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("/**\n"
|
|
|
|
" * @export {this.is.a.long.path.to.a.Type}\n"
|
|
|
|
" */",
|
|
|
|
"/**\n"
|
|
|
|
" * @export {this.is.a.long.path.to.a.Type}\n"
|
|
|
|
" */",
|
|
|
|
getGoogleJSStyleWithColumns(20));
|
2016-01-08 16:14:58 +08:00
|
|
|
}
|
|
|
|
|
2016-03-03 06:44:03 +08:00
|
|
|
TEST_F(FormatTestJS, RequoteStringsSingle) {
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var x = 'foo';", "var x = \"foo\";");
|
|
|
|
verifyFormat("var x = 'fo\\'o\\'';", "var x = \"fo'o'\";");
|
|
|
|
verifyFormat("var x = 'fo\\'o\\'';", "var x = \"fo\\'o'\";");
|
|
|
|
verifyFormat(
|
|
|
|
"var x =\n"
|
|
|
|
" 'foo\\'';",
|
|
|
|
// Code below is 15 chars wide, doesn't fit into the line with the
|
|
|
|
// \ escape added.
|
|
|
|
"var x = \"foo'\";", getGoogleJSStyleWithColumns(15));
|
2016-03-03 06:44:03 +08:00
|
|
|
// Removes no-longer needed \ escape from ".
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var x = 'fo\"o';", "var x = \"fo\\\"o\";");
|
2016-03-03 06:44:03 +08:00
|
|
|
// Code below fits into 15 chars *after* removing the \ escape.
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var x = 'fo\"o';", "var x = \"fo\\\"o\";",
|
|
|
|
getGoogleJSStyleWithColumns(15));
|
2016-03-03 06:44:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FormatTestJS, RequoteStringsDouble) {
|
|
|
|
FormatStyle DoubleQuotes = getGoogleStyle(FormatStyle::LK_JavaScript);
|
|
|
|
DoubleQuotes.JavaScriptQuotes = FormatStyle::JSQS_Double;
|
|
|
|
verifyFormat("var x = \"foo\";", DoubleQuotes);
|
2016-03-15 03:21:36 +08:00
|
|
|
verifyFormat("var x = \"foo\";", "var x = 'foo';", DoubleQuotes);
|
|
|
|
verifyFormat("var x = \"fo'o\";", "var x = 'fo\\'o';", DoubleQuotes);
|
2016-03-03 06:44:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FormatTestJS, RequoteStringsLeave) {
|
|
|
|
FormatStyle LeaveQuotes = getGoogleStyle(FormatStyle::LK_JavaScript);
|
|
|
|
LeaveQuotes.JavaScriptQuotes = FormatStyle::JSQS_Leave;
|
|
|
|
verifyFormat("var x = \"foo\";", LeaveQuotes);
|
|
|
|
verifyFormat("var x = 'foo';", LeaveQuotes);
|
|
|
|
}
|
|
|
|
|
2015-06-23 07:07:51 +08:00
|
|
|
} // end namespace tooling
|
2013-12-03 18:50:16 +08:00
|
|
|
} // end namespace clang
|