FormatTestJS.cpp 58 KB

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