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