File tree Expand file tree Collapse file tree 3 files changed +81
-0
lines changed
core/shared/src/main/scala/weaver
framework-cats/shared/src/test/scala Expand file tree Collapse file tree 3 files changed +81
-0
lines changed Original file line number Diff line number Diff line change @@ -112,6 +112,18 @@ val list = List(1)
112112 } yield expect(y.contains(x))
113113 ```
114114
115+ - Similarly ` matchOrFailFast ` can be used assert an expression matches a given pattern, and return it if so
116+
117+ ``` scala mdoc:compile-only
118+ for {
119+ b <- IO (Some (4 ))
120+ s <- matchOrFailFast[IO ](b) {
121+ case Some (v) => v.toString
122+ }
123+ c <- IO (" 4" )
124+ } yield expect.eql(s, c)
125+ ```
126+
115127## Example suite
116128
117129``` scala mdoc
@@ -221,6 +233,19 @@ object ExpectationsSuite extends SimpleIOSuite {
221233 _ <- expect(clue(h).isEmpty).failFast
222234 } yield success
223235 }
236+
237+ test(" Failing fast match" ) {
238+ for {
239+ h <- IO .pure(Some (4 ))
240+ x <- matchOrFailFast[IO ](h) {
241+ case Some (v) => v
242+ }
243+ g <- IO .pure(Option .empty[Int ])
244+ y <- matchOrFailFast[IO ](g) {
245+ case Some (v) => v
246+ }
247+ } yield expect.eql(x, y)
248+ }
224249}
225250```
226251
Original file line number Diff line number Diff line change @@ -157,6 +157,24 @@ object Expectations {
157157 ))
158158 }
159159
160+ final private [weaver] class PartiallyAppliedMatchOrFailFast [F [_]](
161+ val dummy : Boolean = true )
162+ extends AnyVal {
163+ def apply [A , B ](x : A )(
164+ pf : PartialFunction [A , B ]
165+ )(
166+ implicit loc : SourceLocation ,
167+ F : Sync [F ],
168+ A : Show [A ] = Show .fromToString[A ]): F [B ] =
169+ pf.lift(x).fold[F [B ]] {
170+ Sync [F ].raiseError(
171+ new ExpectationFailed (
172+ " Pattern did not match, got: " + x.show,
173+ NonEmptyList .of(loc)
174+ ))
175+ }(Sync [F ].pure)
176+ }
177+
160178 trait Helpers extends weaver.internals.ClueHelpers {
161179
162180 /**
@@ -231,6 +249,25 @@ object Expectations {
231249 else
232250 failure(" Pattern did not match, got: " + x.show)
233251
252+ /**
253+ * Checks that a given expression matches a certain pattern, returning the
254+ * result of the partial function <code>pf</code> if so, fails otherwise.
255+ *
256+ * @example
257+ * {{{
258+ * val x = Some(4)
259+ * val otherSideEffect = IO.pure("4")
260+ * for {
261+ * b <- matchOrFailFast[IO](x) {
262+ * case Some(v) => v.toString
263+ * }
264+ * c <- otherSideEffect
265+ * } yield expect.eql(b, c)
266+ * }}}
267+ */
268+ def matchOrFailFast [F [_]]: PartiallyAppliedMatchOrFailFast [F ] =
269+ new PartiallyAppliedMatchOrFailFast [F ]
270+
234271 /**
235272 * Alias for `forEach`
236273 */
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ package weaver
22package framework
33package test
44
5+ import cats .effect .IO
56import cats .kernel .Eq
67
78object ExpectationsTests extends SimpleIOSuite {
@@ -61,6 +62,24 @@ object ExpectationsTests extends SimpleIOSuite {
6162 })
6263 }
6364
65+ test(" matchOrFailFast (success)" ) {
66+ matchOrFailFast[IO ](Some (4 )) {
67+ case Some (v) => v
68+ }.as(success)
69+ }
70+
71+ test(" matchOrFailFast (failure)" ) {
72+ matchOrFailFast[IO ](Option .empty[Int ]) {
73+ case Some (v) => v
74+ }
75+ .attempt
76+ .map { either =>
77+ matches(either) { case Left (_ : ExpectationFailed ) =>
78+ success
79+ }
80+ }
81+ }
82+
6483 pureTest(" expect.eql respects cats.kernel.Eq" ) {
6584 implicit val eqInt : Eq [Int ] = Eq .allEqual
6685 expect.eql(0 , 1 )
You can’t perform that action at this time.
0 commit comments