20
20
import java .lang .reflect .Method ;
21
21
import java .util .ArrayList ;
22
22
import java .util .List ;
23
+ import java .util .Optional ;
23
24
import java .util .Set ;
24
25
import java .util .function .Function ;
25
26
import java .util .stream .Collectors ;
27
+ import java .util .stream .Stream ;
26
28
27
29
public class SnapshotMatcher {
28
30
@@ -80,19 +82,15 @@ public static void validateSnapshots() {
80
82
public static Snapshot expect (Object firstObject , Object ... others ) {
81
83
82
84
if (clazz == null ) {
83
- throw new SnapshotMatchException ("SnapshotTester not yet started! Start it on @BeforeClass with SnapshotMatcher.start()" );
84
- }
85
- try {
86
- Object [] objects = mergeObjects (firstObject , others );
87
- StackTraceElement stackElement = findStackElement ();
88
- Method method = getMethod (stackElement , clazz );
89
- Snapshot snapshot = new Snapshot (snapshotFile , clazz , method , jsonFunction , objects );
90
- validateExpectCall (snapshot );
91
- calledSnapshots .add (snapshot );
92
- return snapshot ;
93
- } catch (ClassNotFoundException e ) {
94
- throw new SnapshotMatchException (e .getMessage ());
85
+ throw new SnapshotMatchException ("SnapshotTester not yet started! Start it on @BeforeClass/@BeforeAll with SnapshotMatcher.start()" );
95
86
}
87
+ Object [] objects = mergeObjects (firstObject , others );
88
+ StackTraceElement stackElement = findStackElement ();
89
+ Method method = getMethod (clazz , stackElement .getMethodName ());
90
+ Snapshot snapshot = new Snapshot (snapshotFile , clazz , method , jsonFunction , objects );
91
+ validateExpectCall (snapshot );
92
+ calledSnapshots .add (snapshot );
93
+ return snapshot ;
96
94
}
97
95
98
96
static Function <Object , String > defaultJsonFunction () {
@@ -144,46 +142,39 @@ private static void validateExpectCall(Snapshot snapshot) {
144
142
}
145
143
}
146
144
147
- private static Method getMethod (StackTraceElement testClass , Class clazz ) {
148
- Method method ;
145
+ private static Method getMethod (Class <?> clazz , String methodName ) {
149
146
try {
150
- method = clazz .getMethod ( testClass . getMethodName () );
147
+ return clazz .getDeclaredMethod ( methodName );
151
148
} catch (NoSuchMethodException e ) {
152
- throw new SnapshotMatchException ("Please annotate your test method with @Test and make it without any parameters!" );
149
+ return Optional .ofNullable (clazz .getSuperclass ())
150
+ .map (superclass -> getMethod (superclass , methodName ))
151
+ .orElseThrow (() -> new SnapshotMatchException ("Could not find method " + methodName + " on class " + clazz
152
+ + "\n Please annotate your test method with @Test and make it without any parameters!" ));
153
153
}
154
- return method ;
155
154
}
156
155
157
- private static StackTraceElement findStackElement () throws ClassNotFoundException {
156
+ private static StackTraceElement findStackElement () {
158
157
StackTraceElement [] stackTraceElements = Thread .currentThread ().getStackTrace ();
159
-
160
- int i = 1 ; // Start after stackTrace
161
- while (i < stackTraceElements .length &&
162
- SnapshotMatcher .class .equals (Class .forName (stackTraceElements [i ].getClassName ()))) { //TODO
163
- i ++;
158
+ int elementsToSkip = 1 ; // Start after stackTrace
159
+ while (SnapshotMatcher .class .getName ().equals (stackTraceElements [elementsToSkip ].getClassName ())) {
160
+ elementsToSkip ++;
164
161
}
165
162
166
- for (int j = i ; j < stackTraceElements .length ; j ++) {
167
-
168
- try {
169
- Class clazz = Class .forName (stackTraceElements [j ].getClassName ());
170
- Method method = clazz .getMethod (stackTraceElements [j ].getMethodName ());
171
-
172
- // Navigate into stack until Test class/method level
173
- if (method .isAnnotationPresent (Test .class ) || method .isAnnotationPresent (BeforeClass .class ) ||
174
- method .isAnnotationPresent (org .junit .jupiter .api .Test .class ) || method .isAnnotationPresent (BeforeAll .class )) {
175
- i = j ;
176
- break ;
177
- }
178
- }
179
- catch (NoSuchMethodException ignored ) {
180
-
181
- }
182
- }
163
+ return Stream .of (stackTraceElements )
164
+ .skip (elementsToSkip )
165
+ .filter (stackTraceElement -> hasTestAnnotation (getMethod (getClass (stackTraceElement .getClassName ()), stackTraceElement .getMethodName ())))
166
+ .findFirst ()
167
+ .orElseThrow (() -> new SnapshotMatchException ("Could not locate a method with one of supported test annotations" ));
168
+ }
183
169
184
- return stackTraceElements [i ];
170
+ private static boolean hasTestAnnotation (Method method ) {
171
+ return method .isAnnotationPresent (Test .class )
172
+ || method .isAnnotationPresent (BeforeClass .class )
173
+ || method .isAnnotationPresent (org .junit .jupiter .api .Test .class )
174
+ || method .isAnnotationPresent (BeforeAll .class );
185
175
}
186
176
177
+
187
178
private static Object [] mergeObjects (Object firstObject , Object [] others ) {
188
179
Object [] objects = new Object [1 ];
189
180
objects [0 ] = firstObject ;
@@ -192,4 +183,12 @@ private static Object[] mergeObjects(Object firstObject, Object[] others) {
192
183
}
193
184
return objects ;
194
185
}
186
+
187
+ private static Class <?> getClass (String className ) {
188
+ try {
189
+ return Class .forName (className );
190
+ } catch (ClassNotFoundException e ) {
191
+ throw new IllegalArgumentException (e );
192
+ }
193
+ }
195
194
}
0 commit comments