You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CoverageTestCase.java 38KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940
  1. /* *******************************************************************
  2. * Copyright (c) 2003 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Mik Kersten initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.tools.ajdoc;
  13. import java.io.File;
  14. import java.util.List;
  15. import org.aspectj.util.LangUtil;
  16. /**
  17. * A long way to go until full coverage, but this is the place to add more.
  18. *
  19. * @author Mik Kersten
  20. */
  21. public class CoverageTestCase extends AjdocTestCase {
  22. protected File file0,file1,aspect1,file2,file3,file4,file5,file6,file7,file8,file9,file10;
  23. protected void setUp() throws Exception {
  24. super.setUp();
  25. initialiseProject("coverage");
  26. createFiles();
  27. }
  28. public void testOptions() {
  29. String[] args = {
  30. "-private",
  31. "-encoding",
  32. "EUCJIS",
  33. "-docencoding",
  34. "EUCJIS",
  35. "-charset",
  36. "UTF-8",
  37. "-classpath",
  38. AjdocTests.ASPECTJRT_PATH.getPath(),
  39. "-d",
  40. getAbsolutePathOutdir(),
  41. file0.getAbsolutePath(),
  42. };
  43. org.aspectj.tools.ajdoc.Main.main(args);
  44. assertTrue(true);
  45. }
  46. /**
  47. * Test the "-public" argument
  48. */
  49. public void testCoveragePublicMode() throws Exception {
  50. File[] files = {file3,file9};
  51. runAjdoc("public","9",files);
  52. // have passed the "public" modifier as well as
  53. // one public and one package visible class. There
  54. // should only be ajdoc for the public class
  55. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/PkgVisibleClass.html");
  56. assertFalse("ajdoc for PkgVisibleClass shouldn't exist because passed" +
  57. " the 'public' flag to ajdoc",htmlFile.exists());
  58. htmlFile = new File(getAbsolutePathOutdir() + "/foo/PlainJava.html");
  59. if (!htmlFile.exists()) {
  60. fail("couldn't find " + htmlFile.getAbsolutePath()
  61. + " - were there compilation errors?");
  62. }
  63. // check there's no private fields within the file, that
  64. // the file contains the getI() method but doesn't contain
  65. // the private ClassBar, Bazz and Jazz classes.
  66. String[] strings = { "private", "getI()","ClassBar", "Bazz", "Jazz"};
  67. List missing = AjdocOutputChecker.getMissingStringsInFile(htmlFile,strings);
  68. assertEquals("There should be 4 missing strings",4,missing.size());
  69. assertTrue(htmlFile.getName() + " should not contain the private modifier",missing.contains("private"));
  70. assertTrue(htmlFile.getName() + " should not contain the private ClassBar class",missing.contains("ClassBar"));
  71. assertTrue(htmlFile.getName() + " should not contain the private Bazz class",missing.contains("Bazz"));
  72. assertTrue(htmlFile.getName() + " should not contain the private Jazz class",missing.contains("Jazz"));
  73. }
  74. /**
  75. * Test that the ajdoc for an aspect has the title "Aspect"
  76. */
  77. public void testAJdocHasAspectTitle() throws Exception {
  78. File[] files = {new File(getAbsoluteProjectDir() + "/pkg/A.aj")};
  79. runAjdoc("private","1.6",files);
  80. File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/A.html");
  81. if (!htmlFile.exists()) {
  82. fail("couldn't find " + htmlFile.getAbsolutePath()+ " - were there compilation errors?");
  83. }
  84. assertTrue(htmlFile.getAbsolutePath() + " should have Aspect A as it's title",
  85. AjdocOutputChecker.containsString(htmlFile,"Aspect A"));
  86. }
  87. /**
  88. * Test that the ajdoc for a class has the title "Class"
  89. */
  90. public void testAJdocHasClassTitle() throws Exception {
  91. File[] files = {new File(getAbsoluteProjectDir() + "/pkg/C.java")};
  92. runAjdoc("private","1.6",files);
  93. File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/C.html");
  94. if (!htmlFile.exists()) {
  95. fail("couldn't find " + htmlFile.getAbsolutePath()+ " - were there compilation errors?");
  96. }
  97. assertTrue(htmlFile.getAbsolutePath() + " should have Class C as it's title",
  98. AjdocOutputChecker.containsString(htmlFile,"Class C"));
  99. }
  100. /**
  101. * Test that the ajdoc for an inner aspect is entitled "Aspect" rather
  102. * than "Class", but that the enclosing class is still "Class"
  103. */
  104. public void testInnerAspect() throws Exception {
  105. File[] files = {file1, file2};
  106. runAjdoc("private","1.6",files);
  107. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/ClassA.InnerAspect.html");
  108. if (!htmlFile.exists()) {
  109. fail("couldn't find " + htmlFile.getAbsolutePath()
  110. + " - were there compilation errors?");
  111. }
  112. // ensure that the file is entitled "Aspect ClassA.InnerAspect" rather
  113. // than "Class ClassA.InnerAspect"
  114. String[] strings = null;
  115. if (LangUtil.is18VMOrGreater()) {
  116. strings = new String[] {
  117. "Aspect ClassA.InnerAspect",
  118. "<pre>static aspect <span class=\"typeNameLabel\">ClassA.InnerAspect</span>",
  119. "Class ClassA.InnerAspect",
  120. "<pre>static class <span class=\"typeNameLabel\">ClassA.InnerAspect</span>"};
  121. }
  122. else {
  123. strings = new String[] {
  124. "Aspect ClassA.InnerAspect",
  125. "<PRE>static aspect <B>ClassA.InnerAspect</B><DT>extends java.lang.Object</DL>",
  126. "Class ClassA.InnerAspect",
  127. "<PRE>static class <B>ClassA.InnerAspect</B><DT>extends java.lang.Object</DL>"};
  128. }
  129. List<String> missingStrings = AjdocOutputChecker.getMissingStringsInFile(htmlFile,strings);
  130. StringBuilder buf = new StringBuilder();
  131. for (String str:missingStrings) {
  132. buf.append(str).append("\n");
  133. }
  134. buf.append("HTMLFILE=\n").append(htmlFile).append("\n");
  135. assertEquals("There should be 2 missing strings:\n"+buf.toString(), 2, missingStrings.size());
  136. assertTrue(htmlFile.getName() + " should not have Class as it's title",
  137. missingStrings.contains("Class ClassA.InnerAspect"));
  138. if (LangUtil.is18VMOrGreater()) {
  139. assertTrue(htmlFile.getName() + " should not have class in its subtitle",
  140. missingStrings.contains("<pre>static class <span class=\"typeNameLabel\">ClassA.InnerAspect</span>"));
  141. }
  142. else {
  143. assertTrue(htmlFile.getName() + " should not have class in its subtitle",
  144. missingStrings.contains("<PRE>static class <B>ClassA.InnerAspect</B><DT>extends java.lang.Object</DL>"));
  145. }
  146. // get the html file for the enclosing class
  147. File htmlFileClass = new File(getAbsolutePathOutdir() + "/foo/ClassA.html");
  148. if (!htmlFileClass.exists()) {
  149. fail("couldn't find " + htmlFileClass.getAbsolutePath()
  150. + " - were there compilation errors?");
  151. }
  152. // ensure that the file is entitled "Class ClassA" and
  153. // has not been changed to "Aspect ClassA"
  154. String[] classStrings = null;
  155. if (LangUtil.is18VMOrGreater()) {
  156. classStrings = new String[] {
  157. "Class ClassA</h2>",
  158. "public abstract class <span class=\"typeNameLabel\">ClassA</span>",
  159. "Aspect ClassA</H2>",
  160. "public abstract aspect <span class=\"typeNameLabel\">ClassA</span>"};
  161. }
  162. else {
  163. classStrings = new String[] {
  164. "Class ClassA</H2>",
  165. "public abstract class <B>ClassA</B><DT>extends java.lang.Object<DT>",
  166. "Aspect ClassA</H2>",
  167. "public abstract aspect <B>ClassA</B><DT>extends java.lang.Object<DT>"};
  168. }
  169. List classMissing = AjdocOutputChecker.getMissingStringsInFile(htmlFileClass,classStrings);
  170. assertEquals("There should be 2 missing strings:\n"+classMissing,2,classMissing.size());
  171. assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title",classMissing.contains("Aspect ClassA</H2>"));
  172. if (LangUtil.is18VMOrGreater()) {
  173. assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle",
  174. classMissing.contains("public abstract aspect <span class=\"typeNameLabel\">ClassA</span>"));
  175. }
  176. else {
  177. assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle",
  178. classMissing.contains("public abstract aspect <B>ClassA</B><DT>extends java.lang.Object<DT>"));
  179. }
  180. }
  181. /**
  182. * Test that all the different types of advice appear
  183. * with the named pointcut in it's description
  184. */
  185. public void testAdviceNamingCoverage() throws Exception {
  186. File[] files = {file4};
  187. runAjdoc("private","1.6",files);
  188. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/AdviceNamingCoverage.html");
  189. if (!htmlFile.exists()) {
  190. fail("couldn't find " + htmlFile.getAbsolutePath()
  191. + " - were there compilation errors?");
  192. }
  193. String[] strings = {
  194. "after(): named..",
  195. "afterReturning(int,int): namedWithArgs..",
  196. "afterThrowing(): named..",
  197. "before(): named..",
  198. "around(int): namedWithOneArg..",
  199. "before(int):",
  200. "before(int): named()..",
  201. "before():"};
  202. List missing = AjdocOutputChecker.getMissingStringsInSection(
  203. htmlFile, strings,"ADVICE DETAIL SUMMARY");
  204. assertTrue(htmlFile.getName() + " should contain all advice in the Advice Detail section",missing.isEmpty());
  205. missing = AjdocOutputChecker.getMissingStringsInSection(
  206. htmlFile,strings,"ADVICE SUMMARY");
  207. assertTrue(htmlFile.getName() + " should contain all advice in the Advice Summary section",missing.isEmpty());
  208. }
  209. /**
  210. * Test that all the advises relationships appear in the
  211. * Advice Detail and Advice Summary sections and that
  212. * the links are correct
  213. */
  214. public void testAdvisesRelationshipCoverage() throws Exception {
  215. File[] files = {file4};
  216. runAjdoc("private","1.6",files);
  217. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/AdvisesRelationshipCoverage.html");
  218. if (!htmlFile.exists()) {
  219. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  220. }
  221. String[] strings = {
  222. "before(): methodExecutionP..",
  223. "HREF=\"../foo/Point.html#setX(int)\"",
  224. "before(): constructorExecutionP..",
  225. "HREF=\"../foo/Point.html#Point()\"",
  226. "before(): callMethodP..",
  227. "HREF=\"../foo/Point.html#changeX(int)\"",
  228. "before(): callConstructorP..",
  229. "HREF=\"../foo/Point.html#doIt()\"",
  230. "before(): getP..",
  231. "HREF=\"../foo/Point.html#getX()\"",
  232. "before(): setP..",
  233. "HREF=\"../foo/Point.html\"><tt>foo.Point</tt></A>, <A HREF=\"../foo/Point.html#Point()\"><tt>foo.Point.Point</tt></A>, <A HREF=\"../foo/Point.html#setX(int)\"",
  234. "before(): initializationP..",
  235. "HREF=\"../foo/Point.html#Point()\"",
  236. "before(): staticinitializationP..",
  237. "HREF=\"../foo/Point.html\"",
  238. "before(): handlerP..",
  239. "HREF=\"../foo/Point.html#doIt()\""
  240. };
  241. for (int i = 0; i < strings.length - 1; i = i+2) {
  242. boolean b = AjdocOutputChecker.detailSectionContainsRel(
  243. htmlFile,"ADVICE DETAIL SUMMARY",strings[i],
  244. HtmlDecorator.HtmlRelationshipKind.ADVISES,
  245. strings[i+1]);
  246. assertTrue(strings[i] + " should advise " + strings[i+1] +
  247. " in the Advice Detail section", b);
  248. }
  249. for (int i = 0; i < strings.length - 1; i = i+2) {
  250. boolean b = AjdocOutputChecker.summarySectionContainsRel(
  251. htmlFile,"ADVICE SUMMARY",strings[i],
  252. HtmlDecorator.HtmlRelationshipKind.ADVISES,
  253. strings[i+1]);
  254. assertTrue(strings[i] + " should advise " + strings[i+1] +
  255. " in the Advice Summary section", b);
  256. }
  257. }
  258. /**
  259. * Test that the advised by relationship appears in the ajdoc when the
  260. * advice is associated with a method execution pointcut
  261. */
  262. public void testAdvisedByMethodExecution() throws Exception {
  263. File[] files = {file4};
  264. runAjdoc("private","1.6",files);
  265. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html");
  266. if (!htmlFile.exists()) {
  267. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  268. }
  269. String[] strings = {
  270. toName("setX(int)"),
  271. "HREF=\"../foo/AdvisesRelationshipCoverage.html#before(): methodExecutionP..\""};
  272. boolean b = AjdocOutputChecker.detailSectionContainsRel(
  273. htmlFile,"=== METHOD DETAIL",
  274. strings[0],
  275. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  276. strings[1]);
  277. assertTrue("the Method Detail should have " + strings[0]+" advised by " + strings[1],b);
  278. b = AjdocOutputChecker.summarySectionContainsRel(
  279. htmlFile,"=== METHOD SUMMARY",
  280. strings[0],
  281. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  282. strings[1]);
  283. assertTrue("the Method Summary should have " + strings[0]+" advised by " + strings[1],b);
  284. }
  285. /**
  286. * Test that the advised by relationship appears in the ajdoc when the
  287. * advice is associated with a constructor execution pointcut
  288. */
  289. public void testAdvisedByConstructorExecution() throws Exception {
  290. File[] files = {file4};
  291. runAjdoc("private","1.6",files);
  292. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html");
  293. if (!htmlFile.exists()) {
  294. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  295. }
  296. String[] strings = {
  297. LangUtil.is11VMOrGreater()?"&lt;init&gt;()":toName("Point()"),
  298. "HREF=\"../foo/AdvisesRelationshipCoverage.html#before(): constructorExecutionP..\""};
  299. boolean b = AjdocOutputChecker.detailSectionContainsRel(
  300. htmlFile,"=== CONSTRUCTOR DETAIL",
  301. strings[0],
  302. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  303. strings[1]);
  304. assertTrue("the Constructor Detail should have " + strings[0]+" advised by " + strings[1],b);
  305. // Pre-JDK 11:
  306. // This precedes the line containing strings[1]
  307. // <td class="colOne"><code><span class="memberNameLink"><a href="../foo/Point.html#Point--">Point</a></span>()</code>
  308. // On JDK 11:
  309. // This precedes the line containing strings[1]
  310. // <th class="colConstructorName" scope="row"><code><span class="memberNameLink"><a href="#%3Cinit%3E()">Point</a></span>()</code></th>
  311. b = AjdocOutputChecker.summarySectionContainsRel(
  312. htmlFile,"=== CONSTRUCTOR SUMMARY",
  313. LangUtil.is11VMOrGreater()?"#%3Cinit%3E()":toName("Point()"),
  314. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  315. strings[1]);
  316. assertTrue("the Constructor Summary should have " + strings[0]+" advised by " + strings[1],b);
  317. }
  318. /**
  319. * Test that the advised by relationship appears in the ajdoc when the
  320. * advice is associated with a method call pointcut
  321. */
  322. public void testAdvisedByMethodCall() throws Exception {
  323. File[] files = {file4};
  324. runAjdoc("private","1.6",files);
  325. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html");
  326. if (!htmlFile.exists()) {
  327. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  328. }
  329. String[] strings = {
  330. toName("changeX(int)"),
  331. "HREF=\"../foo/AdvisesRelationshipCoverage.html#before(): callMethodP..\""};
  332. boolean b = AjdocOutputChecker.detailSectionContainsRel(
  333. htmlFile,"=== METHOD DETAIL",
  334. strings[0],
  335. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  336. strings[1]);
  337. assertTrue("the Method Detail should have " + strings[0]+" advised by " + strings[1],b);
  338. b = AjdocOutputChecker.summarySectionContainsRel(
  339. htmlFile,"=== METHOD SUMMARY",
  340. strings[0],
  341. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  342. strings[1]);
  343. assertTrue("the Method Summary should have " + strings[0]+" advised by " + strings[1],b);
  344. }
  345. /**
  346. * Test that the advised by relationship appears in the ajdoc when the
  347. * advice is associated with a constructor call pointcut
  348. */
  349. public void testAdvisedByConstructorCall() throws Exception {
  350. File[] files = {file4};
  351. runAjdoc("private","1.6",files);
  352. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html");
  353. if (!htmlFile.exists()) {
  354. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  355. }
  356. String[] strings = {
  357. toName("doIt()"),
  358. "HREF=\"../foo/AdvisesRelationshipCoverage.html#before(): callConstructorP..\""};
  359. boolean b = AjdocOutputChecker.detailSectionContainsRel(
  360. htmlFile,"=== METHOD DETAIL",
  361. strings[0],
  362. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  363. strings[1]);
  364. assertTrue("the Method Detail should have " + strings[0]+" advised by " + strings[1],b);
  365. b = AjdocOutputChecker.summarySectionContainsRel(
  366. htmlFile,"=== METHOD SUMMARY",
  367. strings[0],
  368. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  369. strings[1]);
  370. assertTrue("the Method Summary should have " + strings[0]+" advised by " + strings[1],b);
  371. }
  372. /**
  373. * Test that the advised by relationship appears in the ajdoc when the
  374. * advice is associated with a get pointcut
  375. */
  376. public void testAdvisedByGet() throws Exception {
  377. File[] files = {file4};
  378. runAjdoc("private","1.6",files);
  379. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html");
  380. if (!htmlFile.exists()) {
  381. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  382. }
  383. String[] strings = {
  384. toName("getX()"),
  385. "HREF=\"../foo/AdvisesRelationshipCoverage.html#before(): getP..\""};
  386. boolean b = AjdocOutputChecker.detailSectionContainsRel(
  387. htmlFile,"=== METHOD DETAIL",
  388. strings[0],
  389. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  390. strings[1]);
  391. assertTrue("the Method Detail should have " + strings[0]+" advised by " + strings[1],b);
  392. b = AjdocOutputChecker.summarySectionContainsRel(
  393. htmlFile,"=== METHOD SUMMARY",
  394. strings[0],
  395. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  396. strings[1]);
  397. assertTrue("the Method Summary should have " + strings[0]+" advised by " + strings[1],b);
  398. }
  399. /**
  400. * Test that the advised by relationship appears in the ajdoc when the
  401. * advice is associated with a set pointcut
  402. */
  403. public void testAdvisedBySet() throws Exception {
  404. File[] files = {file4};
  405. runAjdoc("private","1.6",files);
  406. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html");
  407. if (!htmlFile.exists()) {
  408. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  409. }
  410. String href = "HREF=\"../foo/AdvisesRelationshipCoverage.html#before(): setP..\"";
  411. boolean b = AjdocOutputChecker.detailSectionContainsRel(
  412. htmlFile,"=== METHOD DETAIL",
  413. toName("setX(int)"),
  414. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  415. href);
  416. assertTrue("the Method Detail should have setX(int) advised by " + href,b);
  417. b = AjdocOutputChecker.summarySectionContainsRel(
  418. htmlFile,"=== METHOD SUMMARY",
  419. toName("setX(int)"),
  420. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  421. href);
  422. assertTrue("the Method Summary should have setX(int) advised by " + href,b);
  423. b = AjdocOutputChecker.detailSectionContainsRel(
  424. htmlFile,"=== CONSTRUCTOR DETAIL",
  425. LangUtil.is11VMOrGreater()?"&lt;init&gt;()":toName("Point()"),
  426. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  427. href);
  428. assertTrue("the Constructor Detail should have advised by " + href,b);
  429. b = AjdocOutputChecker.summarySectionContainsRel(
  430. htmlFile,"=== CONSTRUCTOR SUMMARY",
  431. LangUtil.is11VMOrGreater()?"#%3Cinit%3E()":toName("Point()"),
  432. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  433. href);
  434. assertTrue("the Constructor Summary should have advised by " + href,b);
  435. b = AjdocOutputChecker.classDataSectionContainsRel(
  436. htmlFile,
  437. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  438. href);
  439. assertTrue("The class data section should have 'advised by " + href + "'",b);
  440. }
  441. /**
  442. * Test that the advised by relationship appears in the ajdoc when the
  443. * advice is associated with an initialization pointcut
  444. */
  445. public void testAdvisedByInitialization() throws Exception {
  446. File[] files = {file4};
  447. runAjdoc("private","1.6",files);
  448. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html");
  449. if (!htmlFile.exists()) {
  450. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  451. }
  452. String[] strings = {
  453. LangUtil.is11VMOrGreater()?"&lt;init&gt;()":toName("Point()"),
  454. "HREF=\"../foo/AdvisesRelationshipCoverage.html#before(): initializationP..\""};
  455. boolean b = AjdocOutputChecker.detailSectionContainsRel(
  456. htmlFile,
  457. "=== CONSTRUCTOR DETAIL",
  458. strings[0],
  459. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  460. strings[1]);
  461. assertTrue("the Method Detail should have 'setX(int) advised by ... before()'",b);
  462. b = AjdocOutputChecker.summarySectionContainsRel(
  463. htmlFile,
  464. "=== CONSTRUCTOR SUMMARY",
  465. LangUtil.is11VMOrGreater()?"#%3Cinit%3E()":strings[0],
  466. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  467. strings[1]);
  468. assertTrue("the Method Summary should have 'setX(int) advised by ... before()'",b);
  469. }
  470. /**
  471. * Test that the advised by relationship appears in the ajdoc when the
  472. * advice is associated with a staticinitialization pointcut
  473. */
  474. public void testAdvisedByStaticInitialization() throws Exception {
  475. File[] files = {file4};
  476. runAjdoc("private","1.6",files);
  477. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html");
  478. if (!htmlFile.exists()) {
  479. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  480. }
  481. String href = "HREF=\"../foo/AdvisesRelationshipCoverage.html#before(): staticinitializationP..\"";
  482. boolean b = AjdocOutputChecker.classDataSectionContainsRel(
  483. htmlFile,
  484. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  485. href);
  486. assertTrue("The class data section should have 'advised by " + href + "'",b);
  487. }
  488. /**
  489. * Test that the advised by relationship appears in the ajdoc when the
  490. * advice is associated with a handler pointcut
  491. */
  492. public void testAdvisedByHandler() throws Exception {
  493. File[] files = {file4};
  494. runAjdoc("private","1.6",files);
  495. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html");
  496. if (!htmlFile.exists()) {
  497. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  498. }
  499. String[] strings = {
  500. toName("doIt()"),
  501. "HREF=\"../foo/AdvisesRelationshipCoverage.html#before(): handlerP..\""};
  502. boolean b = AjdocOutputChecker.detailSectionContainsRel(
  503. htmlFile,"=== METHOD DETAIL",
  504. strings[0],
  505. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  506. strings[1]);
  507. assertTrue("the Method Detail should have " + strings[0]+" advised by " + strings[1],b);
  508. b = AjdocOutputChecker.summarySectionContainsRel(
  509. htmlFile,"=== METHOD SUMMARY",
  510. strings[0],
  511. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  512. strings[1]);
  513. assertTrue("the Method Summary should have " + strings[0]+" advised by " + strings[1],b);
  514. }
  515. private String toName(String name) {
  516. if (LangUtil.is18VMOrGreater() && !LangUtil.is11VMOrGreater()) {
  517. name = name.replace('(','-');
  518. name = name.replace(')','-');
  519. }
  520. return name;
  521. }
  522. /**
  523. * Test that if have two before advice blocks from the same
  524. * aspect affect the same method, then both appear in the ajdoc
  525. */
  526. public void testTwoBeforeAdvice() throws Exception {
  527. File[] files = {new File(getAbsoluteProjectDir() + "/pkg/A2.aj")};
  528. runAjdoc("private","1.6",files);
  529. File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/C2.html");
  530. if (!htmlFile.exists()) {
  531. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  532. }
  533. String[] strings = {
  534. toName("amethod()"),
  535. "HREF=\"../pkg/A2.html#before(): p..\"",
  536. "HREF=\"../pkg/A2.html#before(): p2..\""};
  537. boolean b = AjdocOutputChecker.detailSectionContainsRel(
  538. htmlFile,"=== METHOD DETAIL",
  539. strings[0],
  540. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  541. strings[1]);
  542. assertTrue("the Method Detail should have " + strings[0]+" advised by " + strings[1],b);
  543. b = AjdocOutputChecker.summarySectionContainsRel(
  544. htmlFile,"=== METHOD SUMMARY",
  545. strings[0],
  546. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  547. strings[1]);
  548. assertTrue("the Method Summary should have " + strings[0]+" advised by " + strings[1],b);
  549. b = AjdocOutputChecker.detailSectionContainsRel(
  550. htmlFile,"=== METHOD DETAIL",
  551. strings[0],
  552. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  553. strings[2]);
  554. assertTrue("the Method Detail should have " + strings[0]+" advised by " + strings[2],b);
  555. b = AjdocOutputChecker.summarySectionContainsRel(
  556. htmlFile,"=== METHOD SUMMARY",
  557. strings[0],
  558. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  559. strings[2]);
  560. assertTrue("the Method Summary should have " + strings[0]+" advised by " + strings[2],b);
  561. }
  562. /**
  563. * Test that there are no spurious "advised by" entries
  564. * against the aspect in the ajdoc
  565. */
  566. public void testNoSpuriousAdvisedByRels() throws Exception {
  567. File[] files = {file4};
  568. runAjdoc("private","1.6",files);
  569. File htmlFile = new File(getAbsolutePathOutdir() + "/foo/AdvisesRelationshipCoverage.html");
  570. if (!htmlFile.exists()) {
  571. fail("couldn't find " + htmlFile.getAbsolutePath() + " - were there compilation errors?");
  572. }
  573. String href = "foo.Point.setX(int)";
  574. boolean b = AjdocOutputChecker.classDataSectionContainsRel(
  575. htmlFile,
  576. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  577. href);
  578. assertFalse("The class data section should not have 'advised by " + href + "'",b);
  579. }
  580. public void testCoverage() {
  581. File[] files = {aspect1,file0,file1,file2,file3,file4,file5,file6,
  582. file7,file8,file9,file10};
  583. runAjdoc("private","1.6",files);
  584. }
  585. /**
  586. * Test that nested aspects appear with "aspect" in their title
  587. * when the ajdoc file is written slightly differently (when it's
  588. * written for this apsect, it's different than for testInnerAspect())
  589. */
  590. public void testNestedAspect() throws Exception {
  591. File[] files = {file9};
  592. runAjdoc("private","1.6",files);
  593. File htmlFile = new File(getAbsolutePathOutdir() + "/PkgVisibleClass.NestedAspect.html");
  594. if (!htmlFile.exists()) {
  595. fail("couldn't find " + htmlFile.getAbsolutePath()
  596. + " - were there compilation errors?");
  597. }
  598. // ensure that the file is entitled "Aspect PkgVisibleClass.NestedAspect" rather
  599. // than "Class PkgVisibleClass.NestedAspect"
  600. String[] strings = null;
  601. if (LangUtil.is18VMOrGreater()) {
  602. strings = new String[] {
  603. "Aspect PkgVisibleClass.NestedAspect",
  604. "<pre>static aspect <span class=\"typeNameLabel\">PkgVisibleClass.NestedAspect</span>",
  605. "Class PkgVisibleClass.NestedAspect",
  606. "<pre>static class <span class=\"typeNameLabel\">PkgVisibleClass.NestedAspect</span>"};
  607. }
  608. else {
  609. strings = new String[] {
  610. "Aspect PkgVisibleClass.NestedAspect",
  611. "<PRE>static aspect <B>PkgVisibleClass.NestedAspect</B><DT>extends java.lang.Object</DL>",
  612. "Class PkgVisibleClass.NestedAspect",
  613. "<PRE>static class <B>PkgVisibleClass.NestedAspect</B><DT>extends java.lang.Object</DL>"};
  614. }
  615. List<String> missing = AjdocOutputChecker.getMissingStringsInFile(htmlFile,strings);
  616. assertEquals("There should be 2 missing strings",2,missing.size());
  617. assertTrue(htmlFile.getName() + " should not have Class as it's title",missing.contains("Class PkgVisibleClass.NestedAspect"));
  618. if (LangUtil.is18VMOrGreater()) {
  619. assertTrue(htmlFile.getName() + " should not have class in its subtitle",
  620. missing.contains("<pre>static class <span class=\"typeNameLabel\">PkgVisibleClass.NestedAspect</span>"));
  621. }
  622. else {
  623. assertTrue(htmlFile.getName() + " should not have class in its subtitle",
  624. missing.contains("<PRE>static class <B>PkgVisibleClass.NestedAspect</B><DT>extends java.lang.Object</DL>"));
  625. }
  626. // get the html file for the enclosing class
  627. File htmlFileClass = new File(getAbsolutePathOutdir() + "/PkgVisibleClass.html");
  628. if (!htmlFileClass.exists()) {
  629. fail("couldn't find " + htmlFileClass.getAbsolutePath()
  630. + " - were there compilation errors?");
  631. }
  632. // ensure that the file is entitled "Class PkgVisibleClass" and
  633. // has not been changed to "Aspect PkgVisibleClass"
  634. String[] classStrings = null;
  635. if (LangUtil.is18VMOrGreater()) {
  636. classStrings = new String[] {
  637. "Class PkgVisibleClass</h2>",
  638. "<pre>class <span class=\"typeNameLabel\">PkgVisibleClass</span>",
  639. "Aspect PkgVisibleClass</h2>",
  640. "<pre>aspect <span class=\"typeNameLabel\">PkgVisibleClass</span>"};
  641. }
  642. else {
  643. classStrings = new String[] {
  644. "Class PkgVisibleClass</H2>",
  645. "class <B>PkgVisibleClass</B><DT>extends java.lang.Object</DL>",
  646. "Aspect PkgVisibleClass</H2>",
  647. "aspect <B>PkgVisibleClass</B><DT>extends java.lang.Object<DT>"};
  648. }
  649. List<String> classMissing = AjdocOutputChecker.getMissingStringsInFile(htmlFileClass,classStrings);
  650. assertEquals("There should be 2 missing strings",2,classMissing.size());
  651. if (LangUtil.is18VMOrGreater()) {
  652. assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title",
  653. classMissing.contains("Aspect PkgVisibleClass</h2>"));
  654. assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle",
  655. classMissing.contains("<pre>aspect <span class=\"typeNameLabel\">PkgVisibleClass</span>"));
  656. }
  657. else {
  658. assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title",classMissing.contains("Aspect PkgVisibleClass</H2>"));
  659. assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle",classMissing.contains("aspect <B>PkgVisibleClass</B><DT>extends java.lang.Object<DT>"));
  660. }
  661. }
  662. /**
  663. * Test that in the case when you have a nested aspect whose
  664. * name is part of the enclosing class, for example a class called
  665. * ClassWithNestedAspect has nested aspect called NestedAspect,
  666. * that the titles for the ajdoc are correct.
  667. */
  668. public void testNestedAspectWithSimilarName() throws Exception {
  669. File[] files = {new File(getAbsoluteProjectDir() + "/pkg/ClassWithNestedAspect.java")};
  670. runAjdoc("private","1.6",files);
  671. File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/ClassWithNestedAspect.NestedAspect.html");
  672. if (!htmlFile.exists()) {
  673. fail("couldn't find " + htmlFile.getAbsolutePath()
  674. + " - were there compilation errors?");
  675. }
  676. // ensure that the file is entitled "Aspect ClassWithNestedAspect.NestedAspect"
  677. // rather than "Class ClassWithNestedAspect.NestedAspect"
  678. String[] strings = null;
  679. if (LangUtil.is18VMOrGreater()) {
  680. strings = new String [] {
  681. "Aspect ClassWithNestedAspect.NestedAspect",
  682. "<pre>static aspect <span class=\"typeNameLabel\">ClassWithNestedAspect.NestedAspect</span>",
  683. "Class ClassWithNestedAspect.NestedAspect",
  684. "<pre>static class <span class=\"typeNameLabel\">ClassWithNestedAspect.NestedAspect</span>"};
  685. }
  686. else {
  687. strings = new String [] {
  688. "Aspect ClassWithNestedAspect.NestedAspect",
  689. "<PRE>static a;spect <B>ClassWithNestedAspect.NestedAspect</B><DT>extends java.lang.Object</DL>",
  690. "Class ClassWithNestedAspect.NestedAspect",
  691. "<PRE>static class <B>ClassWithNestedAspect.NestedAspect</B><DT>extends java.lang.Object</DL>"};
  692. }
  693. List<String> missing = AjdocOutputChecker.getMissingStringsInFile(htmlFile,strings);
  694. assertEquals("There should be 2 missing strings",2,missing.size());
  695. assertTrue(htmlFile.getName() + " should not have Class as it's title",missing.contains("Class ClassWithNestedAspect.NestedAspect"));
  696. if (LangUtil.is18VMOrGreater()) {
  697. assertTrue(htmlFile.getName() + " should not have class in its subtitle",
  698. missing.contains("<pre>static class <span class=\"typeNameLabel\">ClassWithNestedAspect.NestedAspect</span>"));
  699. }
  700. else {
  701. assertTrue(htmlFile.getName() + " should not have class in its subtitle",missing.contains("<PRE>static class <B>ClassWithNestedAspect.NestedAspect</B><DT>extends java.lang.Object</DL>"));
  702. }
  703. // get the html file for the enclosing class
  704. File htmlFileClass = new File(getAbsolutePathOutdir() + "/pkg/ClassWithNestedAspect.html");
  705. if (htmlFileClass == null || !htmlFileClass.exists()) {
  706. fail("couldn't find " + htmlFileClass.getAbsolutePath()
  707. + " - were there compilation errors?");
  708. }
  709. // ensure that the file is entitled "Class ClassWithNestedAspect" and
  710. // has not been changed to "Aspect ClassWithNestedAspect"
  711. String[] classStrings = null;
  712. if (LangUtil.is18VMOrGreater()) {
  713. classStrings = new String[] {
  714. "Class ClassWithNestedAspect</h2>",
  715. "public class <span class=\"typeNameLabel\">ClassWithNestedAspect</span>",
  716. "Aspect ClassWithNestedAspect</h2>",
  717. "public aspect <span class=\"typeNameLabel\">ClassWithNestedAspect</span>"};
  718. }
  719. else {
  720. classStrings = new String[] {
  721. "Class ClassWithNestedAspect</H2>",
  722. "public class <B>ClassWithNestedAspect</B><DT>extends java.lang.Object</DL>",
  723. "Aspect ClassWithNestedAspect</H2>",
  724. "public aspect <B>ClassWithNestedAspect</B><DT>extends java.lang.Object</DL>"};
  725. }
  726. List<String> classMissing = AjdocOutputChecker.getMissingStringsInFile(htmlFileClass,classStrings);
  727. assertEquals("There should be 2 missing strings",2,classMissing.size());
  728. if (LangUtil.is18VMOrGreater()) {
  729. assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title",
  730. classMissing.contains("Aspect ClassWithNestedAspect</h2>"));
  731. assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle",
  732. classMissing.contains("public aspect <span class=\"typeNameLabel\">ClassWithNestedAspect</span>"));
  733. }
  734. else {
  735. assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title",
  736. classMissing.contains("Aspect ClassWithNestedAspect</H2>"));
  737. assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle",
  738. classMissing.contains("public aspect <B>ClassWithNestedAspect</B><DT>extends java.lang.Object</DL>"));
  739. }
  740. }
  741. /**
  742. * Test that everythings being decorated correctly within the ajdoc
  743. * for the aspect when the aspect is a nested aspect
  744. */
  745. public void testAdviceInNestedAspect() throws Exception {
  746. File[] files = {new File(getAbsoluteProjectDir() + "/pkg/ClassWithNestedAspect.java")};
  747. runAjdoc("private","1.6",files);
  748. File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/ClassWithNestedAspect.NestedAspect.html");
  749. if (!htmlFile.exists()) {
  750. fail("couldn't find " + htmlFile.getAbsolutePath()
  751. + " - were there compilation errors?");
  752. }
  753. boolean b = AjdocOutputChecker.detailSectionContainsRel(
  754. htmlFile,"ADVICE DETAIL SUMMARY",
  755. "before(): p..",
  756. HtmlDecorator.HtmlRelationshipKind.ADVISES,
  757. "HREF=\"../pkg/ClassWithNestedAspect.html#amethod()\"");
  758. assertTrue("Should have 'before(): p.. advises HREF=\"../pkg/ClassWithNestedAspect.html#amethod()\"" +
  759. "' in the Advice Detail section", b);
  760. b = AjdocOutputChecker.summarySectionContainsRel(
  761. htmlFile,"ADVICE SUMMARY",
  762. "before(): p..",
  763. HtmlDecorator.HtmlRelationshipKind.ADVISES,
  764. "HREF=\"../pkg/ClassWithNestedAspect.html#amethod()\"");
  765. assertTrue("Should have 'before(): p.. advises HREF=\"../pkg/ClassWithNestedAspect.html#amethod()\"" +
  766. "' in the Advice Summary section", b);
  767. }
  768. /**
  769. * Test that everythings being decorated correctly within the ajdoc
  770. * for the advised class when the aspect is a nested aspect
  771. */
  772. public void testAdvisedByInNestedAspect() throws Exception {
  773. File[] files = {new File(getAbsoluteProjectDir() + "/pkg/ClassWithNestedAspect.java")};
  774. runAjdoc("private","1.6",files);
  775. File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/ClassWithNestedAspect.html");
  776. if (!htmlFile.exists()) {
  777. fail("couldn't find " + htmlFile.getAbsolutePath()
  778. + " - were there compilation errors?");
  779. }
  780. boolean b = AjdocOutputChecker.containsString(htmlFile,"POINTCUT SUMMARY ");
  781. assertFalse(htmlFile.getName() + " should not contain a pointcut summary section",b);
  782. b = AjdocOutputChecker.containsString(htmlFile,"ADVICE SUMMARY ");
  783. assertFalse(htmlFile.getName() + " should not contain an adivce summary section",b);
  784. b = AjdocOutputChecker.containsString(htmlFile,"POINTCUT DETAIL ");
  785. assertFalse(htmlFile.getName() + " should not contain a pointcut detail section",b);
  786. b = AjdocOutputChecker.containsString(htmlFile,"ADVICE DETAIL ");
  787. assertFalse(htmlFile.getName() + " should not contain an advice detail section",b);
  788. b = AjdocOutputChecker.detailSectionContainsRel(
  789. htmlFile,"=== METHOD DETAIL",
  790. toName("amethod()"),
  791. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  792. "HREF=\"../pkg/ClassWithNestedAspect.NestedAspect.html#before(): p..\"");
  793. assertTrue("Should have 'amethod() advised by " +
  794. "HREF=\"../pkg/ClassWithNestedAspect.NestedAspect.html#before(): p..\"" +
  795. "' in the Method Detail section", b);
  796. b = AjdocOutputChecker.detailSectionContainsRel(
  797. htmlFile,"=== METHOD DETAIL",
  798. toName("amethod()"),
  799. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  800. "pkg.ClassWithNestedAspect.NestedAspect.NestedAspect.before(): p..");
  801. assertFalse("Should not have the label " +
  802. "pkg.ClassWithNestedAspect.NestedAspect.NestedAspect.before(): p.." +
  803. " in the Method Detail section", b);
  804. b = AjdocOutputChecker.summarySectionContainsRel(
  805. htmlFile,"=== METHOD SUMMARY",
  806. toName("amethod()"),
  807. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  808. "HREF=\"../pkg/ClassWithNestedAspect.NestedAspect.html#before(): p..\"");
  809. assertTrue("Should have 'amethod() advised by " +
  810. "HREF=\"../pkg/ClassWithNestedAspect.NestedAspect.html#before(): p..\"" +
  811. "' in the Method Summary section", b);
  812. b = AjdocOutputChecker.detailSectionContainsRel(
  813. htmlFile,"=== METHOD SUMMARY",
  814. toName("amethod()"),
  815. HtmlDecorator.HtmlRelationshipKind.ADVISED_BY,
  816. "pkg.ClassWithNestedAspect.NestedAspect.NestedAspect.before(): p..");
  817. assertFalse("Should not have the label " +
  818. "pkg.ClassWithNestedAspect.NestedAspect.NestedAspect.before(): p.." +
  819. " in the Method Summary section", b);
  820. }
  821. private void createFiles() {
  822. file0 = new File(getAbsoluteProjectDir() + "/InDefaultPackage.java");
  823. file1 = new File(getAbsoluteProjectDir() + "/foo/ClassA.java");
  824. aspect1 = new File(getAbsoluteProjectDir() + "/foo/UseThisAspectForLinkCheck.aj");
  825. file2 = new File(getAbsoluteProjectDir() + "/foo/InterfaceI.java");
  826. file3 = new File(getAbsoluteProjectDir() + "/foo/PlainJava.java");
  827. file4 = new File(getAbsoluteProjectDir() + "/foo/ModelCoverage.java");
  828. file5 = new File(getAbsoluteProjectDir() + "/fluffy/Fluffy.java");
  829. file6 = new File(getAbsoluteProjectDir() + "/fluffy/bunny/Bunny.java");
  830. file7 = new File(getAbsoluteProjectDir() + "/fluffy/bunny/rocks/Rocks.java");
  831. file8 = new File(getAbsoluteProjectDir() + "/fluffy/bunny/rocks/UseThisAspectForLinkCheckToo.java");
  832. file9 = new File(getAbsoluteProjectDir() + "/foo/PkgVisibleClass.java");
  833. file10 = new File(getAbsoluteProjectDir() + "/foo/NoMembers.java");
  834. }
  835. // public void testPlainJava() {
  836. // String[] args = { "-d",
  837. // getAbsolutePathOutdir(),
  838. // file3.getAbsolutePath() };
  839. // org.aspectj.tools.ajdoc.Main.main(args);
  840. // }
  841. }