FormatTestJS.cpp 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695
  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.for() = 1;");
  121. verifyFormat("x.as() = 1;");
  122. verifyFormat("x = {\n"
  123. " a: 12,\n"
  124. " interface: 1,\n"
  125. " switch: 1,\n"
  126. "};");
  127. verifyFormat("var struct = 2;");
  128. verifyFormat("var union = 2;");
  129. verifyFormat("var interface = 2;");
  130. verifyFormat("interface = 2;");
  131. verifyFormat("x = interface instanceof y;");
  132. }
  133. TEST_F(FormatTestJS, ReservedWordsMethods) {
  134. verifyFormat(
  135. "class X {\n"
  136. " delete() {\n"
  137. " x();\n"
  138. " }\n"
  139. " interface() {\n"
  140. " x();\n"
  141. " }\n"
  142. " let() {\n"
  143. " x();\n"
  144. " }\n"
  145. "}\n");
  146. }
  147. TEST_F(FormatTestJS, CppKeywords) {
  148. // Make sure we don't mess stuff up because of C++ keywords.
  149. verifyFormat("return operator && (aa);");
  150. }
  151. TEST_F(FormatTestJS, ES6DestructuringAssignment) {
  152. verifyFormat("var [a, b, c] = [1, 2, 3];");
  153. verifyFormat("const [a, b, c] = [1, 2, 3];");
  154. verifyFormat("let [a, b, c] = [1, 2, 3];");
  155. verifyFormat("var {a, b} = {a: 1, b: 2};");
  156. verifyFormat("let {a, b} = {a: 1, b: 2};");
  157. }
  158. TEST_F(FormatTestJS, ContainerLiterals) {
  159. verifyFormat("var x = {\n"
  160. " y: function(a) {\n"
  161. " return a;\n"
  162. " }\n"
  163. "};");
  164. verifyFormat("return {\n"
  165. " link: function() {\n"
  166. " f(); //\n"
  167. " }\n"
  168. "};");
  169. verifyFormat("return {\n"
  170. " a: a,\n"
  171. " link: function() {\n"
  172. " f(); //\n"
  173. " }\n"
  174. "};");
  175. verifyFormat("return {\n"
  176. " a: a,\n"
  177. " link: function() {\n"
  178. " f(); //\n"
  179. " },\n"
  180. " link: function() {\n"
  181. " f(); //\n"
  182. " }\n"
  183. "};");
  184. verifyFormat("var stuff = {\n"
  185. " // comment for update\n"
  186. " update: false,\n"
  187. " // comment for modules\n"
  188. " modules: false,\n"
  189. " // comment for tasks\n"
  190. " tasks: false\n"
  191. "};");
  192. verifyFormat("return {\n"
  193. " 'finish':\n"
  194. " //\n"
  195. " a\n"
  196. "};");
  197. verifyFormat("var obj = {\n"
  198. " fooooooooo: function(x) {\n"
  199. " return x.zIsTooLongForOneLineWithTheDeclarationLine();\n"
  200. " }\n"
  201. "};");
  202. // Simple object literal, as opposed to enum style below.
  203. verifyFormat("var obj = {a: 123};");
  204. // Enum style top level assignment.
  205. verifyFormat("X = {\n a: 123\n};");
  206. verifyFormat("X.Y = {\n a: 123\n};");
  207. // But only on the top level, otherwise its a plain object literal assignment.
  208. verifyFormat("function x() {\n"
  209. " y = {z: 1};\n"
  210. "}");
  211. verifyFormat("x = foo && {a: 123};");
  212. // Arrow functions in object literals.
  213. verifyFormat("var x = {\n"
  214. " y: (a) => {\n"
  215. " return a;\n"
  216. " }\n"
  217. "};");
  218. verifyFormat("var x = {y: (a) => a};");
  219. // Methods in object literals.
  220. verifyFormat("var x = {\n"
  221. " y(a: string): number {\n"
  222. " return a;\n"
  223. " }\n"
  224. "};");
  225. verifyFormat("var x = {\n"
  226. " y(a: string) {\n"
  227. " return a;\n"
  228. " }\n"
  229. "};");
  230. // Computed keys.
  231. verifyFormat("var x = {[a]: 1, b: 2, [c]: 3};");
  232. verifyFormat("var x = {\n"
  233. " [a]: 1,\n"
  234. " b: 2,\n"
  235. " [c]: 3,\n"
  236. "};");
  237. // Object literals can leave out labels.
  238. verifyFormat("f({a}, () => {\n"
  239. " g(); //\n"
  240. "});");
  241. // Keys can be quoted.
  242. verifyFormat("var x = {\n"
  243. " a: a,\n"
  244. " b: b,\n"
  245. " 'c': c,\n"
  246. "};");
  247. // Dict literals can skip the label names.
  248. verifyFormat("var x = {\n"
  249. " aaa,\n"
  250. " aaa,\n"
  251. " aaa,\n"
  252. "};");
  253. }
  254. TEST_F(FormatTestJS, MethodsInObjectLiterals) {
  255. verifyFormat("var o = {\n"
  256. " value: 'test',\n"
  257. " get value() { // getter\n"
  258. " return this.value;\n"
  259. " }\n"
  260. "};");
  261. verifyFormat("var o = {\n"
  262. " value: 'test',\n"
  263. " set value(val) { // setter\n"
  264. " this.value = val;\n"
  265. " }\n"
  266. "};");
  267. verifyFormat("var o = {\n"
  268. " value: 'test',\n"
  269. " someMethod(val) { // method\n"
  270. " doSomething(this.value + val);\n"
  271. " }\n"
  272. "};");
  273. verifyFormat("var o = {\n"
  274. " someMethod(val) { // method\n"
  275. " doSomething(this.value + val);\n"
  276. " },\n"
  277. " someOtherMethod(val) { // method\n"
  278. " doSomething(this.value + val);\n"
  279. " }\n"
  280. "};");
  281. }
  282. TEST_F(FormatTestJS, SpacesInContainerLiterals) {
  283. verifyFormat("var arr = [1, 2, 3];");
  284. verifyFormat("f({a: 1, b: 2, c: 3});");
  285. verifyFormat("var object_literal_with_long_name = {\n"
  286. " a: 'aaaaaaaaaaaaaaaaaa',\n"
  287. " b: 'bbbbbbbbbbbbbbbbbb'\n"
  288. "};");
  289. verifyFormat("f({a: 1, b: 2, c: 3});",
  290. getChromiumStyle(FormatStyle::LK_JavaScript));
  291. verifyFormat("f({'a': [{}]});");
  292. }
  293. TEST_F(FormatTestJS, SingleQuotedStrings) {
  294. verifyFormat("this.function('', true);");
  295. }
  296. TEST_F(FormatTestJS, GoogScopes) {
  297. verifyFormat("goog.scope(function() {\n"
  298. "var x = a.b;\n"
  299. "var y = c.d;\n"
  300. "}); // goog.scope");
  301. verifyFormat("goog.scope(function() {\n"
  302. "// test\n"
  303. "var x = 0;\n"
  304. "// test\n"
  305. "});");
  306. }
  307. TEST_F(FormatTestJS, GoogModules) {
  308. verifyFormat("goog.module('this.is.really.absurdly.long');",
  309. getGoogleJSStyleWithColumns(40));
  310. verifyFormat("goog.require('this.is.really.absurdly.long');",
  311. getGoogleJSStyleWithColumns(40));
  312. verifyFormat("goog.provide('this.is.really.absurdly.long');",
  313. getGoogleJSStyleWithColumns(40));
  314. verifyFormat("var long = goog.require('this.is.really.absurdly.long');",
  315. getGoogleJSStyleWithColumns(40));
  316. verifyFormat("goog.setTestOnly('this.is.really.absurdly.long');",
  317. getGoogleJSStyleWithColumns(40));
  318. verifyFormat("goog.forwardDeclare('this.is.really.absurdly.long');",
  319. getGoogleJSStyleWithColumns(40));
  320. // These should be wrapped normally.
  321. verifyFormat(
  322. "var MyLongClassName =\n"
  323. " goog.module.get('my.long.module.name.followedBy.MyLongClassName');");
  324. }
  325. TEST_F(FormatTestJS, FormatsNamespaces) {
  326. verifyFormat("namespace Foo {\n"
  327. " export let x = 1;\n"
  328. "}\n");
  329. verifyFormat("declare namespace Foo {\n"
  330. " export let x: number;\n"
  331. "}\n");
  332. }
  333. TEST_F(FormatTestJS, NamespacesMayNotWrap) {
  334. verifyFormat("declare namespace foobarbaz {\n"
  335. "}\n", getGoogleJSStyleWithColumns(18));
  336. verifyFormat("declare module foobarbaz {\n"
  337. "}\n", getGoogleJSStyleWithColumns(15));
  338. verifyFormat("namespace foobarbaz {\n"
  339. "}\n", getGoogleJSStyleWithColumns(10));
  340. verifyFormat("module foobarbaz {\n"
  341. "}\n", getGoogleJSStyleWithColumns(7));
  342. }
  343. TEST_F(FormatTestJS, AmbientDeclarations) {
  344. FormatStyle NineCols = getGoogleJSStyleWithColumns(9);
  345. verifyFormat(
  346. "declare class\n"
  347. " X {}",
  348. NineCols);
  349. verifyFormat(
  350. "declare function\n"
  351. "x();", // TODO(martinprobst): should ideally be indented.
  352. NineCols);
  353. verifyFormat("declare function foo();\n"
  354. "let x = 1;\n");
  355. verifyFormat("declare function foo(): string;\n"
  356. "let x = 1;\n");
  357. verifyFormat("declare function foo(): {x: number};\n"
  358. "let x = 1;\n");
  359. verifyFormat("declare class X {}\n"
  360. "let x = 1;\n");
  361. verifyFormat("declare interface Y {}\n"
  362. "let x = 1;\n");
  363. verifyFormat(
  364. "declare enum X {\n"
  365. "}",
  366. NineCols);
  367. verifyFormat(
  368. "declare let\n"
  369. " x: number;",
  370. NineCols);
  371. }
  372. TEST_F(FormatTestJS, FormatsFreestandingFunctions) {
  373. verifyFormat("function outer1(a, b) {\n"
  374. " function inner1(a, b) {\n"
  375. " return a;\n"
  376. " }\n"
  377. " inner1(a, b);\n"
  378. "}\n"
  379. "function outer2(a, b) {\n"
  380. " function inner2(a, b) {\n"
  381. " return a;\n"
  382. " }\n"
  383. " inner2(a, b);\n"
  384. "}");
  385. verifyFormat("function f() {}");
  386. }
  387. TEST_F(FormatTestJS, GeneratorFunctions) {
  388. verifyFormat("function* f() {\n"
  389. " let x = 1;\n"
  390. " yield x;\n"
  391. " yield* something();\n"
  392. " yield [1, 2];\n"
  393. " yield {a: 1};\n"
  394. "}");
  395. verifyFormat("function*\n"
  396. " f() {\n"
  397. "}",
  398. getGoogleJSStyleWithColumns(8));
  399. verifyFormat("export function* f() {\n"
  400. " yield 1;\n"
  401. "}\n");
  402. verifyFormat("class X {\n"
  403. " * generatorMethod() {\n"
  404. " yield x;\n"
  405. " }\n"
  406. "}");
  407. verifyFormat("var x = {\n"
  408. " a: function*() {\n"
  409. " //\n"
  410. " }\n"
  411. "}\n");
  412. }
  413. TEST_F(FormatTestJS, AsyncFunctions) {
  414. verifyFormat("async function f() {\n"
  415. " let x = 1;\n"
  416. " return fetch(x);\n"
  417. "}");
  418. verifyFormat("async function* f() {\n"
  419. " yield fetch(x);\n"
  420. "}");
  421. verifyFormat("export async function f() {\n"
  422. " return fetch(x);\n"
  423. "}");
  424. verifyFormat("let x = async () => f();");
  425. verifyFormat("let x = async();");
  426. verifyFormat("class X {\n"
  427. " async asyncMethod() {\n"
  428. " return fetch(1);\n"
  429. " }\n"
  430. "}");
  431. verifyFormat("function initialize() {\n"
  432. " // Comment.\n"
  433. " return async.then();\n"
  434. "}\n");
  435. }
  436. TEST_F(FormatTestJS, ArrayLiterals) {
  437. verifyFormat("var aaaaa: List<SomeThing> =\n"
  438. " [new SomeThingAAAAAAAAAAAA(), new SomeThingBBBBBBBBB()];");
  439. verifyFormat("return [\n"
  440. " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
  441. " ccccccccccccccccccccccccccc\n"
  442. "];");
  443. verifyFormat("return [\n"
  444. " aaaa().bbbbbbbb('A'),\n"
  445. " aaaa().bbbbbbbb('B'),\n"
  446. " aaaa().bbbbbbbb('C'),\n"
  447. "];");
  448. verifyFormat("var someVariable = SomeFunction([\n"
  449. " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
  450. " ccccccccccccccccccccccccccc\n"
  451. "]);");
  452. verifyFormat("var someVariable = SomeFunction([\n"
  453. " [aaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbb],\n"
  454. "]);",
  455. getGoogleJSStyleWithColumns(51));
  456. verifyFormat("var someVariable = SomeFunction(aaaa, [\n"
  457. " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
  458. " ccccccccccccccccccccccccccc\n"
  459. "]);");
  460. verifyFormat("var someVariable = SomeFunction(\n"
  461. " aaaa,\n"
  462. " [\n"
  463. " aaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
  464. " cccccccccccccccccccccccccc\n"
  465. " ],\n"
  466. " aaaa);");
  467. verifyFormat("var aaaa = aaaaa || // wrap\n"
  468. " [];");
  469. verifyFormat("someFunction([], {a: a});");
  470. verifyFormat("var string = [\n"
  471. " 'aaaaaa',\n"
  472. " 'bbbbbb',\n"
  473. "].join('+');");
  474. }
  475. TEST_F(FormatTestJS, ColumnLayoutForArrayLiterals) {
  476. verifyFormat("var array = [\n"
  477. " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
  478. " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
  479. "];");
  480. verifyFormat("var array = someFunction([\n"
  481. " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
  482. " a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,\n"
  483. "]);");
  484. }
  485. TEST_F(FormatTestJS, FunctionLiterals) {
  486. FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
  487. Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
  488. verifyFormat("doFoo(function() {});");
  489. verifyFormat("doFoo(function() { return 1; });", Style);
  490. verifyFormat("var func = function() {\n"
  491. " return 1;\n"
  492. "};");
  493. verifyFormat("var func = //\n"
  494. " function() {\n"
  495. " return 1;\n"
  496. "};");
  497. verifyFormat("return {\n"
  498. " body: {\n"
  499. " setAttribute: function(key, val) { this[key] = val; },\n"
  500. " getAttribute: function(key) { return this[key]; },\n"
  501. " style: {direction: ''}\n"
  502. " }\n"
  503. "};",
  504. Style);
  505. verifyFormat("abc = xyz ? function() {\n"
  506. " return 1;\n"
  507. "} : function() {\n"
  508. " return -1;\n"
  509. "};");
  510. verifyFormat("var closure = goog.bind(\n"
  511. " function() { // comment\n"
  512. " foo();\n"
  513. " bar();\n"
  514. " },\n"
  515. " this, arg1IsReallyLongAndNeedsLineBreaks,\n"
  516. " arg3IsReallyLongAndNeedsLineBreaks);");
  517. verifyFormat("var closure = goog.bind(function() { // comment\n"
  518. " foo();\n"
  519. " bar();\n"
  520. "}, this);");
  521. verifyFormat("return {\n"
  522. " a: 'E',\n"
  523. " b: function() {\n"
  524. " return function() {\n"
  525. " f(); //\n"
  526. " };\n"
  527. " }\n"
  528. "};");
  529. verifyFormat("{\n"
  530. " var someVariable = function(x) {\n"
  531. " return x.zIsTooLongForOneLineWithTheDeclarationLine();\n"
  532. " };\n"
  533. "}");
  534. verifyFormat("someLooooooooongFunction(\n"
  535. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
  536. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
  537. " function(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n"
  538. " // code\n"
  539. " });");
  540. verifyFormat("return {\n"
  541. " a: function SomeFunction() {\n"
  542. " // ...\n"
  543. " return 1;\n"
  544. " }\n"
  545. "};");
  546. verifyFormat("this.someObject.doSomething(aaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
  547. " .then(goog.bind(function(aaaaaaaaaaa) {\n"
  548. " someFunction();\n"
  549. " someFunction();\n"
  550. " }, this), aaaaaaaaaaaaaaaaa);");
  551. verifyFormat("someFunction(goog.bind(function() {\n"
  552. " doSomething();\n"
  553. " doSomething();\n"
  554. "}, this), goog.bind(function() {\n"
  555. " doSomething();\n"
  556. " doSomething();\n"
  557. "}, this));");
  558. verifyFormat("SomeFunction(function() {\n"
  559. " foo();\n"
  560. " bar();\n"
  561. "}.bind(this));");
  562. // FIXME: This is bad, we should be wrapping before "function() {".
  563. verifyFormat("someFunction(function() {\n"
  564. " doSomething(); // break\n"
  565. "})\n"
  566. " .doSomethingElse(\n"
  567. " // break\n"
  568. " );");
  569. Style.ColumnLimit = 33;
  570. verifyFormat("f({a: function() { return 1; }});", Style);
  571. Style.ColumnLimit = 32;
  572. verifyFormat("f({\n"
  573. " a: function() { return 1; }\n"
  574. "});",
  575. Style);
  576. }
  577. TEST_F(FormatTestJS, InliningFunctionLiterals) {
  578. FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
  579. Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
  580. verifyFormat("var func = function() {\n"
  581. " return 1;\n"
  582. "};",
  583. Style);
  584. verifyFormat("var func = doSomething(function() { return 1; });", Style);
  585. verifyFormat("var outer = function() {\n"
  586. " var inner = function() { return 1; }\n"
  587. "};",
  588. Style);
  589. verifyFormat("function outer1(a, b) {\n"
  590. " function inner1(a, b) { return a; }\n"
  591. "}",
  592. Style);
  593. Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
  594. verifyFormat("var func = function() { return 1; };", Style);
  595. verifyFormat("var func = doSomething(function() { return 1; });", Style);
  596. verifyFormat(
  597. "var outer = function() { var inner = function() { return 1; } };",
  598. Style);
  599. verifyFormat("function outer1(a, b) {\n"
  600. " function inner1(a, b) { return a; }\n"
  601. "}",
  602. Style);
  603. Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
  604. verifyFormat("var func = function() {\n"
  605. " return 1;\n"
  606. "};",
  607. Style);
  608. verifyFormat("var func = doSomething(function() {\n"
  609. " return 1;\n"
  610. "});",
  611. Style);
  612. verifyFormat("var outer = function() {\n"
  613. " var inner = function() {\n"
  614. " return 1;\n"
  615. " }\n"
  616. "};",
  617. Style);
  618. verifyFormat("function outer1(a, b) {\n"
  619. " function inner1(a, b) {\n"
  620. " return a;\n"
  621. " }\n"
  622. "}",
  623. Style);
  624. Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
  625. verifyFormat("var func = function() {\n"
  626. " return 1;\n"
  627. "};",
  628. Style);
  629. }
  630. TEST_F(FormatTestJS, MultipleFunctionLiterals) {
  631. FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
  632. Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
  633. verifyFormat("promise.then(\n"
  634. " function success() {\n"
  635. " doFoo();\n"
  636. " doBar();\n"
  637. " },\n"
  638. " function error() {\n"
  639. " doFoo();\n"
  640. " doBaz();\n"
  641. " },\n"
  642. " []);\n");
  643. verifyFormat("promise.then(\n"
  644. " function success() {\n"
  645. " doFoo();\n"
  646. " doBar();\n"
  647. " },\n"
  648. " [],\n"
  649. " function error() {\n"
  650. " doFoo();\n"
  651. " doBaz();\n"
  652. " });\n");
  653. verifyFormat("promise.then(\n"
  654. " [],\n"
  655. " function success() {\n"
  656. " doFoo();\n"
  657. " doBar();\n"
  658. " },\n"
  659. " function error() {\n"
  660. " doFoo();\n"
  661. " doBaz();\n"
  662. " });\n");
  663. verifyFormat("getSomeLongPromise()\n"
  664. " .then(function(value) { body(); })\n"
  665. " .thenCatch(function(error) {\n"
  666. " body();\n"
  667. " body();\n"
  668. " });",
  669. Style);
  670. verifyFormat("getSomeLongPromise()\n"
  671. " .then(function(value) {\n"
  672. " body();\n"
  673. " body();\n"
  674. " })\n"
  675. " .thenCatch(function(error) {\n"
  676. " body();\n"
  677. " body();\n"
  678. " });");
  679. verifyFormat("getSomeLongPromise()\n"
  680. " .then(function(value) { body(); })\n"
  681. " .thenCatch(function(error) { body(); });",
  682. Style);
  683. verifyFormat("return [aaaaaaaaaaaaaaaaaaaaaa]\n"
  684. " .aaaaaaa(function() {\n"
  685. " //\n"
  686. " })\n"
  687. " .bbbbbb();");
  688. }
  689. TEST_F(FormatTestJS, ArrowFunctions) {
  690. verifyFormat("var x = (a) => {\n"
  691. " return a;\n"
  692. "};");
  693. verifyFormat("var x = (a) => {\n"
  694. " function y() {\n"
  695. " return 42;\n"
  696. " }\n"
  697. " return a;\n"
  698. "};");
  699. verifyFormat("var x = (a: type): {some: type} => {\n"
  700. " return a;\n"
  701. "};");
  702. verifyFormat("var x = (a) => a;");
  703. verifyFormat("return () => [];");
  704. verifyFormat("var aaaaaaaaaaaaaaaaaaaa = {\n"
  705. " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n"
  706. " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
  707. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) =>\n"
  708. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
  709. "};");
  710. verifyFormat("var a = a.aaaaaaa(\n"
  711. " (a: a) => aaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbb) &&\n"
  712. " aaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbb));");
  713. verifyFormat("var a = a.aaaaaaa(\n"
  714. " (a: a) => aaaaaaaaaaaaaaaaaaaaa(bbbbbbbbb) ?\n"
  715. " aaaaaaaaaaaaaaaaaaaaa(bbbbbbb) :\n"
  716. " aaaaaaaaaaaaaaaaaaaaa(bbbbbbb));");
  717. // FIXME: This is bad, we should be wrapping before "() => {".
  718. verifyFormat("someFunction(() => {\n"
  719. " doSomething(); // break\n"
  720. "})\n"
  721. " .doSomethingElse(\n"
  722. " // break\n"
  723. " );");
  724. }
  725. TEST_F(FormatTestJS, ReturnStatements) {
  726. verifyFormat("function() {\n"
  727. " return [hello, world];\n"
  728. "}");
  729. }
  730. TEST_F(FormatTestJS, ForLoops) {
  731. verifyFormat("for (var i in [2, 3]) {\n"
  732. "}");
  733. verifyFormat("for (var i of [2, 3]) {\n"
  734. "}");
  735. verifyFormat("for (let {a, b} of x) {\n"
  736. "}");
  737. verifyFormat("for (let {a, b} in x) {\n"
  738. "}");
  739. }
  740. TEST_F(FormatTestJS, WrapRespectsAutomaticSemicolonInsertion) {
  741. // The following statements must not wrap, as otherwise the program meaning
  742. // would change due to automatic semicolon insertion.
  743. // See http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1.
  744. verifyFormat("return aaaaa;", getGoogleJSStyleWithColumns(10));
  745. verifyFormat("return /* hello! */ aaaaa;", getGoogleJSStyleWithColumns(10));
  746. verifyFormat("continue aaaaa;", getGoogleJSStyleWithColumns(10));
  747. verifyFormat("continue /* hello! */ aaaaa;", getGoogleJSStyleWithColumns(10));
  748. verifyFormat("break aaaaa;", getGoogleJSStyleWithColumns(10));
  749. verifyFormat("throw aaaaa;", getGoogleJSStyleWithColumns(10));
  750. verifyFormat("aaaaaaaaa++;", getGoogleJSStyleWithColumns(10));
  751. verifyFormat("aaaaaaaaa--;", getGoogleJSStyleWithColumns(10));
  752. verifyFormat("return [\n"
  753. " aaa\n"
  754. "];",
  755. getGoogleJSStyleWithColumns(12));
  756. }
  757. TEST_F(FormatTestJS, AutomaticSemicolonInsertionHeuristic) {
  758. verifyFormat("a\n"
  759. "b;",
  760. " a \n"
  761. " b ;");
  762. verifyFormat("a()\n"
  763. "b;",
  764. " a ()\n"
  765. " b ;");
  766. verifyFormat("a[b]\n"
  767. "c;",
  768. "a [b]\n"
  769. "c ;");
  770. verifyFormat("1\n"
  771. "a;",
  772. "1 \n"
  773. "a ;");
  774. verifyFormat("a\n"
  775. "1;",
  776. "a \n"
  777. "1 ;");
  778. verifyFormat("a\n"
  779. "'x';",
  780. "a \n"
  781. " 'x';");
  782. verifyFormat("a++\n"
  783. "b;",
  784. "a ++\n"
  785. "b ;");
  786. verifyFormat("a\n"
  787. "!b && c;",
  788. "a \n"
  789. " ! b && c;");
  790. verifyFormat("a\n"
  791. "if (1) f();",
  792. " a\n"
  793. " if (1) f();");
  794. verifyFormat("a\n"
  795. "class X {}",
  796. " a\n"
  797. " class X {}");
  798. verifyFormat("var a", "var\n"
  799. "a");
  800. verifyFormat("x instanceof String", "x\n"
  801. "instanceof\n"
  802. "String");
  803. verifyFormat("function f(@Foo bar) {}", "function f(@Foo\n"
  804. " bar) {}");
  805. verifyFormat("a = true\n"
  806. "return 1",
  807. "a = true\n"
  808. " return 1");
  809. verifyFormat("a = 's'\n"
  810. "return 1",
  811. "a = 's'\n"
  812. " return 1");
  813. verifyFormat("a = null\n"
  814. "return 1",
  815. "a = null\n"
  816. " return 1");
  817. // Below "class Y {}" should ideally be on its own line.
  818. verifyFormat(
  819. "x = {\n"
  820. " a: 1\n"
  821. "} class Y {}",
  822. " x = {a : 1}\n"
  823. " class Y { }");
  824. verifyFormat(
  825. "if (x) {\n"
  826. "}\n"
  827. "return 1",
  828. "if (x) {}\n"
  829. " return 1");
  830. verifyFormat(
  831. "if (x) {\n"
  832. "}\n"
  833. "class X {}",
  834. "if (x) {}\n"
  835. " class X {}");
  836. }
  837. TEST_F(FormatTestJS, ImportExportASI) {
  838. verifyFormat(
  839. "import {x} from 'y'\n"
  840. "export function z() {}",
  841. "import {x} from 'y'\n"
  842. " export function z() {}");
  843. // Below "class Y {}" should ideally be on its own line.
  844. verifyFormat(
  845. "export {x} class Y {}",
  846. " export {x}\n"
  847. " class Y {\n}");
  848. verifyFormat(
  849. "if (x) {\n"
  850. "}\n"
  851. "export class Y {}",
  852. "if ( x ) { }\n"
  853. " export class Y {}");
  854. }
  855. TEST_F(FormatTestJS, ClosureStyleCasts) {
  856. verifyFormat("var x = /** @type {foo} */ (bar);");
  857. }
  858. TEST_F(FormatTestJS, TryCatch) {
  859. verifyFormat("try {\n"
  860. " f();\n"
  861. "} catch (e) {\n"
  862. " g();\n"
  863. "} finally {\n"
  864. " h();\n"
  865. "}");
  866. // But, of course, "catch" is a perfectly fine function name in JavaScript.
  867. verifyFormat("someObject.catch();");
  868. verifyFormat("someObject.new();");
  869. verifyFormat("someObject.delete();");
  870. }
  871. TEST_F(FormatTestJS, StringLiteralConcatenation) {
  872. verifyFormat("var literal = 'hello ' +\n"
  873. " 'world';");
  874. }
  875. TEST_F(FormatTestJS, RegexLiteralClassification) {
  876. // Regex literals.
  877. verifyFormat("var regex = /abc/;");
  878. verifyFormat("f(/abc/);");
  879. verifyFormat("f(abc, /abc/);");
  880. verifyFormat("some_map[/abc/];");
  881. verifyFormat("var x = a ? /abc/ : /abc/;");
  882. verifyFormat("for (var i = 0; /abc/.test(s[i]); i++) {\n}");
  883. verifyFormat("var x = !/abc/.test(y);");
  884. verifyFormat("var x = foo()! / 10;");
  885. verifyFormat("var x = a && /abc/.test(y);");
  886. verifyFormat("var x = a || /abc/.test(y);");
  887. verifyFormat("var x = a + /abc/.search(y);");
  888. verifyFormat("/abc/.search(y);");
  889. verifyFormat("var regexs = {/abc/, /abc/};");
  890. verifyFormat("return /abc/;");
  891. // Not regex literals.
  892. verifyFormat("var a = a / 2 + b / 3;");
  893. verifyFormat("var a = a++ / 2;");
  894. // Prefix unary can operate on regex literals, not that it makes sense.
  895. verifyFormat("var a = ++/a/;");
  896. // This is a known issue, regular expressions are incorrectly detected if
  897. // directly following a closing parenthesis.
  898. verifyFormat("if (foo) / bar /.exec(baz);");
  899. }
  900. TEST_F(FormatTestJS, RegexLiteralSpecialCharacters) {
  901. verifyFormat("var regex = /=/;");
  902. verifyFormat("var regex = /a*/;");
  903. verifyFormat("var regex = /a+/;");
  904. verifyFormat("var regex = /a?/;");
  905. verifyFormat("var regex = /.a./;");
  906. verifyFormat("var regex = /a\\*/;");
  907. verifyFormat("var regex = /^a$/;");
  908. verifyFormat("var regex = /\\/a/;");
  909. verifyFormat("var regex = /(?:x)/;");
  910. verifyFormat("var regex = /x(?=y)/;");
  911. verifyFormat("var regex = /x(?!y)/;");
  912. verifyFormat("var regex = /x|y/;");
  913. verifyFormat("var regex = /a{2}/;");
  914. verifyFormat("var regex = /a{1,3}/;");
  915. verifyFormat("var regex = /[abc]/;");
  916. verifyFormat("var regex = /[^abc]/;");
  917. verifyFormat("var regex = /[\\b]/;");
  918. verifyFormat("var regex = /[/]/;");
  919. verifyFormat("var regex = /[\\/]/;");
  920. verifyFormat("var regex = /\\[/;");
  921. verifyFormat("var regex = /\\\\[/]/;");
  922. verifyFormat("var regex = /}[\"]/;");
  923. verifyFormat("var regex = /}[/\"]/;");
  924. verifyFormat("var regex = /}[\"/]/;");
  925. verifyFormat("var regex = /\\b/;");
  926. verifyFormat("var regex = /\\B/;");
  927. verifyFormat("var regex = /\\d/;");
  928. verifyFormat("var regex = /\\D/;");
  929. verifyFormat("var regex = /\\f/;");
  930. verifyFormat("var regex = /\\n/;");
  931. verifyFormat("var regex = /\\r/;");
  932. verifyFormat("var regex = /\\s/;");
  933. verifyFormat("var regex = /\\S/;");
  934. verifyFormat("var regex = /\\t/;");
  935. verifyFormat("var regex = /\\v/;");
  936. verifyFormat("var regex = /\\w/;");
  937. verifyFormat("var regex = /\\W/;");
  938. verifyFormat("var regex = /a(a)\\1/;");
  939. verifyFormat("var regex = /\\0/;");
  940. verifyFormat("var regex = /\\\\/g;");
  941. verifyFormat("var regex = /\\a\\\\/g;");
  942. verifyFormat("var regex = /\a\\//g;");
  943. verifyFormat("var regex = /a\\//;\n"
  944. "var x = 0;");
  945. verifyFormat("var regex = /'/g;", "var regex = /'/g ;");
  946. verifyFormat("var regex = /'/g; //'", "var regex = /'/g ; //'");
  947. verifyFormat("var regex = /\\/*/;\n"
  948. "var x = 0;",
  949. "var regex = /\\/*/;\n"
  950. "var x=0;");
  951. verifyFormat("var x = /a\\//;", "var x = /a\\// \n;");
  952. verifyFormat("var regex = /\"/;", getGoogleJSStyleWithColumns(16));
  953. verifyFormat("var regex =\n"
  954. " /\"/;",
  955. getGoogleJSStyleWithColumns(15));
  956. verifyFormat("var regex = //\n"
  957. " /a/;");
  958. verifyFormat("var regexs = [\n"
  959. " /d/, //\n"
  960. " /aa/, //\n"
  961. "];");
  962. }
  963. TEST_F(FormatTestJS, RegexLiteralModifiers) {
  964. verifyFormat("var regex = /abc/g;");
  965. verifyFormat("var regex = /abc/i;");
  966. verifyFormat("var regex = /abc/m;");
  967. verifyFormat("var regex = /abc/y;");
  968. }
  969. TEST_F(FormatTestJS, RegexLiteralLength) {
  970. verifyFormat("var regex = /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
  971. getGoogleJSStyleWithColumns(60));
  972. verifyFormat("var regex =\n"
  973. " /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
  974. getGoogleJSStyleWithColumns(60));
  975. verifyFormat("var regex = /\\xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
  976. getGoogleJSStyleWithColumns(50));
  977. }
  978. TEST_F(FormatTestJS, RegexLiteralExamples) {
  979. verifyFormat("var regex = search.match(/(?:\?|&)times=([^?&]+)/i);");
  980. }
  981. TEST_F(FormatTestJS, IgnoresMpegTS) {
  982. std::string MpegTS(200, ' ');
  983. MpegTS.replace(0, strlen("nearlyLooks + like + ts + code; "),
  984. "nearlyLooks + like + ts + code; ");
  985. MpegTS[0] = 0x47;
  986. MpegTS[188] = 0x47;
  987. verifyFormat(MpegTS, MpegTS);
  988. }
  989. TEST_F(FormatTestJS, TypeAnnotations) {
  990. verifyFormat("var x: string;");
  991. verifyFormat("var x: {a: string; b: number;} = {};");
  992. verifyFormat("function x(): string {\n return 'x';\n}");
  993. verifyFormat("function x(): {x: string} {\n return {x: 'x'};\n}");
  994. verifyFormat("function x(y: string): string {\n return 'x';\n}");
  995. verifyFormat("for (var y: string in x) {\n x();\n}");
  996. verifyFormat("for (var y: string of x) {\n x();\n}");
  997. verifyFormat("function x(y: {a?: number;} = {}): number {\n"
  998. " return 12;\n"
  999. "}");
  1000. verifyFormat("((a: string, b: number): string => a + b);");
  1001. verifyFormat("var x: (y: number) => string;");
  1002. verifyFormat("var x: P<string, (a: number) => string>;");
  1003. verifyFormat("var x = {\n"
  1004. " y: function(): z {\n"
  1005. " return 1;\n"
  1006. " }\n"
  1007. "};");
  1008. verifyFormat("var x = {\n"
  1009. " y: function(): {a: number} {\n"
  1010. " return 1;\n"
  1011. " }\n"
  1012. "};");
  1013. verifyFormat("function someFunc(args: string[]):\n"
  1014. " {longReturnValue: string[]} {}",
  1015. getGoogleJSStyleWithColumns(60));
  1016. verifyFormat(
  1017. "var someValue = (v as aaaaaaaaaaaaaaaaaaaa<T>[])\n"
  1018. " .someFunction(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
  1019. }
  1020. TEST_F(FormatTestJS, UnionIntersectionTypes) {
  1021. verifyFormat("let x: A|B = A | B;");
  1022. verifyFormat("let x: A&B|C = A & B;");
  1023. verifyFormat("let x: Foo<A|B> = new Foo<A|B>();");
  1024. verifyFormat("function(x: A|B): C&D {}");
  1025. verifyFormat("function(x: A|B = A | B): C&D {}");
  1026. verifyFormat("function x(path: number|string) {}");
  1027. verifyFormat("function x(): string|number {}");
  1028. verifyFormat("type Foo = Bar|Baz;");
  1029. verifyFormat("type Foo = Bar<X>|Baz;");
  1030. verifyFormat("type Foo = (Bar<X>|Baz);");
  1031. verifyFormat("let x: Bar|Baz;");
  1032. verifyFormat("let x: Bar<X>|Baz;");
  1033. verifyFormat("let x: (Foo|Bar)[];");
  1034. }
  1035. TEST_F(FormatTestJS, ClassDeclarations) {
  1036. verifyFormat("class C {\n x: string = 12;\n}");
  1037. verifyFormat("class C {\n x(): string => 12;\n}");
  1038. verifyFormat("class C {\n ['x' + 2]: string = 12;\n}");
  1039. verifyFormat("class C {\n private x: string = 12;\n}");
  1040. verifyFormat("class C {\n private static x: string = 12;\n}");
  1041. verifyFormat("class C {\n static x(): string {\n return 'asd';\n }\n}");
  1042. verifyFormat("class C extends P implements I {}");
  1043. verifyFormat("class C extends p.P implements i.I {}");
  1044. verifyFormat(
  1045. "x(class {\n"
  1046. " a(): A {}\n"
  1047. "});");
  1048. verifyFormat("class Test {\n"
  1049. " aaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaa):\n"
  1050. " aaaaaaaaaaaaaaaaaaaaaa {}\n"
  1051. "}");
  1052. verifyFormat("foo = class Name {\n"
  1053. " constructor() {}\n"
  1054. "};");
  1055. verifyFormat("foo = class {\n"
  1056. " constructor() {}\n"
  1057. "};");
  1058. verifyFormat("class C {\n"
  1059. " x: {y: Z;} = {};\n"
  1060. " private y: {y: Z;} = {};\n"
  1061. "}");
  1062. // ':' is not a type declaration here.
  1063. verifyFormat("class X {\n"
  1064. " subs = {\n"
  1065. " 'b': {\n"
  1066. " 'c': 1,\n"
  1067. " },\n"
  1068. " };\n"
  1069. "}");
  1070. verifyFormat("@Component({\n"
  1071. " moduleId: module.id,\n"
  1072. "})\n"
  1073. "class SessionListComponent implements OnDestroy, OnInit {\n"
  1074. "}");
  1075. }
  1076. TEST_F(FormatTestJS, InterfaceDeclarations) {
  1077. verifyFormat("interface I {\n"
  1078. " x: string;\n"
  1079. " enum: string[];\n"
  1080. " enum?: string[];\n"
  1081. "}\n"
  1082. "var y;");
  1083. // Ensure that state is reset after parsing the interface.
  1084. verifyFormat("interface a {}\n"
  1085. "export function b() {}\n"
  1086. "var x;");
  1087. // Arrays of object type literals.
  1088. verifyFormat("interface I {\n"
  1089. " o: {}[];\n"
  1090. "}");
  1091. }
  1092. TEST_F(FormatTestJS, EnumDeclarations) {
  1093. verifyFormat("enum Foo {\n"
  1094. " A = 1,\n"
  1095. " B\n"
  1096. "}");
  1097. verifyFormat("export /* somecomment*/ enum Foo {\n"
  1098. " A = 1,\n"
  1099. " B\n"
  1100. "}");
  1101. verifyFormat("enum Foo {\n"
  1102. " A = 1, // comment\n"
  1103. " B\n"
  1104. "}\n"
  1105. "var x = 1;");
  1106. }
  1107. TEST_F(FormatTestJS, MetadataAnnotations) {
  1108. verifyFormat("@A\nclass C {\n}");
  1109. verifyFormat("@A({arg: 'value'})\nclass C {\n}");
  1110. verifyFormat("@A\n@B\nclass C {\n}");
  1111. verifyFormat("class C {\n @A x: string;\n}");
  1112. verifyFormat("class C {\n"
  1113. " @A\n"
  1114. " private x(): string {\n"
  1115. " return 'y';\n"
  1116. " }\n"
  1117. "}");
  1118. verifyFormat("class C {\n"
  1119. " private x(@A x: string) {}\n"
  1120. "}");
  1121. verifyFormat("class X {}\n"
  1122. "class Y {}");
  1123. }
  1124. TEST_F(FormatTestJS, TypeAliases) {
  1125. verifyFormat("type X = number;\n"
  1126. "class C {}");
  1127. verifyFormat("type X<Y> = Z<Y>;");
  1128. verifyFormat("type X = {\n"
  1129. " y: number\n"
  1130. "};\n"
  1131. "class C {}");
  1132. }
  1133. TEST_F(FormatTestJS, Modules) {
  1134. verifyFormat("import SomeThing from 'some/module.js';");
  1135. verifyFormat("import {X, Y} from 'some/module.js';");
  1136. verifyFormat("import a, {X, Y} from 'some/module.js';");
  1137. verifyFormat("import {X, Y,} from 'some/module.js';");
  1138. verifyFormat("import {X as myLocalX, Y as myLocalY} from 'some/module.js';");
  1139. // Ensure Automatic Semicolon Insertion does not break on "as\n".
  1140. verifyFormat("import {X as myX} from 'm';", "import {X as\n"
  1141. " myX} from 'm';");
  1142. verifyFormat("import * as lib from 'some/module.js';");
  1143. verifyFormat("var x = {import: 1};\nx.import = 2;");
  1144. verifyFormat("export function fn() {\n"
  1145. " return 'fn';\n"
  1146. "}");
  1147. verifyFormat("export function A() {}\n"
  1148. "export default function B() {}\n"
  1149. "export function C() {}");
  1150. verifyFormat("export default () => {\n"
  1151. " let x = 1;\n"
  1152. " return x;\n"
  1153. "}");
  1154. verifyFormat("export const x = 12;");
  1155. verifyFormat("export default class X {}");
  1156. verifyFormat("export {X, Y} from 'some/module.js';");
  1157. verifyFormat("export {X, Y,} from 'some/module.js';");
  1158. verifyFormat("export {SomeVeryLongExport as X, "
  1159. "SomeOtherVeryLongExport as Y} from 'some/module.js';");
  1160. // export without 'from' is wrapped.
  1161. verifyFormat("export let someRatherLongVariableName =\n"
  1162. " someSurprisinglyLongVariable + someOtherRatherLongVar;");
  1163. // ... but not if from is just an identifier.
  1164. verifyFormat("export {\n"
  1165. " from as from,\n"
  1166. " someSurprisinglyLongVariable as\n"
  1167. " from\n"
  1168. "};",
  1169. getGoogleJSStyleWithColumns(20));
  1170. verifyFormat("export class C {\n"
  1171. " x: number;\n"
  1172. " y: string;\n"
  1173. "}");
  1174. verifyFormat("export class X { y: number; }");
  1175. verifyFormat("export abstract class X { y: number; }");
  1176. verifyFormat("export default class X { y: number }");
  1177. verifyFormat("export default function() {\n return 1;\n}");
  1178. verifyFormat("export var x = 12;");
  1179. verifyFormat("class C {}\n"
  1180. "export function f() {}\n"
  1181. "var v;");
  1182. verifyFormat("export var x: number = 12;");
  1183. verifyFormat("export const y = {\n"
  1184. " a: 1,\n"
  1185. " b: 2\n"
  1186. "};");
  1187. verifyFormat("export enum Foo {\n"
  1188. " BAR,\n"
  1189. " // adsdasd\n"
  1190. " BAZ\n"
  1191. "}");
  1192. verifyFormat("export default [\n"
  1193. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
  1194. " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
  1195. "];");
  1196. verifyFormat("export default [];");
  1197. verifyFormat("export default () => {};");
  1198. verifyFormat("export interface Foo { foo: number; }\n"
  1199. "export class Bar {\n"
  1200. " blah(): string {\n"
  1201. " return this.blah;\n"
  1202. " };\n"
  1203. "}");
  1204. }
  1205. TEST_F(FormatTestJS, ImportWrapping) {
  1206. verifyFormat("import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,"
  1207. " VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying"
  1208. "} from 'some/module.js';");
  1209. FormatStyle Style = getGoogleJSStyleWithColumns(80);
  1210. Style.JavaScriptWrapImports = true;
  1211. verifyFormat("import {\n"
  1212. " VeryLongImportsAreAnnoying,\n"
  1213. " VeryLongImportsAreAnnoying,\n"
  1214. " VeryLongImportsAreAnnoying,\n"
  1215. "} from 'some/module.js';",
  1216. Style);
  1217. verifyFormat("import {\n"
  1218. " A,\n"
  1219. " A,\n"
  1220. "} from 'some/module.js';",
  1221. Style);
  1222. verifyFormat("export {\n"
  1223. " A,\n"
  1224. " A,\n"
  1225. "} from 'some/module.js';",
  1226. Style);
  1227. }
  1228. TEST_F(FormatTestJS, TemplateStrings) {
  1229. // Keeps any whitespace/indentation within the template string.
  1230. verifyFormat("var x = `hello\n"
  1231. " ${name}\n"
  1232. " !`;",
  1233. "var x = `hello\n"
  1234. " ${ name }\n"
  1235. " !`;");
  1236. verifyFormat("var x =\n"
  1237. " `hello ${world}` >= some();",
  1238. getGoogleJSStyleWithColumns(34)); // Barely doesn't fit.
  1239. verifyFormat("var x = `hello ${world}` >= some();",
  1240. getGoogleJSStyleWithColumns(35)); // Barely fits.
  1241. verifyFormat("var x = `hellö ${wörld}` >= söme();",
  1242. getGoogleJSStyleWithColumns(35)); // Fits due to UTF-8.
  1243. verifyFormat("var x = `hello\n"
  1244. " ${world}` >=\n"
  1245. " some();",
  1246. "var x =\n"
  1247. " `hello\n"
  1248. " ${world}` >= some();",
  1249. getGoogleJSStyleWithColumns(21)); // Barely doesn't fit.
  1250. verifyFormat("var x = `hello\n"
  1251. " ${world}` >= some();",
  1252. "var x =\n"
  1253. " `hello\n"
  1254. " ${world}` >= some();",
  1255. getGoogleJSStyleWithColumns(22)); // Barely fits.
  1256. verifyFormat("var x =\n"
  1257. " `h`;",
  1258. getGoogleJSStyleWithColumns(11));
  1259. verifyFormat("var x =\n `multi\n line`;", "var x = `multi\n line`;",
  1260. getGoogleJSStyleWithColumns(13));
  1261. verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
  1262. " `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`);");
  1263. // Repro for an obscure width-miscounting issue with template strings.
  1264. verifyFormat(
  1265. "someLongVariable =\n"
  1266. " "
  1267. "`${logPrefix[11]}/${logPrefix[12]}/${logPrefix[13]}${logPrefix[14]}`;",
  1268. "someLongVariable = "
  1269. "`${logPrefix[11]}/${logPrefix[12]}/${logPrefix[13]}${logPrefix[14]}`;");
  1270. // Make sure template strings get a proper ColumnWidth assigned, even if they
  1271. // are first token in line.
  1272. verifyFormat(
  1273. "var a = aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
  1274. " `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`;");
  1275. // Two template strings.
  1276. verifyFormat("var x = `hello` == `hello`;");
  1277. // Comments in template strings.
  1278. verifyFormat("var x = `//a`;\n"
  1279. "var y;",
  1280. "var x =\n `//a`;\n"
  1281. "var y ;");
  1282. verifyFormat("var x = `/*a`;\n"
  1283. "var y;",
  1284. "var x =\n `/*a`;\n"
  1285. "var y;");
  1286. // Unterminated string literals in a template string.
  1287. verifyFormat("var x = `'`; // comment with matching quote '\n"
  1288. "var y;");
  1289. verifyFormat("var x = `\"`; // comment with matching quote \"\n"
  1290. "var y;");
  1291. verifyFormat("it(`'aaaaaaaaaaaaaaa `, aaaaaaaaa);",
  1292. "it(`'aaaaaaaaaaaaaaa `, aaaaaaaaa) ;",
  1293. getGoogleJSStyleWithColumns(40));
  1294. // Backticks in a comment - not a template string.
  1295. verifyFormat("var x = 1 // `/*a`;\n"
  1296. " ;",
  1297. "var x =\n 1 // `/*a`;\n"
  1298. " ;");
  1299. verifyFormat("/* ` */ var x = 1; /* ` */", "/* ` */ var x\n= 1; /* ` */");
  1300. // Comment spans multiple template strings.
  1301. verifyFormat("var x = `/*a`;\n"
  1302. "var y = ` */ `;",
  1303. "var x =\n `/*a`;\n"
  1304. "var y =\n ` */ `;");
  1305. // Escaped backtick.
  1306. verifyFormat("var x = ` \\` a`;\n"
  1307. "var y;",
  1308. "var x = ` \\` a`;\n"
  1309. "var y;");
  1310. // Escaped dollar.
  1311. verifyFormat("var x = ` \\${foo}`;\n");
  1312. // The token stream can contain two string_literals in sequence, but that
  1313. // doesn't mean that they are implicitly concatenated in JavaScript.
  1314. verifyFormat("var f = `aaaa ${a ? 'a' : 'b'}`;");
  1315. // Ensure that scopes are appropriately set around evaluated expressions in
  1316. // template strings.
  1317. verifyFormat("var f = `aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa\n"
  1318. " aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa`;",
  1319. "var f = `aaaaaaaaaaaaa:${aaaaaaa. aaaaa} aaaaaaaa\n"
  1320. " aaaaaaaaaaaaa:${ aaaaaaa. aaaaa} aaaaaaaa`;");
  1321. verifyFormat("var x = someFunction(`${})`) //\n"
  1322. " .oooooooooooooooooon();");
  1323. verifyFormat("var x = someFunction(`${aaaa}${\n"
  1324. " aaaaa( //\n"
  1325. " aaaaa)\n"
  1326. " })`);");
  1327. }
  1328. TEST_F(FormatTestJS, TemplateStringMultiLineExpression) {
  1329. verifyFormat("var f = `aaaaaaaaaaaaaaaaaa: ${\n"
  1330. " aaaaa + //\n"
  1331. " bbbb\n"
  1332. " }`;",
  1333. "var f = `aaaaaaaaaaaaaaaaaa: ${aaaaa + //\n"
  1334. " bbbb}`;");
  1335. verifyFormat("var f = `\n"
  1336. " aaaaaaaaaaaaaaaaaa: ${\n"
  1337. " aaaaa + //\n"
  1338. " bbbb\n"
  1339. " }`;",
  1340. "var f = `\n"
  1341. " aaaaaaaaaaaaaaaaaa: ${ aaaaa + //\n"
  1342. " bbbb }`;");
  1343. verifyFormat("var f = `\n"
  1344. " aaaaaaaaaaaaaaaaaa: ${\n"
  1345. " someFunction(\n"
  1346. " aaaaa + //\n"
  1347. " bbbb)\n"
  1348. " }`;",
  1349. "var f = `\n"
  1350. " aaaaaaaaaaaaaaaaaa: ${someFunction (\n"
  1351. " aaaaa + //\n"
  1352. " bbbb)}`;");
  1353. // It might be preferable to wrap before "someFunction".
  1354. verifyFormat("var f = `\n"
  1355. " aaaaaaaaaaaaaaaaaa: ${someFunction({\n"
  1356. " aaaa: aaaaa,\n"
  1357. " bbbb: bbbbb,\n"
  1358. " })}`;",
  1359. "var f = `\n"
  1360. " aaaaaaaaaaaaaaaaaa: ${someFunction ({\n"
  1361. " aaaa: aaaaa,\n"
  1362. " bbbb: bbbbb,\n"
  1363. " })}`;");
  1364. }
  1365. TEST_F(FormatTestJS, TemplateStringASI) {
  1366. verifyFormat("var x = `hello${world}`;", "var x = `hello${\n"
  1367. " world\n"
  1368. "}`;");
  1369. }
  1370. TEST_F(FormatTestJS, NestedTemplateStrings) {
  1371. verifyFormat(
  1372. "var x = `<ul>${xs.map(x => `<li>${x}</li>`).join('\\n')}</ul>`;");
  1373. verifyFormat("var x = `he${({text: 'll'}.text)}o`;");
  1374. // Crashed at some point.
  1375. verifyFormat("}");
  1376. }
  1377. TEST_F(FormatTestJS, TaggedTemplateStrings) {
  1378. verifyFormat("var x = html`<ul>`;");
  1379. }
  1380. TEST_F(FormatTestJS, CastSyntax) {
  1381. verifyFormat("var x = <type>foo;");
  1382. verifyFormat("var x = foo as type;");
  1383. verifyFormat("let x = (a + b) as\n"
  1384. " LongTypeIsLong;",
  1385. getGoogleJSStyleWithColumns(20));
  1386. verifyFormat("foo = <Bar[]>[\n"
  1387. " 1, //\n"
  1388. " 2\n"
  1389. "];");
  1390. verifyFormat("var x = [{x: 1} as type];");
  1391. verifyFormat("x = x as [a, b];");
  1392. verifyFormat("x = x as {a: string};");
  1393. verifyFormat("x = x as (string);");
  1394. verifyFormat("x = x! as (string);");
  1395. verifyFormat("var x = something.someFunction() as\n"
  1396. " something;",
  1397. getGoogleJSStyleWithColumns(40));
  1398. }
  1399. TEST_F(FormatTestJS, TypeArguments) {
  1400. verifyFormat("class X<Y> {}");
  1401. verifyFormat("new X<Y>();");
  1402. verifyFormat("foo<Y>(a);");
  1403. verifyFormat("var x: X<Y>[];");
  1404. verifyFormat("class C extends D<E> implements F<G>, H<I> {}");
  1405. verifyFormat("function f(a: List<any> = null) {}");
  1406. verifyFormat("function f(): List<any> {}");
  1407. verifyFormat("function aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa():\n"
  1408. " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {}");
  1409. verifyFormat("function aaaaaaaaaa(\n"
  1410. " aaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaa,\n"
  1411. " aaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaa):\n"
  1412. " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {}");
  1413. }
  1414. TEST_F(FormatTestJS, UserDefinedTypeGuards) {
  1415. verifyFormat(
  1416. "function foo(check: Object):\n"
  1417. " check is {foo: string, bar: string, baz: string, foobar: string} {\n"
  1418. " return 'bar' in check;\n"
  1419. "}\n");
  1420. }
  1421. TEST_F(FormatTestJS, OptionalTypes) {
  1422. verifyFormat("function x(a?: b, c?, d?) {}");
  1423. verifyFormat("class X {\n"
  1424. " y?: z;\n"
  1425. " z?;\n"
  1426. "}");
  1427. verifyFormat("interface X {\n"
  1428. " y?(): z;\n"
  1429. "}");
  1430. verifyFormat("constructor({aa}: {\n"
  1431. " aa?: string,\n"
  1432. " aaaaaaaa?: string,\n"
  1433. " aaaaaaaaaaaaaaa?: boolean,\n"
  1434. " aaaaaa?: List<string>\n"
  1435. "}) {}");
  1436. }
  1437. TEST_F(FormatTestJS, IndexSignature) {
  1438. verifyFormat("var x: {[k: string]: v};");
  1439. }
  1440. TEST_F(FormatTestJS, WrapAfterParen) {
  1441. verifyFormat("xxxxxxxxxxx(\n"
  1442. " aaa, aaa);",
  1443. getGoogleJSStyleWithColumns(20));
  1444. verifyFormat("xxxxxxxxxxx(\n"
  1445. " aaa, aaa, aaa,\n"
  1446. " aaa, aaa, aaa);",
  1447. getGoogleJSStyleWithColumns(20));
  1448. verifyFormat("xxxxxxxxxxx(\n"
  1449. " aaaaaaaaaaaaaaaaaaaaaaaa,\n"
  1450. " function(x) {\n"
  1451. " y(); //\n"
  1452. " });",
  1453. getGoogleJSStyleWithColumns(40));
  1454. verifyFormat("while (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&\n"
  1455. " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}");
  1456. }
  1457. TEST_F(FormatTestJS, JSDocAnnotations) {
  1458. verifyFormat("/**\n"
  1459. " * @export {this.is.a.long.path.to.a.Type}\n"
  1460. " */",
  1461. "/**\n"
  1462. " * @export {this.is.a.long.path.to.a.Type}\n"
  1463. " */",
  1464. getGoogleJSStyleWithColumns(20));
  1465. verifyFormat("/**\n"
  1466. " * @mods {this.is.a.long.path.to.a.Type}\n"
  1467. " */",
  1468. "/**\n"
  1469. " * @mods {this.is.a.long.path.to.a.Type}\n"
  1470. " */",
  1471. getGoogleJSStyleWithColumns(20));
  1472. verifyFormat("/**\n"
  1473. " * @param {this.is.a.long.path.to.a.Type}\n"
  1474. " */",
  1475. "/**\n"
  1476. " * @param {this.is.a.long.path.to.a.Type}\n"
  1477. " */",
  1478. getGoogleJSStyleWithColumns(20));
  1479. verifyFormat(
  1480. "/**\n"
  1481. " * @param This is a\n"
  1482. " * long comment but\n"
  1483. " * no type\n"
  1484. " */",
  1485. "/**\n"
  1486. " * @param This is a long comment but no type\n"
  1487. " */",
  1488. getGoogleJSStyleWithColumns(20));
  1489. }
  1490. TEST_F(FormatTestJS, RequoteStringsSingle) {
  1491. verifyFormat("var x = 'foo';", "var x = \"foo\";");
  1492. verifyFormat("var x = 'fo\\'o\\'';", "var x = \"fo'o'\";");
  1493. verifyFormat("var x = 'fo\\'o\\'';", "var x = \"fo\\'o'\";");
  1494. verifyFormat(
  1495. "var x =\n"
  1496. " 'foo\\'';",
  1497. // Code below is 15 chars wide, doesn't fit into the line with the
  1498. // \ escape added.
  1499. "var x = \"foo'\";", getGoogleJSStyleWithColumns(15));
  1500. // Removes no-longer needed \ escape from ".
  1501. verifyFormat("var x = 'fo\"o';", "var x = \"fo\\\"o\";");
  1502. // Code below fits into 15 chars *after* removing the \ escape.
  1503. verifyFormat("var x = 'fo\"o';", "var x = \"fo\\\"o\";",
  1504. getGoogleJSStyleWithColumns(15));
  1505. verifyFormat("// clang-format off\n"
  1506. "let x = \"double\";\n"
  1507. "// clang-format on\n"
  1508. "let x = 'single';\n",
  1509. "// clang-format off\n"
  1510. "let x = \"double\";\n"
  1511. "// clang-format on\n"
  1512. "let x = \"single\";\n");
  1513. }
  1514. TEST_F(FormatTestJS, RequoteAndIndent) {
  1515. verifyFormat("let x = someVeryLongFunctionThatGoesOnAndOn(\n"
  1516. " 'double quoted string that needs wrapping');",
  1517. "let x = someVeryLongFunctionThatGoesOnAndOn("
  1518. "\"double quoted string that needs wrapping\");");
  1519. verifyFormat("let x =\n"
  1520. " 'foo\\'oo';\n"
  1521. "let x =\n"
  1522. " 'foo\\'oo';",
  1523. "let x=\"foo'oo\";\n"
  1524. "let x=\"foo'oo\";",
  1525. getGoogleJSStyleWithColumns(15));
  1526. }
  1527. TEST_F(FormatTestJS, RequoteStringsDouble) {
  1528. FormatStyle DoubleQuotes = getGoogleStyle(FormatStyle::LK_JavaScript);
  1529. DoubleQuotes.JavaScriptQuotes = FormatStyle::JSQS_Double;
  1530. verifyFormat("var x = \"foo\";", DoubleQuotes);
  1531. verifyFormat("var x = \"foo\";", "var x = 'foo';", DoubleQuotes);
  1532. verifyFormat("var x = \"fo'o\";", "var x = 'fo\\'o';", DoubleQuotes);
  1533. }
  1534. TEST_F(FormatTestJS, RequoteStringsLeave) {
  1535. FormatStyle LeaveQuotes = getGoogleStyle(FormatStyle::LK_JavaScript);
  1536. LeaveQuotes.JavaScriptQuotes = FormatStyle::JSQS_Leave;
  1537. verifyFormat("var x = \"foo\";", LeaveQuotes);
  1538. verifyFormat("var x = 'foo';", LeaveQuotes);
  1539. }
  1540. TEST_F(FormatTestJS, SupportShebangLines) {
  1541. verifyFormat("#!/usr/bin/env node\n"
  1542. "var x = hello();",
  1543. "#!/usr/bin/env node\n"
  1544. "var x = hello();");
  1545. }
  1546. TEST_F(FormatTestJS, NonNullAssertionOperator) {
  1547. verifyFormat("let x = foo!.bar();\n");
  1548. verifyFormat("let x = foo ? bar! : baz;\n");
  1549. verifyFormat("let x = !foo;\n");
  1550. verifyFormat("let x = foo[0]!;\n");
  1551. verifyFormat("let x = (foo)!;\n");
  1552. verifyFormat("let x = foo! - 1;\n");
  1553. verifyFormat("let x = {foo: 1}!;\n");
  1554. }
  1555. TEST_F(FormatTestJS, Conditional) {
  1556. verifyFormat("y = x ? 1 : 2;");
  1557. verifyFormat("x ? 1 : 2;");
  1558. verifyFormat("class Foo {\n"
  1559. " field = true ? 1 : 2;\n"
  1560. " method(a = true ? 1 : 2) {}\n"
  1561. "}");
  1562. }
  1563. TEST_F(FormatTestJS, ImportComments) {
  1564. verifyFormat("import {x} from 'x'; // from some location",
  1565. getGoogleJSStyleWithColumns(25));
  1566. verifyFormat("// taze: x from 'location'", getGoogleJSStyleWithColumns(10));
  1567. }
  1568. } // end namespace tooling
  1569. } // end namespace clang