FormatTestJS.cpp 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362
  1. //===- unittest/Format/FormatTestJS.cpp - Formatting unit tests for JS ----===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "FormatTestUtils.h"
  10. #include "clang/Format/Format.h"
  11. #include "llvm/Support/Debug.h"
  12. #include "gtest/gtest.h"
  13. #define DEBUG_TYPE "format-test"
  14. namespace clang {
  15. namespace format {
  16. class FormatTestJS : public ::testing::Test {
  17. protected:
  18. static std::string format(llvm::StringRef Code, unsigned Offset,
  19. unsigned Length, const FormatStyle &Style) {
  20. DEBUG(llvm::errs() << "---\n");
  21. DEBUG(llvm::errs() << Code << "\n\n");
  22. std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
  23. bool IncompleteFormat = false;
  24. tooling::Replacements Replaces =
  25. reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat);
  26. EXPECT_FALSE(IncompleteFormat);
  27. auto Result = applyAllReplacements(Code, Replaces);
  28. EXPECT_TRUE(static_cast<bool>(Result));
  29. DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
  30. return *Result;
  31. }
  32. static std::string format(
  33. llvm::StringRef Code,
  34. const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_JavaScript)) {
  35. return format(Code, 0, Code.size(), Style);
  36. }
  37. static FormatStyle getGoogleJSStyleWithColumns(unsigned ColumnLimit) {
  38. FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
  39. Style.ColumnLimit = ColumnLimit;
  40. return Style;
  41. }
  42. static void verifyFormat(
  43. llvm::StringRef Code,
  44. const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_JavaScript)) {
  45. std::string Result = format(test::messUp(Code), Style);
  46. EXPECT_EQ(Code.str(), Result) << "Formatted:\n" << Result;
  47. }
  48. static void verifyFormat(
  49. llvm::StringRef Expected,
  50. llvm::StringRef Code,
  51. const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_JavaScript)) {
  52. std::string Result = format(Code, Style);
  53. EXPECT_EQ(Expected.str(), Result) << "Formatted:\n" << Result;
  54. }
  55. };
  56. TEST_F(FormatTestJS, BlockComments) {
  57. verifyFormat("/* aaaaaaaaaaaaa */ aaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
  58. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
  59. }
  60. TEST_F(FormatTestJS, UnderstandsJavaScriptOperators) {
  61. verifyFormat("a == = b;");
  62. verifyFormat("a != = b;");
  63. verifyFormat("a === b;");
  64. verifyFormat("aaaaaaa ===\n b;", getGoogleJSStyleWithColumns(10));
  65. verifyFormat("a !== b;");
  66. verifyFormat("aaaaaaa !==\n b;", getGoogleJSStyleWithColumns(10));
  67. verifyFormat("if (a + b + c +\n"
  68. " d !==\n"
  69. " e + f + g)\n"
  70. " q();",
  71. getGoogleJSStyleWithColumns(20));
  72. verifyFormat("a >> >= b;");
  73. verifyFormat("a >>> b;");
  74. verifyFormat("aaaaaaa >>>\n b;", getGoogleJSStyleWithColumns(10));
  75. verifyFormat("a >>>= b;");
  76. verifyFormat("aaaaaaa >>>=\n b;", getGoogleJSStyleWithColumns(10));
  77. verifyFormat("if (a + b + c +\n"
  78. " d >>>\n"
  79. " e + f + g)\n"
  80. " q();",
  81. getGoogleJSStyleWithColumns(20));
  82. verifyFormat("var x = aaaaaaaaaa ?\n"
  83. " bbbbbb :\n"
  84. " ccc;",
  85. getGoogleJSStyleWithColumns(20));
  86. verifyFormat("var b = a.map((x) => x + 1);");
  87. verifyFormat("return ('aaa') in bbbb;");
  88. verifyFormat("var x = aaaaaaaaaaaaaaaaaaaaaaaaa() in\n"
  89. " aaaa.aaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
  90. FormatStyle Style = getGoogleJSStyleWithColumns(80);
  91. Style.AlignOperands = true;
  92. verifyFormat("var x = aaaaaaaaaaaaaaaaaaaaaaaaa() in\n"
  93. " aaaa.aaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
  94. Style);
  95. Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
  96. verifyFormat("var x = aaaaaaaaaaaaaaaaaaaaaaaaa()\n"
  97. " in aaaa.aaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
  98. Style);
  99. // ES6 spread operator.
  100. verifyFormat("someFunction(...a);");
  101. verifyFormat("var x = [1, ...a, 2];");
  102. }
  103. TEST_F(FormatTestJS, UnderstandsAmpAmp) {
  104. verifyFormat("e && e.SomeFunction();");
  105. }
  106. TEST_F(FormatTestJS, LiteralOperatorsCanBeKeywords) {
  107. verifyFormat("not.and.or.not_eq = 1;");
  108. }
  109. TEST_F(FormatTestJS, ReservedWords) {
  110. // JavaScript reserved words (aka keywords) are only illegal when used as
  111. // Identifiers, but are legal as IdentifierNames.
  112. verifyFormat("x.class.struct = 1;");
  113. verifyFormat("x.case = 1;");
  114. verifyFormat("x.interface = 1;");
  115. verifyFormat("x.for = 1;");
  116. verifyFormat("x.of() = 1;");
  117. verifyFormat("x.in() = 1;");
  118. verifyFormat("x.let() = 1;");
  119. verifyFormat("x.var() = 1;");
  120. verifyFormat("x = {\n"
  121. " a: 12,\n"
  122. " interface: 1,\n"
  123. " switch: 1,\n"
  124. "};");
  125. verifyFormat("var struct = 2;");
  126. verifyFormat("var union = 2;");
  127. verifyFormat("var interface = 2;");
  128. verifyFormat("interface = 2;");
  129. verifyFormat("x = interface instanceof y;");
  130. }
  131. TEST_F(FormatTestJS, CppKeywords) {
  132. // Make sure we don't mess stuff up because of C++ keywords.
  133. verifyFormat("return operator && (aa);");
  134. }
  135. TEST_F(FormatTestJS, ES6DestructuringAssignment) {
  136. verifyFormat("var [a, b, c] = [1, 2, 3];");
  137. verifyFormat("const [a, b, c] = [1, 2, 3];");
  138. verifyFormat("let [a, b, c] = [1, 2, 3];");
  139. verifyFormat("var {a, b} = {a: 1, b: 2};");
  140. verifyFormat("let {a, b} = {a: 1, b: 2};");
  141. }
  142. TEST_F(FormatTestJS, ContainerLiterals) {
  143. verifyFormat("var x = {y: function(a) { return a; }};");
  144. verifyFormat("return {\n"
  145. " link: function() {\n"
  146. " f(); //\n"
  147. " }\n"
  148. "};");
  149. verifyFormat("return {\n"
  150. " a: a,\n"
  151. " link: function() {\n"
  152. " f(); //\n"
  153. " }\n"
  154. "};");
  155. verifyFormat("return {\n"
  156. " a: a,\n"
  157. " link: function() {\n"
  158. " f(); //\n"
  159. " },\n"
  160. " link: function() {\n"
  161. " f(); //\n"
  162. " }\n"
  163. "};");
  164. verifyFormat("var stuff = {\n"
  165. " // comment for update\n"
  166. " update: false,\n"
  167. " // comment for modules\n"
  168. " modules: false,\n"
  169. " // comment for tasks\n"
  170. " tasks: false\n"
  171. "};");
  172. verifyFormat("return {\n"
  173. " 'finish':\n"
  174. " //\n"
  175. " a\n"
  176. "};");
  177. verifyFormat("var obj = {\n"
  178. " fooooooooo: function(x) {\n"
  179. " return x.zIsTooLongForOneLineWithTheDeclarationLine();\n"
  180. " }\n"
  181. "};");
  182. // Simple object literal, as opposed to enum style below.
  183. verifyFormat("var obj = {a: 123};");
  184. // Enum style top level assignment.
  185. verifyFormat("X = {\n a: 123\n};");
  186. verifyFormat("X.Y = {\n a: 123\n};");
  187. // But only on the top level, otherwise its a plain object literal assignment.
  188. verifyFormat("function x() {\n"
  189. " y = {z: 1};\n"
  190. "}");
  191. verifyFormat("x = foo && {a: 123};");
  192. // Arrow functions in object literals.
  193. verifyFormat("var x = {y: (a) => { return a; }};");
  194. verifyFormat("var x = {y: (a) => a};");
  195. // Computed keys.
  196. verifyFormat("var x = {[a]: 1, b: 2, [c]: 3};");
  197. verifyFormat("var x = {\n"
  198. " [a]: 1,\n"
  199. " b: 2,\n"
  200. " [c]: 3,\n"
  201. "};");
  202. // Object literals can leave out labels.
  203. verifyFormat("f({a}, () => {\n"
  204. " g(); //\n"
  205. "});");
  206. // Keys can be quoted.
  207. verifyFormat("var x = {\n"
  208. " a: a,\n"
  209. " b: b,\n"
  210. " 'c': c,\n"
  211. "};");
  212. }
  213. TEST_F(FormatTestJS, MethodsInObjectLiterals) {
  214. verifyFormat("var o = {\n"
  215. " value: 'test',\n"
  216. " get value() { // getter\n"
  217. " return this.value;\n"
  218. " }\n"
  219. "};");
  220. verifyFormat("var o = {\n"
  221. " value: 'test',\n"
  222. " set value(val) { // setter\n"
  223. " this.value = val;\n"
  224. " }\n"
  225. "};");
  226. verifyFormat("var o = {\n"
  227. " value: 'test',\n"
  228. " someMethod(val) { // method\n"
  229. " doSomething(this.value + val);\n"
  230. " }\n"
  231. "};");
  232. verifyFormat("var o = {\n"
  233. " someMethod(val) { // method\n"
  234. " doSomething(this.value + val);\n"
  235. " },\n"
  236. " someOtherMethod(val) { // method\n"
  237. " doSomething(this.value + val);\n"
  238. " }\n"
  239. "};");
  240. }
  241. TEST_F(FormatTestJS, SpacesInContainerLiterals) {
  242. verifyFormat("var arr = [1, 2, 3];");
  243. verifyFormat("f({a: 1, b: 2, c: 3});");
  244. verifyFormat("var object_literal_with_long_name = {\n"
  245. " a: 'aaaaaaaaaaaaaaaaaa',\n"
  246. " b: 'bbbbbbbbbbbbbbbbbb'\n"
  247. "};");
  248. verifyFormat("f({a: 1, b: 2, c: 3});",
  249. getChromiumStyle(FormatStyle::LK_JavaScript));
  250. verifyFormat("f({'a': [{}]});");
  251. }
  252. TEST_F(FormatTestJS, SingleQuotedStrings) {
  253. verifyFormat("this.function('', true);");
  254. }
  255. TEST_F(FormatTestJS, GoogScopes) {
  256. verifyFormat("goog.scope(function() {\n"
  257. "var x = a.b;\n"
  258. "var y = c.d;\n"
  259. "}); // goog.scope");
  260. verifyFormat("goog.scope(function() {\n"
  261. "// test\n"
  262. "var x = 0;\n"
  263. "// test\n"
  264. "});");
  265. }
  266. TEST_F(FormatTestJS, GoogModules) {
  267. verifyFormat("goog.module('this.is.really.absurdly.long');",
  268. getGoogleJSStyleWithColumns(40));
  269. verifyFormat("goog.require('this.is.really.absurdly.long');",
  270. getGoogleJSStyleWithColumns(40));
  271. verifyFormat("goog.provide('this.is.really.absurdly.long');",
  272. getGoogleJSStyleWithColumns(40));
  273. verifyFormat("var long = goog.require('this.is.really.absurdly.long');",
  274. getGoogleJSStyleWithColumns(40));
  275. verifyFormat("goog.setTestOnly('this.is.really.absurdly.long');",
  276. getGoogleJSStyleWithColumns(40));
  277. verifyFormat("goog.forwardDeclare('this.is.really.absurdly.long');",
  278. getGoogleJSStyleWithColumns(40));
  279. // These should be wrapped normally.
  280. verifyFormat(
  281. "var MyLongClassName =\n"
  282. " goog.module.get('my.long.module.name.followedBy.MyLongClassName');");
  283. }
  284. TEST_F(FormatTestJS, FormatsNamespaces) {
  285. verifyFormat("namespace Foo {\n"
  286. " export let x = 1;\n"
  287. "}\n");
  288. verifyFormat("declare namespace Foo {\n"
  289. " export let x: number;\n"
  290. "}\n");
  291. }
  292. TEST_F(FormatTestJS, FormatsFreestandingFunctions) {
  293. verifyFormat("function outer1(a, b) {\n"
  294. " function inner1(a, b) { return a; }\n"
  295. " inner1(a, b);\n"
  296. "}\n"
  297. "function outer2(a, b) {\n"
  298. " function inner2(a, b) { return a; }\n"
  299. " inner2(a, b);\n"
  300. "}");
  301. verifyFormat("function f() {}");
  302. }
  303. TEST_F(FormatTestJS, GeneratorFunctions) {
  304. verifyFormat("function* f() {\n"
  305. " let x = 1;\n"
  306. " yield x;\n"
  307. " yield* something();\n"
  308. "}");
  309. verifyFormat("function*\n"
  310. " f() {\n"
  311. "}",
  312. getGoogleJSStyleWithColumns(8));
  313. verifyFormat("export function* f() {\n"
  314. " yield 1;\n"
  315. "}\n");
  316. verifyFormat("class X {\n"
  317. " * generatorMethod() { yield x; }\n"
  318. "}");
  319. }
  320. TEST_F(FormatTestJS, AsyncFunctions) {
  321. verifyFormat("async function f() {\n"
  322. " let x = 1;\n"
  323. " return fetch(x);\n"
  324. "}");
  325. verifyFormat("async function* f() {\n"
  326. " yield fetch(x);\n"
  327. "}");
  328. verifyFormat("export async function f() {\n"
  329. " return fetch(x);\n"
  330. "}");
  331. verifyFormat("class X {\n"
  332. " async asyncMethod() { return fetch(1); }\n"
  333. "}");
  334. verifyFormat("function initialize() {\n"
  335. " // Comment.\n"
  336. " return async.then();\n"
  337. "}\n");
  338. }
  339. TEST_F(FormatTestJS, ArrayLiterals) {
  340. verifyFormat("var aaaaa: List<SomeThing> =\n"
  341. " [new SomeThingAAAAAAAAAAAA(), new SomeThingBBBBBBBBB()];");
  342. verifyFormat("return [\n"
  343. " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
  344. " ccccccccccccccccccccccccccc\n"
  345. "];");
  346. verifyFormat("return [\n"
  347. " aaaa().bbbbbbbb('A'),\n"
  348. " aaaa().bbbbbbbb('B'),\n"
  349. " aaaa().bbbbbbbb('C'),\n"
  350. "];");
  351. verifyFormat("var someVariable = SomeFunction([\n"
  352. " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
  353. " ccccccccccccccccccccccccccc\n"
  354. "]);");
  355. verifyFormat("var someVariable = SomeFunction([\n"
  356. " [aaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbb],\n"
  357. "]);",
  358. getGoogleJSStyleWithColumns(51));
  359. verifyFormat("var someVariable = SomeFunction(aaaa, [\n"
  360. " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
  361. " ccccccccccccccccccccccccccc\n"
  362. "]);");
  363. verifyFormat("var someVariable = SomeFunction(\n"
  364. " aaaa,\n"
  365. " [\n"
  366. " aaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
  367. " cccccccccccccccccccccccccc\n"
  368. " ],\n"
  369. " aaaa);");
  370. verifyFormat("var aaaa = aaaaa || // wrap\n"
  371. " [];");
  372. verifyFormat("someFunction([], {a: a});");
  373. }
  374. TEST_F(FormatTestJS, ColumnLayoutForArrayLiterals) {
  375. verifyFormat("var array = [\n"
  376. " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
  377. " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
  378. "];");
  379. verifyFormat("var array = someFunction([\n"
  380. " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
  381. " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
  382. "]);");
  383. }
  384. TEST_F(FormatTestJS, FunctionLiterals) {
  385. verifyFormat("doFoo(function() {});");
  386. verifyFormat("doFoo(function() { return 1; });");
  387. verifyFormat("var func = function() {\n"
  388. " return 1;\n"
  389. "};");
  390. verifyFormat("var func = //\n"
  391. " function() {\n"
  392. " return 1;\n"
  393. "};");
  394. verifyFormat("return {\n"
  395. " body: {\n"
  396. " setAttribute: function(key, val) { this[key] = val; },\n"
  397. " getAttribute: function(key) { return this[key]; },\n"
  398. " style: {direction: ''}\n"
  399. " }\n"
  400. "};");
  401. verifyFormat("abc = xyz ? function() {\n"
  402. " return 1;\n"
  403. "} : function() {\n"
  404. " return -1;\n"
  405. "};");
  406. verifyFormat("var closure = goog.bind(\n"
  407. " function() { // comment\n"
  408. " foo();\n"
  409. " bar();\n"
  410. " },\n"
  411. " this, arg1IsReallyLongAndNeeedsLineBreaks,\n"
  412. " arg3IsReallyLongAndNeeedsLineBreaks);");
  413. verifyFormat("var closure = goog.bind(function() { // comment\n"
  414. " foo();\n"
  415. " bar();\n"
  416. "}, this);");
  417. verifyFormat("return {\n"
  418. " a: 'E',\n"
  419. " b: function() {\n"
  420. " return function() {\n"
  421. " f(); //\n"
  422. " };\n"
  423. " }\n"
  424. "};");
  425. verifyFormat("{\n"
  426. " var someVariable = function(x) {\n"
  427. " return x.zIsTooLongForOneLineWithTheDeclarationLine();\n"
  428. " };\n"
  429. "}");
  430. verifyFormat("someLooooooooongFunction(\n"
  431. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
  432. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
  433. " function(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n"
  434. " // code\n"
  435. " });");
  436. verifyFormat("f({a: function() { return 1; }});",
  437. getGoogleJSStyleWithColumns(33));
  438. verifyFormat("f({\n"
  439. " a: function() { return 1; }\n"
  440. "});",
  441. getGoogleJSStyleWithColumns(32));
  442. verifyFormat("return {\n"
  443. " a: function SomeFunction() {\n"
  444. " // ...\n"
  445. " return 1;\n"
  446. " }\n"
  447. "};");
  448. verifyFormat("this.someObject.doSomething(aaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
  449. " .then(goog.bind(function(aaaaaaaaaaa) {\n"
  450. " someFunction();\n"
  451. " someFunction();\n"
  452. " }, this), aaaaaaaaaaaaaaaaa);");
  453. verifyFormat("someFunction(goog.bind(function() {\n"
  454. " doSomething();\n"
  455. " doSomething();\n"
  456. "}, this), goog.bind(function() {\n"
  457. " doSomething();\n"
  458. " doSomething();\n"
  459. "}, this));");
  460. // FIXME: This is bad, we should be wrapping before "function() {".
  461. verifyFormat("someFunction(function() {\n"
  462. " doSomething(); // break\n"
  463. "})\n"
  464. " .doSomethingElse(\n"
  465. " // break\n"
  466. " );");
  467. }
  468. TEST_F(FormatTestJS, InliningFunctionLiterals) {
  469. FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
  470. Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
  471. verifyFormat("var func = function() {\n"
  472. " return 1;\n"
  473. "};",
  474. Style);
  475. verifyFormat("var func = doSomething(function() { return 1; });", Style);
  476. verifyFormat("var outer = function() {\n"
  477. " var inner = function() { return 1; }\n"
  478. "};",
  479. Style);
  480. verifyFormat("function outer1(a, b) {\n"
  481. " function inner1(a, b) { return a; }\n"
  482. "}",
  483. Style);
  484. Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
  485. verifyFormat("var func = function() { return 1; };", Style);
  486. verifyFormat("var func = doSomething(function() { return 1; });", Style);
  487. verifyFormat(
  488. "var outer = function() { var inner = function() { return 1; } };",
  489. Style);
  490. verifyFormat("function outer1(a, b) {\n"
  491. " function inner1(a, b) { return a; }\n"
  492. "}",
  493. Style);
  494. Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
  495. verifyFormat("var func = function() {\n"
  496. " return 1;\n"
  497. "};",
  498. Style);
  499. verifyFormat("var func = doSomething(function() {\n"
  500. " return 1;\n"
  501. "});",
  502. Style);
  503. verifyFormat("var outer = function() {\n"
  504. " var inner = function() {\n"
  505. " return 1;\n"
  506. " }\n"
  507. "};",
  508. Style);
  509. verifyFormat("function outer1(a, b) {\n"
  510. " function inner1(a, b) {\n"
  511. " return a;\n"
  512. " }\n"
  513. "}",
  514. Style);
  515. Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
  516. verifyFormat("var func = function() {\n"
  517. " return 1;\n"
  518. "};",
  519. Style);
  520. }
  521. TEST_F(FormatTestJS, MultipleFunctionLiterals) {
  522. verifyFormat("promise.then(\n"
  523. " function success() {\n"
  524. " doFoo();\n"
  525. " doBar();\n"
  526. " },\n"
  527. " function error() {\n"
  528. " doFoo();\n"
  529. " doBaz();\n"
  530. " },\n"
  531. " []);\n");
  532. verifyFormat("promise.then(\n"
  533. " function success() {\n"
  534. " doFoo();\n"
  535. " doBar();\n"
  536. " },\n"
  537. " [],\n"
  538. " function error() {\n"
  539. " doFoo();\n"
  540. " doBaz();\n"
  541. " });\n");
  542. verifyFormat("promise.then(\n"
  543. " [],\n"
  544. " function success() {\n"
  545. " doFoo();\n"
  546. " doBar();\n"
  547. " },\n"
  548. " function error() {\n"
  549. " doFoo();\n"
  550. " doBaz();\n"
  551. " });\n");
  552. verifyFormat("getSomeLongPromise()\n"
  553. " .then(function(value) { body(); })\n"
  554. " .thenCatch(function(error) {\n"
  555. " body();\n"
  556. " body();\n"
  557. " });");
  558. verifyFormat("getSomeLongPromise()\n"
  559. " .then(function(value) {\n"
  560. " body();\n"
  561. " body();\n"
  562. " })\n"
  563. " .thenCatch(function(error) {\n"
  564. " body();\n"
  565. " body();\n"
  566. " });");
  567. verifyFormat("getSomeLongPromise()\n"
  568. " .then(function(value) { body(); })\n"
  569. " .thenCatch(function(error) { body(); });");
  570. verifyFormat("return [aaaaaaaaaaaaaaaaaaaaaa]\n"
  571. " .aaaaaaa(function() {\n"
  572. " //\n"
  573. " })\n"
  574. " .bbbbbb();");
  575. }
  576. TEST_F(FormatTestJS, ArrowFunctions) {
  577. verifyFormat("var x = (a) => {\n"
  578. " return a;\n"
  579. "};");
  580. verifyFormat("var x = (a) => {\n"
  581. " function y() { return 42; }\n"
  582. " return a;\n"
  583. "};");
  584. verifyFormat("var x = (a: type): {some: type} => {\n"
  585. " return a;\n"
  586. "};");
  587. verifyFormat("var x = (a) => a;");
  588. verifyFormat("return () => [];");
  589. verifyFormat("var aaaaaaaaaaaaaaaaaaaa = {\n"
  590. " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n"
  591. " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
  592. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) =>\n"
  593. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
  594. "};");
  595. verifyFormat("var a = a.aaaaaaa(\n"
  596. " (a: a) => aaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbb) &&\n"
  597. " aaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbb));");
  598. verifyFormat("var a = a.aaaaaaa(\n"
  599. " (a: a) => aaaaaaaaaaaaaaaaaaaaa(bbbbbbbbb) ?\n"
  600. " aaaaaaaaaaaaaaaaaaaaa(bbbbbbb) :\n"
  601. " aaaaaaaaaaaaaaaaaaaaa(bbbbbbb));");
  602. // FIXME: This is bad, we should be wrapping before "() => {".
  603. verifyFormat("someFunction(() => {\n"
  604. " doSomething(); // break\n"
  605. "})\n"
  606. " .doSomethingElse(\n"
  607. " // break\n"
  608. " );");
  609. }
  610. TEST_F(FormatTestJS, ReturnStatements) {
  611. verifyFormat("function() {\n"
  612. " return [hello, world];\n"
  613. "}");
  614. }
  615. TEST_F(FormatTestJS, ForLoops) {
  616. verifyFormat("for (var i in [2, 3]) {\n"
  617. "}");
  618. verifyFormat("for (var i of [2, 3]) {\n"
  619. "}");
  620. verifyFormat("for (let {a, b} of x) {\n"
  621. "}");
  622. verifyFormat("for (let {a, b} in x) {\n"
  623. "}");
  624. }
  625. TEST_F(FormatTestJS, WrapRespectsAutomaticSemicolonInsertion) {
  626. // The following statements must not wrap, as otherwise the program meaning
  627. // would change due to automatic semicolon insertion.
  628. // See http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1.
  629. verifyFormat("return aaaaa;", getGoogleJSStyleWithColumns(10));
  630. verifyFormat("continue aaaaa;", getGoogleJSStyleWithColumns(10));
  631. verifyFormat("break aaaaa;", getGoogleJSStyleWithColumns(10));
  632. verifyFormat("throw aaaaa;", getGoogleJSStyleWithColumns(10));
  633. verifyFormat("aaaaaaaaa++;", getGoogleJSStyleWithColumns(10));
  634. verifyFormat("aaaaaaaaa--;", getGoogleJSStyleWithColumns(10));
  635. verifyFormat("return [\n"
  636. " aaa\n"
  637. "];",
  638. getGoogleJSStyleWithColumns(12));
  639. }
  640. TEST_F(FormatTestJS, AutomaticSemicolonInsertionHeuristic) {
  641. verifyFormat("a\n"
  642. "b;",
  643. " a \n"
  644. " b ;");
  645. verifyFormat("a()\n"
  646. "b;",
  647. " a ()\n"
  648. " b ;");
  649. verifyFormat("a[b]\n"
  650. "c;",
  651. "a [b]\n"
  652. "c ;");
  653. verifyFormat("1\n"
  654. "a;",
  655. "1 \n"
  656. "a ;");
  657. verifyFormat("a\n"
  658. "1;",
  659. "a \n"
  660. "1 ;");
  661. verifyFormat("a\n"
  662. "'x';",
  663. "a \n"
  664. " 'x';");
  665. verifyFormat("a++\n"
  666. "b;",
  667. "a ++\n"
  668. "b ;");
  669. verifyFormat("a\n"
  670. "!b && c;",
  671. "a \n"
  672. " ! b && c;");
  673. verifyFormat("a\n"
  674. "if (1) f();",
  675. " a\n"
  676. " if (1) f();");
  677. verifyFormat("a\n"
  678. "class X {}",
  679. " a\n"
  680. " class X {}");
  681. verifyFormat("var a", "var\n"
  682. "a");
  683. verifyFormat("x instanceof String", "x\n"
  684. "instanceof\n"
  685. "String");
  686. verifyFormat("function f(@Foo bar) {}", "function f(@Foo\n"
  687. " bar) {}");
  688. }
  689. TEST_F(FormatTestJS, ClosureStyleCasts) {
  690. verifyFormat("var x = /** @type {foo} */ (bar);");
  691. }
  692. TEST_F(FormatTestJS, TryCatch) {
  693. verifyFormat("try {\n"
  694. " f();\n"
  695. "} catch (e) {\n"
  696. " g();\n"
  697. "} finally {\n"
  698. " h();\n"
  699. "}");
  700. // But, of course, "catch" is a perfectly fine function name in JavaScript.
  701. verifyFormat("someObject.catch();");
  702. verifyFormat("someObject.new();");
  703. verifyFormat("someObject.delete();");
  704. }
  705. TEST_F(FormatTestJS, StringLiteralConcatenation) {
  706. verifyFormat("var literal = 'hello ' +\n"
  707. " 'world';");
  708. }
  709. TEST_F(FormatTestJS, RegexLiteralClassification) {
  710. // Regex literals.
  711. verifyFormat("var regex = /abc/;");
  712. verifyFormat("f(/abc/);");
  713. verifyFormat("f(abc, /abc/);");
  714. verifyFormat("some_map[/abc/];");
  715. verifyFormat("var x = a ? /abc/ : /abc/;");
  716. verifyFormat("for (var i = 0; /abc/.test(s[i]); i++) {\n}");
  717. verifyFormat("var x = !/abc/.test(y);");
  718. verifyFormat("var x = a && /abc/.test(y);");
  719. verifyFormat("var x = a || /abc/.test(y);");
  720. verifyFormat("var x = a + /abc/.search(y);");
  721. verifyFormat("/abc/.search(y);");
  722. verifyFormat("var regexs = {/abc/, /abc/};");
  723. verifyFormat("return /abc/;");
  724. // Not regex literals.
  725. verifyFormat("var a = a / 2 + b / 3;");
  726. verifyFormat("var a = a++ / 2;");
  727. // Prefix unary can operate on regex literals, not that it makes sense.
  728. verifyFormat("var a = ++/a/;");
  729. // This is a known issue, regular expressions are incorrectly detected if
  730. // directly following a closing parenthesis.
  731. verifyFormat("if (foo) / bar /.exec(baz);");
  732. }
  733. TEST_F(FormatTestJS, RegexLiteralSpecialCharacters) {
  734. verifyFormat("var regex = /=/;");
  735. verifyFormat("var regex = /a*/;");
  736. verifyFormat("var regex = /a+/;");
  737. verifyFormat("var regex = /a?/;");
  738. verifyFormat("var regex = /.a./;");
  739. verifyFormat("var regex = /a\\*/;");
  740. verifyFormat("var regex = /^a$/;");
  741. verifyFormat("var regex = /\\/a/;");
  742. verifyFormat("var regex = /(?:x)/;");
  743. verifyFormat("var regex = /x(?=y)/;");
  744. verifyFormat("var regex = /x(?!y)/;");
  745. verifyFormat("var regex = /x|y/;");
  746. verifyFormat("var regex = /a{2}/;");
  747. verifyFormat("var regex = /a{1,3}/;");
  748. verifyFormat("var regex = /[abc]/;");
  749. verifyFormat("var regex = /[^abc]/;");
  750. verifyFormat("var regex = /[\\b]/;");
  751. verifyFormat("var regex = /[/]/;");
  752. verifyFormat("var regex = /[\\/]/;");
  753. verifyFormat("var regex = /\\[/;");
  754. verifyFormat("var regex = /\\\\[/]/;");
  755. verifyFormat("var regex = /}[\"]/;");
  756. verifyFormat("var regex = /}[/\"]/;");
  757. verifyFormat("var regex = /}[\"/]/;");
  758. verifyFormat("var regex = /\\b/;");
  759. verifyFormat("var regex = /\\B/;");
  760. verifyFormat("var regex = /\\d/;");
  761. verifyFormat("var regex = /\\D/;");
  762. verifyFormat("var regex = /\\f/;");
  763. verifyFormat("var regex = /\\n/;");
  764. verifyFormat("var regex = /\\r/;");
  765. verifyFormat("var regex = /\\s/;");
  766. verifyFormat("var regex = /\\S/;");
  767. verifyFormat("var regex = /\\t/;");
  768. verifyFormat("var regex = /\\v/;");
  769. verifyFormat("var regex = /\\w/;");
  770. verifyFormat("var regex = /\\W/;");
  771. verifyFormat("var regex = /a(a)\\1/;");
  772. verifyFormat("var regex = /\\0/;");
  773. verifyFormat("var regex = /\\\\/g;");
  774. verifyFormat("var regex = /\\a\\\\/g;");
  775. verifyFormat("var regex = /\a\\//g;");
  776. verifyFormat("var regex = /a\\//;\n"
  777. "var x = 0;");
  778. verifyFormat("var regex = /'/g;", "var regex = /'/g ;");
  779. verifyFormat("var regex = /'/g; //'", "var regex = /'/g ; //'");
  780. verifyFormat("var regex = /\\/*/;\n"
  781. "var x = 0;",
  782. "var regex = /\\/*/;\n"
  783. "var x=0;");
  784. verifyFormat("var x = /a\\//;", "var x = /a\\// \n;");
  785. verifyFormat("var regex = /\"/;", getGoogleJSStyleWithColumns(16));
  786. verifyFormat("var regex =\n"
  787. " /\"/;",
  788. getGoogleJSStyleWithColumns(15));
  789. verifyFormat("var regex = //\n"
  790. " /a/;");
  791. verifyFormat("var regexs = [\n"
  792. " /d/, //\n"
  793. " /aa/, //\n"
  794. "];");
  795. }
  796. TEST_F(FormatTestJS, RegexLiteralModifiers) {
  797. verifyFormat("var regex = /abc/g;");
  798. verifyFormat("var regex = /abc/i;");
  799. verifyFormat("var regex = /abc/m;");
  800. verifyFormat("var regex = /abc/y;");
  801. }
  802. TEST_F(FormatTestJS, RegexLiteralLength) {
  803. verifyFormat("var regex = /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
  804. getGoogleJSStyleWithColumns(60));
  805. verifyFormat("var regex =\n"
  806. " /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
  807. getGoogleJSStyleWithColumns(60));
  808. verifyFormat("var regex = /\\xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
  809. getGoogleJSStyleWithColumns(50));
  810. }
  811. TEST_F(FormatTestJS, RegexLiteralExamples) {
  812. verifyFormat("var regex = search.match(/(?:\?|&)times=([^?&]+)/i);");
  813. }
  814. TEST_F(FormatTestJS, TypeAnnotations) {
  815. verifyFormat("var x: string;");
  816. verifyFormat("var x: {a: string; b: number;} = {};");
  817. verifyFormat("function x(): string {\n return 'x';\n}");
  818. verifyFormat("function x(): {x: string} {\n return {x: 'x'};\n}");
  819. verifyFormat("function x(y: string): string {\n return 'x';\n}");
  820. verifyFormat("for (var y: string in x) {\n x();\n}");
  821. verifyFormat("for (var y: string of x) {\n x();\n}");
  822. verifyFormat("function x(y: {a?: number;} = {}): number {\n"
  823. " return 12;\n"
  824. "}");
  825. verifyFormat("((a: string, b: number): string => a + b);");
  826. verifyFormat("var x: (y: number) => string;");
  827. verifyFormat("var x: P<string, (a: number) => string>;");
  828. verifyFormat("var x = {y: function(): z { return 1; }};");
  829. verifyFormat("var x = {y: function(): {a: number} { return 1; }};");
  830. verifyFormat("function someFunc(args: string[]):\n"
  831. " {longReturnValue: string[]} {}",
  832. getGoogleJSStyleWithColumns(60));
  833. }
  834. TEST_F(FormatTestJS, UnionIntersectionTypes) {
  835. verifyFormat("let x: A|B = A | B;");
  836. verifyFormat("let x: A&B|C = A & B;");
  837. verifyFormat("let x: Foo<A|B> = new Foo<A|B>();");
  838. verifyFormat("function(x: A|B): C&D {}");
  839. verifyFormat("function(x: A|B = A | B): C&D {}");
  840. verifyFormat("function x(path: number|string) {}");
  841. verifyFormat("function x(): string|number {}");
  842. verifyFormat("type Foo = Bar|Baz;");
  843. verifyFormat("type Foo = Bar<X>|Baz;");
  844. verifyFormat("type Foo = (Bar<X>|Baz);");
  845. verifyFormat("let x: Bar|Baz;");
  846. verifyFormat("let x: Bar<X>|Baz;");
  847. verifyFormat("let x: (Foo|Bar)[];");
  848. }
  849. TEST_F(FormatTestJS, ClassDeclarations) {
  850. verifyFormat("class C {\n x: string = 12;\n}");
  851. verifyFormat("class C {\n x(): string => 12;\n}");
  852. verifyFormat("class C {\n ['x' + 2]: string = 12;\n}");
  853. verifyFormat("class C {\n private x: string = 12;\n}");
  854. verifyFormat("class C {\n private static x: string = 12;\n}");
  855. verifyFormat("class C {\n static x(): string { return 'asd'; }\n}");
  856. verifyFormat("class C extends P implements I {}");
  857. verifyFormat("class C extends p.P implements i.I {}");
  858. verifyFormat("class Test {\n"
  859. " aaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaa):\n"
  860. " aaaaaaaaaaaaaaaaaaaaaa {}\n"
  861. "}");
  862. verifyFormat("foo = class Name {\n"
  863. " constructor() {}\n"
  864. "};");
  865. verifyFormat("foo = class {\n"
  866. " constructor() {}\n"
  867. "};");
  868. verifyFormat("class C {\n"
  869. " x: {y: Z;} = {};\n"
  870. " private y: {y: Z;} = {};\n"
  871. "}");
  872. // ':' is not a type declaration here.
  873. verifyFormat("class X {\n"
  874. " subs = {\n"
  875. " 'b': {\n"
  876. " 'c': 1,\n"
  877. " },\n"
  878. " };\n"
  879. "}");
  880. verifyFormat("@Component({\n"
  881. " moduleId: module.id,\n"
  882. "})\n"
  883. "class SessionListComponent implements OnDestroy, OnInit {\n"
  884. "}");
  885. }
  886. TEST_F(FormatTestJS, InterfaceDeclarations) {
  887. verifyFormat("interface I {\n"
  888. " x: string;\n"
  889. " enum: string[];\n"
  890. " enum?: string[];\n"
  891. "}\n"
  892. "var y;");
  893. // Ensure that state is reset after parsing the interface.
  894. verifyFormat("interface a {}\n"
  895. "export function b() {}\n"
  896. "var x;");
  897. // Arrays of object type literals.
  898. verifyFormat("interface I {\n"
  899. " o: {}[];\n"
  900. "}");
  901. }
  902. TEST_F(FormatTestJS, EnumDeclarations) {
  903. verifyFormat("enum Foo {\n"
  904. " A = 1,\n"
  905. " B\n"
  906. "}");
  907. verifyFormat("export /* somecomment*/ enum Foo {\n"
  908. " A = 1,\n"
  909. " B\n"
  910. "}");
  911. verifyFormat("enum Foo {\n"
  912. " A = 1, // comment\n"
  913. " B\n"
  914. "}\n"
  915. "var x = 1;");
  916. }
  917. TEST_F(FormatTestJS, MetadataAnnotations) {
  918. verifyFormat("@A\nclass C {\n}");
  919. verifyFormat("@A({arg: 'value'})\nclass C {\n}");
  920. verifyFormat("@A\n@B\nclass C {\n}");
  921. verifyFormat("class C {\n @A x: string;\n}");
  922. verifyFormat("class C {\n"
  923. " @A\n"
  924. " private x(): string {\n"
  925. " return 'y';\n"
  926. " }\n"
  927. "}");
  928. verifyFormat("class C {\n"
  929. " private x(@A x: string) {}\n"
  930. "}");
  931. verifyFormat("class X {}\n"
  932. "class Y {}");
  933. }
  934. TEST_F(FormatTestJS, TypeAliases) {
  935. verifyFormat("type X = number;\n"
  936. "class C {}");
  937. verifyFormat("type X<Y> = Z<Y>;");
  938. verifyFormat("type X = {\n"
  939. " y: number\n"
  940. "};\n"
  941. "class C {}");
  942. }
  943. TEST_F(FormatTestJS, Modules) {
  944. verifyFormat("import SomeThing from 'some/module.js';");
  945. verifyFormat("import {X, Y} from 'some/module.js';");
  946. verifyFormat("import a, {X, Y} from 'some/module.js';");
  947. verifyFormat("import {X, Y,} from 'some/module.js';");
  948. verifyFormat("import {X as myLocalX, Y as myLocalY} from 'some/module.js';");
  949. // Ensure Automatic Semicolon Insertion does not break on "as\n".
  950. verifyFormat("import {X as myX} from 'm';", "import {X as\n"
  951. " myX} from 'm';");
  952. verifyFormat("import * as lib from 'some/module.js';");
  953. verifyFormat("var x = {import: 1};\nx.import = 2;");
  954. verifyFormat("export function fn() {\n"
  955. " return 'fn';\n"
  956. "}");
  957. verifyFormat("export function A() {}\n"
  958. "export default function B() {}\n"
  959. "export function C() {}");
  960. verifyFormat("export default () => {\n"
  961. " let x = 1;\n"
  962. " return x;\n"
  963. "}");
  964. verifyFormat("export const x = 12;");
  965. verifyFormat("export default class X {}");
  966. verifyFormat("export {X, Y} from 'some/module.js';");
  967. verifyFormat("export {X, Y,} from 'some/module.js';");
  968. verifyFormat("export {SomeVeryLongExport as X, "
  969. "SomeOtherVeryLongExport as Y} from 'some/module.js';");
  970. // export without 'from' is wrapped.
  971. verifyFormat("export let someRatherLongVariableName =\n"
  972. " someSurprisinglyLongVariable + someOtherRatherLongVar;");
  973. // ... but not if from is just an identifier.
  974. verifyFormat("export {\n"
  975. " from as from,\n"
  976. " someSurprisinglyLongVariable as\n"
  977. " from\n"
  978. "};",
  979. getGoogleJSStyleWithColumns(20));
  980. verifyFormat("export class C {\n"
  981. " x: number;\n"
  982. " y: string;\n"
  983. "}");
  984. verifyFormat("export class X { y: number; }");
  985. verifyFormat("export abstract class X { y: number; }");
  986. verifyFormat("export default class X { y: number }");
  987. verifyFormat("export default function() {\n return 1;\n}");
  988. verifyFormat("export var x = 12;");
  989. verifyFormat("class C {}\n"
  990. "export function f() {}\n"
  991. "var v;");
  992. verifyFormat("export var x: number = 12;");
  993. verifyFormat("export const y = {\n"
  994. " a: 1,\n"
  995. " b: 2\n"
  996. "};");
  997. verifyFormat("export enum Foo {\n"
  998. " BAR,\n"
  999. " // adsdasd\n"
  1000. " BAZ\n"
  1001. "}");
  1002. verifyFormat("export default [\n"
  1003. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
  1004. " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
  1005. "];");
  1006. verifyFormat("export default [];");
  1007. verifyFormat("export default () => {};");
  1008. verifyFormat("export interface Foo { foo: number; }\n"
  1009. "export class Bar {\n"
  1010. " blah(): string { return this.blah; };\n"
  1011. "}");
  1012. }
  1013. TEST_F(FormatTestJS, ImportWrapping) {
  1014. verifyFormat("import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,"
  1015. " VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying"
  1016. "} from 'some/module.js';");
  1017. FormatStyle Style = getGoogleJSStyleWithColumns(80);
  1018. Style.JavaScriptWrapImports = true;
  1019. verifyFormat("import {\n"
  1020. " VeryLongImportsAreAnnoying,\n"
  1021. " VeryLongImportsAreAnnoying,\n"
  1022. " VeryLongImportsAreAnnoying,\n"
  1023. "} from 'some/module.js';",
  1024. Style);
  1025. verifyFormat("import {\n"
  1026. " A,\n"
  1027. " A,\n"
  1028. "} from 'some/module.js';",
  1029. Style);
  1030. verifyFormat("export {\n"
  1031. " A,\n"
  1032. " A,\n"
  1033. "} from 'some/module.js';",
  1034. Style);
  1035. }
  1036. TEST_F(FormatTestJS, TemplateStrings) {
  1037. // Keeps any whitespace/indentation within the template string.
  1038. verifyFormat("var x = `hello\n"
  1039. " ${ name }\n"
  1040. " !`;",
  1041. "var x = `hello\n"
  1042. " ${ name }\n"
  1043. " !`;");
  1044. verifyFormat("var x =\n"
  1045. " `hello ${world}` >= some();",
  1046. getGoogleJSStyleWithColumns(34)); // Barely doesn't fit.
  1047. verifyFormat("var x = `hello ${world}` >= some();",
  1048. getGoogleJSStyleWithColumns(35)); // Barely fits.
  1049. verifyFormat("var x = `hellö ${wörld}` >= söme();",
  1050. getGoogleJSStyleWithColumns(35)); // Fits due to UTF-8.
  1051. verifyFormat("var x = `hello\n"
  1052. " ${world}` >=\n"
  1053. " some();",
  1054. "var x =\n"
  1055. " `hello\n"
  1056. " ${world}` >= some();",
  1057. getGoogleJSStyleWithColumns(21)); // Barely doesn't fit.
  1058. verifyFormat("var x = `hello\n"
  1059. " ${world}` >= some();",
  1060. "var x =\n"
  1061. " `hello\n"
  1062. " ${world}` >= some();",
  1063. getGoogleJSStyleWithColumns(22)); // Barely fits.
  1064. verifyFormat("var x =\n"
  1065. " `h`;",
  1066. getGoogleJSStyleWithColumns(11));
  1067. verifyFormat("var x =\n `multi\n line`;", "var x = `multi\n line`;",
  1068. getGoogleJSStyleWithColumns(13));
  1069. verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
  1070. " `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`);");
  1071. // Repro for an obscure width-miscounting issue with template strings.
  1072. verifyFormat(
  1073. "someLongVariable =\n"
  1074. " "
  1075. "`${logPrefix[11]}/${logPrefix[12]}/${logPrefix[13]}${logPrefix[14]}`;",
  1076. "someLongVariable = "
  1077. "`${logPrefix[11]}/${logPrefix[12]}/${logPrefix[13]}${logPrefix[14]}`;");
  1078. // Make sure template strings get a proper ColumnWidth assigned, even if they
  1079. // are first token in line.
  1080. verifyFormat(
  1081. "var a = aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
  1082. " `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`;");
  1083. // Two template strings.
  1084. verifyFormat("var x = `hello` == `hello`;");
  1085. // Comments in template strings.
  1086. verifyFormat("var x = `//a`;\n"
  1087. "var y;",
  1088. "var x =\n `//a`;\n"
  1089. "var y ;");
  1090. verifyFormat("var x = `/*a`;\n"
  1091. "var y;",
  1092. "var x =\n `/*a`;\n"
  1093. "var y;");
  1094. // Unterminated string literals in a template string.
  1095. verifyFormat("var x = `'`; // comment with matching quote '\n"
  1096. "var y;");
  1097. verifyFormat("var x = `\"`; // comment with matching quote \"\n"
  1098. "var y;");
  1099. verifyFormat("it(`'aaaaaaaaaaaaaaa `, aaaaaaaaa);",
  1100. "it(`'aaaaaaaaaaaaaaa `, aaaaaaaaa) ;",
  1101. getGoogleJSStyleWithColumns(40));
  1102. // Backticks in a comment - not a template string.
  1103. verifyFormat("var x = 1 // `/*a`;\n"
  1104. " ;",
  1105. "var x =\n 1 // `/*a`;\n"
  1106. " ;");
  1107. verifyFormat("/* ` */ var x = 1; /* ` */", "/* ` */ var x\n= 1; /* ` */");
  1108. // Comment spans multiple template strings.
  1109. verifyFormat("var x = `/*a`;\n"
  1110. "var y = ` */ `;",
  1111. "var x =\n `/*a`;\n"
  1112. "var y =\n ` */ `;");
  1113. // Escaped backtick.
  1114. verifyFormat("var x = ` \\` a`;\n"
  1115. "var y;",
  1116. "var x = ` \\` a`;\n"
  1117. "var y;");
  1118. }
  1119. TEST_F(FormatTestJS, CastSyntax) {
  1120. verifyFormat("var x = <type>foo;");
  1121. verifyFormat("var x = foo as type;");
  1122. verifyFormat("let x = (a + b) as\n"
  1123. " LongTypeIsLong;",
  1124. getGoogleJSStyleWithColumns(20));
  1125. verifyFormat("foo = <Bar[]>[\n"
  1126. " 1, //\n"
  1127. " 2\n"
  1128. "];");
  1129. }
  1130. TEST_F(FormatTestJS, TypeArguments) {
  1131. verifyFormat("class X<Y> {}");
  1132. verifyFormat("new X<Y>();");
  1133. verifyFormat("foo<Y>(a);");
  1134. verifyFormat("var x: X<Y>[];");
  1135. verifyFormat("class C extends D<E> implements F<G>, H<I> {}");
  1136. verifyFormat("function f(a: List<any> = null) {}");
  1137. verifyFormat("function f(): List<any> {}");
  1138. verifyFormat("function aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa():\n"
  1139. " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {}");
  1140. verifyFormat("function aaaaaaaaaa(\n"
  1141. " aaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaa,\n"
  1142. " aaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaa):\n"
  1143. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {}");
  1144. }
  1145. TEST_F(FormatTestJS, UserDefinedTypeGuards) {
  1146. verifyFormat(
  1147. "function foo(check: Object):\n"
  1148. " check is {foo: string, bar: string, baz: string, foobar: string} {\n"
  1149. " return 'bar' in check;\n"
  1150. "}\n");
  1151. }
  1152. TEST_F(FormatTestJS, OptionalTypes) {
  1153. verifyFormat("function x(a?: b, c?, d?) {}");
  1154. verifyFormat("class X {\n"
  1155. " y?: z;\n"
  1156. " z?;\n"
  1157. "}");
  1158. verifyFormat("interface X {\n"
  1159. " y?(): z;\n"
  1160. "}");
  1161. verifyFormat("constructor({aa}: {\n"
  1162. " aa?: string,\n"
  1163. " aaaaaaaa?: string,\n"
  1164. " aaaaaaaaaaaaaaa?: boolean,\n"
  1165. " aaaaaa?: List<string>\n"
  1166. "}) {}");
  1167. }
  1168. TEST_F(FormatTestJS, IndexSignature) {
  1169. verifyFormat("var x: {[k: string]: v};");
  1170. }
  1171. TEST_F(FormatTestJS, WrapAfterParen) {
  1172. verifyFormat("xxxxxxxxxxx(\n"
  1173. " aaa, aaa);",
  1174. getGoogleJSStyleWithColumns(20));
  1175. verifyFormat("xxxxxxxxxxx(\n"
  1176. " aaa, aaa, aaa,\n"
  1177. " aaa, aaa, aaa);",
  1178. getGoogleJSStyleWithColumns(20));
  1179. verifyFormat("xxxxxxxxxxx(\n"
  1180. " aaaaaaaaaaaaaaaaaaaaaaaa,\n"
  1181. " function(x) {\n"
  1182. " y(); //\n"
  1183. " });",
  1184. getGoogleJSStyleWithColumns(40));
  1185. verifyFormat("while (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&\n"
  1186. " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}");
  1187. }
  1188. TEST_F(FormatTestJS, JSDocAnnotations) {
  1189. verifyFormat("/**\n"
  1190. " * @export {this.is.a.long.path.to.a.Type}\n"
  1191. " */",
  1192. "/**\n"
  1193. " * @export {this.is.a.long.path.to.a.Type}\n"
  1194. " */",
  1195. getGoogleJSStyleWithColumns(20));
  1196. }
  1197. TEST_F(FormatTestJS, RequoteStringsSingle) {
  1198. verifyFormat("var x = 'foo';", "var x = \"foo\";");
  1199. verifyFormat("var x = 'fo\\'o\\'';", "var x = \"fo'o'\";");
  1200. verifyFormat("var x = 'fo\\'o\\'';", "var x = \"fo\\'o'\";");
  1201. verifyFormat(
  1202. "var x =\n"
  1203. " 'foo\\'';",
  1204. // Code below is 15 chars wide, doesn't fit into the line with the
  1205. // \ escape added.
  1206. "var x = \"foo'\";", getGoogleJSStyleWithColumns(15));
  1207. // Removes no-longer needed \ escape from ".
  1208. verifyFormat("var x = 'fo\"o';", "var x = \"fo\\\"o\";");
  1209. // Code below fits into 15 chars *after* removing the \ escape.
  1210. verifyFormat("var x = 'fo\"o';", "var x = \"fo\\\"o\";",
  1211. getGoogleJSStyleWithColumns(15));
  1212. verifyFormat("// clang-format off\n"
  1213. "let x = \"double\";\n"
  1214. "// clang-format on\n"
  1215. "let x = 'single';\n",
  1216. "// clang-format off\n"
  1217. "let x = \"double\";\n"
  1218. "// clang-format on\n"
  1219. "let x = \"single\";\n");
  1220. }
  1221. TEST_F(FormatTestJS, RequoteStringsDouble) {
  1222. FormatStyle DoubleQuotes = getGoogleStyle(FormatStyle::LK_JavaScript);
  1223. DoubleQuotes.JavaScriptQuotes = FormatStyle::JSQS_Double;
  1224. verifyFormat("var x = \"foo\";", DoubleQuotes);
  1225. verifyFormat("var x = \"foo\";", "var x = 'foo';", DoubleQuotes);
  1226. verifyFormat("var x = \"fo'o\";", "var x = 'fo\\'o';", DoubleQuotes);
  1227. }
  1228. TEST_F(FormatTestJS, RequoteStringsLeave) {
  1229. FormatStyle LeaveQuotes = getGoogleStyle(FormatStyle::LK_JavaScript);
  1230. LeaveQuotes.JavaScriptQuotes = FormatStyle::JSQS_Leave;
  1231. verifyFormat("var x = \"foo\";", LeaveQuotes);
  1232. verifyFormat("var x = 'foo';", LeaveQuotes);
  1233. }
  1234. TEST_F(FormatTestJS, SupportShebangLines) {
  1235. verifyFormat("#!/usr/bin/env node\n"
  1236. "var x = hello();",
  1237. "#!/usr/bin/env node\n"
  1238. "var x = hello();");
  1239. }
  1240. TEST_F(FormatTestJS, NonNullAssertionOperator) {
  1241. verifyFormat("let x = foo!.bar();\n");
  1242. verifyFormat("let x = foo ? bar! : baz;\n");
  1243. verifyFormat("let x = !foo;\n");
  1244. verifyFormat("let x = foo[0]!;\n");
  1245. verifyFormat("let x = (foo)!;\n");
  1246. verifyFormat("let x = {foo: 1}!;\n");
  1247. }
  1248. TEST_F(FormatTestJS, Conditional) {
  1249. verifyFormat("y = x ? 1 : 2;");
  1250. verifyFormat("x ? 1: 2;"); // Known issue with top level conditionals.
  1251. verifyFormat("class Foo {\n"
  1252. " field = true ? 1 : 2;\n"
  1253. " method(a = true ? 1 : 2) {}\n"
  1254. "}");
  1255. }
  1256. } // end namespace tooling
  1257. } // end namespace clang