Home | History | Annotate | Download | only in parameters
      1 package junitparams.internal.parameters;
      2 
      3 import junitparams.Parameters;
      4 import org.junit.runners.model.FrameworkMethod;
      5 
      6 import java.lang.reflect.Method;
      7 import java.lang.reflect.Modifier;
      8 import java.util.ArrayList;
      9 import java.util.Arrays;
     10 import java.util.List;
     11 
     12 class ParametersFromExternalClassProvideMethod implements ParametrizationStrategy {
     13     private final ParamsFromMethodCommon paramsFromMethodCommon;
     14     private Parameters annotation;
     15 
     16     ParametersFromExternalClassProvideMethod(FrameworkMethod frameworkMethod) {
     17         this.paramsFromMethodCommon = new ParamsFromMethodCommon(frameworkMethod);
     18         annotation = frameworkMethod.getAnnotation(Parameters.class);
     19     }
     20 
     21     @Override
     22     public Object[] getParameters() {
     23         Class<?> sourceClass = annotation.source();
     24         return fillResultWithAllParamProviderMethods(sourceClass);
     25     }
     26 
     27     @Override
     28     public boolean isApplicable() {
     29         return annotation != null
     30                 && !annotation.source().isAssignableFrom(Void.class)
     31                 && annotation.method().isEmpty();
     32     }
     33 
     34     private Object[] fillResultWithAllParamProviderMethods(Class<?> sourceClass) {
     35         if (sourceClass.isEnum()) {
     36             return sourceClass.getEnumConstants();
     37         }
     38 
     39         List<Object> result = getParamsFromSourceHierarchy(sourceClass);
     40         if (result.isEmpty())
     41             throw new RuntimeException(
     42                     "No methods starting with provide or they return no result in the parameters source class: "
     43                             + sourceClass.getName());
     44 
     45         return result.toArray();
     46     }
     47 
     48     private List<Object> getParamsFromSourceHierarchy(Class<?> sourceClass) {
     49         List<Object> result = new ArrayList<Object>();
     50         while (sourceClass.getSuperclass() != null) {
     51             result.addAll(gatherParamsFromAllMethodsFrom(sourceClass));
     52             sourceClass = sourceClass.getSuperclass();
     53         }
     54 
     55         return result;
     56     }
     57 
     58     private List<Object> gatherParamsFromAllMethodsFrom(Class<?> sourceClass) {
     59         List<Object> result = new ArrayList<Object>();
     60         Method[] methods = sourceClass.getDeclaredMethods();
     61         for (Method prividerMethod : methods) {
     62             if (prividerMethod.getName().startsWith("provide")) {
     63                 if (!Modifier.isStatic(prividerMethod.getModifiers())) {
     64                     throw new RuntimeException("Parameters source method " +
     65                             prividerMethod.getName() +
     66                             " is not declared as static. Change it to a static method.");
     67                 }
     68                 try {
     69                     result.addAll(
     70                             Arrays.asList(paramsFromMethodCommon.getDataFromMethod(prividerMethod)));
     71                 } catch (Exception e) {
     72                     throw new RuntimeException("Cannot invoke parameters source method: " + prividerMethod.getName(),
     73                             e);
     74                 }
     75             }
     76         }
     77         return result;
     78     }
     79 }