diff --git a/src/main/scala-3/com/raquo/airstream/split/SplitMatchOneMacros.scala b/src/main/scala-3/com/raquo/airstream/split/SplitMatchOneMacros.scala index 81e18aec..913e6542 100644 --- a/src/main/scala-3/com/raquo/airstream/split/SplitMatchOneMacros.scala +++ b/src/main/scala-3/com/raquo/airstream/split/SplitMatchOneMacros.scala @@ -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]) { @@ -130,7 +130,7 @@ object SplitMatchOneMacros { "Macro expansion failed, please use `splitMatchOne` instead of creating new SplitMatchOneObservable explicitly" ) } - + innerHandleCaseImpl( observableExpr, caseExprSeq, diff --git a/src/main/scala-3/com/raquo/airstream/split/SplitMatchSeqMacros.scala b/src/main/scala-3/com/raquo/airstream/split/SplitMatchSeqMacros.scala index 04025965..195d4c97 100644 --- a/src/main/scala-3/com/raquo/airstream/split/SplitMatchSeqMacros.scala +++ b/src/main/scala-3/com/raquo/airstream/split/SplitMatchSeqMacros.scala @@ -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], @@ -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]( @@ -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( diff --git a/src/test/scala-3/com/raquo/airstream/split/SplitMatchOneSpec.scala b/src/test/scala-3/com/raquo/airstream/split/SplitMatchOneSpec.scala index 9f2507ad..85a74636 100644 --- a/src/test/scala-3/com/raquo/airstream/split/SplitMatchOneSpec.scala +++ b/src/test/scala-3/com/raquo/airstream/split/SplitMatchOneSpec.scala @@ -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 @@ -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)") ) @@ -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() @@ -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 @@ -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)") ) @@ -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() @@ -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 @@ -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)") ) @@ -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() diff --git a/src/test/scala-3/com/raquo/airstream/split/SplitMatchSeqSpec.scala b/src/test/scala-3/com/raquo/airstream/split/SplitMatchSeqSpec.scala index d17c2a6c..8d5e6726 100644 --- a/src/test/scala-3/com/raquo/airstream/split/SplitMatchSeqSpec.scala +++ b/src/test/scala-3/com/raquo/airstream/split/SplitMatchSeqSpec.scala @@ -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 @@ -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)") ) @@ -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 @@ -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))") ) @@ -321,7 +307,7 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter { //effects.clear() } } - + it("split signal - raw semantics") { withOrWithoutDuplicateKeyWarnings { val effects = mutable.Buffer[Effect[String]]() @@ -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 @@ -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))") ) @@ -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() @@ -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)") ) @@ -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 @@ -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)") @@ -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)") ) @@ -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() // -- @@ -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() @@ -715,7 +676,7 @@ class SplitMatchSeqSpec extends UnitSpec with BeforeAndAfter { .handleType[FooC] { (initialFooC, _) => Bar(initialFooC.id) } - .handleValue(FooO) { _ => + .handleValue(FooO) { Bar(FooO.id) } .toSignal @@ -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 } } diff --git a/src/test/scala/com/raquo/airstream/distinct/DistinctSpec.scala b/src/test/scala/com/raquo/airstream/distinct/DistinctSpec.scala index 008b2874..f7b68577 100644 --- a/src/test/scala/com/raquo/airstream/distinct/DistinctSpec.scala +++ b/src/test/scala/com/raquo/airstream/distinct/DistinctSpec.scala @@ -221,7 +221,7 @@ class DistinctSpec extends UnitSpec { effects.clear() // -- - + sub3.kill() _var.writer.onNext(3) @@ -248,7 +248,7 @@ class DistinctSpec extends UnitSpec { calculations shouldBe mutable.Buffer() effects shouldBe mutable.Buffer() - + // -- _var.writer.onNext(4)