Home | History | Annotate | Download | only in util
      1 /**
      2  * Copyright (C) 2008 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.inject.internal.util;
     18 
     19 import static com.google.inject.Asserts.assertContains;
     20 import static com.google.inject.Asserts.getDeclaringSourcePart;
     21 
     22 import com.google.inject.AbstractModule;
     23 import com.google.inject.CreationException;
     24 import com.google.inject.Guice;
     25 import com.google.inject.Injector;
     26 import com.google.inject.matcher.Matchers;
     27 
     28 import junit.framework.TestCase;
     29 
     30 import java.lang.reflect.Modifier;
     31 
     32 import javax.inject.Inject;
     33 
     34 /**
     35  * @author jessewilson (at) google.com (Jesse Wilson)
     36  */
     37 public class LineNumbersTest extends TestCase {
     38 
     39   public void testLineNumbers() {
     40     try {
     41       Guice.createInjector(new AbstractModule() {
     42         protected void configure() {
     43           bind(A.class);
     44         }
     45       });
     46       fail();
     47     } catch (CreationException expected) {
     48       assertContains(expected.getMessage(),
     49           "1) No implementation for " + B.class.getName() + " was bound.",
     50           "for parameter 0 at " + A.class.getName() + ".<init>(LineNumbersTest.java:",
     51           "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
     52     }
     53   }
     54 
     55   static class A {
     56     @Inject A(B b) {}
     57   }
     58   public interface B {}
     59 
     60   /*if[AOP]*/
     61   public void testCanHandleLineNumbersForGuiceGeneratedClasses() {
     62     try {
     63       Guice.createInjector(new AbstractModule() {
     64         protected void configure() {
     65           bindInterceptor(Matchers.only(A.class), Matchers.any(),
     66               new org.aopalliance.intercept.MethodInterceptor() {
     67                 public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation) {
     68                   return null;
     69                 }
     70               });
     71 
     72           bind(A.class);
     73         }
     74       });
     75       fail();
     76     } catch (CreationException expected) {
     77       assertContains(expected.getMessage(),
     78           "1) No implementation for " + B.class.getName() + " was bound.",
     79           "for parameter 0 at " + A.class.getName() + ".<init>(LineNumbersTest.java:",
     80           "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
     81     }
     82   }
     83 
     84   static class GeneratingClassLoader extends ClassLoader {
     85     static String name = "__generated";
     86 
     87     GeneratingClassLoader() {
     88       super(B.class.getClassLoader());
     89     }
     90 
     91     Class<?> generate() {
     92       org.objectweb.asm.ClassWriter cw =
     93           new org.objectweb.asm.ClassWriter(org.objectweb.asm.ClassWriter.COMPUTE_MAXS);
     94       cw.visit(org.objectweb.asm.Opcodes.V1_5,
     95           Modifier.PUBLIC, name, null,
     96           org.objectweb.asm.Type.getInternalName(Object.class), null);
     97 
     98       String sig = "("+org.objectweb.asm.Type.getDescriptor(B.class)+")V";
     99 
    100       org.objectweb.asm.MethodVisitor mv = cw.visitMethod(Modifier.PUBLIC, "<init>", sig, null, null);
    101 
    102       mv.visitAnnotation(org.objectweb.asm.Type.getDescriptor(Inject.class), true);
    103       mv.visitCode();
    104       mv.visitVarInsn(org.objectweb.asm.Opcodes.ALOAD, 0);
    105       mv.visitMethodInsn(org.objectweb.asm.Opcodes.INVOKESPECIAL,
    106           org.objectweb.asm.Type.getInternalName(Object.class), "<init>", "()V" );
    107       mv.visitInsn(org.objectweb.asm.Opcodes.RETURN);
    108       mv.visitMaxs(0, 0);
    109       mv.visitEnd();
    110       cw.visitEnd();
    111 
    112       byte[] buf = cw.toByteArray();
    113 
    114       return defineClass(name.replace('/', '.'), buf, 0, buf.length);
    115     }
    116   }
    117 
    118   public void testUnavailableByteCodeShowsUnknownSource() {
    119     try {
    120       Guice.createInjector(new AbstractModule() {
    121         protected void configure() {
    122           bind(new GeneratingClassLoader().generate());
    123         }
    124       });
    125       fail();
    126     } catch (CreationException expected) {
    127       assertContains(expected.getMessage(),
    128           "1) No implementation for " + B.class.getName() + " was bound.",
    129           "for parameter 0 at " + GeneratingClassLoader.name + ".<init>(Unknown Source)",
    130           "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
    131     }
    132   }
    133 
    134   public void testGeneratedClassesCanSucceed() {
    135     final Class<?> generated = new GeneratingClassLoader().generate();
    136     Injector injector = Guice.createInjector(new AbstractModule() {
    137       protected void configure() {
    138         bind(generated);
    139         bind(B.class).toInstance(new B() {});
    140       }
    141     });
    142     Object instance = injector.getInstance(generated);
    143     assertEquals(instance.getClass(), generated);
    144   }
    145   /*end[AOP]*/
    146 }
    147