View Javadoc
1   package org.apache.maven.plugins.javadoc;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.io.StringReader;
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.List;
28  import java.util.Properties;
29  
30  import org.apache.maven.execution.MavenSession;
31  import org.apache.maven.plugin.logging.Log;
32  import org.apache.maven.plugin.testing.AbstractMojoTestCase;
33  import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
34  import org.apache.maven.plugins.javadoc.AbstractFixJavadocMojo.JavaEntityTags;
35  import org.apache.maven.shared.invoker.MavenInvocationException;
36  import org.codehaus.plexus.languages.java.version.JavaVersion;
37  import org.codehaus.plexus.util.FileUtils;
38  import org.codehaus.plexus.util.StringUtils;
39  
40  import com.thoughtworks.qdox.JavaProjectBuilder;
41  import com.thoughtworks.qdox.model.DocletTag;
42  import com.thoughtworks.qdox.model.JavaClass;
43  import com.thoughtworks.qdox.model.JavaMethod;
44  
45  import junitx.util.PrivateAccessor;
46  
47  /**
48   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
49   */
50  public class FixJavadocMojoTest
51      extends AbstractMojoTestCase
52  {
53      /** The vm line separator */
54      private static final String EOL = System.getProperty( "line.separator" );
55  
56      /** flag to copy repo only one time */
57      private static boolean TEST_REPO_CREATED = false;
58  
59      /** {@inheritDoc} */
60      @Override
61      protected void setUp()
62          throws Exception
63      {
64          super.setUp();
65  
66          createTestRepo();
67      }
68  
69      /**
70       * Create test repository in target directory.
71       *
72       * @throws IOException if any
73       */
74      private void createTestRepo()
75          throws Exception
76      {
77          if ( TEST_REPO_CREATED )
78          {
79              return;
80          }
81  
82          File localRepo = new File( getBasedir(), "target/local-repo/" );
83          localRepo.mkdirs();
84  
85          // ----------------------------------------------------------------------
86          // fix-test-1.0.jar
87          // ----------------------------------------------------------------------
88  
89          File sourceDir = new File( getBasedir(), "src/test/resources/unit/fix-test/repo/" );
90          assertTrue( sourceDir.exists() );
91          FileUtils.copyDirectoryStructure( sourceDir, localRepo );
92  
93  
94          // Remove SCM files
95          List<String> files =
96              FileUtils.getFileAndDirectoryNames( localRepo, FileUtils.getDefaultExcludesAsString(), null, true,
97                                                  true, true, true );
98          for ( String filename : files )
99          {
100             File file = new File( filename );
101 
102             if ( file.isDirectory() )
103             {
104                 FileUtils.deleteDirectory( file );
105             }
106             else
107             {
108                 file.delete();
109             }
110         }
111 
112         TEST_REPO_CREATED = true;
113     }
114 
115     /**
116      * @throws Exception if any
117      */
118     public void testFix()
119         throws Exception
120     {
121         File testPomBasedir = new File( getBasedir(), "target/test/unit/fix-test" );
122 
123         executeMojoAndTest( testPomBasedir, new String[] { "ClassWithJavadoc.java", "ClassWithNoJavadoc.java",
124             "InterfaceWithJavadoc.java", "InterfaceWithNoJavadoc.java" } );
125     }
126 
127     // ----------------------------------------------------------------------
128     // Test private static methods
129     // ----------------------------------------------------------------------
130 
131     /**
132      * @throws Throwable if any
133      */
134     public void testAutodetectIndentation()
135         throws Throwable
136     {
137         String s = null;
138         assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
139                                                   new Class[] { String.class }, new Object[] { s } ) );
140 
141         s = "no indentation";
142         assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
143                                                   new Class[] { String.class }, new Object[] { s } ) );
144 
145         s = "no indentation with right spaces  ";
146         assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
147                                                   new Class[] { String.class }, new Object[] { s } ) );
148 
149         s = "    indentation";
150         assertEquals( "    ", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
151                                                       new Class[] { String.class }, new Object[] { s } ) );
152 
153         s = "    indentation with right spaces  ";
154         assertEquals( "    ", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
155                                                       new Class[] { String.class }, new Object[] { s } ) );
156 
157         s = "\ttab indentation";
158         assertEquals( "\t", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
159                                                     new Class[] { String.class }, new Object[] { s } ) );
160 
161         s = "  \n  indentation with right spaces  ";
162         assertEquals( "  \n  ", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
163                                                         new Class[] { String.class }, new Object[] { s } ) );
164     }
165 
166     /**
167      * @throws Throwable if any
168      */
169     public void testTrimLeft()
170         throws Throwable
171     {
172         assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
173                                                   new Class[] { String.class }, new Object[] { null } ) );
174         assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
175                                                   new Class[] { String.class }, new Object[] { "  " } ) );
176         assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
177                                                   new Class[] { String.class }, new Object[] { "  \t  " } ) );
178         assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
179                                                    new Class[] { String.class }, new Object[] { "a" } ) );
180         assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
181                                                    new Class[] { String.class }, new Object[] { "  a" } ) );
182         assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
183                                                    new Class[] { String.class }, new Object[] { "\ta" } ) );
184         assertEquals( "a  ", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
185                                                      new Class[] { String.class }, new Object[] { "  a  " } ) );
186         assertEquals( "a\t", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
187                                                      new Class[] { String.class }, new Object[] { "\ta\t" } ) );
188     }
189 
190     /**
191      * @throws Throwable if any
192      */
193     public void testTrimRight()
194         throws Throwable
195     {
196         assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
197                                                   new Class[] { String.class }, new Object[] { null } ) );
198         assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
199                                                   new Class[] { String.class }, new Object[] { "  " } ) );
200         assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
201                                                   new Class[] { String.class }, new Object[] { "  \t  " } ) );
202         assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
203                                                    new Class[] { String.class }, new Object[] { "a" } ) );
204         assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
205                                                    new Class[] { String.class }, new Object[] { "a  " } ) );
206         assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
207                                                    new Class[] { String.class }, new Object[] { "a\t" } ) );
208         assertEquals( "  a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
209                                                      new Class[] { String.class }, new Object[] { "  a  " } ) );
210         assertEquals( "\ta", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
211                                                      new Class[] { String.class }, new Object[] { "\ta\t" } ) );
212     }
213 
214     /**
215      * @throws Throwable if any
216      */
217     public void testHasInheritedTag()
218         throws Throwable
219     {
220         String content = "/** {@inheritDoc} */";
221         Boolean has =
222             (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
223                                               new Class[] { String.class }, new Object[] { content } );
224         assertEquals( Boolean.TRUE, has );
225 
226         content = "/**{@inheritDoc}*/";
227         has =
228             (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
229                                               new Class[] { String.class }, new Object[] { content } );
230         assertEquals( Boolean.TRUE, has );
231 
232         content = "/**{@inheritDoc  }  */";
233         has =
234             (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
235                                               new Class[] { String.class }, new Object[] { content } );
236         assertEquals( Boolean.TRUE, has );
237 
238         content = "/**  {@inheritDoc  }  */";
239         has =
240             (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
241                                               new Class[] { String.class }, new Object[] { content } );
242         assertEquals( Boolean.TRUE, has );
243 
244         content = "/** */";
245         has =
246             (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
247                                               new Class[] { String.class }, new Object[] { content } );
248         assertEquals( Boolean.FALSE, has );
249 
250         content = "/**{  @inheritDoc  }*/";
251         has =
252             (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
253                                               new Class[] { String.class }, new Object[] { content } );
254         assertEquals( Boolean.FALSE, has );
255 
256         content = "/**{@ inheritDoc}*/";
257         has =
258             (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
259                                               new Class[] { String.class }, new Object[] { content } );
260         assertEquals( Boolean.FALSE, has );
261     }
262 
263     /**
264      * @throws Throwable if any
265      */
266     public void testJavadocComment()
267         throws Throwable
268     {
269         String content = "/**" + EOL +
270                 " * Dummy Class." + EOL +
271                 " */" + EOL +
272                 "public class DummyClass" + EOL +
273                 "{" + EOL +
274                 "    /**" + EOL +
275                 "     *" + EOL +
276                 "     * Dummy" + EOL +
277                 "     *" + EOL +
278                 "     *      Method." + EOL +
279                 "     *" + EOL +
280                 "     * @param args not" + EOL +
281                 "     *" + EOL +
282                 "     * null" + EOL +
283                 "     * @param i non negative" + EOL +
284                 "     * @param object could" + EOL +
285                 "     * be" + EOL +
286                 "     *      null" + EOL +
287                 "     * @return a" + EOL +
288                 "     * String" + EOL +
289                 "     *" + EOL +
290                 "     * @throws Exception if" + EOL +
291                 "     * any" + EOL +
292                 "     *" + EOL +
293                 "     */" + EOL +
294                 "    public static String dummyMethod( String[] args, int i, Object object )" + EOL +
295                 "        throws Exception" + EOL +
296                 "    {" + EOL +
297                 "        return null;" + EOL +
298                 "    }" + EOL +
299                 "}";
300 
301         JavaProjectBuilder builder = new JavaProjectBuilder();
302         builder.setEncoding( "UTF-8" );
303         builder.addSource( new StringReader( content ) );
304 
305         JavaClass clazz = builder.addSource( new StringReader( content ) ).getClassByName( "DummyClass" );
306 
307         JavaMethod javaMethod = clazz.getMethods().get( 0 );
308 
309         String javadoc = AbstractFixJavadocMojo.extractOriginalJavadoc( content, javaMethod );
310         assertEquals( "    /**" + EOL +
311                 "     *" + EOL +
312                 "     * Dummy" + EOL +
313                 "     *" + EOL +
314                 "     *      Method." + EOL +
315                 "     *" + EOL +
316                 "     * @param args not" + EOL +
317                 "     *" + EOL +
318                 "     * null" + EOL +
319                 "     * @param i non negative" + EOL +
320                 "     * @param object could" + EOL +
321                 "     * be" + EOL +
322                 "     *      null" + EOL +
323                 "     * @return a" + EOL +
324                 "     * String" + EOL +
325                 "     *" + EOL +
326                 "     * @throws Exception if" + EOL +
327                 "     * any" + EOL +
328                 "     *" + EOL +
329                 "     */", javadoc );
330 
331         String javadocContent = AbstractFixJavadocMojo.extractOriginalJavadocContent( content, javaMethod );
332         assertEquals( "     *" + EOL +
333                       "     * Dummy" + EOL +
334                       "     *" + EOL +
335                       "     *      Method." + EOL +
336                       "     *" + EOL +
337                       "     * @param args not" + EOL +
338                       "     *" + EOL +
339                       "     * null" + EOL +
340                       "     * @param i non negative" + EOL +
341                       "     * @param object could" + EOL +
342                       "     * be" + EOL +
343                       "     *      null" + EOL +
344                       "     * @return a" + EOL +
345                       "     * String" + EOL +
346                       "     *" + EOL +
347                       "     * @throws Exception if" + EOL +
348                       "     * any" + EOL +
349                       "     *", javadocContent );
350 
351         String withoutEmptyJavadocLines =
352             (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
353                                              new Class[] { String.class }, new Object[] { javadocContent } );
354         assertTrue( withoutEmptyJavadocLines.endsWith( "any" ) );
355 
356         String methodJavadoc = AbstractFixJavadocMojo.getJavadocComment( content, javaMethod );
357         assertEquals( "     *" + EOL +
358                 "     * Dummy" + EOL +
359                 "     *" + EOL +
360                 "     *      Method." + EOL +
361                 "     *", methodJavadoc );
362         withoutEmptyJavadocLines =
363             (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
364                                              new Class[] { String.class }, new Object[] { methodJavadoc } );
365         assertTrue( withoutEmptyJavadocLines.endsWith( "Method." ) );
366 
367         assertEquals( 5, javaMethod.getTags().size() );
368 
369         AbstractFixJavadocMojo mojoInstance = new FixJavadocMojo();
370         setVariableValueToObject( mojoInstance, "fixTagsSplitted", new String[] { "all" } );
371 
372         DocletTag tag = javaMethod.getTags().get( 0 );
373         String tagJavadoc = mojoInstance.getJavadocComment( content, javaMethod, tag);
374         assertEquals( "     * @param args not" + EOL +
375                 "     *" + EOL +
376                 "     * null", tagJavadoc );
377         withoutEmptyJavadocLines =
378             (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
379                                              new Class[] { String.class }, new Object[] { tagJavadoc } );
380         assertTrue( withoutEmptyJavadocLines.endsWith( "null" ) );
381 
382         tag = javaMethod.getTags().get( 1 );
383         tagJavadoc = mojoInstance.getJavadocComment( content, javaMethod, tag );
384         assertEquals( "     * @param i non negative", tagJavadoc );
385         withoutEmptyJavadocLines =
386             (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
387                                              new Class[] { String.class }, new Object[] { tagJavadoc } );
388         assertTrue( withoutEmptyJavadocLines.endsWith( "negative" ) );
389 
390         tag = javaMethod.getTags().get( 2 );
391         tagJavadoc = mojoInstance.getJavadocComment( content, javaMethod, tag );
392         assertEquals( "     * @param object could" + EOL +
393                 "     * be" + EOL +
394                 "     *      null", tagJavadoc );
395         withoutEmptyJavadocLines =
396             (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
397                                              new Class[] { String.class }, new Object[] { tagJavadoc } );
398         assertTrue( withoutEmptyJavadocLines.endsWith( "null" ) );
399 
400         tag = javaMethod.getTags().get( 3 );
401         tagJavadoc = mojoInstance.getJavadocComment( content, javaMethod, tag );
402         assertEquals( "     * @return a" + EOL +
403                 "     * String" + EOL +
404                 "     *", tagJavadoc );
405         withoutEmptyJavadocLines =
406             (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
407                                              new Class[] { String.class }, new Object[] { tagJavadoc } );
408         assertTrue( withoutEmptyJavadocLines.endsWith( "String" ) );
409 
410         tag = javaMethod.getTags().get( 4 );
411         tagJavadoc = mojoInstance.getJavadocComment( content, javaMethod, tag );
412         assertEquals( "     * @throws Exception if" + EOL +
413                 "     * any" + EOL +
414                 "     *", tagJavadoc );
415         withoutEmptyJavadocLines =
416             (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
417                                              new Class[] { String.class }, new Object[] { tagJavadoc } );
418         assertTrue( withoutEmptyJavadocLines.endsWith( "any" ) );
419     }
420 
421     public void testJavadocCommentJdk5()
422         throws Exception
423     {
424         String content = "/**" + EOL +
425                 " * Dummy Class." + EOL +
426                 " */" + EOL +
427                 "public class DummyClass" + EOL +
428                 "{" + EOL +
429                 "    /**" + EOL +
430                 "     * Dummy method." + EOL +
431                 "     *" + EOL +
432                 "     * @param <K>  The Key type for the method" + EOL +
433                 "     * @param <V>  The Value type for the method" + EOL +
434                 "     * @param name The name." + EOL +
435                 "     * @return A map configured." + EOL +
436                 "     */" + EOL +
437                 "    public <K, V> java.util.Map<K, V> dummyMethod( String name )" + EOL +
438                 "    {" + EOL +
439                 "        return null;" + EOL +
440                 "    }" + EOL +
441                 "}";
442 
443         JavaProjectBuilder builder = new JavaProjectBuilder();
444         builder.setEncoding( "UTF-8" );
445         JavaClass clazz = builder.addSource( new StringReader( content ) ).getClassByName( "DummyClass" );
446 
447         JavaMethod javaMethod = clazz.getMethods().get( 0 );
448 
449         String methodJavadoc = AbstractFixJavadocMojo.getJavadocComment( content, javaMethod );
450         assertEquals( "     * Dummy method." + EOL +
451                 "     *", methodJavadoc );
452 
453         assertEquals( 4, javaMethod.getTags().size() );
454 
455         AbstractFixJavadocMojo mojoInstance = new FixJavadocMojo();
456         setVariableValueToObject( mojoInstance, "fixTagsSplitted", new String[] { "all" } );
457 
458         DocletTag tag = javaMethod.getTags().get( 0 );
459         String tagJavadoc = mojoInstance.getJavadocComment( content, javaMethod, tag );
460         assertEquals( "     * @param <K>  The Key type for the method", tagJavadoc );
461 
462         tag = javaMethod.getTags().get( 1 );
463         tagJavadoc = mojoInstance.getJavadocComment( content, javaMethod, tag );
464         assertEquals( "     * @param <V>  The Value type for the method", tagJavadoc );
465 
466         tag = javaMethod.getTags().get( 2 );
467         tagJavadoc = mojoInstance.getJavadocComment( content, javaMethod, tag );
468         assertEquals( "     * @param name The name.", tagJavadoc );
469 
470         tag = javaMethod.getTags().get( 3 );
471         tagJavadoc = mojoInstance.getJavadocComment( content, javaMethod, tag );
472         assertEquals( "     * @return A map configured.", tagJavadoc );
473     }
474     
475     public void testInitParameters() 
476         throws Throwable
477     {
478         AbstractFixJavadocMojo mojoInstance = new FixJavadocMojo();
479         setVariableValueToObject( mojoInstance, "fixTags", "author, version, since, param, return, throws, link" );
480         setVariableValueToObject(mojoInstance, "defaultSince", "1.0");
481         setVariableValueToObject(mojoInstance, "level", "protected");
482         
483         PrivateAccessor.invoke( mojoInstance, "init", new Class[] { }, new String[] { } );
484         
485         String[] fixTags = (String[]) getVariableValueFromObject(mojoInstance, "fixTagsSplitted");
486         
487         assertEquals("author", fixTags[0]);
488         assertEquals("version", fixTags[1]);
489         assertEquals("since", fixTags[2]);
490         assertEquals("param", fixTags[3]);
491         assertEquals("return", fixTags[4]);
492         assertEquals("throws", fixTags[5]);
493         assertEquals("link", fixTags[6]);
494         assertEquals(7, fixTags.length);
495         
496         setVariableValueToObject( mojoInstance, "fixTags", "return, fake_value" );
497         PrivateAccessor.invoke( mojoInstance, "init", new Class[] { }, new String[] { } );
498         fixTags = (String[]) getVariableValueFromObject(mojoInstance, "fixTagsSplitted");
499         
500         assertEquals("return", fixTags[0]);
501         assertEquals(1, fixTags.length);
502     }
503     
504     public void testRemoveUnknownExceptions() throws Exception
505     {
506         AbstractFixJavadocMojo mojoInstance = new FixJavadocMojo();
507         setVariableValueToObject( mojoInstance, "fixTagsSplitted", new String[] { "all" } );
508         setVariableValueToObject( mojoInstance, "project", new MavenProjectStub() );
509 
510         String source = "package a.b.c;" + EOL
511                         + "public class Clazz {" + EOL
512                         + " /**" + EOL
513                         + " * @throws java.lang.RuntimeException" + EOL
514                         + " * @throws NumberFormatException" + EOL
515                         + " * @throws java.lang.Exception" + EOL // not thrown and no RTE -> remove
516                         + " * @throws com.foo.FatalException" + EOL // not on classpath (?!) -> see removeUnknownThrows
517                         + " */" + EOL
518                         + " public void method() {}" + EOL                        
519                         + "}";
520 
521         JavaProjectBuilder builder = new JavaProjectBuilder();
522         JavaMethod javaMethod = builder.addSource( new StringReader( source ) ).getClassByName( "Clazz" ).getMethods().get( 0 );
523         
524         JavaEntityTags javaEntityTags = mojoInstance.parseJavadocTags( source, javaMethod, "", true );
525         
526         StringBuilder sb = new StringBuilder();
527         mojoInstance.writeThrowsTag( sb, javaMethod, javaEntityTags, Arrays.asList( "java.lang.RuntimeException" ) );
528         assertEquals( " * @throws java.lang.RuntimeException", sb.toString() );
529 
530         sb = new StringBuilder();
531         mojoInstance.writeThrowsTag( sb, javaMethod, javaEntityTags, Arrays.asList( "NumberFormatException" ) );
532         assertEquals( " * @throws java.lang.NumberFormatException", sb.toString() );
533 
534         sb = new StringBuilder();
535         mojoInstance.writeThrowsTag( sb, javaMethod, javaEntityTags, Arrays.asList( "java.lang.Exception" ) );
536         assertEquals( "", sb.toString() );
537         
538         setVariableValueToObject( mojoInstance, "removeUnknownThrows", true );
539         sb = new StringBuilder();
540         mojoInstance.writeThrowsTag( sb, javaMethod, javaEntityTags, Arrays.asList( "com.foo.FatalException" ) );
541         assertEquals( "", sb.toString() );
542 
543         setVariableValueToObject( mojoInstance, "removeUnknownThrows", false );
544         sb = new StringBuilder();
545         mojoInstance.writeThrowsTag( sb, javaMethod, javaEntityTags, Arrays.asList( "com.foo.FatalException" ) );
546         assertEquals( " * @throws com.foo.FatalException if any.", sb.toString() );
547     }
548 
549     // ----------------------------------------------------------------------
550     // private methods
551     // ----------------------------------------------------------------------
552 
553     /**
554      * @param testPomBasedir the basedir for the test project
555      * @param clazzToCompare an array of the classes name to compare
556      * @throws Exception if any
557      */
558     private void executeMojoAndTest( File testPomBasedir, String[] clazzToCompare )
559         throws Exception
560     {
561         prepareTestProjects( testPomBasedir.getName() );
562 
563         File testPom = new File( testPomBasedir, "pom.xml" );
564         assertTrue( testPom.getAbsolutePath() + " should exist", testPom.exists() );
565 
566         FixJavadocMojo mojo = (FixJavadocMojo) lookupMojo( "fix", testPom );
567         assertNotNull( mojo );
568         
569         MavenSession session = newMavenSession( mojo.getProject() );
570         // Ensure remote repo connection uses SSL
571         File globalSettingsFile = new File( getBasedir(), "target/test-classes/unit/settings.xml" );
572         session.getRequest().setGlobalSettingsFile( globalSettingsFile );
573         setVariableValueToObject( mojo, "session", session );
574 
575         // compile the test project
576         invokeCompileGoal( testPom, globalSettingsFile, mojo.getLog() );
577         assertTrue( new File( testPomBasedir, "target/classes" ).exists() );
578 
579         mojo.execute();
580 
581         File expectedDir = new File( testPomBasedir, "expected/src/main/java/fix/test" );
582         assertTrue( expectedDir.exists() );
583 
584         File generatedDir = new File( testPomBasedir, "target/generated/fix/test" );
585         assertTrue( generatedDir.exists() );
586 
587         for (String className : clazzToCompare) {
588             assertEquals(new File(expectedDir, className), new File(generatedDir, className));
589         }
590     }
591 
592     /**
593      * Invoke the compilation on the given pom file.
594      *
595      * @param testPom not null
596      * @param log not null
597      * @throws MavenInvocationException if any
598      */
599     private void invokeCompileGoal( File testPom, File globalSettingsFile, Log log )
600         throws Exception
601     {
602         List<String> goals = new ArrayList<>();
603         goals.add( "clean" );
604         goals.add( "compile" );
605         File invokerDir = new File( getBasedir(), "target/invoker" );
606         invokerDir.mkdirs();
607         File invokerLogFile = FileUtils.createTempFile( "FixJavadocMojoTest", ".txt", invokerDir );
608         
609         Properties properties = new Properties();
610 
611         if ( JavaVersion.JAVA_SPECIFICATION_VERSION.isAtLeast( "12" ) )
612         {
613             properties.put( "maven.compiler.source", "1.7" );
614             properties.put( "maven.compiler.target", "1.7" );
615         }
616         else if ( JavaVersion.JAVA_SPECIFICATION_VERSION.isAtLeast( "9" ) )
617         {
618             properties.put( "maven.compiler.source", "1.6" );
619             properties.put( "maven.compiler.target", "1.6" );
620         }
621         
622         // @todo unittests shouldn't need to go remote
623         if ( JavaVersion.JAVA_SPECIFICATION_VERSION.isBefore( "8" ) )
624         {
625             // ensure that Java7 picks up TLSv1.2 when connecting with Central
626             properties.put( "https.protocols", "TLSv1.2" );
627         }
628         
629         JavadocUtil.invokeMaven( log, new File( getBasedir(), "target/local-repo" ), testPom, goals, properties,
630                                  invokerLogFile, globalSettingsFile );
631     }
632 
633     // ----------------------------------------------------------------------
634     // static methods
635     // ----------------------------------------------------------------------
636 
637     /**
638      * Asserts that files are equal. If they are not an AssertionFailedError is thrown.
639      *
640      * @throws IOException if any
641      */
642     private static void assertEquals( File expected, File actual )
643         throws Exception
644     {
645         assertTrue( " Expected file DNE: " + expected, expected.exists() );
646         String expectedContent = StringUtils.unifyLineSeparators( readFile( expected ) );
647 
648         assertTrue( " Actual file DNE: " + actual, actual.exists() );
649         String actualContent = StringUtils.unifyLineSeparators( readFile( actual ) );
650 
651         assertEquals( "Expected file: " + expected.getAbsolutePath() + ", actual file: "
652             + actual.getAbsolutePath(), expectedContent, actualContent );
653     }
654 
655     /**
656      * @param testProjectDirName not null
657      * @throws IOException if any
658      */
659     private static void prepareTestProjects( String testProjectDirName )
660         throws Exception
661     {
662         File testPomBasedir = new File( getBasedir(), "target/test/unit/" + testProjectDirName );
663 
664         // Using unit test dir
665         FileUtils
666                  .copyDirectoryStructure(
667                                           new File( getBasedir(), "src/test/resources/unit/" + testProjectDirName ),
668                                           testPomBasedir );
669         List<String> scmFiles = FileUtils.getDirectoryNames( testPomBasedir, "**/.svn", null, true );
670         for ( String filename : scmFiles )
671         {
672             File dir = new File( filename );
673 
674             if ( dir.isDirectory() )
675             {
676                 FileUtils.deleteDirectory( dir );
677             }
678         }
679     }
680 
681     /**
682      * @param file not null
683      * @return the content of the given file
684      * @throws IOException if any
685      */
686     private static String readFile( File file )
687         throws Exception
688     {
689         String content = FileUtils.fileRead( file, "UTF-8" );
690         return content;
691     }
692 }