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 ParametersFromExternalClassProvideMethod(FrameworkMethod frameworkMethod)16 ParametersFromExternalClassProvideMethod(FrameworkMethod frameworkMethod) { 17 this.paramsFromMethodCommon = new ParamsFromMethodCommon(frameworkMethod); 18 annotation = frameworkMethod.getAnnotation(Parameters.class); 19 } 20 21 @Override getParameters()22 public Object[] getParameters() { 23 Class<?> sourceClass = annotation.source(); 24 return fillResultWithAllParamProviderMethods(sourceClass); 25 } 26 27 @Override isApplicable()28 public boolean isApplicable() { 29 return annotation != null 30 && !annotation.source().isAssignableFrom(Void.class) 31 && annotation.method().isEmpty(); 32 } 33 fillResultWithAllParamProviderMethods(Class<?> sourceClass)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 getParamsFromSourceHierarchy(Class<?> sourceClass)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 gatherParamsFromAllMethodsFrom(Class<?> sourceClass)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 }