Skip to content

Commit

Permalink
API: Align handleValue API with Waypoint collectStatic
Browse files Browse the repository at this point in the history
  • Loading branch information
raquo committed Nov 16, 2024
1 parent dcff9ed commit 93e710f
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ object SplitMatchOneMacros {
handleValueApplyImpl('{ matchValueObservable }, '{ handleFn })
}

inline def apply[O1 >: O](inline handleFn: Signal[V] => O1): SplitMatchOneObservable[Self, I, O1] = deglate { (_, vSignal) => handleFn(vSignal) }
inline def apply[O1 >: O](inline handle: => O1): SplitMatchOneObservable[Self, I, O1] = deglate { (_, _) => handle }
}

extension [I, O](inline matchSplitObservable: SplitMatchOneObservable[Signal, I, O]) {
Expand Down Expand Up @@ -130,7 +130,7 @@ object SplitMatchOneMacros {
"Macro expansion failed, please use `splitMatchOne` instead of creating new SplitMatchOneObservable explicitly"
)
}

innerHandleCaseImpl(
observableExpr,
caseExprSeq,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import scala.quoted.Varargs
import com.raquo.airstream.split.MacrosUtilities.{CaseAny, HandlerAny, MatchTypeHandler, MatchValueHandler, innerObservableImpl}

object SplitMatchSeqMacros {

extension [Self[+_] <: Observable[_], I, K, CC[_]](inline observable: BaseObservable[Self, CC[I]]) {
inline def splitMatchSeq(
inline keyFn: Function1[I, K],
Expand Down Expand Up @@ -53,7 +53,7 @@ object SplitMatchSeqMacros {
handleValueApplyImpl('{ matchValueObservable }, '{ handleFn })
}

inline def apply[O1 >: O](inline handleFn: Signal[V] => O1): SplitMatchSeqObservable[Self, I, K, O1, CC] = deglate { (_, vSignal) => handleFn(vSignal) }
inline def apply[O1 >: O](inline handle: => O1): SplitMatchSeqObservable[Self, I, K, O1, CC] = deglate { (_, _) => handle }
}

private def handleCaseImpl[Self[+_] <: Observable[_]: Type, I: Type, K: Type, O: Type, O1 >: O: Type, CC[_]: Type, A: Type, B: Type](
Expand Down Expand Up @@ -416,7 +416,7 @@ object SplitMatchSeqMacros {
case None => report.errorAndAbort(
"Macro expansion failed, cannot find Splittable instance of " + MacrosUtilities.ShowType.nameOf[CC]
)
case Some(splittableExpr) => {
case Some(splittableExpr) => {
val caseExprSeq = caseExpr match {
case Varargs(caseExprSeq) => caseExprSeq
case _ => report.errorAndAbort(
Expand Down
36 changes: 6 additions & 30 deletions src/test/scala-3/com/raquo/airstream/split/SplitMatchOneSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,8 @@ class SplitMatchOneSpec extends UnitSpec {

Res("Baz")
}
.handleValue(Tar) { tarSignal =>
.handleValue(Tar) {
effects += Effect("init-child", s"Tar-${10}")
// @Note keep foreach or addObserver here – this is important.
// It tests that SplitSignal does not cause an infinite loop trying to evaluate its initialValue.
tarSignal.foreach { _ =>
effects += Effect("update-child", s"Tar-${10}")
}(owner)

Res("Tar")
}
.toSignal
Expand Down Expand Up @@ -139,7 +133,6 @@ class SplitMatchOneSpec extends UnitSpec {

effects shouldBe mutable.Buffer(
Effect("init-child", "Tar-10"),
Effect("update-child", "Tar-10"),
Effect("result", "Res(Tar)")
)

Expand All @@ -148,8 +141,7 @@ class SplitMatchOneSpec extends UnitSpec {
myVar.writer.onNext(Tar)

effects shouldBe mutable.Buffer(
Effect("result", "Res(Tar)"),
Effect("update-child", "Tar-10")
Effect("result", "Res(Tar)")
)

effects.clear()
Expand Down Expand Up @@ -189,14 +181,8 @@ class SplitMatchOneSpec extends UnitSpec {

Res("Baz1")
}
.handleValue(Tar) { tarSignal =>
.handleValue(Tar) {
effects += Effect("init-child", s"Tar-${10}")
// @Note keep foreach or addObserver here – this is important.
// It tests that SplitSignal does not cause an infinite loop trying to evaluate its initialValue.
tarSignal.foreach { _ =>
effects += Effect("update-child", s"Tar-${10}")
}(owner)

Res("Tar")
}
.toSignal
Expand Down Expand Up @@ -238,7 +224,6 @@ class SplitMatchOneSpec extends UnitSpec {

effects shouldBe mutable.Buffer(
Effect("init-child", "Tar-10"),
Effect("update-child", "Tar-10"),
Effect("result", "Res(Tar)")
)

Expand All @@ -247,8 +232,7 @@ class SplitMatchOneSpec extends UnitSpec {
myVar.writer.onNext(Tar)

effects shouldBe mutable.Buffer(
Effect("result", "Res(Tar)"),
Effect("update-child", "Tar-10")
Effect("result", "Res(Tar)")
)

effects.clear()
Expand Down Expand Up @@ -287,14 +271,8 @@ class SplitMatchOneSpec extends UnitSpec {

Res("Baz")
}
.handleValue(Tar){ tarSignal =>
.handleValue(Tar) {
effects += Effect("init-child", s"Tar-${10}")
// @Note keep foreach or addObserver here – this is important.
// It tests that SplitSignal does not cause an infinite loop trying to evaluate its initialValue.
tarSignal.foreach { _ =>
effects += Effect("update-child", s"Tar-${10}")
}(owner)

Res("Tar")
}
.toStream
Expand Down Expand Up @@ -365,7 +343,6 @@ class SplitMatchOneSpec extends UnitSpec {

effects shouldBe mutable.Buffer(
Effect("init-child", "Tar-10"),
Effect("update-child", "Tar-10"),
Effect("result", "Res(Tar)")
)

Expand All @@ -374,8 +351,7 @@ class SplitMatchOneSpec extends UnitSpec {
myEventBus.writer.onNext(Tar)

effects shouldBe mutable.Buffer(
Effect("result", "Res(Tar)"),
Effect("update-child", "Tar-10")
Effect("result", "Res(Tar)")
)

effects.clear()
Expand Down
85 changes: 23 additions & 62 deletions src/test/scala-3/com/raquo/airstream/split/SplitMatchSeqSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,8 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
}(owner)
Bar(initialFooC.id)
}
.handleValue(FooO) { fooOSignal =>
.handleValue(FooO) {
effects += Effect("init-child", s"FooO(${FooO.id})")
// @Note keep foreach or addObserver here – this is important.
// It tests that SplitSignal does not cause an infinite loop trying to evaluate its initialValue.
fooOSignal.foreach { fooO =>
assert(FooO.id == fooO.id, "Subsequent value does not match initial key")
effects += Effect("update-child", s"FooO(${fooO.id})")
}(owner)
Bar(FooO.id)
}
.toSignal
Expand Down Expand Up @@ -151,7 +145,6 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
Effect("init-child", "FooC(b-1)"),
Effect("update-child", "FooC(b-1)"),
Effect("init-child", "FooO(object)"),
Effect("update-child", "FooO(object)"),
Effect("result", "List(Bar(1), Bar(a), Bar(b), Bar(object))"),
Effect("update-child", "FooC(a-3)")
)
Expand Down Expand Up @@ -221,14 +214,8 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
}(owner)
Bar(initialFooC.id)
}
.handleValue(FooO) { fooOSignal =>
.handleValue(FooO) {
effects += Effect("init-child", s"FooO(${FooO.id})")
// @Note keep foreach or addObserver here – this is important.
// It tests that SplitSignal does not cause an infinite loop trying to evaluate its initialValue.
fooOSignal.foreach { fooO =>
assert(FooO.id == fooO.id, "Subsequent value does not match initial key")
effects += Effect("update-child", s"FooO(${fooO.id})")
}(owner)
Bar(FooO.id)
}
.toSignal
Expand All @@ -243,7 +230,6 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
Effect("init-child", "FooE(0)"),
Effect("update-child", "FooE(0)"),
Effect("init-child", "FooO(object)"),
Effect("update-child", "FooO(object)"),
Effect("result", "List(Bar(initial), Bar(0), Bar(object))")
)

Expand Down Expand Up @@ -321,7 +307,7 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
//effects.clear()
}
}

it("split signal - raw semantics") {
withOrWithoutDuplicateKeyWarnings {
val effects = mutable.Buffer[Effect[String]]()
Expand Down Expand Up @@ -356,14 +342,8 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
}(owner)
Bar(initialFooC.id)
}
.handleValue(FooO) { fooOSignal =>
.handleValue(FooO) {
effects += Effect(s"init-child-${FooO.id}", s"FooO(${FooO.id})")
// @Note keep foreach or addObserver here – this is important.
// It tests that SplitSignal does not cause an infinite loop trying to evaluate its initialValue.
fooOSignal.foreach { fooO =>
assert(FooO.id == fooO.id, "Subsequent value does not match initial key")
effects += Effect(s"update-child-${fooO.id}", s"FooO(${fooO.id})")
}(owner)
Bar(FooO.id)
}
.toSignal
Expand All @@ -378,7 +358,6 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
Effect("init-child-0", "FooE(0)"),
Effect("update-child-0", "FooE(0)"),
Effect("init-child-object", "FooO(object)"),
Effect("update-child-object", "FooO(object)"),
Effect("result", "List(Bar(initial), Bar(0), Bar(object))")
)

Expand All @@ -391,8 +370,7 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
effects shouldBe mutable.Buffer(
Effect("init-child-a", "FooC(a-1)"),
Effect("update-child-a", "FooC(a-1)"),
Effect("result", "List(Bar(object), Bar(a))"),
Effect("update-child-object", "FooO(object)")
Effect("result", "List(Bar(object), Bar(a))")
)

effects.clear()
Expand All @@ -403,7 +381,6 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {

effects shouldBe mutable.Buffer(
Effect("result", "List(Bar(a), Bar(object))"),
Effect("update-child-object", "FooO(object)"),
Effect("update-child-a", "FooC(a-2)")
)

Expand Down Expand Up @@ -553,17 +530,8 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
)
Bar(initialFooC.id)
}
.handleValue(FooO) { fooOSignal =>
.handleValue(FooO) {
effects += Effect(s"init-child-${FooO.id}", s"FooO(${FooO.id})")
// @Note keep foreach or addObserver here – this is important.
// It tests that SplitSignal does not cause an infinite loop trying to evaluate its initialValue.
DynamicSubscription.subscribeCallback(
innerDynamicOwnerO,
owner => fooOSignal.foreach { fooO =>
assert(FooO.id == fooO.id, "Subsequent value does not match initial key")
effects += Effect(s"update-child-${fooO.id}", s"FooO(${fooO.id})")
}(owner)
)
Bar(FooO.id)
}
.toSignal
Expand All @@ -579,7 +547,6 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
Effect("init-child-initial", "FooC(initial-1)"),
Effect("update-child-initial", "FooC(initial-1)"),
Effect("init-child-object", "FooO(object)"),
Effect("update-child-object", "FooO(object)"),
Effect("init-child-0", "FooE(0)"),
Effect("result", "List(Bar(initial), Bar(object), Bar(0))"),
Effect("update-child-0", "FooE(0)")
Expand All @@ -597,7 +564,6 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
Effect("init-child-a", "FooC(a-3)"),
Effect("update-child-a", "FooC(a-3)"),
Effect("result", "List(Bar(0), Bar(b), Bar(object), Bar(a))"),
Effect("update-child-object", "FooO(object)"),
Effect("update-child-0", "FooE(0)")
)

Expand Down Expand Up @@ -635,11 +601,7 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {

innerDynamicOwnerO.activate()

effects shouldBe mutable.Buffer(
Effect("update-child-object", "FooO(object)")
)

effects.clear()
effects shouldBe mutable.Buffer()

// --

Expand All @@ -659,8 +621,7 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
effects shouldBe mutable.Buffer(
Effect("result", "List(Bar(b), Bar(a), Bar(object))"),
Effect("update-child-b", "FooC(b-2)"),
Effect("update-child-a", "FooC(a-3)"),
Effect("update-child-object", "FooO(object)")
Effect("update-child-a", "FooC(a-3)")
)

effects.clear()
Expand Down Expand Up @@ -715,7 +676,7 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
.handleType[FooC] { (initialFooC, _) =>
Bar(initialFooC.id)
}
.handleValue(FooO) { _ =>
.handleValue(FooO) {
Bar(FooO.id)
}
.toSignal
Expand Down Expand Up @@ -750,23 +711,23 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter {
it("split list / vector / set / js.array / immutable.seq / collection.seq / option compiles") {
// Having this test pass on all supported Scala versions is important to ensure that the implicits are actually usable.
{
(new EventBus[List[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[Vector[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[Set[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[js.Array[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[immutable.Seq[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[collection.Seq[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[collection.Seq[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[List[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[Vector[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[Set[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[js.Array[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[immutable.Seq[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[collection.Seq[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[collection.Seq[Foo]]).events.splitMatchSeq(_.id).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
}
// And now the same, but with `distinctCompose = identity`, because that somehow affects implicit resolution in Scala 3.0.0
{
(new EventBus[List[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[Vector[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[Set[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[js.Array[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[immutable.Seq[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[collection.Seq[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[collection.Seq[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(_ => 30).toSignal
(new EventBus[List[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[Vector[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[Set[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[js.Array[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[immutable.Seq[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[collection.Seq[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
(new EventBus[collection.Seq[Foo]]).events.splitMatchSeq(_.id, identity).handleCase{ case e: FooE => e }((_, _) => 10).handleType[FooC]((_, _) => 20).handleValue(FooO)(30).toSignal
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ class DistinctSpec extends UnitSpec {
effects.clear()

// --

sub3.kill()

_var.writer.onNext(3)
Expand All @@ -248,7 +248,7 @@ class DistinctSpec extends UnitSpec {

calculations shouldBe mutable.Buffer()
effects shouldBe mutable.Buffer()

// --

_var.writer.onNext(4)
Expand Down

0 comments on commit 93e710f

Please sign in to comment.