16
16
package org .springframework .modulith .test ;
17
17
18
18
import java .time .Duration ;
19
- import java .util .Arrays ;
20
19
import java .util .concurrent .Callable ;
21
20
import java .util .function .BiConsumer ;
22
21
import java .util .function .BiFunction ;
55
54
@ API (status = Status .EXPERIMENTAL )
56
55
public class Scenario {
57
56
57
+ private static final Predicate <Object > DEFAULT_ACCEPTANCE = it -> {
58
+
59
+ if (it instanceof Optional <?> o ) {
60
+ return o .isPresent ();
61
+ }
62
+
63
+ if (it instanceof Boolean b ) {
64
+ return b ;
65
+ }
66
+
67
+ return it != null ;
68
+ };
69
+
58
70
private final TransactionOperations transactionOperations ;
59
71
private final ApplicationEventPublisher publisher ;
60
72
private final AssertablePublishedEvents events ;
@@ -86,9 +98,9 @@ public class Scenario {
86
98
* @param event must not be {@literal null}.
87
99
* @return will never be {@literal null}.
88
100
*/
89
- public When <Void > publish (Object ... event ) {
101
+ public When <Void > publish (Object event ) {
90
102
return stimulate ((tx , e ) -> {
91
- tx .executeWithoutResult (__ -> Arrays . stream (event ). forEach ( e :: publishEvent ));
103
+ tx .executeWithoutResult (__ -> e . publishEvent (event ));
92
104
});
93
105
}
94
106
@@ -99,11 +111,10 @@ public When<Void> publish(Object... event) {
99
111
* @param events must not be {@literal null}.
100
112
* @return will never be {@literal null}.
101
113
*/
102
- @ SuppressWarnings ("unchecked" )
103
- public When <Void > publish (Supplier <Object >... events ) {
114
+ public When <Void > publish (Supplier <Object > event ) {
104
115
105
116
return stimulate ((tx , e ) -> {
106
- tx .executeWithoutResult (__ -> Arrays . stream ( events ). map ( Supplier :: get ). forEach ( e :: publishEvent ));
117
+ tx .executeWithoutResult (__ -> e . publishEvent ( event . get () ));
107
118
});
108
119
}
109
120
@@ -120,7 +131,7 @@ public When<Void> stimulate(Runnable runnable) {
120
131
return stimulate (() -> {
121
132
runnable .run ();
122
133
return null ;
123
- }, __ -> {} );
134
+ });
124
135
}
125
136
126
137
/**
@@ -134,24 +145,7 @@ public When<Void> stimulate(Runnable runnable) {
134
145
* @see EventResult#toArriveAndVerify(Consumer)
135
146
*/
136
147
public <S > When <S > stimulate (Supplier <S > supplier ) {
137
- return stimulate (supplier , __ -> {});
138
- }
139
-
140
- /**
141
- * Stimulates the system using the given {@link Supplier}, keeping the supplied value around for later verification
142
- * but also registers a cleanup callback to make sure potential state changes are rolled back for the test execution.
143
- *
144
- * @param <S> the type of the value returned by the stimulus.
145
- * @param supplier must not be {@literal null}.
146
- * @param cleanupCallback must not be {@literal null}.
147
- * @return will never be {@literal null}.
148
- */
149
- public <S > When <S > stimulate (Supplier <S > supplier , Consumer <S > cleanupCallback ) {
150
-
151
- Assert .notNull (supplier , "Supplier must not be null!" );
152
- Assert .notNull (cleanupCallback , "Cleanup callback must not be null!" );
153
-
154
- return stimulate ((tx ) -> tx .execute (status -> supplier .get ()), cleanupCallback );
148
+ return stimulate (__ -> supplier .get ());
155
149
}
156
150
157
151
/**
@@ -163,25 +157,9 @@ public <S> When<S> stimulate(Supplier<S> supplier, Consumer<S> cleanupCallback)
163
157
* @return will never be {@literal null}.
164
158
*/
165
159
public <S > When <S > stimulate (Function <TransactionOperations , S > function ) {
166
- return stimulate (function , __ -> {});
167
- }
168
-
169
- /**
170
- * Stimulates the system using the given function providing access to the {@link TransactionOperations} and keeping
171
- * the supplied value around for later verification but also registers a cleanup callback to make sure potential state
172
- * changes are rolled back for the test execution.
173
- *
174
- * @param <S> the type of the value returned by the stimulus.
175
- * @param function must not be {@literal null}.
176
- * @param cleanupCallback must not be {@literal null}.
177
- * @return will never be {@literal null}.
178
- */
179
- public <S > When <S > stimulate (Function <TransactionOperations , S > function , Consumer <S > cleanupCallback ) {
180
-
181
- Assert .notNull (function , "Function must not be null!" );
182
- Assert .notNull (cleanupCallback , "Cleanup callback must not be null!" );
183
-
184
- return stimulate ((tx , events ) -> function .apply (tx ), cleanupCallback );
160
+ return stimulate ((tx , __ ) -> {
161
+ return function .apply (tx );
162
+ });
185
163
}
186
164
187
165
/**
@@ -195,24 +173,10 @@ public When<Void> stimulate(BiConsumer<TransactionOperations, ApplicationEventPu
195
173
196
174
Assert .notNull (stimulus , "Stimulus must not be null!" );
197
175
198
- return stimulate (stimulus , () -> {});
199
- }
200
-
201
- /**
202
- * @param stimulus must not be {@literal null}.
203
- * @param cleanupCallback must not be {@literal null}.
204
- * @return will never be {@literal null}.
205
- */
206
- public When <Void > stimulate (BiConsumer <TransactionOperations , ApplicationEventPublisher > stimulus ,
207
- Runnable cleanupCallback ) {
208
-
209
- Assert .notNull (stimulus , "Stimulus must not be null!" );
210
- Assert .notNull (cleanupCallback , "Cleanup callback must not be null!" );
211
-
212
176
return stimulate ((tx , e ) -> {
213
177
stimulus .accept (tx , e );
214
178
return (Void ) null ;
215
- }, __ -> cleanupCallback . run () );
179
+ });
216
180
}
217
181
218
182
/**
@@ -227,26 +191,7 @@ public <S> When<S> stimulate(BiFunction<TransactionOperations, ApplicationEventP
227
191
228
192
Assert .notNull (stimulus , "Stimulus must not be null!" );
229
193
230
- return stimulate (stimulus , __ -> {});
231
- }
232
-
233
- /**
234
- * Stimulate the system using the given {@link TransactionOperations} and {@link ApplicationEventPublisher} (usually a
235
- * method on some application service or event publication is triggered), produce a result and a callback to clean up
236
- * after the verification has completed.
237
- *
238
- * @param <S> the type of the result.
239
- * @param stimulus must not be {@literal null}.
240
- * @param cleanupCallback must not be {@literal null}.
241
- * @return will never be {@literal null}.
242
- */
243
- public <S > When <S > stimulate (BiFunction <TransactionOperations , ApplicationEventPublisher , S > stimulus ,
244
- Consumer <S > cleanupCallback ) {
245
-
246
- Assert .notNull (stimulus , "Stimulus must not be null!" );
247
- Assert .notNull (cleanupCallback , "Cleanup callback must not be null!" );
248
-
249
- return new When <>(stimulus , cleanupCallback , Function .identity ());
194
+ return new When <>(stimulus , __ -> {}, Function .identity ());
250
195
}
251
196
252
197
public class When <T > {
@@ -267,6 +212,34 @@ public class When<T> {
267
212
this .customizer = customizer ;
268
213
}
269
214
215
+ /**
216
+ * Registers the given {@link Runnable} as cleanup callback to always run after completion of the {@link Scenario},
217
+ * no matter the outcome of its execution (error or success).
218
+ *
219
+ * @param runnable must not be {@literal null}.
220
+ * @return will never be {@literal null}.
221
+ */
222
+ public When <T > andCleanup (Runnable runnable ) {
223
+
224
+ Assert .notNull (runnable , "Cleanup callback must not be null!" );
225
+
226
+ return andCleanup (__ -> runnable .run ());
227
+ }
228
+
229
+ /**
230
+ * Registers the given {@link Consumer} as cleanup callback to always run after completion of the {@link Scenario},
231
+ * no matter the outcome of its execution (error or success).
232
+ *
233
+ * @param consumer must not be {@literal null}.
234
+ * @return will never be {@literal null}.
235
+ */
236
+ public When <T > andCleanup (Consumer <T > consumer ) {
237
+
238
+ Assert .notNull (consumer , "Cleanup callback must not be null!" );
239
+
240
+ return new When <>(stimulus , consumer , customizer );
241
+ }
242
+
270
243
// Customize
271
244
272
245
/**
@@ -319,7 +292,7 @@ public <E> EventResult<E> forEventOfType(Class<E> type) {
319
292
* @see #andWaitForStateChange(Supplier)
320
293
*/
321
294
public <S > StateChangeResult <S > forStateChange (Supplier <S > supplier ) {
322
- return andWaitForStateChange (supplier );
295
+ return forStateChange (supplier , DEFAULT_ACCEPTANCE );
323
296
}
324
297
325
298
/**
@@ -347,25 +320,23 @@ public <E> EventResult<E> andWaitForEventOfType(Class<E> type) {
347
320
}
348
321
349
322
/**
350
- * Expects a particular state change on the module to produce a result and uses the given {@link Predicate} to
351
- * determine whether the value is conclusive.
323
+ * Expects a particular state change on the module to produce a result. By default, a non-{@literal null} value
324
+ * would indicate success, except for {@link java.util.Optional}s, in which case we'd check for the presence of a
325
+ * value and {@code booleans}, for which we accept {@literal true} as conclusive signal. For more control about the
326
+ * result matching, use {@link #andWaitForStateChange(Supplier, Predicate)}.
352
327
*
353
328
* @param <S> the type of the result.
354
329
* @param supplier must not be {@literal null}.
355
330
* @return will never be {@literal null}.
356
331
* @see #forStateChange(Supplier)
357
332
*/
358
333
public <S > StateChangeResult <S > andWaitForStateChange (Supplier <S > supplier ) {
359
-
360
- Predicate <S > acceptanceCriteria = it -> it instanceof Optional <?> o ? o .isPresent () : it != null ;
361
-
362
- return andWaitForStateChange (supplier , acceptanceCriteria );
334
+ return andWaitForStateChange (supplier , DEFAULT_ACCEPTANCE );
363
335
}
364
336
365
337
/**
366
- * Expects a particular state change on the module to produce a result. By default, a non-{@literal null} value
367
- * would indicate success, except for {@link java.util.Optional}s, in which case we'd check for the presence of a
368
- * value. For more control about the result matching, use {@link #andWaitForStateChange(Supplier, Predicate)}
338
+ * Expects a particular state change on the module to produce a result and uses the given {@link Predicate} to
339
+ * determine whether the value is conclusive.
369
340
*
370
341
* @param <S> the type of the result for the state change
371
342
* @param supplier must not be {@literal null}.
0 commit comments