|
28 | 28 | import java.util.Map; |
29 | 29 | import java.util.Objects; |
30 | 30 | import java.util.function.Function; |
| 31 | +import java.util.stream.Stream; |
31 | 32 |
|
32 | 33 | import org.spockframework.lang.ISpecificationContext; |
33 | 34 | import org.spockframework.lang.Wildcard; |
@@ -424,6 +425,60 @@ public <U> void verifyEach( |
424 | 425 | verifyEach(Arrays.asList(things), namer, closure); |
425 | 426 | } |
426 | 427 |
|
| 428 | + /** |
| 429 | + * Performs assertions on each element of a stream, collecting up failures instead of stopping at first. |
| 430 | + * <p> |
| 431 | + * Exception messages will contain a toString() of the element to identify it. |
| 432 | + * <p> |
| 433 | + * The closure can either use one or two parameters. |
| 434 | + * The first parameter will always be the element. |
| 435 | + * The second optional parameter will be the iteration index of the element. |
| 436 | + * |
| 437 | + * @param things the stream to inspect |
| 438 | + * @param closure a code block containing top-level conditions |
| 439 | + * @param <U> type of elements in things |
| 440 | + * @since 2.5 |
| 441 | + */ |
| 442 | + @Beta |
| 443 | + public <U> void verifyEach( |
| 444 | + Stream<U> things, |
| 445 | + @ClosureParams(value = FromString.class, options = {"U", "U, int"}) |
| 446 | + @DelegatesTo(type = "U", strategy = Closure.DELEGATE_FIRST) |
| 447 | + Closure<?> closure |
| 448 | + ) { |
| 449 | + verifyEach(things, Objects::toString, closure); |
| 450 | + } |
| 451 | + |
| 452 | + /** |
| 453 | + * Performs assertions on each element of a stream, collecting up failures instead of stopping at first. |
| 454 | + * <p> |
| 455 | + * Exception messages will contain the result of calling the namer for an element to identify it. |
| 456 | + * <p> |
| 457 | + * The closure can either use one or two parameters. |
| 458 | + * The first parameter will always be the element. |
| 459 | + * The second optional parameter will be the iteration index of the element. |
| 460 | + * |
| 461 | + * @param things the stream to inspect |
| 462 | + * @param namer the namer function to use when rendering the exception |
| 463 | + * @param closure a code block containing top-level conditions |
| 464 | + * @param <U> type of elements in things |
| 465 | + * @since 2.5 |
| 466 | + */ |
| 467 | + @Beta |
| 468 | + public <U> void verifyEach( |
| 469 | + Stream<U> things, |
| 470 | + Function<? super U, ?> namer, |
| 471 | + @ClosureParams(value = FromString.class, options = {"U", "U, int"}) |
| 472 | + @DelegatesTo(type = "U", strategy = Closure.DELEGATE_FIRST) |
| 473 | + Closure<?> closure |
| 474 | + ) { |
| 475 | + if (things == null) { |
| 476 | + throw new SpockAssertionError("Target of 'verifyEach' block must not be null"); |
| 477 | + } |
| 478 | + // a Stream is single-use, so adapt it to an Iterable that iterates it exactly once |
| 479 | + verifyEach((Iterable<U>) things::iterator, namer, closure); |
| 480 | + } |
| 481 | + |
427 | 482 | /** |
428 | 483 | * Performs assertions on each entry of a map, collecting up failures instead of stopping at first. |
429 | 484 | * <p> |
|
0 commit comments