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