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