1b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot/** 2b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * 3b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 4b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotpackage org.junit.experimental.theories.internal; 5b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 6b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.lang.reflect.Array; 7b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.lang.reflect.Field; 8b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.lang.reflect.Modifier; 9b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.util.ArrayList; 10b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.util.List; 11b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 12b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.experimental.theories.DataPoint; 13b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.experimental.theories.DataPoints; 14b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.experimental.theories.ParameterSignature; 15b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.experimental.theories.ParameterSupplier; 16b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.experimental.theories.PotentialAssignment; 17b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runners.model.FrameworkMethod; 18b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runners.model.TestClass; 19b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 20b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot/** 21b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Supplies Theory parameters based on all public members of the target class. 22b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 23b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotpublic class AllMembersSupplier extends ParameterSupplier { 24b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot static class MethodParameterValue extends PotentialAssignment { 25b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private final FrameworkMethod fMethod; 26b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 27b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private MethodParameterValue(FrameworkMethod dataPointMethod) { 28b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot fMethod= dataPointMethod; 29b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 30b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 31b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot @Override 32b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public Object getValue() throws CouldNotGenerateValueException { 33b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot try { 34b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return fMethod.invokeExplosively(null); 35b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (IllegalArgumentException e) { 36b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot throw new RuntimeException( 37b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot "unexpected: argument length is checked"); 38b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (IllegalAccessException e) { 39b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot throw new RuntimeException( 40b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot "unexpected: getMethods returned an inaccessible method"); 41b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (Throwable e) { 42b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot throw new CouldNotGenerateValueException(); 43b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // do nothing, just look for more values 44b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 45b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 46b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 47b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot @Override 48b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public String getDescription() throws CouldNotGenerateValueException { 49b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return fMethod.getName(); 50b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 51b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 52b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 53b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private final TestClass fClass; 54b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 55b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 56b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Constructs a new supplier for {@code type} 57b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 58b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public AllMembersSupplier(TestClass type) { 59b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot fClass= type; 60b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 61b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 62b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot @Override 63b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public List<PotentialAssignment> getValueSources(ParameterSignature sig) { 64b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot List<PotentialAssignment> list= new ArrayList<PotentialAssignment>(); 65b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 66b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot addFields(sig, list); 67b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot addSinglePointMethods(sig, list); 68b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot addMultiPointMethods(list); 69b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 70b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return list; 71b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 72b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 73b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private void addMultiPointMethods(List<PotentialAssignment> list) { 74b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot for (FrameworkMethod dataPointsMethod : fClass 75b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot .getAnnotatedMethods(DataPoints.class)) 76b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot try { 77b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot addArrayValues(dataPointsMethod.getName(), list, dataPointsMethod.invokeExplosively(null)); 78b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (Throwable e) { 79b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // ignore and move on 80b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 81b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 82b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 83b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot @SuppressWarnings("deprecation") 84b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private void addSinglePointMethods(ParameterSignature sig, 85b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot List<PotentialAssignment> list) { 86b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot for (FrameworkMethod dataPointMethod : fClass 87b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot .getAnnotatedMethods(DataPoint.class)) { 88b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot Class<?> type= sig.getType(); 89b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot if ((dataPointMethod.producesType(type))) 90b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot list.add(new MethodParameterValue(dataPointMethod)); 91b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 92b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 93b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 94b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private void addFields(ParameterSignature sig, 95b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot List<PotentialAssignment> list) { 96b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot for (final Field field : fClass.getJavaClass().getFields()) { 97b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot if (Modifier.isStatic(field.getModifiers())) { 98b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot Class<?> type= field.getType(); 99b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot if (sig.canAcceptArrayType(type) 100b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot && field.getAnnotation(DataPoints.class) != null) { 101b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot addArrayValues(field.getName(), list, getStaticFieldValue(field)); 102b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } else if (sig.canAcceptType(type) 103b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot && field.getAnnotation(DataPoint.class) != null) { 104b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot list.add(PotentialAssignment 105b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot .forValue(field.getName(), getStaticFieldValue(field))); 106b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 107b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 108b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 109b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 110b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 111b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private void addArrayValues(String name, List<PotentialAssignment> list, Object array) { 112b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot for (int i= 0; i < Array.getLength(array); i++) 113b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot list.add(PotentialAssignment.forValue(name + "[" + i + "]", Array.get(array, i))); 114b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 115b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 116b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private Object getStaticFieldValue(final Field field) { 117b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot try { 118b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return field.get(null); 119b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (IllegalArgumentException e) { 120b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot throw new RuntimeException( 121b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot "unexpected: field from getClass doesn't exist on object"); 122b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (IllegalAccessException e) { 123b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot throw new RuntimeException( 124b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot "unexpected: getFields returned an inaccessible field"); 125b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 126b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 127b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot}