3
3
import com .github .therapi .runtimejavadoc .scribe .JavadocAnnotationProcessor ;
4
4
import com .google .testing .compile .Compilation ;
5
5
import com .google .testing .compile .JavaFileObjects ;
6
+ import java .util .Arrays ;
7
+ import static org .junit .Assert .assertFalse ;
6
8
import org .junit .Test ;
7
9
8
10
import javax .tools .JavaFileObject ;
@@ -26,6 +28,14 @@ public class JavadocAnnotationProcessorTest {
26
28
private static final String DOCUMENTED_CLASS = "javasource.foo.DocumentedClass" ;
27
29
private static final String DOCUMENTED_ENUM = "javasource.foo.DocumentedEnum" ;
28
30
private static final String COMPLEX_ENUM = "javasource.foo.ComplexEnum" ;
31
+ private static final String OVERRIDING_CLASS_IN_ANOTHER_PACKAGE = "javasource.bar.OverridingClassInAnotherPackage" ;
32
+ private static final String OVERRIDING_CLASS = "javasource.foo.OverridingClass" ;
33
+ private static final String OVERRIDING_CLASS_2_DEGREES = "javasource.foo.OverridingClass2Degrees" ;
34
+ private static final String OTHER_INTERFACE = "javasource.foo.OtherInterface" ;
35
+ private static final String DOCUMENTED_INTERFACE = "javasource.foo.DocumentedInterface" ;
36
+ private static final String DOCUMENTED_IMPLEMENTATION = "javasource.foo.DocumentedImplementation" ;
37
+ private static final String COMPLEX_IMPLEMENTATION = "javasource.foo.ComplexImplementation" ;
38
+ private static final String VERY_COMPLEX_IMPLEMENTATION = "javasource.foo.VeryComplexImplementation" ;
29
39
private static final String ANOTHER_DOCUMENTED_CLASS = "javasource.bar.AnotherDocumentedClass" ;
30
40
private static final String ANNOTATED_WITH_RETAIN_JAVADOC = "javasource.bar.YetAnotherDocumentedClass" ;
31
41
private static final String UNDOCUMENTED = "javasource.bar.UndocumentedClass" ;
@@ -41,6 +51,14 @@ private static List<JavaFileObject> sources() {
41
51
"javasource/foo/DocumentedClass.java" ,
42
52
"javasource/foo/DocumentedEnum.java" ,
43
53
"javasource/foo/ComplexEnum.java" ,
54
+ "javasource/foo/OverridingClass.java" ,
55
+ "javasource/foo/OverridingClass2Degrees.java" ,
56
+ "javasource/foo/DocumentedInterface.java" ,
57
+ "javasource/foo/DocumentedImplementation.java" ,
58
+ "javasource/foo/ComplexImplementation.java" ,
59
+ "javasource/foo/VeryComplexImplementation.java" ,
60
+ "javasource/foo/OtherInterface.java" ,
61
+ "javasource/bar/OverridingClassInAnotherPackage.java" ,
44
62
"javasource/bar/AnotherDocumentedClass.java" ,
45
63
"javasource/bar/YetAnotherDocumentedClass.java" ,
46
64
"javasource/bar/UndocumentedClass.java" ,
@@ -80,6 +98,17 @@ public void classNameIsPreserved() throws Exception {
80
98
}
81
99
}
82
100
101
+ @ Test
102
+ public void methodsFullyPopulatedByDefault () throws Exception {
103
+ try (CompilationClassLoader classLoader = compile (null )) {
104
+ Class <?> c = classLoader .loadClass (OVERRIDING_CLASS );
105
+ ClassJavadoc classJavadoc = expectJavadoc (c );
106
+
107
+ Method m = c .getMethod ("frobulate" , String .class , List .class );
108
+ assertFalse (classJavadoc .findMatchingMethod (m ).isEmpty ());
109
+ }
110
+ }
111
+
83
112
@ Test
84
113
public void retainFromAllPackages () throws Exception {
85
114
try (CompilationClassLoader classLoader = compile (null )) {
@@ -231,6 +260,228 @@ public void methodsMatchDespiteOverload() throws Exception {
231
260
232
261
assertMethodMatches (m1 , "Frobulate <code>a</code> by <code>b</code>" );
233
262
assertMethodMatches (m2 , "Frobulate <code>a</code> by multiple oopsifizzle constants" );
263
+
264
+ Method m3 = c .getDeclaredMethod ("equals" , Object .class );
265
+
266
+ // javadoc tools do not inherit javadoc from Object
267
+ expectNoJavadoc (m3 );
268
+ }
269
+ }
270
+
271
+ @ Test
272
+ public void methodsMatchDespiteExtendingFromAnotherPackage () throws Exception {
273
+ try (CompilationClassLoader classLoader = compile (null )) {
274
+ Class <?> c = classLoader .loadClass (OVERRIDING_CLASS_IN_ANOTHER_PACKAGE );
275
+
276
+ final String methodName = "frobulate" ;
277
+ Method m1 = c .getDeclaredMethod (methodName , String .class , int .class );
278
+ Method m2 = c .getDeclaredMethod (methodName , String .class , List .class );
279
+
280
+ assertMethodDescriptionMatches (m1 , "Quick frobulate <code>a</code> by <code>b</code> using thin frobulation" );
281
+ assertMethodDescriptionMatches (m2 , "Frobulate <code>a</code> by multiple oopsifizzle constants" );
282
+ }
283
+ }
284
+
285
+ @ Test
286
+ public void methodsMatchWithExtendedClass () throws Exception {
287
+ try (CompilationClassLoader classLoader = compile (null )) {
288
+ Class <?> c = classLoader .loadClass (OVERRIDING_CLASS );
289
+
290
+ final String methodName = "frobulate" ;
291
+ Method m1 = c .getDeclaredMethod (methodName , String .class , int .class );
292
+
293
+ MethodJavadoc methodJavadoc1 = expectJavadoc (m1 );
294
+ assertEquals (m1 .getName (), methodJavadoc1 .getName ());
295
+
296
+ String actualDesc = formatter .format (methodJavadoc1 .getComment ());
297
+ assertEquals ("Super frobulate <code>a</code> by <code>b</code> using extended frobulation" , actualDesc );
298
+ assertEquals (2 , methodJavadoc1 .getParams ().size ());
299
+ assertFalse (methodJavadoc1 .getReturns ().getElements ().isEmpty ());
300
+ assertFalse (methodJavadoc1 .getThrows ().isEmpty ());
301
+
302
+ Method m2 = c .getDeclaredMethod (methodName , String .class , List .class );
303
+ assertMethodDescriptionMatches (m2 , "Frobulate <code>a</code> by multiple oopsifizzle constants" );
304
+ }
305
+ }
306
+
307
+ @ Test
308
+ public void methodsMatchWithExtendedClass2Degrees () throws Exception {
309
+ try (CompilationClassLoader classLoader = compile (null )) {
310
+ Class <?> c = classLoader .loadClass (OVERRIDING_CLASS_2_DEGREES );
311
+
312
+ final String methodName = "skipMethod" ;
313
+ Method m1 = c .getDeclaredMethod (methodName );
314
+
315
+ MethodJavadoc methodJavadoc1 = expectJavadoc (m1 );
316
+ assertEquals (m1 .getName (), methodJavadoc1 .getName ());
317
+
318
+ String actualDesc = formatter .format (methodJavadoc1 .getComment ());
319
+ assertEquals ("I am also a simple method" , actualDesc );
320
+ assertFalse (methodJavadoc1 .getThrows ().isEmpty ());
321
+ }
322
+ }
323
+
324
+ @ Test
325
+ public void genericMethodsMatchWithExtendedClass () throws Exception {
326
+ try (CompilationClassLoader classLoader = compile (null )) {
327
+ Class <?> c = classLoader .loadClass (OVERRIDING_CLASS );
328
+
329
+ final String methodName1 = "genericMethod" ;
330
+ Method m1 = c .getDeclaredMethod (methodName1 , String .class );
331
+
332
+ assertMethodDescriptionMatches (m1 , "Generic method to do generic things" );
333
+
334
+ final String methodName2 = "separateGeneric" ;
335
+ Method m2 = c .getDeclaredMethod (methodName2 , Integer .class );
336
+
337
+ expectNoJavadoc (m2 );
338
+ }
339
+ }
340
+
341
+ @ Test
342
+ public void genericMethodsMatchWithClass () throws Exception {
343
+ try (CompilationClassLoader classLoader = compile (null )) {
344
+ Class <?> c = classLoader .loadClass (DOCUMENTED_CLASS );
345
+
346
+ final String methodName1 = "genericMethod" ;
347
+ Method m1 = c .getDeclaredMethod (methodName1 , Object .class );
348
+
349
+ assertMethodDescriptionMatches (m1 , "Generic method to do generic things" );
350
+
351
+ final String methodName2 = "separateGeneric" ;
352
+ Method m2 = c .getDeclaredMethod (methodName2 , Comparable .class );
353
+
354
+ assertMethodDescriptionMatches (m2 , "Generic method to do other things" );
355
+ }
356
+ }
357
+
358
+ @ Test
359
+ public void methodsMatchWithImplementation () throws Exception {
360
+ try (CompilationClassLoader classLoader = compile (null )) {
361
+ Class <?> c = classLoader .loadClass (DOCUMENTED_IMPLEMENTATION );
362
+
363
+ final String methodName = "hoodwink" ;
364
+ Method m1 = c .getDeclaredMethod (methodName , String .class );
365
+
366
+ MethodJavadoc methodJavadoc1 = expectJavadoc (m1 );
367
+ assertEquals (m1 .getName (), methodJavadoc1 .getName ());
368
+
369
+ String actualDesc = formatter .format (methodJavadoc1 .getComment ());
370
+ assertEquals ("hoodwink a stranger" , actualDesc );
371
+ assertEquals (1 , methodJavadoc1 .getParams ().size ());
372
+ assertFalse (methodJavadoc1 .getReturns ().getElements ().isEmpty ());
373
+ assertFalse (methodJavadoc1 .getThrows ().isEmpty ());
374
+
375
+ final String methodName2 = "snaggle" ;
376
+ Method m2 = c .getDeclaredMethod (methodName2 , String .class );
377
+ assertMethodDescriptionMatches (m2 , "Snaggle a kerfluffin" );
378
+ }
379
+ }
380
+
381
+ @ Test
382
+ public void genericMethodsMatchWithImplementation () throws Exception {
383
+ try (CompilationClassLoader classLoader = compile (null )) {
384
+ Class <?> c = classLoader .loadClass (DOCUMENTED_IMPLEMENTATION );
385
+
386
+ final String methodName1 = "fling" ;
387
+
388
+ Method m1 = c .getDeclaredMethod (methodName1 , Integer .class );
389
+
390
+ MethodJavadoc methodJavadoc1 = expectJavadoc (m1 );
391
+ assertEquals (m1 .getName (), methodJavadoc1 .getName ());
392
+ String actualDesc = formatter .format (methodJavadoc1 .getComment ());
393
+ assertEquals ("Fling the tea" , actualDesc );
394
+ assertEquals (1 , methodJavadoc1 .getParams ().size ());
395
+ assertFalse (methodJavadoc1 .getReturns ().getElements ().isEmpty ());
396
+ assertFalse (methodJavadoc1 .getThrows ().isEmpty ());
397
+ assertEquals (methodJavadoc1 .getParamTypes (), Arrays .asList ("java.lang.Integer" ));
398
+ assertEquals ("the tea weight" , formatter .format (methodJavadoc1 .getParams ().get (0 ).getComment ()));
399
+
400
+ Method m2 = c .getDeclaredMethod (methodName1 , Object .class );
401
+ expectNoJavadoc (m2 );
402
+ }
403
+ }
404
+
405
+ @ Test
406
+ public void methodsMatchOnInterface () throws Exception {
407
+ try (CompilationClassLoader classLoader = compile (null )) {
408
+ Class <?> c1 = classLoader .loadClass (DOCUMENTED_INTERFACE );
409
+ Class <?> c2 = classLoader .loadClass (OTHER_INTERFACE );
410
+
411
+ final String methodName1 = "hoodwink" ;
412
+ Method m1 = c1 .getDeclaredMethod (methodName1 , String .class );
413
+ Method m2 = c2 .getDeclaredMethod (methodName1 , String .class );
414
+
415
+ assertMethodDescriptionMatches (m1 , "Hoodwink a kerfluffin" );
416
+ assertMethodDescriptionMatches (m2 , "Hoodwink a schmadragon" );
417
+
418
+ final String methodName2 = "snaggle" ;
419
+ Method m3 = c1 .getDeclaredMethod (methodName2 , String .class );
420
+ assertMethodDescriptionMatches (m3 , "Snaggle a kerfluffin" );
421
+ }
422
+ }
423
+
424
+ @ Test
425
+ public void genericMethodsMatchOnInterface () throws Exception {
426
+ try (CompilationClassLoader classLoader = compile (null )) {
427
+ Class <?> c1 = classLoader .loadClass (DOCUMENTED_INTERFACE );
428
+ Class <?> c2 = classLoader .loadClass (OTHER_INTERFACE );
429
+
430
+ final String methodName3 = "fling" ;
431
+ Method m4 = c1 .getDeclaredMethod (methodName3 , Number .class );
432
+ Method m5 = c2 .getDeclaredMethod (methodName3 , Number .class );
433
+ assertMethodDescriptionMatches (m4 , "Fling the tea" );
434
+ assertMethodDescriptionMatches (m5 , "Fling the vorrdin" );
435
+ }
436
+ }
437
+
438
+ @ Test
439
+ public void methodsMatchOnMultipleImplementedInterface () throws Exception {
440
+ try (CompilationClassLoader classLoader = compile (null )) {
441
+ Class <?> c1 = classLoader .loadClass (COMPLEX_IMPLEMENTATION );
442
+
443
+ final String methodName1 = "hoodwink" ;
444
+ Method m1 = c1 .getDeclaredMethod (methodName1 , String .class );
445
+
446
+ assertMethodDescriptionMatches (m1 , "Hoodwink a kerfluffin" );
447
+
448
+ final String methodName2 = "snaggle" ;
449
+ Method m2 = c1 .getDeclaredMethod (methodName2 , String .class );
450
+ assertMethodDescriptionMatches (m2 , "Snaggle a kerfluffin" );
451
+ }
452
+ }
453
+
454
+ @ Test
455
+ public void genericMethodsMatchOnMultipleImplementedInterface () throws Exception {
456
+ try (CompilationClassLoader classLoader = compile (null )) {
457
+ Class <?> c1 = classLoader .loadClass (COMPLEX_IMPLEMENTATION );
458
+
459
+ final String methodName3 = "fling" ;
460
+ Method m3 = c1 .getDeclaredMethod (methodName3 , Integer .class );
461
+ assertMethodDescriptionMatches (m3 , "Fling the tea" );
462
+ }
463
+ }
464
+
465
+ @ Test
466
+ public void methodsMatchOnExtendedClassAndImplementedInterface () throws Exception {
467
+ try (CompilationClassLoader classLoader = compile (null )) {
468
+ Class <?> c1 = classLoader .loadClass (VERY_COMPLEX_IMPLEMENTATION );
469
+
470
+ final String methodName1 = "hoodwink" ;
471
+ Method m1 = c1 .getDeclaredMethod (methodName1 , String .class );
472
+
473
+ assertMethodDescriptionMatches (m1 , "hoodwink a stranger" );
474
+ }
475
+ }
476
+
477
+ @ Test
478
+ public void genericMethodsMatchOnExtendedClassAndImplementedInterface () throws Exception {
479
+ try (CompilationClassLoader classLoader = compile (null )) {
480
+ Class <?> c1 = classLoader .loadClass (VERY_COMPLEX_IMPLEMENTATION );
481
+
482
+ final String methodName3 = "fling" ;
483
+ Method m2 = c1 .getDeclaredMethod (methodName3 , Integer .class );
484
+ assertMethodDescriptionMatches (m2 , "Fling the tea" );
234
485
}
235
486
}
236
487
@@ -275,6 +526,14 @@ private static void assertMethodMatches(Method method, String expectedDescriptio
275
526
assertEquals (seeAlso4 .getHtmlLink ().getText (), "Moomoo land" );
276
527
}
277
528
529
+ private static void assertMethodDescriptionMatches (Method method , String expectedDescription ) {
530
+ MethodJavadoc methodDoc = expectJavadoc (method );
531
+ assertEquals (method .getName (), methodDoc .getName ());
532
+
533
+ String actualDesc = formatter .format (methodDoc .getComment ());
534
+ assertEquals (expectedDescription , actualDesc );
535
+ }
536
+
278
537
@ Test
279
538
public void nestedClassNameIsPreserved () throws Exception {
280
539
try (CompilationClassLoader classLoader = compile (null )) {
@@ -374,6 +633,13 @@ private static void expectNoJavadoc(Class<?> c) {
374
633
assertEquals (c .getName (), doc .getName ());
375
634
}
376
635
636
+ private static void expectNoJavadoc (Method m ) {
637
+ MethodJavadoc doc = RuntimeJavadoc .getJavadoc (m );
638
+ assertNotNull (doc );
639
+ assertTrue (doc .isEmpty ());
640
+ assertEquals (m .getName (), doc .getName ());
641
+ }
642
+
377
643
private static <T extends BaseJavadoc > T assertPresent (T value , String msg ) {
378
644
if (value == null || value .isEmpty ()) {
379
645
throw new AssertionError (msg );
0 commit comments