1 package org.djunits;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4 import static org.junit.jupiter.api.Assertions.fail;
5
6 import java.io.Serializable;
7 import java.lang.reflect.Method;
8 import java.lang.reflect.Modifier;
9 import java.util.Collection;
10
11 import org.junit.jupiter.api.Test;
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 public class VerifyRequiredMethods
27 {
28
29
30
31 private static String packageName = "org.djunits";
32
33
34
35
36
37 public final void toStringTest()
38 {
39 int failures = 0;
40 Collection<Class<?>> classList = ClassList.classList(packageName, true);
41 for (Class<?> c : classList)
42 {
43 if (Exception.class.isAssignableFrom(c))
44 {
45 continue;
46 }
47 if (ClassList.isAnonymousInnerClass(c))
48 {
49 continue;
50 }
51 Method toStringMethod = null;
52 boolean isAbstract = false;
53 for (String modifierString : Modifier.toString(c.getModifiers()).split(" "))
54 {
55 if (modifierString.equals("abstract"))
56 {
57 isAbstract = true;
58 break;
59 }
60 }
61 for (Method m : c.getDeclaredMethods())
62 {
63 if (m.getName().equals("toString") && m.getParameterCount() == 0)
64 {
65 toStringMethod = m;
66 }
67 }
68 if (null == toStringMethod)
69 {
70
71 try
72 {
73 toStringMethod = c.getMethod("toString");
74 }
75 catch (NoSuchMethodException | SecurityException exception)
76 {
77 exception.printStackTrace();
78 fail("Cannot happen: getMethod(\"toString\") should never fail - there is one in Object");
79 }
80 boolean isFinal = false;
81 for (String modifierString : Modifier.toString(toStringMethod.getModifiers()).split(" "))
82 {
83 if ("final".equals(modifierString))
84 {
85 isFinal = true;
86 break;
87 }
88 }
89 if (isFinal)
90 {
91
92
93 }
94 else if (!ClassList.hasNonStaticFields(c))
95 {
96
97
98 }
99 else if (isAbstract)
100 {
101
102
103 }
104 else if (c.isEnum())
105 {
106
107
108 }
109 else if (toStringMethod.getDeclaringClass().getPackage().getName().startsWith(packageName))
110 {
111
112
113
114 }
115 else
116 {
117 System.err.println("Class " + c.getName() + " does not (but should) override toString");
118 failures++;
119 }
120 }
121 }
122 assertEquals(0, failures, "Failures to implement toString");
123 }
124
125
126
127
128
129 @SuppressWarnings({"checkstyle:methodlength", "checkstyle:emptyblock"})
130 public final void serializableTest()
131 {
132 int failures = 0;
133 Collection<Class<?>> classList = ClassList.classList(packageName, true);
134 for (Class<?> c : classList)
135 {
136 if (Serializable.class.isAssignableFrom(c))
137 {
138 if (c.isEnum())
139 {
140
141 }
142 else if (!ClassList.hasNonStaticFields(c))
143 {
144 System.err.println("Class " + c.getName()
145 + " does not contain non-static fields and should NOT implement Serializable");
146 failures++;
147 }
148 else if (Thread.class.isAssignableFrom(c))
149 {
150 System.err.println("Class " + c.getName() + " is a thread and should NOT implement Serializable");
151 failures++;
152 }
153 else if (ClassList.isAnonymousInnerClass(c))
154 {
155 System.err.println(
156 "Class " + c.getName() + " is an anonymous inner class and should NOT implement Serializable");
157 failures++;
158 }
159 else if (Exception.class.isAssignableFrom(c))
160 {
161
162 }
163 else
164 {
165
166 }
167 }
168 else
169 {
170 if (c.isEnum())
171 {
172 System.err
173 .println("Class " + c.getName() + " is an enum and should (by inheritence) implement Serializable");
174 failures++;
175 }
176 else if (!ClassList.hasNonStaticFields(c))
177 {
178
179
180 }
181 else if (Thread.class.isAssignableFrom(c))
182 {
183
184
185 }
186 else if (ClassList.isAnonymousInnerClass(c))
187 {
188
189
190 }
191 else if (Exception.class.isAssignableFrom(c))
192 {
193 System.err.println(
194 "Class " + c.getName() + " is an Exception and should (but does NOT) implement Serializable");
195 failures++;
196 }
197 else
198 {
199 System.err.println("Class " + c.getName() + " should (but does NOT) implement Serializable");
200 failures++;
201 }
202 }
203 }
204 assertEquals(0, failures, "Failures to implement serializable");
205 }
206
207
208
209
210 @Test
211 @SuppressWarnings("checkstyle:emptyblock")
212 public final void equalsAndHashCodeTest()
213 {
214 int failures = 0;
215 Collection<Class<?>> classList = ClassList.classList(packageName, true);
216 for (Class<?> c : classList)
217 {
218 if (Exception.class.isAssignableFrom(c))
219 {
220 continue;
221 }
222 Method equalsMethod = null;
223 Method hashCodeMethod = null;
224 for (Method m : c.getDeclaredMethods())
225 {
226 if (m.getName().equals("equals"))
227 {
228 equalsMethod = m;
229 }
230 else if (m.getName().equals("hashCode"))
231 {
232 hashCodeMethod = m;
233 }
234 }
235 if (null == equalsMethod)
236 {
237 if (null == hashCodeMethod)
238 {
239
240 }
241 else
242 {
243 System.err.println("Class " + c.getName() + " implements hashCode, but not equals");
244 failures++;
245 }
246 }
247 else if (null == hashCodeMethod)
248 {
249 System.err.println("Class " + c.getName() + " implements equals but NOT hashCode");
250 failures++;
251 }
252 else
253 {
254
255 }
256 }
257 assertEquals(0, failures, "Failures to implement both hashCode and equals");
258 }
259
260 }