FormatTestJS.cpp 40 KB

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