1fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffinpackage junitparams.internal.parameters; 2fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 3fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffinimport java.lang.reflect.InvocationTargetException; 4fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffinimport java.lang.reflect.Method; 5fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffinimport java.util.ArrayList; 6fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffinimport java.util.Iterator; 7fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffinimport java.util.List; 8fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 9fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffinimport org.junit.runners.model.FrameworkMethod; 10fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 11fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffinimport junitparams.Parameters; 12fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 13fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffinclass ParamsFromMethodCommon { 14fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin private FrameworkMethod frameworkMethod; 15fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 16fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin ParamsFromMethodCommon(FrameworkMethod frameworkMethod) { 17fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin this.frameworkMethod = frameworkMethod; 18fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 19fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 20fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin Object[] paramsFromMethod(Class<?> sourceClass) { 21fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin String methodAnnotation = frameworkMethod.getAnnotation(Parameters.class).method(); 22fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 23fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin if (methodAnnotation.isEmpty()) { 24fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return invokeMethodWithParams(defaultMethodName(), sourceClass); 25fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 26fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 27fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin List<Object> result = new ArrayList<Object>(); 28fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin for (String methodName : methodAnnotation.split(",")) { 29fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin for (Object param : invokeMethodWithParams(methodName.trim(), sourceClass)) 30fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin result.add(param); 31fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 32fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 33fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return result.toArray(); 34fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 35fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 36fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin Object[] getDataFromMethod(Method providerMethod) throws IllegalAccessException, InvocationTargetException { 37fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return encapsulateParamsIntoArrayIfSingleParamsetPassed((Object[]) providerMethod.invoke(null)); 38fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 39fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 40fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin boolean containsDefaultParametersProvidingMethod(Class<?> sourceClass) { 41fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return findMethodInTestClassHierarchy(defaultMethodName(), sourceClass) != null; 42fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 43fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 44fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin private String defaultMethodName() { 45fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return "parametersFor" + frameworkMethod.getName().substring(0, 1).toUpperCase() 46fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin + this.frameworkMethod.getName().substring(1); 47fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 48fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 49fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin private Object[] invokeMethodWithParams(String methodName, Class<?> sourceClass) { 50fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin Method providerMethod = findMethodInTestClassHierarchy(methodName, sourceClass); 51fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin if (providerMethod == null) { 52fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin throw new RuntimeException("Could not find method: " + methodName + " so no params were used."); 53fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 54fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 55fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return invokeParamsProvidingMethod(providerMethod, sourceClass); 56fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 57fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 58fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin @SuppressWarnings("unchecked") 59fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin private Object[] invokeParamsProvidingMethod(Method provideMethod, Class<?> sourceClass) { 60fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin try { 61fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin Object testObject = sourceClass.newInstance(); 62fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin provideMethod.setAccessible(true); 63fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin Object result = provideMethod.invoke(testObject); 64fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 65fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin if (Object[].class.isAssignableFrom(result.getClass())) { 66fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin Object[] params = (Object[]) result; 67fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return encapsulateParamsIntoArrayIfSingleParamsetPassed(params); 68fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 69fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 70fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin if (Iterable.class.isAssignableFrom(result.getClass())) { 71fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin try { 72fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin ArrayList<Object[]> res = new ArrayList<Object[]>(); 73fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin for (Object[] paramSet : (Iterable<Object[]>) result) 74fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin res.add(paramSet); 75fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return res.toArray(); 76fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } catch (ClassCastException e1) { 77fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin // Iterable with consecutive paramsets, each of one param 78fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin ArrayList<Object> res = new ArrayList<Object>(); 79fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin for (Object param : (Iterable<?>) result) 80fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin res.add(new Object[]{param}); 81fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return res.toArray(); 82fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 83fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 84fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 85fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin if (Iterator.class.isAssignableFrom(result.getClass())) { 86fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin Object iteratedElement = null; 87fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin try { 88fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin ArrayList<Object[]> res = new ArrayList<Object[]>(); 89fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin Iterator<Object[]> iterator = (Iterator<Object[]>) result; 90fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin while (iterator.hasNext()) { 91fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin iteratedElement = iterator.next(); 92fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin // ClassCastException will occur in the following line 93fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin // if the iterator is actually Iterator<Object> in Java 7 94fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin res.add((Object[]) iteratedElement); 95fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 96fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return res.toArray(); 97fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } catch (ClassCastException e1) { 98fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin // Iterator with consecutive paramsets, each of one param 99fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin ArrayList<Object> res = new ArrayList<Object>(); 100fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin Iterator<?> iterator = (Iterator<?>) result; 101fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin // The first element is already stored in iteratedElement 102fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin res.add(iteratedElement); 103fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin while (iterator.hasNext()) { 104fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin res.add(new Object[]{iterator.next()}); 105fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 106fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return res.toArray(); 107fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 108fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 109fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 110fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin throw new ClassCastException(); 111fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 112fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } catch (ClassCastException e) { 113fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin throw new RuntimeException("The return type of: " + provideMethod.getName() + " defined in class " + 114fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin sourceClass + " is not Object[][] nor Iterable<Object[]>. Fix it!", e); 115fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } catch (Exception e) { 116fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin throw new RuntimeException("Could not invoke method: " + provideMethod.getName() + " defined in class " + 117fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin sourceClass + " so no params were used.", e); 118fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 119fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 120fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 121fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin private Method findMethodInTestClassHierarchy(String methodName, Class<?> sourceClass) { 122fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin Class<?> declaringClass = sourceClass; 123fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin while (declaringClass.getSuperclass() != null) { 124fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin try { 125fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return declaringClass.getDeclaredMethod(methodName); 126fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } catch (Exception ignore) { 127fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 128fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin declaringClass = declaringClass.getSuperclass(); 129fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 130fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return null; 131fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 132fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 133fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin private Object[] encapsulateParamsIntoArrayIfSingleParamsetPassed(Object[] params) { 134fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin if (frameworkMethod.getMethod().getParameterTypes().length != params.length) { 135fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return params; 136fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 137fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 138fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin if (params.length == 0) { 139fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return params; 140fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 141fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 142fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin Object param = params[0]; 143fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin if (param == null || !param.getClass().isArray()) { 144fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return new Object[]{params}; 145fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 146fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 147fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin return params; 148fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin } 149fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin 150fd1f9491413fcdbfae3cbd43651db31fdabce41aPaul Duffin} 151