1 package org.opentrafficsim.road.gtu.perception;
2
3 import static org.junit.Assert.fail;
4
5 import java.lang.reflect.Field;
6 import java.lang.reflect.Method;
7 import java.lang.reflect.Modifier;
8 import java.util.ArrayList;
9 import java.util.Collection;
10 import java.util.HashSet;
11 import java.util.List;
12 import java.util.Set;
13
14 import org.junit.Test;
15 import org.opentrafficsim.base.TimeStampedObject;
16 import org.opentrafficsim.core.gtu.perception.AbstractPerceptionCategory;
17 import org.opentrafficsim.road.ClassList;
18
19
20
21
22
23
24
25
26
27
28
29
30 public class VerifyPerceptionCategoryMethods
31 {
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 @Test
65 public final void perceptionCategoryTest()
66 {
67 Collection<Class<?>> classList = ClassList.classList("org.opentrafficsim", true);
68 for (Class<?> c : classList)
69 {
70 if (AbstractPerceptionCategory.class.isAssignableFrom(c) && !Modifier.isAbstract(c.getModifiers()))
71 {
72 Set<String> fieldsDone = new HashSet<>();
73 List<String> fieldNames = new ArrayList<>();
74 List<String> methodNames = new ArrayList<>();
75 List<Class<?>> methodReturnTypes = new ArrayList<>();
76 for (Field field : c.getDeclaredFields())
77 {
78 fieldNames.add(field.getName());
79 }
80 for (Method method : c.getMethods())
81 {
82 methodNames.add(method.getName());
83 methodReturnTypes.add(method.getReturnType());
84 }
85 for (Method method : c.getDeclaredMethods())
86 {
87 if (Modifier.isPrivate(method.getModifiers()))
88 {
89 continue;
90 }
91 String name = method.getName();
92 String field = null;
93 boolean isBoolean = false;
94 if (name.startsWith("is") && name.endsWith("TimeStamped"))
95 {
96 field = name.substring(2, name.length() - 11);
97 isBoolean = true;
98 }
99 else if (name.startsWith("is"))
100 {
101 field = name.substring(2);
102 isBoolean = true;
103 }
104 else if (name.startsWith("getTimeStamped"))
105 {
106 field = name.substring(14);
107 }
108 else if (name.startsWith("get"))
109 {
110 field = name.substring(3);
111 }
112
113 if (field != null)
114 {
115 String fieldDown = field.substring(0, 1).toLowerCase() + field.substring(1);
116 if (!fieldsDone.contains(fieldDown))
117 {
118 String fieldUp = field.substring(0, 1).toUpperCase() + field.substring(1);
119 if (isBoolean)
120 {
121 testGetter(c, fieldNames, methodNames, methodReturnTypes, fieldDown, "is" + fieldUp,
122 "is" + fieldUp + "TimeStamped", "update" + fieldUp);
123 }
124 else
125 {
126 testGetter(c, fieldNames, methodNames, methodReturnTypes, fieldDown, "get" + fieldUp,
127 "getTimeStamped" + fieldUp, "update" + fieldUp);
128 }
129 fieldsDone.add(fieldDown);
130 }
131 }
132
133 }
134 }
135 }
136 }
137
138
139
140
141
142
143
144
145
146
147
148 @SuppressWarnings("checkstyle:parameternumber")
149 private void testGetter(final Class<?> c, final List<String> fieldNames, final List<String> methodNames,
150 final List<Class<?>> methodReturnTypes, final String field, final String getter, final String timeStampedGetter,
151 final String updater)
152 {
153 boolean fieldFound = false;
154 int i = 0;
155 while (!fieldFound && i < fieldNames.size())
156 {
157 fieldFound = fieldNames.get(i).startsWith(field);
158 i++;
159 }
160 if (!fieldFound)
161 {
162
163 Field[] fields = c.getDeclaredFields();
164 i = 0;
165 while (!fieldFound && i < fields.length)
166 {
167 if (AbstractPerceptionCategory.class.isAssignableFrom(fields[i].getType()))
168 {
169
170 Field[] wrappedFields = fields[i].getType().getDeclaredFields();
171 int j = 0;
172 while (!fieldFound && j < wrappedFields.length)
173 {
174 fieldFound = wrappedFields[j].getName().startsWith(field);
175 j++;
176 }
177 }
178 i++;
179 }
180 }
181 if (!fieldFound)
182 {
183
184 fail("Class " + c + " does not have a field '" + field + "*', nor wraps a perception category that does.");
185 }
186 if (methodNames.contains(getter))
187 {
188 if (getter.startsWith("is") && !methodReturnTypes.get(methodNames.indexOf(getter)).equals(boolean.class))
189 {
190 fail("Class " + c + "'s method '" + getter + "' does not return a boolean.");
191 }
192 else if (methodReturnTypes.get(methodNames.indexOf(getter)).equals(void.class))
193 {
194 fail("Class " + c + "'s method '" + getter + "' does not return anything.");
195 }
196
197 }
198 else
199 {
200 fail("Class " + c + " does not contain a method '" + getter + "'.");
201 }
202 if (methodNames.contains(timeStampedGetter))
203 {
204 if (!methodReturnTypes.get(methodNames.indexOf(timeStampedGetter)).equals(TimeStampedObject.class))
205 {
206 fail("Class " + c + "'s method '" + timeStampedGetter + "' does not return a TimeStampedObject.");
207 }
208
209
210 }
211 else
212 {
213
214
215
216 }
217 if (!methodNames.contains(updater))
218 {
219
220 System.err.print("Class " + c + " does not contain a method '" + updater + "'.");
221
222 }
223 }
224
225
226
227
228 public static void main(final String[] args)
229 {
230 VerifyPerceptionCategoryMethods t = new VerifyPerceptionCategoryMethods();
231 t.perceptionCategoryTest();
232 }
233
234 }