Coverage Report - org.truth0.IteratingVerb
 
Classes in this File Line Coverage Branch Coverage Complexity
IteratingVerb
54%
17/31
N/A
3.833
IteratingVerb$1
100%
2/2
N/A
3.833
 
 1  
 package org.truth0;
 2  
 
 3  
 import com.google.common.annotations.GwtIncompatible;
 4  
 import com.google.common.cache.CacheBuilder;
 5  
 import com.google.common.cache.CacheLoader;
 6  
 import com.google.common.cache.LoadingCache;
 7  
 import java.lang.reflect.Constructor;
 8  
 import java.lang.reflect.InvocationTargetException;
 9  
 import java.lang.reflect.Type;
 10  
 import java.util.concurrent.ExecutionException;
 11  
 import org.truth0.codegen.CompilingClassLoader;
 12  
 import org.truth0.codegen.CompilingClassLoader.CompilerException;
 13  
 import org.truth0.codegen.IteratingWrapperClassBuilder;
 14  
 import org.truth0.subjects.Subject;
 15  
 import org.truth0.subjects.SubjectFactory;
 16  
 /**
 17  
  * A verb that iterates over data and applies the predicate iteratively
 18  
  */
 19  
 @GwtIncompatible("Code generation and loading.")
 20  2
 public class IteratingVerb<T> extends AbstractVerb {
 21  
 
 22  
   private static final String CANNOT_WRAP_MSG = "Cannot build an iterating wrapper around ";
 23  
 
 24  1
   private static LoadingCache<SubjectFactory<?,?>, Class<?>> WRAPPER_CACHE = CacheBuilder.newBuilder().build(
 25  3
       new CacheLoader<SubjectFactory<?,?>, Class<?>>() {
 26  
         @Override public Class<?> load(SubjectFactory<?,?> subjectFactory) throws Exception {
 27  2
           return compileWrapperClass(subjectFactory);
 28  
         }
 29  
       });
 30  
 
 31  
   private final Iterable<T> data;
 32  
 
 33  
   public IteratingVerb(Iterable<T> data, FailureStrategy fs) {
 34  4
     super(fs);
 35  4
     this.data = data;
 36  4
   }
 37  
 
 38  
   public <S extends Subject<S,T>, SF extends SubjectFactory<S, T>> S thatEach(SF factory) {
 39  4
     return wrap(getFailureStrategy(), factory, data);
 40  
   }
 41  
 
 42  
   private <S extends Subject<S,T>, SF extends SubjectFactory<S, T>>
 43  
       S wrap(FailureStrategy fs, SF factory, Iterable<T> data) {
 44  4
     Type t = factory.getSubjectClass();
 45  
     Class<?> wrapperClass;
 46  
     try {
 47  4
       wrapperClass = WRAPPER_CACHE.get(factory);
 48  4
       return instantiate(wrapperClass, t, fs, factory, data);
 49  0
     } catch (ExecutionException e) {
 50  0
       throw new RuntimeException(CANNOT_WRAP_MSG + t, e);
 51  
     }
 52  
   }
 53  
 
 54  
   @SuppressWarnings("unchecked")
 55  
   private <SF, S> S instantiate(Class<?> wrapperType, Type t, FailureStrategy fs, SF factory,
 56  
       Iterable<T> data) {
 57  
     try {
 58  4
       Constructor<S> c = (Constructor<S>)wrapperType.getConstructors()[0];
 59  4
       return c.newInstance(fs, factory, data);
 60  0
     } catch (SecurityException e) {
 61  0
       throw new RuntimeException(CANNOT_WRAP_MSG + t, e);
 62  0
     } catch (InstantiationException e) {
 63  0
       throw new RuntimeException(CANNOT_WRAP_MSG + t, e);
 64  0
     } catch (IllegalAccessException e) {
 65  0
       throw new RuntimeException(CANNOT_WRAP_MSG + t, e);
 66  0
     } catch (InvocationTargetException e) {
 67  0
       throw new RuntimeException(CANNOT_WRAP_MSG + t, e);
 68  
     }
 69  
   }
 70  
 
 71  
   private static Class<?> compileWrapperClass(SubjectFactory<?, ?> subjectFactory) {
 72  2
     IteratingWrapperClassBuilder builder = new IteratingWrapperClassBuilder(subjectFactory);
 73  2
     String out = builder.build().toString();
 74  
     ClassLoader classLoader;
 75  
     try {
 76  2
       classLoader = new CompilingClassLoader(
 77  
           subjectFactory.getSubjectClass().getClassLoader(), builder.className, out, null);
 78  0
     } catch (CompilerException e) {
 79  0
       throw new Error("Could not compile class " + builder.className + " with source:\n" + out , e);
 80  2
     }
 81  
     try {
 82  2
       Class<?> wrapper = classLoader.loadClass(builder.className);
 83  2
       return wrapper;
 84  0
     } catch (ClassNotFoundException e) {
 85  0
       throw new Error("Could not load class " + subjectFactory.getSubjectClass().getSimpleName(), e);
 86  
     }
 87  
   }
 88  
 
 89  
 }