View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.dependency.analyzer.asm;
20  
21  import org.junit.jupiter.api.BeforeEach;
22  import org.junit.jupiter.api.Test;
23  import org.objectweb.asm.AnnotationVisitor;
24  import org.objectweb.asm.Attribute;
25  import org.objectweb.asm.FieldVisitor;
26  import org.objectweb.asm.Label;
27  import org.objectweb.asm.MethodVisitor;
28  import org.objectweb.asm.Opcodes;
29  import org.objectweb.asm.Type;
30  import org.objectweb.asm.signature.SignatureVisitor;
31  
32  import static org.assertj.core.api.Assertions.assertThat;
33  
34  /**
35   * Tests <code>DependencyVisitor</code>.
36   *
37   * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
38   */
39  class DependencyVisitorTest {
40      private final ResultCollector resultCollector = new ResultCollector();
41      private DefaultClassVisitor visitor;
42      private MethodVisitor mv;
43  
44      private String usedByClass = "com.example.MyClass";
45  
46      @BeforeEach
47      void setUp() {
48          AnnotationVisitor annotationVisitor = new DefaultAnnotationVisitor(resultCollector, usedByClass);
49          SignatureVisitor signatureVisitor = new DefaultSignatureVisitor(resultCollector, usedByClass);
50          FieldVisitor fieldVisitor = new DefaultFieldVisitor(annotationVisitor, resultCollector, usedByClass);
51          mv = new DefaultMethodVisitor(annotationVisitor, signatureVisitor, resultCollector, usedByClass);
52          visitor = new DefaultClassVisitor(
53                  signatureVisitor, annotationVisitor, fieldVisitor, mv, resultCollector, usedByClass);
54      }
55  
56      @Test
57      void testVisitWithDefaultSuperclass() {
58          // class a.b.c
59          visitor.visit(50, 0, "a/b/c", null, "java/lang/Object", null);
60  
61          assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object");
62      }
63  
64      @Test
65      void testVisitWithSuperclass() {
66          // class a.b.c
67          visitor.visit(50, 0, "a/b/c", null, "x/y/z", null);
68  
69          assertThat(resultCollector.getDependencies()).containsOnly("x.y.z");
70      }
71  
72      @Test
73      void testVisitWithInterface() {
74          // class a.b.c implements x.y.z
75          visitor.visit(50, 0, "a/b/c", null, "java/lang/Object", new String[] {"x/y/z"});
76  
77          assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "x.y.z");
78      }
79  
80      @Test
81      void testVisitWithInterfaces() {
82          // class a.b.c implements p.q.r, x.y.z
83          visitor.visit(50, 0, "a/b/c", null, "java/lang/Object", new String[] {"p/q/r", "x/y/z"});
84  
85          assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "p.q.r", "x.y.z");
86      }
87  
88      @Test
89      void testVisitWithUnboundedClassTypeParameter() {
90          // class a.b.c<T>
91          String signature = "<T:Ljava/lang/Object;>Ljava/lang/Object;";
92  
93          visitor.visit(50, 0, "a/b/c", signature, "java/lang/Object", null);
94  
95          assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object");
96      }
97  
98      @Test
99      void testVisitWithBoundedClassTypeParameter() {
100         // class a.b.c<T extends x.y.z>
101         String signature = "<T:Lx/y/z;>Ljava/lang/Object;";
102 
103         visitor.visit(50, 0, "a/b/c", signature, "java/lang/Object", null);
104 
105         assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "x.y.z");
106     }
107 
108     @Test
109     void testVisitWithBoundedClassTypeParameters() {
110         // class a.b.c<K extends p.q.r, V extends x.y.z>
111         String signature = "<K:Lp/q/r;V:Lx/y/z;>Ljava/lang/Object;";
112 
113         visitor.visit(50, 0, "a/b/c", signature, "java/lang/Object", null);
114 
115         assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "p.q.r", "x.y.z");
116     }
117 
118     @Test
119     void testVisitWithGenericInterface() {
120         // class a.b.c implements p.q.r<x.y.z>
121         String signature = "Ljava/lang/Object;Lp/q/r<Lx/y/z;>;";
122 
123         visitor.visit(50, 0, "a/b/c", signature, "java/lang/Object", new String[] {"p.q.r"});
124 
125         assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "p.q.r", "x.y.z");
126     }
127 
128     @Test
129     void testVisitWithInterfaceBound() {
130         // class a.b.c<T> implements x.y.z<T>
131         String signature = "<T:Ljava/lang/Object;>Ljava/lang/Object;Lx/y/z<TT;>;";
132 
133         visitor.visit(50, 0, "a/b/c", signature, "java/lang/Object", new String[] {"x.y.z"});
134 
135         assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "x.y.z");
136     }
137 
138     // visitSource tests ------------------------------------------------------
139 
140     @Test
141     void testVisitSource() {
142         visitor.visitSource(null, null);
143 
144         assertThat(resultCollector.getDependencies()).isEmpty();
145     }
146 
147     // visitOuterClass tests --------------------------------------------------
148 
149     @Test
150     void testVisitOuterClass() {
151         // class a.b.c
152         // {
153         //     class ...
154         //     {
155         //     }
156         // }
157         visitor.visitOuterClass("a/b/c", null, null);
158 
159         assertThat(resultCollector.getDependencies()).isEmpty();
160     }
161 
162     @Test
163     void testVisitOuterClassInMethod() {
164         // class a.b.c
165         // {
166         //     x.y.z x(p.q.r p)
167         //     {
168         //         class ...
169         //         {
170         //         }
171         //     }
172         // }
173         visitor.visitOuterClass("a/b/c", "x", "(Lp/q/r;)Lx/y/z;");
174 
175         assertThat(resultCollector.getDependencies()).isEmpty();
176     }
177 
178     // visitAnnotation tests --------------------------------------------------
179 
180     @Test
181     void testVisitAnnotation() {
182         assertVisitor(visitor.visitAnnotation("La/b/c;", false));
183 
184         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
185     }
186 
187     @Test
188     void testVisitAnnotationWithRuntimeVisibility() {
189         assertVisitor(visitor.visitAnnotation("La/b/c;", true));
190 
191         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
192     }
193 
194     // visitAttribute tests ---------------------------------------------------
195 
196     @Test
197     void testVisitAttribute() {
198         visitor.visitAttribute(new MockAttribute("a"));
199 
200         assertThat(resultCollector.getDependencies()).isEmpty();
201     }
202 
203     // visitInnerClass tests --------------------------------------------------
204 
205     @Test
206     void testVisitInnerClass() {
207         // TODO: ensure innerName is correct
208 
209         // class a.b.c { class x.y.z { } }
210         visitor.visitInnerClass("x/y/z", "a/b/c", "z", 0);
211 
212         assertThat(resultCollector.getDependencies()).isEmpty();
213     }
214 
215     @Test
216     void testVisitInnerClassAnonymous() {
217         // class a.b.c { new class x.y.z { } }
218         visitor.visitInnerClass("x/y/z$1", "a/b/c", null, 0);
219 
220         assertThat(resultCollector.getDependencies()).isEmpty();
221     }
222 
223     // visitField tests -------------------------------------------------------
224 
225     @Test
226     void testVisitField() {
227         // a.b.c a
228         assertVisitor(visitor.visitField(0, "a", "La/b/c;", null, null));
229 
230         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
231     }
232 
233     // TODO: determine actual use of default values
234     // void testVisitFieldWithValue()
235     // {
236     // }
237 
238     @Test
239     void testVisitFieldArray() {
240         // a.b.c[] a
241         assertVisitor(visitor.visitField(0, "a", "[La/b/c;", null, null));
242 
243         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
244     }
245 
246     @Test
247     void testVisitFieldGeneric() {
248         // a.b.c<x.y.z> a
249         assertVisitor(visitor.visitField(0, "a", "La/b/c;", "La/b/c<Lx/y/z;>;", null));
250 
251         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
252     }
253 
254     // visitMethod tests ------------------------------------------------------
255 
256     @Test
257     void testVisitMethod() {
258         // void a()
259         assertVisitor(visitor.visitMethod(0, "a", "()V", null, null));
260 
261         assertThat(resultCollector.getDependencies()).isEmpty();
262     }
263 
264     @Test
265     void testVisitMethodWithPrimitiveArgument() {
266         // void a(int)
267         assertVisitor(visitor.visitMethod(0, "a", "(I)V", null, null));
268 
269         assertThat(resultCollector.getDependencies()).isEmpty();
270     }
271 
272     @Test
273     void testVisitMethodWithPrimitiveArrayArgument() {
274         // void a(int[])
275         assertVisitor(visitor.visitMethod(0, "a", "([I)V", null, null));
276 
277         assertThat(resultCollector.getDependencies()).isEmpty();
278     }
279 
280     @Test
281     void testVisitMethodWithObjectArgument() {
282         // void a(a.b.c)
283         assertVisitor(visitor.visitMethod(0, "a", "(La/b/c;)V", null, null));
284 
285         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
286     }
287 
288     @Test
289     void testVisitMethodWithObjectArguments() {
290         // void a(a.b.c, x.y.z)
291         assertVisitor(visitor.visitMethod(0, "a", "(La/b/c;Lx/y/z;)V", null, null));
292 
293         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
294     }
295 
296     @Test
297     void testVisitMethodWithObjectArrayArgument() {
298         // void a(a.b.c[])
299         assertVisitor(visitor.visitMethod(0, "a", "([La/b/c;)V", null, null));
300 
301         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
302     }
303 
304     @Test
305     void testVisitMethodWithGenericArgument() {
306         // void a(a.b.c<x.y.z>)
307         assertVisitor(visitor.visitMethod(0, "a", "(La/b/c;)V", "(La/b/c<Lx/y/z;>;)V", null));
308 
309         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
310     }
311 
312     @Test
313     void testVisitMethodWithPrimitiveReturnType() {
314         // int a()
315         assertVisitor(visitor.visitMethod(0, "a", "()I", null, null));
316 
317         assertThat(resultCollector.getDependencies()).isEmpty();
318     }
319 
320     @Test
321     void testVisitMethodWithPrimitiveArrayReturnType() {
322         // int[] a()
323         assertVisitor(visitor.visitMethod(0, "a", "()[I", null, null));
324 
325         assertThat(resultCollector.getDependencies()).isEmpty();
326     }
327 
328     @Test
329     void testVisitMethodWithObjectReturnType() {
330         // a.b.c a()
331         assertVisitor(visitor.visitMethod(0, "a", "()La/b/c;", null, null));
332 
333         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
334     }
335 
336     @Test
337     void testVisitMethodWithObjectArrayReturnType() {
338         // a.b.c[] a()
339         assertVisitor(visitor.visitMethod(0, "a", "()[La/b/c;", null, null));
340 
341         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
342     }
343 
344     @Test
345     void testVisitMethodWithException() {
346         // void a() throws a.b.c
347         assertVisitor(visitor.visitMethod(0, "a", "()V", null, new String[] {"a/b/c"}));
348 
349         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
350     }
351 
352     @Test
353     void testVisitMethodWithExceptions() {
354         // void a() throws a.b.c, x.y.z
355         assertVisitor(visitor.visitMethod(0, "a", "()V", null, new String[] {"a/b/c", "x/y/z"}));
356 
357         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
358     }
359 
360     // visitAnnotationDefault tests -------------------------------------------
361 
362     @Test
363     void testVisitAnnotationDefault() {
364         assertVisitor(mv.visitAnnotationDefault());
365         assertThat(resultCollector.getDependencies()).isEmpty();
366     }
367 
368     // visitParameterAnnotation tests -------------------------------------------
369 
370     @Test
371     void testVisitParameterAnnotation() {
372         // @a.b.c
373         assertVisitor(mv.visitParameterAnnotation(0, "La/b/c;", false));
374 
375         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
376     }
377 
378     // visitCode tests --------------------------------------------------------
379 
380     @Test
381     void testVisitCode() {
382         mv.visitCode();
383 
384         assertThat(resultCollector.getDependencies()).isEmpty();
385     }
386 
387     // visitFrame tests -------------------------------------------------------
388 
389     @Test
390     void testVisitFrame() {
391         mv.visitFrame(Opcodes.F_NEW, 0, new Object[0], 0, new Object[0]);
392 
393         assertThat(resultCollector.getDependencies()).isEmpty();
394     }
395 
396     // visitInsn tests --------------------------------------------------------
397 
398     @Test
399     void testVisitInsn() {
400         mv.visitInsn(Opcodes.NOP);
401 
402         assertThat(resultCollector.getDependencies()).isEmpty();
403     }
404 
405     // visitIntInsn tests -----------------------------------------------------
406 
407     @Test
408     void testVisitIntInsn() {
409         mv.visitIntInsn(Opcodes.BIPUSH, 0);
410 
411         assertThat(resultCollector.getDependencies()).isEmpty();
412     }
413 
414     // visitVarInsn tests -----------------------------------------------------
415 
416     @Test
417     void testVisitVarInsn() {
418         mv.visitVarInsn(Opcodes.ILOAD, 0);
419 
420         assertThat(resultCollector.getDependencies()).isEmpty();
421     }
422 
423     // visitTypeInsn tests ----------------------------------------------------
424 
425     @Test
426     void testVisitTypeInsn() {
427         mv.visitTypeInsn(Opcodes.NEW, "a/b/c");
428 
429         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
430     }
431 
432     // visitFieldInsn tests ---------------------------------------------------
433 
434     @Test
435     void testVisitFieldInsnWithPrimitive() {
436         mv.visitFieldInsn(Opcodes.GETFIELD, "a/b/c", "x", "I");
437 
438         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
439     }
440 
441     @Test
442     void testVisitFieldInsnWithObject() {
443         mv.visitFieldInsn(Opcodes.GETFIELD, "a/b/c", "x", "Lx/y/z;");
444 
445         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
446     }
447 
448     // visitMethodInsn tests --------------------------------------------------
449 
450     @Test
451     void testVisitMethodInsn() {
452         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()V", false);
453 
454         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
455     }
456 
457     @Test
458     void testVisitMethodInsnWithPrimitiveArgument() {
459         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "(I)V", false);
460 
461         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
462     }
463 
464     @Test
465     void testVisitMethodInsnWithPrimitiveArrayArgument() {
466         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "([I)V", false);
467 
468         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
469     }
470 
471     @Test
472     void testVisitMethodInsnWithObjectArgument() {
473         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "(Lx/y/z;)V", false);
474 
475         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
476     }
477 
478     @Test
479     void testVisitMethodInsnWithObjectArguments() {
480         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "(Lp/q/r;Lx/y/z;)V", false);
481 
482         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
483     }
484 
485     @Test
486     void testVisitMethodInsnWithObjectArrayArgument() {
487         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "([Lx/y/z;)V", false);
488 
489         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
490     }
491 
492     @Test
493     void testVisitMethodInsnWithPrimitiveReturnType() {
494         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()I", false);
495 
496         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
497     }
498 
499     @Test
500     void testVisitMethodInsnWithPrimitiveArrayReturnType() {
501         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()[I", false);
502 
503         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
504     }
505 
506     @Test
507     void testVisitMethodInsnWithObjectReturnType() {
508         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()Lx/y/z;", false);
509 
510         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
511     }
512 
513     @Test
514     void testVisitMethodInsnWithObjectArrayReturnType() {
515         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()[Lx/y/z;", false);
516 
517         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
518     }
519 
520     // visitJumpInsn tests ----------------------------------------------------
521 
522     @Test
523     void testVisitJumpInsn() {
524         mv.visitJumpInsn(Opcodes.IFEQ, new Label());
525 
526         assertThat(resultCollector.getDependencies()).isEmpty();
527     }
528 
529     // visitLabel tests -------------------------------------------------------
530 
531     @Test
532     void testVisitLabel() {
533         mv.visitLabel(new Label());
534 
535         assertThat(resultCollector.getDependencies()).isEmpty();
536     }
537 
538     // visitLdcInsn tests -----------------------------------------------------
539 
540     @Test
541     void testVisitLdcInsnWithNonType() {
542         mv.visitLdcInsn("a");
543 
544         assertThat(resultCollector.getDependencies()).isEmpty();
545     }
546 
547     @Test
548     void testVisitLdcInsnWithPrimitiveType() {
549         mv.visitLdcInsn(Type.INT_TYPE);
550 
551         assertThat(resultCollector.getDependencies()).isEmpty();
552     }
553 
554     @Test
555     void testVisitLdcInsnWithObjectType() {
556         mv.visitLdcInsn(Type.getType("La/b/c;"));
557 
558         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
559     }
560 
561     // visitIincInsn tests ----------------------------------------------------
562 
563     @Test
564     void testVisitIincInsn() {
565         mv.visitIincInsn(0, 1);
566 
567         assertThat(resultCollector.getDependencies()).isEmpty();
568     }
569 
570     // visitTableSwitchInsn tests ---------------------------------------------
571 
572     @Test
573     void testVisitTableSwitchInsn() {
574         mv.visitTableSwitchInsn(0, 1, new Label(), new Label());
575 
576         assertThat(resultCollector.getDependencies()).isEmpty();
577     }
578 
579     // visitLookupSwitchInsn tests --------------------------------------------
580 
581     @Test
582     void testVisitLookupSwitchInsn() {
583         mv.visitLookupSwitchInsn(new Label(), new int[] {0}, new Label[] {new Label()});
584 
585         assertThat(resultCollector.getDependencies()).isEmpty();
586     }
587 
588     // visitMultiANewArrayInsn tests ------------------------------------------
589 
590     @Test
591     void testVisitMultiANewArrayInsnWithPrimitive() {
592         mv.visitMultiANewArrayInsn("I", 2);
593 
594         assertThat(resultCollector.getDependencies()).isEmpty();
595     }
596 
597     @Test
598     void testVisitMultiANewArrayInsnWithObject() {
599         mv.visitMultiANewArrayInsn("La/b/c;", 2);
600 
601         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
602     }
603 
604     // visitTryCatchBlock tests -----------------------------------------------
605 
606     @Test
607     void testVisitTryCatchBlock() {
608         mv.visitTryCatchBlock(new Label(), new Label(), new Label(), "a/b/c");
609 
610         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
611     }
612 
613     @Test
614     void testVisitTryCatchBlockForFinally() {
615         mv.visitTryCatchBlock(new Label(), new Label(), new Label(), null);
616 
617         assertThat(resultCollector.getDependencies()).isEmpty();
618     }
619 
620     // visitLocalVariable tests -----------------------------------------------
621 
622     @Test
623     void testVisitLocalVariableWithPrimitive() {
624         mv.visitLocalVariable("a", "I", null, new Label(), new Label(), 0);
625 
626         assertThat(resultCollector.getDependencies()).isEmpty();
627     }
628 
629     @Test
630     void testVisitLocalVariableWithPrimitiveArray() {
631         mv.visitLocalVariable("a", "[I", null, new Label(), new Label(), 0);
632 
633         assertThat(resultCollector.getDependencies()).isEmpty();
634     }
635 
636     @Test
637     void testVisitLocalVariableWithObject() {
638         mv.visitLocalVariable("a", "La/b/c;", null, new Label(), new Label(), 0);
639 
640         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
641     }
642 
643     @Test
644     void testVisitLocalVariableWithObjectArray() {
645         mv.visitLocalVariable("a", "[La/b/c;", null, new Label(), new Label(), 0);
646 
647         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
648     }
649 
650     @Test
651     void testVisitLocalVariableWithGenericObject() {
652         mv.visitLocalVariable("a", "La/b/c;", "La/b/c<Lx/y/z;>;", new Label(), new Label(), 0);
653 
654         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
655     }
656 
657     @Test
658     void testVisitLocalVariableWithGenericObjectArray() {
659         mv.visitLocalVariable("a", "La/b/c;", "[La/b/c<Lx/y/z;>;", new Label(), new Label(), 0);
660 
661         assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
662     }
663 
664     // visitLineNumber tests --------------------------------------------------
665 
666     @Test
667     void testVisitLineNumber() {
668         mv.visitLineNumber(0, new Label());
669 
670         assertThat(resultCollector.getDependencies()).isEmpty();
671     }
672 
673     // visitMaxs tests --------------------------------------------------------
674 
675     @Test
676     void testVisitMaxs() {
677         mv.visitMaxs(0, 0);
678 
679         assertThat(resultCollector.getDependencies()).isEmpty();
680     }
681 
682     // visitInvokeDynamicInsn tests -------------------------------------------
683     @Test
684     void testVisitInvokeDynamic() {
685         Type type = Type.getType("(La/b/C;)V");
686         mv.visitInvokeDynamicInsn("a", "", null, type);
687         assertThat(resultCollector.getDependencies()).contains("a.b.C");
688     }
689 
690     private void assertVisitor(Object actualVisitor) {
691         // assertEquals( visitor, actualVisitor );
692     }
693 
694     /**
695      * A simple ASM <code>Attribute</code> for use in tests.
696      *
697      * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
698      */
699     static class MockAttribute extends Attribute {
700         MockAttribute(String type) {
701             super(type);
702         }
703     }
704 }