diff --git a/core/shared/src/main/scala/monocle/Fold.scala b/core/shared/src/main/scala/monocle/Fold.scala index c18ec2e6a..3aa8a4061 100644 --- a/core/shared/src/main/scala/monocle/Fold.scala +++ b/core/shared/src/main/scala/monocle/Fold.scala @@ -5,7 +5,7 @@ import cats.arrow.Choice import cats.instances.int._ import cats.instances.list._ import cats.syntax.either._ -import monocle.function.Each +import monocle.function.{At, Each, Index} import monocle.internal.Monoids /** A [[Fold]] can be seen as a [[Getter]] with many targets or @@ -100,6 +100,12 @@ abstract class Fold[S, A] extends Serializable { self => private def adapt[A1](implicit evA: A =:= A1): Fold[S, A1] = evA.substituteCo[Fold[S, *]](this) + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): Fold[S, A1] = + composeLens(evAt.at(i)) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): Fold[S, A1] = + composeOptional(evIndex.index(i)) + /** compose a [[Fold]] with another [[Fold]] */ final def andThen[B](other: Fold[A, B]): Fold[S, B] = new Fold[S, B] { diff --git a/core/shared/src/main/scala/monocle/Getter.scala b/core/shared/src/main/scala/monocle/Getter.scala index a6042160c..8c8fb2a5f 100644 --- a/core/shared/src/main/scala/monocle/Getter.scala +++ b/core/shared/src/main/scala/monocle/Getter.scala @@ -3,7 +3,7 @@ package monocle import cats.{Eq, Monoid, Semigroupal} import cats.arrow.{Arrow, Choice} import cats.implicits._ -import monocle.function.Each +import monocle.function.{At, Each, Index} /** A [[Getter]] can be seen as a glorified get method between * a type S and a type A. @@ -65,6 +65,12 @@ abstract class Getter[S, A] extends Serializable { self => private def adapt[A1](implicit evA: A =:= A1): Getter[S, A1] = evA.substituteCo[Getter[S, *]](this) + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): Getter[S, A1] = + composeLens(evAt.at(i)) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): Fold[S, A1] = + composeOptional(evIndex.index(i)) + /** compose a [[Getter]] with a [[Fold]] */ final def andThen[B](other: Fold[A, B]): Fold[S, B] = asFold.andThen(other) diff --git a/core/shared/src/main/scala/monocle/Iso.scala b/core/shared/src/main/scala/monocle/Iso.scala index 4ea255c1b..a470ae597 100644 --- a/core/shared/src/main/scala/monocle/Iso.scala +++ b/core/shared/src/main/scala/monocle/Iso.scala @@ -4,7 +4,7 @@ import cats.{Applicative, Eq, Functor, Monoid} import cats.arrow.Category import cats.evidence.{<~<, Is} import cats.syntax.either._ -import monocle.function.Each +import monocle.function.{At, Each, Index} /** [[Iso]] is a type alias for [[PIso]] where `S` = `A` and `T` = `B`: * {{{ @@ -408,4 +408,10 @@ final case class IsoSyntax[S, A](private val self: Iso[S, A]) extends AnyVal { def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): Iso[S, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): Lens[S, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): Optional[S, A1] = + self composeOptional evIndex.index(i) } diff --git a/core/shared/src/main/scala/monocle/Lens.scala b/core/shared/src/main/scala/monocle/Lens.scala index 79d516e99..35b237134 100644 --- a/core/shared/src/main/scala/monocle/Lens.scala +++ b/core/shared/src/main/scala/monocle/Lens.scala @@ -3,7 +3,7 @@ package monocle import cats.{Applicative, Eq, Functor, Monoid} import cats.arrow.Choice import cats.syntax.either._ -import monocle.function.Each +import monocle.function.{At, Each, Index} /** A [[PLens]] can be seen as a pair of functions: * - `get: S => A` i.e. from an `S`, we can extract an `A` @@ -319,4 +319,10 @@ final case class LensSyntax[S, A](private val self: Lens[S, A]) extends AnyVal { def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): Lens[S, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): Lens[S, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): Optional[S, A1] = + self composeOptional evIndex.index(i) } diff --git a/core/shared/src/main/scala/monocle/Optional.scala b/core/shared/src/main/scala/monocle/Optional.scala index 998381edd..f405b6daa 100644 --- a/core/shared/src/main/scala/monocle/Optional.scala +++ b/core/shared/src/main/scala/monocle/Optional.scala @@ -3,7 +3,7 @@ package monocle import cats.{Applicative, Eq, Monoid} import cats.arrow.Choice import cats.syntax.either._ -import monocle.function.Each +import monocle.function.{At, Each, Index} /** A [[POptional]] can be seen as a pair of functions: * - `getOrModify: S => Either[T, A]` @@ -335,4 +335,10 @@ final case class OptionalSyntax[S, A](private val self: Optional[S, A]) extends def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): Optional[S, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): Optional[S, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): Optional[S, A1] = + self composeOptional evIndex.index(i) } diff --git a/core/shared/src/main/scala/monocle/Prism.scala b/core/shared/src/main/scala/monocle/Prism.scala index 8ebc58174..ce90b9455 100644 --- a/core/shared/src/main/scala/monocle/Prism.scala +++ b/core/shared/src/main/scala/monocle/Prism.scala @@ -5,7 +5,7 @@ import cats.arrow.Category import cats.evidence.{<~<, Is} import cats.instances.option._ import cats.syntax.either._ -import monocle.function.Each +import monocle.function.{At, Each, Index} /** A [[PPrism]] can be seen as a pair of functions: * - `getOrModify: S => Either[T, A]` @@ -374,4 +374,10 @@ final case class PrismSyntax[S, A](private val self: Prism[S, A]) extends AnyVal def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): Prism[S, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): Optional[S, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): Optional[S, A1] = + self composeOptional evIndex.index(i) } diff --git a/core/shared/src/main/scala/monocle/Setter.scala b/core/shared/src/main/scala/monocle/Setter.scala index 2cf02933b..c76807b27 100644 --- a/core/shared/src/main/scala/monocle/Setter.scala +++ b/core/shared/src/main/scala/monocle/Setter.scala @@ -4,7 +4,7 @@ import cats.{Contravariant, Eq, Functor} import cats.arrow.Choice import cats.arrow.Profunctor import cats.syntax.either._ -import monocle.function.Each +import monocle.function.{At, Each, Index} /** A [[PSetter]] is a generalisation of Functor map: * - `map: (A => B) => F[A] => F[B]` @@ -198,4 +198,10 @@ final case class SetterSyntax[S, A](private val self: Setter[S, A]) extends AnyV def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): Setter[S, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): Setter[S, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): Setter[S, A1] = + self composeOptional evIndex.index(i) } diff --git a/core/shared/src/main/scala/monocle/Traversal.scala b/core/shared/src/main/scala/monocle/Traversal.scala index 56c637108..d6e716fcf 100644 --- a/core/shared/src/main/scala/monocle/Traversal.scala +++ b/core/shared/src/main/scala/monocle/Traversal.scala @@ -6,7 +6,7 @@ import cats.data.Const import cats.instances.int._ import cats.instances.list._ import cats.syntax.either._ -import monocle.function.Each +import monocle.function.{At, Each, Index} import monocle.internal.Monoids /** A [[PTraversal]] can be seen as a [[POptional]] generalised to 0 to n targets @@ -345,4 +345,10 @@ final case class TraversalSyntax[S, A](private val self: Traversal[S, A]) extend def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): Traversal[S, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): Traversal[S, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): Traversal[S, A1] = + self composeOptional evIndex.index(i) } diff --git a/core/shared/src/main/scala/monocle/function/Index.scala b/core/shared/src/main/scala/monocle/function/Index.scala index 5276fef58..2b5924f70 100644 --- a/core/shared/src/main/scala/monocle/function/Index.scala +++ b/core/shared/src/main/scala/monocle/function/Index.scala @@ -49,8 +49,7 @@ object Index extends IndexFunctions { */ implicit def listIndex[A]: Index[List[A], Int, A] = Index(i => - if (i < 0) - Optional[List[A], A](_ => None)(_ => identity) + if (i < 0) Optional.void else Optional[List[A], A](_.drop(i).headOption)(a => s => Try(s.updated(i, a)).getOrElse(s)) ) diff --git a/core/shared/src/main/scala/monocle/syntax/ApplyFold.scala b/core/shared/src/main/scala/monocle/syntax/ApplyFold.scala index 07a0515b5..d2b453311 100644 --- a/core/shared/src/main/scala/monocle/syntax/ApplyFold.scala +++ b/core/shared/src/main/scala/monocle/syntax/ApplyFold.scala @@ -1,7 +1,7 @@ package monocle.syntax import cats.{Eq, Monoid} -import monocle.function.Each +import monocle.function.{At, Each, Index} import monocle.{std, Fold, Getter, PIso, PLens, POptional, PPrism, PTraversal} case class ApplyFold[S, A](s: S, _fold: Fold[S, A]) { @@ -26,6 +26,12 @@ case class ApplyFold[S, A](s: S, _fold: Fold[S, A]) { def withDefault[A1: Eq](defaultValue: A1)(implicit ev1: A =:= Option[A1]): ApplyFold[S, A1] = adapt[Option[A1]] composeIso (std.option.withDefault(defaultValue)) + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): ApplyFold[S, A1] = + composeLens(evAt.at(i)) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): ApplyFold[S, A1] = + composeOptional(evIndex.index(i)) + private def adapt[A1](implicit evA: A =:= A1): ApplyFold[S, A1] = evA.substituteCo[ApplyFold[S, *]](this) diff --git a/core/shared/src/main/scala/monocle/syntax/ApplyGetter.scala b/core/shared/src/main/scala/monocle/syntax/ApplyGetter.scala index f7141c362..694177c13 100644 --- a/core/shared/src/main/scala/monocle/syntax/ApplyGetter.scala +++ b/core/shared/src/main/scala/monocle/syntax/ApplyGetter.scala @@ -1,7 +1,7 @@ package monocle.syntax import cats.Eq -import monocle.function.Each +import monocle.function.{At, Each, Index} import monocle.{std, Fold, Getter, PIso, PLens, POptional, PPrism, PTraversal} final case class ApplyGetter[S, A](s: S, getter: Getter[S, A]) { @@ -18,6 +18,12 @@ final case class ApplyGetter[S, A](s: S, getter: Getter[S, A]) { def withDefault[A1: Eq](defaultValue: A1)(implicit ev1: A =:= Option[A1]): ApplyGetter[S, A1] = adapt[Option[A1]] composeIso (std.option.withDefault(defaultValue)) + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): ApplyGetter[S, A1] = + composeLens(evAt.at(i)) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): ApplyFold[S, A1] = + composeOptional(evIndex.index(i)) + private def adapt[A1](implicit evA: A =:= A1): ApplyGetter[S, A1] = evA.substituteCo[ApplyGetter[S, *]](this) diff --git a/core/shared/src/main/scala/monocle/syntax/ApplyIso.scala b/core/shared/src/main/scala/monocle/syntax/ApplyIso.scala index 7ea6cb678..98274dada 100644 --- a/core/shared/src/main/scala/monocle/syntax/ApplyIso.scala +++ b/core/shared/src/main/scala/monocle/syntax/ApplyIso.scala @@ -1,7 +1,7 @@ package monocle.syntax import cats.{Eq, Functor} -import monocle.function.Each +import monocle.function.{At, Each, Index} import monocle.{std, Fold, Getter, PIso, PLens, POptional, PPrism, PSetter, PTraversal} final case class ApplyIso[S, T, A, B](s: S, iso: PIso[S, T, A, B]) { @@ -75,4 +75,10 @@ final case class ApplyIsoSyntax[S, A](private val self: ApplyIso[S, S, A, A]) ex def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): ApplyIso[S, S, A1, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): ApplyLens[S, S, A1, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): ApplyOptional[S, S, A1, A1] = + self composeOptional evIndex.index(i) } diff --git a/core/shared/src/main/scala/monocle/syntax/ApplyLens.scala b/core/shared/src/main/scala/monocle/syntax/ApplyLens.scala index 60d110243..d6c9f074e 100644 --- a/core/shared/src/main/scala/monocle/syntax/ApplyLens.scala +++ b/core/shared/src/main/scala/monocle/syntax/ApplyLens.scala @@ -1,7 +1,7 @@ package monocle.syntax import cats.{Eq, Functor} -import monocle.function.Each +import monocle.function.{At, Each, Index} import monocle.{std, Fold, Getter, PIso, PLens, POptional, PPrism, PSetter, PTraversal} final case class ApplyLens[S, T, A, B](s: S, lens: PLens[S, T, A, B]) { @@ -76,4 +76,10 @@ final case class ApplyLensSyntax[S, A](private val self: ApplyLens[S, S, A, A]) def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): ApplyLens[S, S, A1, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): ApplyLens[S, S, A1, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): ApplyOptional[S, S, A1, A1] = + self composeOptional evIndex.index(i) } diff --git a/core/shared/src/main/scala/monocle/syntax/ApplyOptional.scala b/core/shared/src/main/scala/monocle/syntax/ApplyOptional.scala index 1c11f822f..a31bb077d 100644 --- a/core/shared/src/main/scala/monocle/syntax/ApplyOptional.scala +++ b/core/shared/src/main/scala/monocle/syntax/ApplyOptional.scala @@ -1,7 +1,7 @@ package monocle.syntax import cats.{Applicative, Eq} -import monocle.function.Each +import monocle.function.{At, Each, Index} import monocle.{std, Fold, PIso, PLens, POptional, PPrism, PSetter, PTraversal} final case class ApplyOptional[S, T, A, B](s: S, optional: POptional[S, T, A, B]) { @@ -83,4 +83,10 @@ final case class ApplyOptionalSyntax[S, A](private val self: ApplyOptional[S, S, def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): ApplyOptional[S, S, A1, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): ApplyOptional[S, S, A1, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): ApplyOptional[S, S, A1, A1] = + self composeOptional evIndex.index(i) } diff --git a/core/shared/src/main/scala/monocle/syntax/ApplyPrism.scala b/core/shared/src/main/scala/monocle/syntax/ApplyPrism.scala index b0a2a5978..f7c27a956 100644 --- a/core/shared/src/main/scala/monocle/syntax/ApplyPrism.scala +++ b/core/shared/src/main/scala/monocle/syntax/ApplyPrism.scala @@ -1,7 +1,7 @@ package monocle.syntax import cats.{Applicative, Eq} -import monocle.function.Each +import monocle.function.{At, Each, Index} import monocle.{std, Fold, PIso, PLens, POptional, PPrism, PSetter, PTraversal} final case class ApplyPrism[S, T, A, B](s: S, prism: PPrism[S, T, A, B]) { @@ -81,4 +81,10 @@ final case class ApplyPrismSyntax[S, A](private val self: ApplyPrism[S, S, A, A] def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): ApplyPrism[S, S, A1, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): ApplyOptional[S, S, A1, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): ApplyOptional[S, S, A1, A1] = + self composeOptional evIndex.index(i) } diff --git a/core/shared/src/main/scala/monocle/syntax/ApplySetter.scala b/core/shared/src/main/scala/monocle/syntax/ApplySetter.scala index 2f83c5bdf..fbe91f802 100644 --- a/core/shared/src/main/scala/monocle/syntax/ApplySetter.scala +++ b/core/shared/src/main/scala/monocle/syntax/ApplySetter.scala @@ -1,7 +1,7 @@ package monocle.syntax import cats.Eq -import monocle.function.Each +import monocle.function.{At, Each, Index} import monocle.{std, PIso, PLens, POptional, PPrism, PSetter, PTraversal} final case class ApplySetter[S, T, A, B](s: S, setter: PSetter[S, T, A, B]) { @@ -66,4 +66,10 @@ final case class ApplySetterSyntax[S, A](private val self: ApplySetter[S, S, A, def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): ApplySetter[S, S, A1, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): ApplySetter[S, S, A1, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): ApplySetter[S, S, A1, A1] = + self composeOptional evIndex.index(i) } diff --git a/core/shared/src/main/scala/monocle/syntax/ApplyTraversal.scala b/core/shared/src/main/scala/monocle/syntax/ApplyTraversal.scala index 4a989a228..ce59f126c 100644 --- a/core/shared/src/main/scala/monocle/syntax/ApplyTraversal.scala +++ b/core/shared/src/main/scala/monocle/syntax/ApplyTraversal.scala @@ -1,7 +1,7 @@ package monocle.syntax import cats.{Applicative, Eq} -import monocle.function.Each +import monocle.function.{At, Each, Index} import monocle.{std, Fold, PIso, PLens, POptional, PPrism, PSetter, PTraversal} final case class ApplyTraversal[S, T, A, B](s: S, traversal: PTraversal[S, T, A, B]) { @@ -81,4 +81,10 @@ final case class ApplyTraversalSyntax[S, A](private val self: ApplyTraversal[S, def withDefault[A1: Eq](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): ApplyTraversal[S, S, A1, A1] = self.adapt[Option[A1], Option[A1]] composeIso (std.option.withDefault(defaultValue)) + + def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): ApplyTraversal[S, S, A1, A1] = + self composeLens evAt.at(i) + + def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): ApplyTraversal[S, S, A1, A1] = + self composeOptional evIndex.index(i) } diff --git a/test/shared/src/test/scala/monocle/FoldSpec.scala b/test/shared/src/test/scala/monocle/FoldSpec.scala index 388e8e83d..157e20448 100644 --- a/test/shared/src/test/scala/monocle/FoldSpec.scala +++ b/test/shared/src/test/scala/monocle/FoldSpec.scala @@ -2,6 +2,9 @@ package monocle import cats.Monoid import cats.arrow.{Category, Choice, Compose} +import cats.data.{Chain, NonEmptyChain, NonEmptyList, NonEmptyVector} + +import scala.collection.immutable class FoldSpec extends MonocleSuite { val eachLi: Fold[List[Int], Int] = Fold.fromFoldable[List, Int] @@ -122,4 +125,161 @@ class FoldSpec extends MonocleSuite { assertEquals(fold.each.getAll(numbers), List(1, 2, 3, 4)) assertEquals(numbers.applyFold(fold).each.getAll, List(1, 2, 3, 4)) } + + test("at") { + val tuple2 = (1, 2) + val tuple2Fold = Fold.id[(Int, Int)] + assertEquals(tuple2Fold.at(1).getAll(tuple2), List(1)) + assertEquals(tuple2Fold.at(2).getAll(tuple2), List(2)) + assertEquals(tuple2.applyFold(tuple2Fold).at(1).getAll, List(1)) + assertEquals(tuple2.applyFold(tuple2Fold).at(2).getAll, List(2)) + + val tuple3 = (1, 2, 3) + val tuple3Fold = Fold.id[(Int, Int, Int)] + assertEquals(tuple3Fold.at(1).getAll(tuple3), List(1)) + assertEquals(tuple3Fold.at(2).getAll(tuple3), List(2)) + assertEquals(tuple3Fold.at(3).getAll(tuple3), List(3)) + assertEquals(tuple3.applyFold(tuple3Fold).at(1).getAll, List(1)) + assertEquals(tuple3.applyFold(tuple3Fold).at(2).getAll, List(2)) + assertEquals(tuple3.applyFold(tuple3Fold).at(3).getAll, List(3)) + + val tuple4 = (1, 2, 3, 4) + val tuple4Fold = Fold.id[(Int, Int, Int, Int)] + assertEquals(tuple4Fold.at(1).getAll(tuple4), List(1)) + assertEquals(tuple4Fold.at(2).getAll(tuple4), List(2)) + assertEquals(tuple4Fold.at(3).getAll(tuple4), List(3)) + assertEquals(tuple4Fold.at(4).getAll(tuple4), List(4)) + assertEquals(tuple4.applyFold(tuple4Fold).at(1).getAll, List(1)) + assertEquals(tuple4.applyFold(tuple4Fold).at(2).getAll, List(2)) + assertEquals(tuple4.applyFold(tuple4Fold).at(3).getAll, List(3)) + assertEquals(tuple4.applyFold(tuple4Fold).at(4).getAll, List(4)) + + val tuple5 = (1, 2, 3, 4, 5) + val tuple5Fold = Fold.id[(Int, Int, Int, Int, Int)] + assertEquals(tuple5Fold.at(1).getAll(tuple5), List(1)) + assertEquals(tuple5Fold.at(2).getAll(tuple5), List(2)) + assertEquals(tuple5Fold.at(3).getAll(tuple5), List(3)) + assertEquals(tuple5Fold.at(4).getAll(tuple5), List(4)) + assertEquals(tuple5Fold.at(5).getAll(tuple5), List(5)) + assertEquals(tuple5.applyFold(tuple5Fold).at(1).getAll, List(1)) + assertEquals(tuple5.applyFold(tuple5Fold).at(2).getAll, List(2)) + assertEquals(tuple5.applyFold(tuple5Fold).at(3).getAll, List(3)) + assertEquals(tuple5.applyFold(tuple5Fold).at(4).getAll, List(4)) + assertEquals(tuple5.applyFold(tuple5Fold).at(5).getAll, List(5)) + + val tuple6 = (1, 2, 3, 4, 5, 6) + val tuple6Fold = Fold.id[(Int, Int, Int, Int, Int, Int)] + assertEquals(tuple6Fold.at(1).getAll(tuple6), List(1)) + assertEquals(tuple6Fold.at(2).getAll(tuple6), List(2)) + assertEquals(tuple6Fold.at(3).getAll(tuple6), List(3)) + assertEquals(tuple6Fold.at(4).getAll(tuple6), List(4)) + assertEquals(tuple6Fold.at(5).getAll(tuple6), List(5)) + assertEquals(tuple6Fold.at(6).getAll(tuple6), List(6)) + assertEquals(tuple6.applyFold(tuple6Fold).at(1).getAll, List(1)) + assertEquals(tuple6.applyFold(tuple6Fold).at(2).getAll, List(2)) + assertEquals(tuple6.applyFold(tuple6Fold).at(3).getAll, List(3)) + assertEquals(tuple6.applyFold(tuple6Fold).at(4).getAll, List(4)) + assertEquals(tuple6.applyFold(tuple6Fold).at(5).getAll, List(5)) + assertEquals(tuple6.applyFold(tuple6Fold).at(6).getAll, List(6)) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapFold = Fold.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapFold.at(1).getAll(sortedMap), List(Some("one"))) + assertEquals(sortedMapFold.at(0).getAll(sortedMap), List(None)) + assertEquals(sortedMap.applyFold(sortedMapFold).at(1).getAll, List(Some("one"))) + assertEquals(sortedMap.applyFold(sortedMapFold).at(0).getAll, List(None)) + + val listMap = immutable.ListMap(1 -> "one") + val listMapFold = Fold.id[immutable.ListMap[Int, String]] + assertEquals(listMapFold.at(1).getAll(listMap), List(Some("one"))) + assertEquals(listMapFold.at(0).getAll(listMap), List(None)) + assertEquals(listMap.applyFold(listMapFold).at(1).getAll, List(Some("one"))) + assertEquals(listMap.applyFold(listMapFold).at(0).getAll, List(None)) + + val map = immutable.Map(1 -> "one") + val mapFold = Fold.id[Map[Int, String]] + assertEquals(mapFold.at(1).getAll(map), List(Some("one"))) + assertEquals(mapFold.at(0).getAll(map), List(None)) + assertEquals(map.applyFold(mapFold).at(1).getAll, List(Some("one"))) + assertEquals(map.applyFold(mapFold).at(0).getAll, List(None)) + + val set = Set(1) + val setFold = Fold.id[Set[Int]] + assertEquals(setFold.at(1).getAll(set), List(true)) + assertEquals(setFold.at(0).getAll(set), List(false)) + assertEquals(set.applyFold(setFold).at(1).getAll, List(true)) + assertEquals(set.applyFold(setFold).at(0).getAll, List(false)) + } + + test("index") { + val list = List(1) + val listFold = Fold.id[List[Int]] + assertEquals(listFold.index(0).getAll(list), List(1)) + assertEquals(listFold.index(1).getAll(list), Nil) + assertEquals(list.applyFold(listFold).index(0).getAll, List(1)) + assertEquals(list.applyFold(listFold).index(1).getAll, Nil) + + val lazyList = LazyList(1) + val lazyListFold = Fold.id[LazyList[Int]] + assertEquals(lazyListFold.index(0).getAll(lazyList), List(1)) + assertEquals(lazyListFold.index(1).getAll(lazyList), Nil) + assertEquals(lazyList.applyFold(lazyListFold).index(0).getAll, List(1)) + assertEquals(lazyList.applyFold(lazyListFold).index(1).getAll, Nil) + + val listMap = immutable.ListMap(1 -> "one") + val listMapFold = Fold.id[immutable.ListMap[Int, String]] + assertEquals(listMapFold.index(0).getAll(listMap), Nil) + assertEquals(listMapFold.index(1).getAll(listMap), List("one")) + assertEquals(listMap.applyFold(listMapFold).index(0).getAll, Nil) + assertEquals(listMap.applyFold(listMapFold).index(1).getAll, List("one")) + + val map = Map(1 -> "one") + val mapFold = Fold.id[Map[Int, String]] + assertEquals(mapFold.index(0).getAll(map), Nil) + assertEquals(mapFold.index(1).getAll(map), List("one")) + assertEquals(map.applyFold(mapFold).index(0).getAll, Nil) + assertEquals(map.applyFold(mapFold).index(1).getAll, List("one")) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapFold = Fold.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapFold.index(0).getAll(sortedMap), Nil) + assertEquals(sortedMapFold.index(1).getAll(sortedMap), List("one")) + assertEquals(sortedMap.applyFold(sortedMapFold).index(0).getAll, Nil) + assertEquals(sortedMap.applyFold(sortedMapFold).index(1).getAll, List("one")) + + val vector = Vector(1) + val vectorFold = Fold.id[Vector[Int]] + assertEquals(vectorFold.index(0).getAll(vector), List(1)) + assertEquals(vectorFold.index(1).getAll(vector), Nil) + assertEquals(vector.applyFold(vectorFold).index(0).getAll, List(1)) + assertEquals(vector.applyFold(vectorFold).index(1).getAll, Nil) + + val chain = Chain.one(1) + val chainFold = Fold.id[Chain[Int]] + assertEquals(chainFold.index(0).getAll(chain), List(1)) + assertEquals(chainFold.index(1).getAll(chain), Nil) + assertEquals(chain.applyFold(chainFold).index(0).getAll, List(1)) + assertEquals(chain.applyFold(chainFold).index(1).getAll, Nil) + + val nec = NonEmptyChain.one(1) + val necFold = Fold.id[NonEmptyChain[Int]] + assertEquals(necFold.index(0).getAll(nec), List(1)) + assertEquals(necFold.index(1).getAll(nec), Nil) + assertEquals(nec.applyFold(necFold).index(0).getAll, List(1)) + assertEquals(nec.applyFold(necFold).index(1).getAll, Nil) + + val nev = NonEmptyVector.one(1) + val nevFold = Fold.id[NonEmptyVector[Int]] + assertEquals(nevFold.index(0).getAll(nev), List(1)) + assertEquals(nevFold.index(1).getAll(nev), Nil) + assertEquals(nev.applyFold(nevFold).index(0).getAll, List(1)) + assertEquals(nev.applyFold(nevFold).index(1).getAll, Nil) + + val nel = NonEmptyList.one(1) + val nelFold = Fold.id[NonEmptyList[Int]] + assertEquals(nelFold.index(0).getAll(nel), List(1)) + assertEquals(nelFold.index(1).getAll(nel), Nil) + assertEquals(nel.applyFold(nelFold).index(0).getAll, List(1)) + assertEquals(nel.applyFold(nelFold).index(1).getAll, Nil) + } } diff --git a/test/shared/src/test/scala/monocle/GetterSpec.scala b/test/shared/src/test/scala/monocle/GetterSpec.scala index 39a3c143e..1256d194b 100644 --- a/test/shared/src/test/scala/monocle/GetterSpec.scala +++ b/test/shared/src/test/scala/monocle/GetterSpec.scala @@ -2,6 +2,9 @@ package monocle import cats.Semigroupal import cats.arrow.{Arrow, Category, Choice, Compose, Profunctor} +import cats.data.{Chain, NonEmptyChain, NonEmptyList, NonEmptyVector} + +import scala.collection.immutable class GetterSpec extends MonocleSuite { case class Bar(i: Int) @@ -105,4 +108,161 @@ class GetterSpec extends MonocleSuite { assertEquals(getter.each.getAll(obj), List(1, 2, 3)) assertEquals(obj.applyGetter(getter).each.getAll, List(1, 2, 3)) } + + test("at") { + val tuple2 = (1, 2) + val tuple2Getter = Getter.id[(Int, Int)] + assertEquals(tuple2Getter.at(1).get(tuple2), 1) + assertEquals(tuple2Getter.at(2).get(tuple2), 2) + assertEquals(tuple2.applyGetter(tuple2Getter).at(1).get, 1) + assertEquals(tuple2.applyGetter(tuple2Getter).at(2).get, 2) + + val tuple3 = (1, 2, 3) + val tuple3Getter = Getter.id[(Int, Int, Int)] + assertEquals(tuple3Getter.at(1).get(tuple3), 1) + assertEquals(tuple3Getter.at(2).get(tuple3), 2) + assertEquals(tuple3Getter.at(3).get(tuple3), 3) + assertEquals(tuple3.applyGetter(tuple3Getter).at(1).get, 1) + assertEquals(tuple3.applyGetter(tuple3Getter).at(2).get, 2) + assertEquals(tuple3.applyGetter(tuple3Getter).at(3).get, 3) + + val tuple4 = (1, 2, 3, 4) + val tuple4Getter = Getter.id[(Int, Int, Int, Int)] + assertEquals(tuple4Getter.at(1).get(tuple4), 1) + assertEquals(tuple4Getter.at(2).get(tuple4), 2) + assertEquals(tuple4Getter.at(3).get(tuple4), 3) + assertEquals(tuple4Getter.at(4).get(tuple4), 4) + assertEquals(tuple4.applyGetter(tuple4Getter).at(1).get, 1) + assertEquals(tuple4.applyGetter(tuple4Getter).at(2).get, 2) + assertEquals(tuple4.applyGetter(tuple4Getter).at(3).get, 3) + assertEquals(tuple4.applyGetter(tuple4Getter).at(4).get, 4) + + val tuple5 = (1, 2, 3, 4, 5) + val tuple5Getter = Getter.id[(Int, Int, Int, Int, Int)] + assertEquals(tuple5Getter.at(1).get(tuple5), 1) + assertEquals(tuple5Getter.at(2).get(tuple5), 2) + assertEquals(tuple5Getter.at(3).get(tuple5), 3) + assertEquals(tuple5Getter.at(4).get(tuple5), 4) + assertEquals(tuple5Getter.at(5).get(tuple5), 5) + assertEquals(tuple5.applyGetter(tuple5Getter).at(1).get, 1) + assertEquals(tuple5.applyGetter(tuple5Getter).at(2).get, 2) + assertEquals(tuple5.applyGetter(tuple5Getter).at(3).get, 3) + assertEquals(tuple5.applyGetter(tuple5Getter).at(4).get, 4) + assertEquals(tuple5.applyGetter(tuple5Getter).at(5).get, 5) + + val tuple6 = (1, 2, 3, 4, 5, 6) + val tuple6Getter = Getter.id[(Int, Int, Int, Int, Int, Int)] + assertEquals(tuple6Getter.at(1).get(tuple6), 1) + assertEquals(tuple6Getter.at(2).get(tuple6), 2) + assertEquals(tuple6Getter.at(3).get(tuple6), 3) + assertEquals(tuple6Getter.at(4).get(tuple6), 4) + assertEquals(tuple6Getter.at(5).get(tuple6), 5) + assertEquals(tuple6Getter.at(6).get(tuple6), 6) + assertEquals(tuple6.applyGetter(tuple6Getter).at(1).get, 1) + assertEquals(tuple6.applyGetter(tuple6Getter).at(2).get, 2) + assertEquals(tuple6.applyGetter(tuple6Getter).at(3).get, 3) + assertEquals(tuple6.applyGetter(tuple6Getter).at(4).get, 4) + assertEquals(tuple6.applyGetter(tuple6Getter).at(5).get, 5) + assertEquals(tuple6.applyGetter(tuple6Getter).at(6).get, 6) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapGetter = Getter.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapGetter.at(1).get(sortedMap), Some("one")) + assertEquals(sortedMapGetter.at(0).get(sortedMap), None) + assertEquals(sortedMap.applyGetter(sortedMapGetter).at(1).get, Some("one")) + assertEquals(sortedMap.applyGetter(sortedMapGetter).at(0).get, None) + + val listMap = immutable.ListMap(1 -> "one") + val listMapGetter = Getter.id[immutable.ListMap[Int, String]] + assertEquals(listMapGetter.at(1).get(listMap), Some("one")) + assertEquals(listMapGetter.at(0).get(listMap), None) + assertEquals(listMap.applyGetter(listMapGetter).at(1).get, Some("one")) + assertEquals(listMap.applyGetter(listMapGetter).at(0).get, None) + + val map = immutable.Map(1 -> "one") + val mapGetter = Getter.id[Map[Int, String]] + assertEquals(mapGetter.at(1).get(map), Some("one")) + assertEquals(mapGetter.at(0).get(map), None) + assertEquals(map.applyGetter(mapGetter).at(1).get, Some("one")) + assertEquals(map.applyGetter(mapGetter).at(0).get, None) + + val set = Set(1) + val setGetter = Getter.id[Set[Int]] + assertEquals(setGetter.at(1).get(set), true) + assertEquals(setGetter.at(0).get(set), false) + assertEquals(set.applyGetter(setGetter).at(1).get, true) + assertEquals(set.applyGetter(setGetter).at(0).get, false) + } + + test("index") { + val list = List(1) + val listGetter = Getter.id[List[Int]] + assertEquals(listGetter.index(0).getAll(list), List(1)) + assertEquals(listGetter.index(1).getAll(list), Nil) + assertEquals(list.applyGetter(listGetter).index(0).getAll, List(1)) + assertEquals(list.applyGetter(listGetter).index(1).getAll, Nil) + + val lazyList = LazyList(1) + val lazyListGetter = Getter.id[LazyList[Int]] + assertEquals(lazyListGetter.index(0).getAll(lazyList), List(1)) + assertEquals(lazyListGetter.index(1).getAll(lazyList), Nil) + assertEquals(lazyList.applyGetter(lazyListGetter).index(0).getAll, List(1)) + assertEquals(lazyList.applyGetter(lazyListGetter).index(1).getAll, Nil) + + val listMap = immutable.ListMap(1 -> "one") + val listMapGetter = Getter.id[immutable.ListMap[Int, String]] + assertEquals(listMapGetter.index(0).getAll(listMap), Nil) + assertEquals(listMapGetter.index(1).getAll(listMap), List("one")) + assertEquals(listMap.applyGetter(listMapGetter).index(0).getAll, Nil) + assertEquals(listMap.applyGetter(listMapGetter).index(1).getAll, List("one")) + + val map = Map(1 -> "one") + val mapGetter = Getter.id[Map[Int, String]] + assertEquals(mapGetter.index(0).getAll(map), Nil) + assertEquals(mapGetter.index(1).getAll(map), List("one")) + assertEquals(map.applyGetter(mapGetter).index(0).getAll, Nil) + assertEquals(map.applyGetter(mapGetter).index(1).getAll, List("one")) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapGetter = Getter.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapGetter.index(0).getAll(sortedMap), Nil) + assertEquals(sortedMapGetter.index(1).getAll(sortedMap), List("one")) + assertEquals(sortedMap.applyGetter(sortedMapGetter).index(0).getAll, Nil) + assertEquals(sortedMap.applyGetter(sortedMapGetter).index(1).getAll, List("one")) + + val vector = Vector(1) + val vectorGetter = Getter.id[Vector[Int]] + assertEquals(vectorGetter.index(0).getAll(vector), List(1)) + assertEquals(vectorGetter.index(1).getAll(vector), Nil) + assertEquals(vector.applyGetter(vectorGetter).index(0).getAll, List(1)) + assertEquals(vector.applyGetter(vectorGetter).index(1).getAll, Nil) + + val chain = Chain.one(1) + val chainGetter = Getter.id[Chain[Int]] + assertEquals(chainGetter.index(0).getAll(chain), List(1)) + assertEquals(chainGetter.index(1).getAll(chain), Nil) + assertEquals(chain.applyGetter(chainGetter).index(0).getAll, List(1)) + assertEquals(chain.applyGetter(chainGetter).index(1).getAll, Nil) + + val nec = NonEmptyChain.one(1) + val necGetter = Getter.id[NonEmptyChain[Int]] + assertEquals(necGetter.index(0).getAll(nec), List(1)) + assertEquals(necGetter.index(1).getAll(nec), Nil) + assertEquals(nec.applyGetter(necGetter).index(0).getAll, List(1)) + assertEquals(nec.applyGetter(necGetter).index(1).getAll, Nil) + + val nev = NonEmptyVector.one(1) + val nevGetter = Getter.id[NonEmptyVector[Int]] + assertEquals(nevGetter.index(0).getAll(nev), List(1)) + assertEquals(nevGetter.index(1).getAll(nev), Nil) + assertEquals(nev.applyGetter(nevGetter).index(0).getAll, List(1)) + assertEquals(nev.applyGetter(nevGetter).index(1).getAll, Nil) + + val nel = NonEmptyList.one(1) + val nelGetter = Getter.id[NonEmptyList[Int]] + assertEquals(nelGetter.index(0).getAll(nel), List(1)) + assertEquals(nelGetter.index(1).getAll(nel), Nil) + assertEquals(nel.applyGetter(nelGetter).index(0).getAll, List(1)) + assertEquals(nel.applyGetter(nelGetter).index(1).getAll, Nil) + } } diff --git a/test/shared/src/test/scala/monocle/IsoSpec.scala b/test/shared/src/test/scala/monocle/IsoSpec.scala index 309df82fe..74a8d0e18 100644 --- a/test/shared/src/test/scala/monocle/IsoSpec.scala +++ b/test/shared/src/test/scala/monocle/IsoSpec.scala @@ -4,9 +4,11 @@ import monocle.law.discipline._ import monocle.macros.GenIso import org.scalacheck.{Arbitrary, Gen} import org.scalacheck.Arbitrary._ - import cats.Eq import cats.arrow.{Category, Compose} +import cats.data.{Chain, NonEmptyChain, NonEmptyList, NonEmptyVector} + +import scala.collection.immutable class IsoSpec extends MonocleSuite { val _nullary: Iso[Nullary, Unit] = Iso[Nullary, Unit](n => ()) { case () => @@ -198,4 +200,161 @@ assertEquals( (Nullary() match { case _nullary(unit) => unit }) , (())) assertEquals(iso.each.getAll(obj), List(1, 2, 3)) assertEquals(obj.applyIso(iso).each.getAll, List(1, 2, 3)) } + + test("at") { + val tuple2 = (1, 2) + val tuple2Lens = Iso.id[(Int, Int)] + assertEquals(tuple2Lens.at(1).get(tuple2), 1) + assertEquals(tuple2Lens.at(2).get(tuple2), 2) + assertEquals(tuple2.applyIso(tuple2Lens).at(1).get, 1) + assertEquals(tuple2.applyIso(tuple2Lens).at(2).get, 2) + + val tuple3 = (1, 2, 3) + val tuple3Lens = Iso.id[(Int, Int, Int)] + assertEquals(tuple3Lens.at(1).get(tuple3), 1) + assertEquals(tuple3Lens.at(2).get(tuple3), 2) + assertEquals(tuple3Lens.at(3).get(tuple3), 3) + assertEquals(tuple3.applyIso(tuple3Lens).at(1).get, 1) + assertEquals(tuple3.applyIso(tuple3Lens).at(2).get, 2) + assertEquals(tuple3.applyIso(tuple3Lens).at(3).get, 3) + + val tuple4 = (1, 2, 3, 4) + val tuple4Lens = Iso.id[(Int, Int, Int, Int)] + assertEquals(tuple4Lens.at(1).get(tuple4), 1) + assertEquals(tuple4Lens.at(2).get(tuple4), 2) + assertEquals(tuple4Lens.at(3).get(tuple4), 3) + assertEquals(tuple4Lens.at(4).get(tuple4), 4) + assertEquals(tuple4.applyIso(tuple4Lens).at(1).get, 1) + assertEquals(tuple4.applyIso(tuple4Lens).at(2).get, 2) + assertEquals(tuple4.applyIso(tuple4Lens).at(3).get, 3) + assertEquals(tuple4.applyIso(tuple4Lens).at(4).get, 4) + + val tuple5 = (1, 2, 3, 4, 5) + val tuple5Lens = Iso.id[(Int, Int, Int, Int, Int)] + assertEquals(tuple5Lens.at(1).get(tuple5), 1) + assertEquals(tuple5Lens.at(2).get(tuple5), 2) + assertEquals(tuple5Lens.at(3).get(tuple5), 3) + assertEquals(tuple5Lens.at(4).get(tuple5), 4) + assertEquals(tuple5Lens.at(5).get(tuple5), 5) + assertEquals(tuple5.applyIso(tuple5Lens).at(1).get, 1) + assertEquals(tuple5.applyIso(tuple5Lens).at(2).get, 2) + assertEquals(tuple5.applyIso(tuple5Lens).at(3).get, 3) + assertEquals(tuple5.applyIso(tuple5Lens).at(4).get, 4) + assertEquals(tuple5.applyIso(tuple5Lens).at(5).get, 5) + + val tuple6 = (1, 2, 3, 4, 5, 6) + val tuple6Lens = Iso.id[(Int, Int, Int, Int, Int, Int)] + assertEquals(tuple6Lens.at(1).get(tuple6), 1) + assertEquals(tuple6Lens.at(2).get(tuple6), 2) + assertEquals(tuple6Lens.at(3).get(tuple6), 3) + assertEquals(tuple6Lens.at(4).get(tuple6), 4) + assertEquals(tuple6Lens.at(5).get(tuple6), 5) + assertEquals(tuple6Lens.at(6).get(tuple6), 6) + assertEquals(tuple6.applyIso(tuple6Lens).at(1).get, 1) + assertEquals(tuple6.applyIso(tuple6Lens).at(2).get, 2) + assertEquals(tuple6.applyIso(tuple6Lens).at(3).get, 3) + assertEquals(tuple6.applyIso(tuple6Lens).at(4).get, 4) + assertEquals(tuple6.applyIso(tuple6Lens).at(5).get, 5) + assertEquals(tuple6.applyIso(tuple6Lens).at(6).get, 6) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapLens = Iso.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapLens.at(1).get(sortedMap), Some("one")) + assertEquals(sortedMapLens.at(2).get(sortedMap), None) + assertEquals(sortedMap.applyIso(sortedMapLens).at(1).get, Some("one")) + assertEquals(sortedMap.applyIso(sortedMapLens).at(2).get, None) + + val listMap = immutable.ListMap(1 -> "one") + val listMapLens = Iso.id[immutable.ListMap[Int, String]] + assertEquals(listMapLens.at(1).get(listMap), Some("one")) + assertEquals(listMapLens.at(2).get(listMap), None) + assertEquals(listMap.applyIso(listMapLens).at(1).get, Some("one")) + assertEquals(listMap.applyIso(listMapLens).at(2).get, None) + + val map = immutable.Map(1 -> "one") + val mapLens = Iso.id[Map[Int, String]] + assertEquals(mapLens.at(1).get(map), Some("one")) + assertEquals(mapLens.at(2).get(map), None) + assertEquals(map.applyIso(mapLens).at(1).get, Some("one")) + assertEquals(map.applyIso(mapLens).at(2).get, None) + + val set = Set(1) + val setLens = Iso.id[Set[Int]] + assertEquals(setLens.at(1).get(set), true) + assertEquals(setLens.at(2).get(set), false) + assertEquals(set.applyIso(setLens).at(1).get, true) + assertEquals(set.applyIso(setLens).at(2).get, false) + } + + test("index") { + val list = List(1) + val listLens = Iso.id[List[Int]] + assertEquals(listLens.index(0).getOption(list), Some(1)) + assertEquals(listLens.index(1).getOption(list), None) + assertEquals(list.applyIso(listLens).index(0).getOption, Some(1)) + assertEquals(list.applyIso(listLens).index(1).getOption, None) + + val lazyList = LazyList(1) + val lazyListLens = Iso.id[LazyList[Int]] + assertEquals(lazyListLens.index(0).getOption(lazyList), Some(1)) + assertEquals(lazyListLens.index(1).getOption(lazyList), None) + assertEquals(lazyList.applyIso(lazyListLens).index(0).getOption, Some(1)) + assertEquals(lazyList.applyIso(lazyListLens).index(1).getOption, None) + + val listMap = immutable.ListMap(1 -> "one") + val listMapLens = Iso.id[immutable.ListMap[Int, String]] + assertEquals(listMapLens.index(0).getOption(listMap), None) + assertEquals(listMapLens.index(1).getOption(listMap), Some("one")) + assertEquals(listMap.applyIso(listMapLens).index(0).getOption, None) + assertEquals(listMap.applyIso(listMapLens).index(1).getOption, Some("one")) + + val map = Map(1 -> "one") + val mapLens = Iso.id[Map[Int, String]] + assertEquals(mapLens.index(1).getOption(map), Some("one")) + assertEquals(mapLens.index(0).getOption(map), None) + assertEquals(map.applyIso(mapLens).index(1).getOption, Some("one")) + assertEquals(map.applyIso(mapLens).index(0).getOption, None) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapLens = Iso.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapLens.index(1).getOption(sortedMap), Some("one")) + assertEquals(sortedMapLens.index(0).getOption(sortedMap), None) + assertEquals(sortedMap.applyIso(sortedMapLens).index(1).getOption, Some("one")) + assertEquals(sortedMap.applyIso(sortedMapLens).index(0).getOption, None) + + val vector = Vector(1) + val vectorLens = Iso.id[Vector[Int]] + assertEquals(vectorLens.index(0).getOption(vector), Some(1)) + assertEquals(vectorLens.index(1).getOption(vector), None) + assertEquals(vector.applyIso(vectorLens).index(0).getOption, Some(1)) + assertEquals(vector.applyIso(vectorLens).index(1).getOption, None) + + val chain = Chain.one(1) + val chainLens = Iso.id[Chain[Int]] + assertEquals(chainLens.index(0).getOption(chain), Some(1)) + assertEquals(chainLens.index(1).getOption(chain), None) + assertEquals(chain.applyIso(chainLens).index(0).getOption, Some(1)) + assertEquals(chain.applyIso(chainLens).index(1).getOption, None) + + val nec = NonEmptyChain.one(1) + val necLens = Iso.id[NonEmptyChain[Int]] + assertEquals(necLens.index(0).getOption(nec), Some(1)) + assertEquals(necLens.index(1).getOption(nec), None) + assertEquals(nec.applyIso(necLens).index(0).getOption, Some(1)) + assertEquals(nec.applyIso(necLens).index(1).getOption, None) + + val nev = NonEmptyVector.one(1) + val nevLens = Iso.id[NonEmptyVector[Int]] + assertEquals(nevLens.index(0).getOption(nev), Some(1)) + assertEquals(nevLens.index(1).getOption(nev), None) + assertEquals(nev.applyIso(nevLens).index(0).getOption, Some(1)) + assertEquals(nev.applyIso(nevLens).index(1).getOption, None) + + val nel = NonEmptyList.one(1) + val nelLens = Iso.id[NonEmptyList[Int]] + assertEquals(nelLens.index(0).getOption(nel), Some(1)) + assertEquals(nelLens.index(1).getOption(nel), None) + assertEquals(nel.applyIso(nelLens).index(0).getOption, Some(1)) + assertEquals(nel.applyIso(nelLens).index(1).getOption, None) + } } diff --git a/test/shared/src/test/scala/monocle/LensSpec.scala b/test/shared/src/test/scala/monocle/LensSpec.scala index 6c5401e78..b23ba7d90 100644 --- a/test/shared/src/test/scala/monocle/LensSpec.scala +++ b/test/shared/src/test/scala/monocle/LensSpec.scala @@ -1,12 +1,14 @@ package monocle +import cats.Eq +import cats.arrow.{Category, Choice, Compose} +import cats.data.{Chain, NonEmptyChain, NonEmptyList, NonEmptyVector} import monocle.law.discipline.{LensTests, OptionalTests, SetterTests, TraversalTests} import monocle.macros.{GenLens, Lenses} import org.scalacheck.Arbitrary import org.scalacheck.Arbitrary._ -import cats.Eq -import cats.arrow.{Category, Choice, Compose} +import scala.collection.immutable case class Point(x: Int, y: Int) @Lenses case class Example(s: String, p: Point) @@ -128,4 +130,160 @@ class LensSpec extends MonocleSuite { assertEquals(obj.applyLens(lens).each.getAll, List(1, 2, 3)) } + test("at") { + val tuple2 = (1, 2) + val tuple2Lens = Lens.id[(Int, Int)] + assertEquals(tuple2Lens.at(1).get(tuple2), 1) + assertEquals(tuple2Lens.at(2).get(tuple2), 2) + assertEquals(tuple2.applyLens(tuple2Lens).at(1).get, 1) + assertEquals(tuple2.applyLens(tuple2Lens).at(2).get, 2) + + val tuple3 = (1, 2, 3) + val tuple3Lens = Lens.id[(Int, Int, Int)] + assertEquals(tuple3Lens.at(1).get(tuple3), 1) + assertEquals(tuple3Lens.at(2).get(tuple3), 2) + assertEquals(tuple3Lens.at(3).get(tuple3), 3) + assertEquals(tuple3.applyLens(tuple3Lens).at(1).get, 1) + assertEquals(tuple3.applyLens(tuple3Lens).at(2).get, 2) + assertEquals(tuple3.applyLens(tuple3Lens).at(3).get, 3) + + val tuple4 = (1, 2, 3, 4) + val tuple4Lens = Lens.id[(Int, Int, Int, Int)] + assertEquals(tuple4Lens.at(1).get(tuple4), 1) + assertEquals(tuple4Lens.at(2).get(tuple4), 2) + assertEquals(tuple4Lens.at(3).get(tuple4), 3) + assertEquals(tuple4Lens.at(4).get(tuple4), 4) + assertEquals(tuple4.applyLens(tuple4Lens).at(1).get, 1) + assertEquals(tuple4.applyLens(tuple4Lens).at(2).get, 2) + assertEquals(tuple4.applyLens(tuple4Lens).at(3).get, 3) + assertEquals(tuple4.applyLens(tuple4Lens).at(4).get, 4) + + val tuple5 = (1, 2, 3, 4, 5) + val tuple5Lens = Lens.id[(Int, Int, Int, Int, Int)] + assertEquals(tuple5Lens.at(1).get(tuple5), 1) + assertEquals(tuple5Lens.at(2).get(tuple5), 2) + assertEquals(tuple5Lens.at(3).get(tuple5), 3) + assertEquals(tuple5Lens.at(4).get(tuple5), 4) + assertEquals(tuple5Lens.at(5).get(tuple5), 5) + assertEquals(tuple5.applyLens(tuple5Lens).at(1).get, 1) + assertEquals(tuple5.applyLens(tuple5Lens).at(2).get, 2) + assertEquals(tuple5.applyLens(tuple5Lens).at(3).get, 3) + assertEquals(tuple5.applyLens(tuple5Lens).at(4).get, 4) + assertEquals(tuple5.applyLens(tuple5Lens).at(5).get, 5) + + val tuple6 = (1, 2, 3, 4, 5, 6) + val tuple6Lens = Lens.id[(Int, Int, Int, Int, Int, Int)] + assertEquals(tuple6Lens.at(1).get(tuple6), 1) + assertEquals(tuple6Lens.at(2).get(tuple6), 2) + assertEquals(tuple6Lens.at(3).get(tuple6), 3) + assertEquals(tuple6Lens.at(4).get(tuple6), 4) + assertEquals(tuple6Lens.at(5).get(tuple6), 5) + assertEquals(tuple6Lens.at(6).get(tuple6), 6) + assertEquals(tuple6.applyLens(tuple6Lens).at(1).get, 1) + assertEquals(tuple6.applyLens(tuple6Lens).at(2).get, 2) + assertEquals(tuple6.applyLens(tuple6Lens).at(3).get, 3) + assertEquals(tuple6.applyLens(tuple6Lens).at(4).get, 4) + assertEquals(tuple6.applyLens(tuple6Lens).at(5).get, 5) + assertEquals(tuple6.applyLens(tuple6Lens).at(6).get, 6) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapLens = Lens.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapLens.at(1).get(sortedMap), Some("one")) + assertEquals(sortedMapLens.at(2).get(sortedMap), None) + assertEquals(sortedMap.applyLens(sortedMapLens).at(1).get, Some("one")) + assertEquals(sortedMap.applyLens(sortedMapLens).at(2).get, None) + + val listMap = immutable.ListMap(1 -> "one") + val listMapLens = Lens.id[immutable.ListMap[Int, String]] + assertEquals(listMapLens.at(1).get(listMap), Some("one")) + assertEquals(listMapLens.at(2).get(listMap), None) + assertEquals(listMap.applyLens(listMapLens).at(1).get, Some("one")) + assertEquals(listMap.applyLens(listMapLens).at(2).get, None) + + val map = immutable.Map(1 -> "one") + val mapLens = Lens.id[Map[Int, String]] + assertEquals(mapLens.at(1).get(map), Some("one")) + assertEquals(mapLens.at(2).get(map), None) + assertEquals(map.applyLens(mapLens).at(1).get, Some("one")) + assertEquals(map.applyLens(mapLens).at(2).get, None) + + val set = Set(1) + val setLens = Lens.id[Set[Int]] + assertEquals(setLens.at(1).get(set), true) + assertEquals(setLens.at(2).get(set), false) + assertEquals(set.applyLens(setLens).at(1).get, true) + assertEquals(set.applyLens(setLens).at(2).get, false) + } + + test("index") { + val list = List(1) + val listLens = Lens.id[List[Int]] + assertEquals(listLens.index(0).getOption(list), Some(1)) + assertEquals(listLens.index(1).getOption(list), None) + assertEquals(list.applyLens(listLens).index(0).getOption, Some(1)) + assertEquals(list.applyLens(listLens).index(1).getOption, None) + + val lazyList = LazyList(1) + val lazyListLens = Lens.id[LazyList[Int]] + assertEquals(lazyListLens.index(0).getOption(lazyList), Some(1)) + assertEquals(lazyListLens.index(1).getOption(lazyList), None) + assertEquals(lazyList.applyLens(lazyListLens).index(0).getOption, Some(1)) + assertEquals(lazyList.applyLens(lazyListLens).index(1).getOption, None) + + val listMap = immutable.ListMap(1 -> "one") + val listMapLens = Lens.id[immutable.ListMap[Int, String]] + assertEquals(listMapLens.index(0).getOption(listMap), None) + assertEquals(listMapLens.index(1).getOption(listMap), Some("one")) + assertEquals(listMap.applyLens(listMapLens).index(0).getOption, None) + assertEquals(listMap.applyLens(listMapLens).index(1).getOption, Some("one")) + + val map = Map(1 -> "one") + val mapLens = Lens.id[Map[Int, String]] + assertEquals(mapLens.index(1).getOption(map), Some("one")) + assertEquals(mapLens.index(0).getOption(map), None) + assertEquals(map.applyLens(mapLens).index(1).getOption, Some("one")) + assertEquals(map.applyLens(mapLens).index(0).getOption, None) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapLens = Lens.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapLens.index(1).getOption(sortedMap), Some("one")) + assertEquals(sortedMapLens.index(0).getOption(sortedMap), None) + assertEquals(sortedMap.applyLens(sortedMapLens).index(1).getOption, Some("one")) + assertEquals(sortedMap.applyLens(sortedMapLens).index(0).getOption, None) + + val vector = Vector(1) + val vectorLens = Lens.id[Vector[Int]] + assertEquals(vectorLens.index(0).getOption(vector), Some(1)) + assertEquals(vectorLens.index(1).getOption(vector), None) + assertEquals(vector.applyLens(vectorLens).index(0).getOption, Some(1)) + assertEquals(vector.applyLens(vectorLens).index(1).getOption, None) + + val chain = Chain.one(1) + val chainLens = Lens.id[Chain[Int]] + assertEquals(chainLens.index(0).getOption(chain), Some(1)) + assertEquals(chainLens.index(1).getOption(chain), None) + assertEquals(chain.applyLens(chainLens).index(0).getOption, Some(1)) + assertEquals(chain.applyLens(chainLens).index(1).getOption, None) + + val nec = NonEmptyChain.one(1) + val necLens = Lens.id[NonEmptyChain[Int]] + assertEquals(necLens.index(0).getOption(nec), Some(1)) + assertEquals(necLens.index(1).getOption(nec), None) + assertEquals(nec.applyLens(necLens).index(0).getOption, Some(1)) + assertEquals(nec.applyLens(necLens).index(1).getOption, None) + + val nev = NonEmptyVector.one(1) + val nevLens = Lens.id[NonEmptyVector[Int]] + assertEquals(nevLens.index(0).getOption(nev), Some(1)) + assertEquals(nevLens.index(1).getOption(nev), None) + assertEquals(nev.applyLens(nevLens).index(0).getOption, Some(1)) + assertEquals(nev.applyLens(nevLens).index(1).getOption, None) + + val nel = NonEmptyList.one(1) + val nelLens = Lens.id[NonEmptyList[Int]] + assertEquals(nelLens.index(0).getOption(nel), Some(1)) + assertEquals(nelLens.index(1).getOption(nel), None) + assertEquals(nel.applyLens(nelLens).index(0).getOption, Some(1)) + assertEquals(nel.applyLens(nelLens).index(1).getOption, None) + } } diff --git a/test/shared/src/test/scala/monocle/OptionalSpec.scala b/test/shared/src/test/scala/monocle/OptionalSpec.scala index 6b4d0e109..8676c1193 100644 --- a/test/shared/src/test/scala/monocle/OptionalSpec.scala +++ b/test/shared/src/test/scala/monocle/OptionalSpec.scala @@ -2,8 +2,11 @@ package monocle import monocle.law.discipline.{OptionalTests, SetterTests, TraversalTests} import cats.arrow.{Category, Choice, Compose} +import cats.data.{Chain, NonEmptyChain, NonEmptyList, NonEmptyVector} import monocle.macros.GenLens +import scala.collection.immutable + class OptionalSpec extends MonocleSuite { def headOption[A]: Optional[List[A], A] = Optional[List[A], A](_.headOption) { a => @@ -141,4 +144,161 @@ class OptionalSpec extends MonocleSuite { assertEquals(optional.each.getAll(obj), List(1, 2, 3)) assertEquals(obj.applyOptional(optional).each.getAll, List(1, 2, 3)) } + + test("at") { + val tuple2 = (1, 2) + val tuple2Optional = Optional.id[(Int, Int)] + assertEquals(tuple2Optional.at(1).getOption(tuple2), Some(1)) + assertEquals(tuple2Optional.at(2).getOption(tuple2), Some(2)) + assertEquals(tuple2.applyOptional(tuple2Optional).at(1).getOption, Some(1)) + assertEquals(tuple2.applyOptional(tuple2Optional).at(2).getOption, Some(2)) + + val tuple3 = (1, 2, 3) + val tuple3Optional = Optional.id[(Int, Int, Int)] + assertEquals(tuple3Optional.at(1).getOption(tuple3), Some(1)) + assertEquals(tuple3Optional.at(2).getOption(tuple3), Some(2)) + assertEquals(tuple3Optional.at(3).getOption(tuple3), Some(3)) + assertEquals(tuple3.applyOptional(tuple3Optional).at(1).getOption, Some(1)) + assertEquals(tuple3.applyOptional(tuple3Optional).at(2).getOption, Some(2)) + assertEquals(tuple3.applyOptional(tuple3Optional).at(3).getOption, Some(3)) + + val tuple4 = (1, 2, 3, 4) + val tuple4Optional = Optional.id[(Int, Int, Int, Int)] + assertEquals(tuple4Optional.at(1).getOption(tuple4), Some(1)) + assertEquals(tuple4Optional.at(2).getOption(tuple4), Some(2)) + assertEquals(tuple4Optional.at(3).getOption(tuple4), Some(3)) + assertEquals(tuple4Optional.at(4).getOption(tuple4), Some(4)) + assertEquals(tuple4.applyOptional(tuple4Optional).at(1).getOption, Some(1)) + assertEquals(tuple4.applyOptional(tuple4Optional).at(2).getOption, Some(2)) + assertEquals(tuple4.applyOptional(tuple4Optional).at(3).getOption, Some(3)) + assertEquals(tuple4.applyOptional(tuple4Optional).at(4).getOption, Some(4)) + + val tuple5 = (1, 2, 3, 4, 5) + val tuple5Optional = Optional.id[(Int, Int, Int, Int, Int)] + assertEquals(tuple5Optional.at(1).getOption(tuple5), Some(1)) + assertEquals(tuple5Optional.at(2).getOption(tuple5), Some(2)) + assertEquals(tuple5Optional.at(3).getOption(tuple5), Some(3)) + assertEquals(tuple5Optional.at(4).getOption(tuple5), Some(4)) + assertEquals(tuple5Optional.at(5).getOption(tuple5), Some(5)) + assertEquals(tuple5.applyOptional(tuple5Optional).at(1).getOption, Some(1)) + assertEquals(tuple5.applyOptional(tuple5Optional).at(2).getOption, Some(2)) + assertEquals(tuple5.applyOptional(tuple5Optional).at(3).getOption, Some(3)) + assertEquals(tuple5.applyOptional(tuple5Optional).at(4).getOption, Some(4)) + assertEquals(tuple5.applyOptional(tuple5Optional).at(5).getOption, Some(5)) + + val tuple6 = (1, 2, 3, 4, 5, 6) + val tuple6Optional = Optional.id[(Int, Int, Int, Int, Int, Int)] + assertEquals(tuple6Optional.at(1).getOption(tuple6), Some(1)) + assertEquals(tuple6Optional.at(2).getOption(tuple6), Some(2)) + assertEquals(tuple6Optional.at(3).getOption(tuple6), Some(3)) + assertEquals(tuple6Optional.at(4).getOption(tuple6), Some(4)) + assertEquals(tuple6Optional.at(5).getOption(tuple6), Some(5)) + assertEquals(tuple6Optional.at(6).getOption(tuple6), Some(6)) + assertEquals(tuple6.applyOptional(tuple6Optional).at(1).getOption, Some(1)) + assertEquals(tuple6.applyOptional(tuple6Optional).at(2).getOption, Some(2)) + assertEquals(tuple6.applyOptional(tuple6Optional).at(3).getOption, Some(3)) + assertEquals(tuple6.applyOptional(tuple6Optional).at(4).getOption, Some(4)) + assertEquals(tuple6.applyOptional(tuple6Optional).at(5).getOption, Some(5)) + assertEquals(tuple6.applyOptional(tuple6Optional).at(6).getOption, Some(6)) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapOptional = Optional.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapOptional.at(1).getOption(sortedMap), Some(Some("one"))) + assertEquals(sortedMapOptional.at(0).getOption(sortedMap), Some(None)) + assertEquals(sortedMap.applyOptional(sortedMapOptional).at(1).getOption, Some(Some("one"))) + assertEquals(sortedMap.applyOptional(sortedMapOptional).at(0).getOption, Some(None)) + + val listMap = immutable.ListMap(1 -> "one") + val listMapOptional = Optional.id[immutable.ListMap[Int, String]] + assertEquals(listMapOptional.at(1).getOption(listMap), Some(Some("one"))) + assertEquals(listMapOptional.at(0).getOption(listMap), Some(None)) + assertEquals(listMap.applyOptional(listMapOptional).at(1).getOption, Some(Some("one"))) + assertEquals(listMap.applyOptional(listMapOptional).at(0).getOption, Some(None)) + + val map = immutable.Map(1 -> "one") + val mapOptional = Optional.id[Map[Int, String]] + assertEquals(mapOptional.at(1).getOption(map), Some(Some("one"))) + assertEquals(mapOptional.at(0).getOption(map), Some(None)) + assertEquals(map.applyOptional(mapOptional).at(1).getOption, Some(Some("one"))) + assertEquals(map.applyOptional(mapOptional).at(0).getOption, Some(None)) + + val set = Set(1) + val setOptional = Optional.id[Set[Int]] + assertEquals(setOptional.at(1).getOption(set), Some(true)) + assertEquals(setOptional.at(0).getOption(set), Some(false)) + assertEquals(set.applyOptional(setOptional).at(1).getOption, Some(true)) + assertEquals(set.applyOptional(setOptional).at(0).getOption, Some(false)) + } + + test("index") { + val list = List(1) + val listOptional = Optional.id[List[Int]] + assertEquals(listOptional.index(0).getOption(list), Some(1)) + assertEquals(listOptional.index(1).getOption(list), None) + assertEquals(list.applyOptional(listOptional).index(0).getOption, Some(1)) + assertEquals(list.applyOptional(listOptional).index(1).getOption, None) + + val lazyList = LazyList(1) + val lazyListOptional = Optional.id[LazyList[Int]] + assertEquals(lazyListOptional.index(0).getOption(lazyList), Some(1)) + assertEquals(lazyListOptional.index(1).getOption(lazyList), None) + assertEquals(lazyList.applyOptional(lazyListOptional).index(0).getOption, Some(1)) + assertEquals(lazyList.applyOptional(lazyListOptional).index(1).getOption, None) + + val listMap = immutable.ListMap(1 -> "one") + val listMapOptional = Optional.id[immutable.ListMap[Int, String]] + assertEquals(listMapOptional.index(0).getOption(listMap), None) + assertEquals(listMapOptional.index(1).getOption(listMap), Some("one")) + assertEquals(listMap.applyOptional(listMapOptional).index(0).getOption, None) + assertEquals(listMap.applyOptional(listMapOptional).index(1).getOption, Some("one")) + + val map = Map(1 -> "one") + val mapOptional = Optional.id[Map[Int, String]] + assertEquals(mapOptional.index(0).getOption(map), None) + assertEquals(mapOptional.index(1).getOption(map), Some("one")) + assertEquals(map.applyOptional(mapOptional).index(0).getOption, None) + assertEquals(map.applyOptional(mapOptional).index(1).getOption, Some("one")) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapOptional = Optional.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapOptional.index(0).getOption(sortedMap), None) + assertEquals(sortedMapOptional.index(1).getOption(sortedMap), Some("one")) + assertEquals(sortedMap.applyOptional(sortedMapOptional).index(0).getOption, None) + assertEquals(sortedMap.applyOptional(sortedMapOptional).index(1).getOption, Some("one")) + + val vector = Vector(1) + val vectorOptional = Optional.id[Vector[Int]] + assertEquals(vectorOptional.index(0).getOption(vector), Some(1)) + assertEquals(vectorOptional.index(1).getOption(vector), None) + assertEquals(vector.applyOptional(vectorOptional).index(0).getOption, Some(1)) + assertEquals(vector.applyOptional(vectorOptional).index(1).getOption, None) + + val chain = Chain.one(1) + val chainOptional = Optional.id[Chain[Int]] + assertEquals(chainOptional.index(0).getOption(chain), Some(1)) + assertEquals(chainOptional.index(1).getOption(chain), None) + assertEquals(chain.applyOptional(chainOptional).index(0).getOption, Some(1)) + assertEquals(chain.applyOptional(chainOptional).index(1).getOption, None) + + val nec = NonEmptyChain.one(1) + val necOptional = Optional.id[NonEmptyChain[Int]] + assertEquals(necOptional.index(0).getOption(nec), Some(1)) + assertEquals(necOptional.index(1).getOption(nec), None) + assertEquals(nec.applyOptional(necOptional).index(0).getOption, Some(1)) + assertEquals(nec.applyOptional(necOptional).index(1).getOption, None) + + val nev = NonEmptyVector.one(1) + val nevOptional = Optional.id[NonEmptyVector[Int]] + assertEquals(nevOptional.index(0).getOption(nev), Some(1)) + assertEquals(nevOptional.index(1).getOption(nev), None) + assertEquals(nev.applyOptional(nevOptional).index(0).getOption, Some(1)) + assertEquals(nev.applyOptional(nevOptional).index(1).getOption, None) + + val nel = NonEmptyList.one(1) + val nelOptional = Optional.id[NonEmptyList[Int]] + assertEquals(nelOptional.index(0).getOption(nel), Some(1)) + assertEquals(nelOptional.index(1).getOption(nel), None) + assertEquals(nel.applyOptional(nelOptional).index(0).getOption, Some(1)) + assertEquals(nel.applyOptional(nelOptional).index(1).getOption, None) + } } diff --git a/test/shared/src/test/scala/monocle/PrismSpec.scala b/test/shared/src/test/scala/monocle/PrismSpec.scala index 64f7b3f92..447f98395 100644 --- a/test/shared/src/test/scala/monocle/PrismSpec.scala +++ b/test/shared/src/test/scala/monocle/PrismSpec.scala @@ -3,8 +3,11 @@ package monocle import monocle.law.discipline.{OptionalTests, PrismTests, SetterTests, TraversalTests} import monocle.macros.{GenIso, GenPrism} import cats.arrow.{Category, Compose} +import cats.data.{Chain, NonEmptyChain, NonEmptyList, NonEmptyVector} import cats.syntax.either._ +import scala.collection.immutable + class PrismSpec extends MonocleSuite { def _right[E, A]: Prism[Either[E, A], A] = Prism[Either[E, A], A](_.toOption)(Either.right) @@ -214,4 +217,161 @@ assertEquals( ((Nullary(): Arities) match { case _nullary(unit) => unit }) , assertEquals(prism.each.getAll(obj), List(1, 2, 3)) assertEquals(obj.applyPrism(prism).each.getAll, List(1, 2, 3)) } + + test("at") { + val tuple2 = (1, 2) + val tuple2Prism = Prism.id[(Int, Int)] + assertEquals(tuple2Prism.at(1).getOption(tuple2), Some(1)) + assertEquals(tuple2Prism.at(2).getOption(tuple2), Some(2)) + assertEquals(tuple2.applyPrism(tuple2Prism).at(1).getOption, Some(1)) + assertEquals(tuple2.applyPrism(tuple2Prism).at(2).getOption, Some(2)) + + val tuple3 = (1, 2, 3) + val tuple3Prism = Prism.id[(Int, Int, Int)] + assertEquals(tuple3Prism.at(1).getOption(tuple3), Some(1)) + assertEquals(tuple3Prism.at(2).getOption(tuple3), Some(2)) + assertEquals(tuple3Prism.at(3).getOption(tuple3), Some(3)) + assertEquals(tuple3.applyPrism(tuple3Prism).at(1).getOption, Some(1)) + assertEquals(tuple3.applyPrism(tuple3Prism).at(2).getOption, Some(2)) + assertEquals(tuple3.applyPrism(tuple3Prism).at(3).getOption, Some(3)) + + val tuple4 = (1, 2, 3, 4) + val tuple4Prism = Prism.id[(Int, Int, Int, Int)] + assertEquals(tuple4Prism.at(1).getOption(tuple4), Some(1)) + assertEquals(tuple4Prism.at(2).getOption(tuple4), Some(2)) + assertEquals(tuple4Prism.at(3).getOption(tuple4), Some(3)) + assertEquals(tuple4Prism.at(4).getOption(tuple4), Some(4)) + assertEquals(tuple4.applyPrism(tuple4Prism).at(1).getOption, Some(1)) + assertEquals(tuple4.applyPrism(tuple4Prism).at(2).getOption, Some(2)) + assertEquals(tuple4.applyPrism(tuple4Prism).at(3).getOption, Some(3)) + assertEquals(tuple4.applyPrism(tuple4Prism).at(4).getOption, Some(4)) + + val tuple5 = (1, 2, 3, 4, 5) + val tuple5Prism = Prism.id[(Int, Int, Int, Int, Int)] + assertEquals(tuple5Prism.at(1).getOption(tuple5), Some(1)) + assertEquals(tuple5Prism.at(2).getOption(tuple5), Some(2)) + assertEquals(tuple5Prism.at(3).getOption(tuple5), Some(3)) + assertEquals(tuple5Prism.at(4).getOption(tuple5), Some(4)) + assertEquals(tuple5Prism.at(5).getOption(tuple5), Some(5)) + assertEquals(tuple5.applyPrism(tuple5Prism).at(1).getOption, Some(1)) + assertEquals(tuple5.applyPrism(tuple5Prism).at(2).getOption, Some(2)) + assertEquals(tuple5.applyPrism(tuple5Prism).at(3).getOption, Some(3)) + assertEquals(tuple5.applyPrism(tuple5Prism).at(4).getOption, Some(4)) + assertEquals(tuple5.applyPrism(tuple5Prism).at(5).getOption, Some(5)) + + val tuple6 = (1, 2, 3, 4, 5, 6) + val tuple6Prism = Prism.id[(Int, Int, Int, Int, Int, Int)] + assertEquals(tuple6Prism.at(1).getOption(tuple6), Some(1)) + assertEquals(tuple6Prism.at(2).getOption(tuple6), Some(2)) + assertEquals(tuple6Prism.at(3).getOption(tuple6), Some(3)) + assertEquals(tuple6Prism.at(4).getOption(tuple6), Some(4)) + assertEquals(tuple6Prism.at(5).getOption(tuple6), Some(5)) + assertEquals(tuple6Prism.at(6).getOption(tuple6), Some(6)) + assertEquals(tuple6.applyPrism(tuple6Prism).at(1).getOption, Some(1)) + assertEquals(tuple6.applyPrism(tuple6Prism).at(2).getOption, Some(2)) + assertEquals(tuple6.applyPrism(tuple6Prism).at(3).getOption, Some(3)) + assertEquals(tuple6.applyPrism(tuple6Prism).at(4).getOption, Some(4)) + assertEquals(tuple6.applyPrism(tuple6Prism).at(5).getOption, Some(5)) + assertEquals(tuple6.applyPrism(tuple6Prism).at(6).getOption, Some(6)) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapPrism = Prism.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapPrism.at(1).getOption(sortedMap), Some(Some("one"))) + assertEquals(sortedMapPrism.at(0).getOption(sortedMap), Some(None)) + assertEquals(sortedMap.applyPrism(sortedMapPrism).at(1).getOption, Some(Some("one"))) + assertEquals(sortedMap.applyPrism(sortedMapPrism).at(0).getOption, Some(None)) + + val listMap = immutable.ListMap(1 -> "one") + val listMapPrism = Prism.id[immutable.ListMap[Int, String]] + assertEquals(listMapPrism.at(1).getOption(listMap), Some(Some("one"))) + assertEquals(listMapPrism.at(0).getOption(listMap), Some(None)) + assertEquals(listMap.applyPrism(listMapPrism).at(1).getOption, Some(Some("one"))) + assertEquals(listMap.applyPrism(listMapPrism).at(0).getOption, Some(None)) + + val map = immutable.Map(1 -> "one") + val mapPrism = Prism.id[Map[Int, String]] + assertEquals(mapPrism.at(1).getOption(map), Some(Some("one"))) + assertEquals(mapPrism.at(0).getOption(map), Some(None)) + assertEquals(map.applyPrism(mapPrism).at(1).getOption, Some(Some("one"))) + assertEquals(map.applyPrism(mapPrism).at(0).getOption, Some(None)) + + val set = Set(1) + val setPrism = Prism.id[Set[Int]] + assertEquals(setPrism.at(1).getOption(set), Some(true)) + assertEquals(setPrism.at(0).getOption(set), Some(false)) + assertEquals(set.applyPrism(setPrism).at(1).getOption, Some(true)) + assertEquals(set.applyPrism(setPrism).at(0).getOption, Some(false)) + } + + test("index") { + val list = List(1) + val listPrism = Prism.id[List[Int]] + assertEquals(listPrism.index(0).getOption(list), Some(1)) + assertEquals(listPrism.index(1).getOption(list), None) + assertEquals(list.applyPrism(listPrism).index(0).getOption, Some(1)) + assertEquals(list.applyPrism(listPrism).index(1).getOption, None) + + val lazyList = LazyList(1) + val lazyListPrism = Prism.id[LazyList[Int]] + assertEquals(lazyListPrism.index(0).getOption(lazyList), Some(1)) + assertEquals(lazyListPrism.index(1).getOption(lazyList), None) + assertEquals(lazyList.applyPrism(lazyListPrism).index(0).getOption, Some(1)) + assertEquals(lazyList.applyPrism(lazyListPrism).index(1).getOption, None) + + val listMap = immutable.ListMap(1 -> "one") + val listMapPrism = Prism.id[immutable.ListMap[Int, String]] + assertEquals(listMapPrism.index(0).getOption(listMap), None) + assertEquals(listMapPrism.index(1).getOption(listMap), Some("one")) + assertEquals(listMap.applyPrism(listMapPrism).index(0).getOption, None) + assertEquals(listMap.applyPrism(listMapPrism).index(1).getOption, Some("one")) + + val map = Map(1 -> "one") + val mapPrism = Prism.id[Map[Int, String]] + assertEquals(mapPrism.index(0).getOption(map), None) + assertEquals(mapPrism.index(1).getOption(map), Some("one")) + assertEquals(map.applyPrism(mapPrism).index(0).getOption, None) + assertEquals(map.applyPrism(mapPrism).index(1).getOption, Some("one")) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapPrism = Prism.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapPrism.index(0).getOption(sortedMap), None) + assertEquals(sortedMapPrism.index(1).getOption(sortedMap), Some("one")) + assertEquals(sortedMap.applyPrism(sortedMapPrism).index(0).getOption, None) + assertEquals(sortedMap.applyPrism(sortedMapPrism).index(1).getOption, Some("one")) + + val vector = Vector(1) + val vectorPrism = Prism.id[Vector[Int]] + assertEquals(vectorPrism.index(0).getOption(vector), Some(1)) + assertEquals(vectorPrism.index(1).getOption(vector), None) + assertEquals(vector.applyPrism(vectorPrism).index(0).getOption, Some(1)) + assertEquals(vector.applyPrism(vectorPrism).index(1).getOption, None) + + val chain = Chain.one(1) + val chainPrism = Prism.id[Chain[Int]] + assertEquals(chainPrism.index(0).getOption(chain), Some(1)) + assertEquals(chainPrism.index(1).getOption(chain), None) + assertEquals(chain.applyPrism(chainPrism).index(0).getOption, Some(1)) + assertEquals(chain.applyPrism(chainPrism).index(1).getOption, None) + + val nec = NonEmptyChain.one(1) + val necPrism = Prism.id[NonEmptyChain[Int]] + assertEquals(necPrism.index(0).getOption(nec), Some(1)) + assertEquals(necPrism.index(1).getOption(nec), None) + assertEquals(nec.applyPrism(necPrism).index(0).getOption, Some(1)) + assertEquals(nec.applyPrism(necPrism).index(1).getOption, None) + + val nev = NonEmptyVector.one(1) + val nevPrism = Prism.id[NonEmptyVector[Int]] + assertEquals(nevPrism.index(0).getOption(nev), Some(1)) + assertEquals(nevPrism.index(1).getOption(nev), None) + assertEquals(nev.applyPrism(nevPrism).index(0).getOption, Some(1)) + assertEquals(nev.applyPrism(nevPrism).index(1).getOption, None) + + val nel = NonEmptyList.one(1) + val nelPrism = Prism.id[NonEmptyList[Int]] + assertEquals(nelPrism.index(0).getOption(nel), Some(1)) + assertEquals(nelPrism.index(1).getOption(nel), None) + assertEquals(nel.applyPrism(nelPrism).index(0).getOption, Some(1)) + assertEquals(nel.applyPrism(nelPrism).index(1).getOption, None) + } } diff --git a/test/shared/src/test/scala/monocle/SetterSpec.scala b/test/shared/src/test/scala/monocle/SetterSpec.scala index 5219e49c8..feac945cb 100644 --- a/test/shared/src/test/scala/monocle/SetterSpec.scala +++ b/test/shared/src/test/scala/monocle/SetterSpec.scala @@ -1,8 +1,11 @@ package monocle import cats.arrow.{Category, Choice, Compose} +import cats.data.{Chain, NonEmptyChain, NonEmptyList, NonEmptyVector} import monocle.macros.GenLens +import scala.collection.immutable + class SetterSpec extends MonocleSuite { def eachL[A]: Setter[List[A], A] = PSetter.fromFunctor[List, A, A] def even[A]: Setter[List[A], A] = @@ -75,4 +78,167 @@ class SetterSpec extends MonocleSuite { assertEquals(setter.each.replace(3)(obj), SomeTest(1, List(3, 3, 3))) assertEquals(obj.applySetter(setter).each.replace(3), SomeTest(1, List(3, 3, 3))) } + + test("at") { + val tuple2 = (1, 2) + val tuple2Setter = Setter.id[(Int, Int)] + assertEquals(tuple2Setter.at(1).replace(2)(tuple2), (2, 2)) + assertEquals(tuple2Setter.at(2).replace(3)(tuple2), (1, 3)) + assertEquals(tuple2.applySetter(tuple2Setter).at(1).replace(2), (2, 2)) + assertEquals(tuple2.applySetter(tuple2Setter).at(2).replace(3), (1, 3)) + + val tuple3 = (1, 2, 3) + val tuple3Setter = Setter.id[(Int, Int, Int)] + assertEquals(tuple3Setter.at(1).replace(2)(tuple3), (2, 2, 3)) + assertEquals(tuple3Setter.at(2).replace(3)(tuple3), (1, 3, 3)) + assertEquals(tuple3Setter.at(3).replace(4)(tuple3), (1, 2, 4)) + assertEquals(tuple3.applySetter(tuple3Setter).at(1).replace(2), (2, 2, 3)) + assertEquals(tuple3.applySetter(tuple3Setter).at(2).replace(3), (1, 3, 3)) + assertEquals(tuple3.applySetter(tuple3Setter).at(3).replace(4), (1, 2, 4)) + + val tuple4 = (1, 2, 3, 4) + val tuple4Setter = Setter.id[(Int, Int, Int, Int)] + assertEquals(tuple4Setter.at(1).replace(2)(tuple4), (2, 2, 3, 4)) + assertEquals(tuple4Setter.at(2).replace(3)(tuple4), (1, 3, 3, 4)) + assertEquals(tuple4Setter.at(3).replace(4)(tuple4), (1, 2, 4, 4)) + assertEquals(tuple4Setter.at(4).replace(1)(tuple4), (1, 2, 3, 1)) + assertEquals(tuple4.applySetter(tuple4Setter).at(1).replace(2), (2, 2, 3, 4)) + assertEquals(tuple4.applySetter(tuple4Setter).at(2).replace(3), (1, 3, 3, 4)) + assertEquals(tuple4.applySetter(tuple4Setter).at(3).replace(4), (1, 2, 4, 4)) + assertEquals(tuple4.applySetter(tuple4Setter).at(4).replace(1), (1, 2, 3, 1)) + + val tuple5 = (1, 2, 3, 4, 5) + val tuple5Setter = Setter.id[(Int, Int, Int, Int, Int)] + assertEquals(tuple5Setter.at(1).replace(2)(tuple5), (2, 2, 3, 4, 5)) + assertEquals(tuple5Setter.at(2).replace(3)(tuple5), (1, 3, 3, 4, 5)) + assertEquals(tuple5Setter.at(3).replace(4)(tuple5), (1, 2, 4, 4, 5)) + assertEquals(tuple5Setter.at(4).replace(5)(tuple5), (1, 2, 3, 5, 5)) + assertEquals(tuple5Setter.at(5).replace(1)(tuple5), (1, 2, 3, 4, 1)) + assertEquals(tuple5.applySetter(tuple5Setter).at(1).replace(2), (2, 2, 3, 4, 5)) + assertEquals(tuple5.applySetter(tuple5Setter).at(2).replace(3), (1, 3, 3, 4, 5)) + assertEquals(tuple5.applySetter(tuple5Setter).at(3).replace(4), (1, 2, 4, 4, 5)) + assertEquals(tuple5.applySetter(tuple5Setter).at(4).replace(5), (1, 2, 3, 5, 5)) + assertEquals(tuple5.applySetter(tuple5Setter).at(5).replace(1), (1, 2, 3, 4, 1)) + + val tuple6 = (1, 2, 3, 4, 5, 6) + val tuple6Setter = Setter.id[(Int, Int, Int, Int, Int, Int)] + assertEquals(tuple6Setter.at(1).replace(2)(tuple6), (2, 2, 3, 4, 5, 6)) + assertEquals(tuple6Setter.at(2).replace(3)(tuple6), (1, 3, 3, 4, 5, 6)) + assertEquals(tuple6Setter.at(3).replace(4)(tuple6), (1, 2, 4, 4, 5, 6)) + assertEquals(tuple6Setter.at(4).replace(5)(tuple6), (1, 2, 3, 5, 5, 6)) + assertEquals(tuple6Setter.at(5).replace(6)(tuple6), (1, 2, 3, 4, 6, 6)) + assertEquals(tuple6Setter.at(6).replace(1)(tuple6), (1, 2, 3, 4, 5, 1)) + assertEquals(tuple6.applySetter(tuple6Setter).at(1).replace(2), (2, 2, 3, 4, 5, 6)) + assertEquals(tuple6.applySetter(tuple6Setter).at(2).replace(3), (1, 3, 3, 4, 5, 6)) + assertEquals(tuple6.applySetter(tuple6Setter).at(3).replace(4), (1, 2, 4, 4, 5, 6)) + assertEquals(tuple6.applySetter(tuple6Setter).at(4).replace(5), (1, 2, 3, 5, 5, 6)) + assertEquals(tuple6.applySetter(tuple6Setter).at(5).replace(6), (1, 2, 3, 4, 6, 6)) + assertEquals(tuple6.applySetter(tuple6Setter).at(6).replace(1), (1, 2, 3, 4, 5, 1)) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapSetter = Setter.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapSetter.at(1).replace(Some("two"))(sortedMap), immutable.SortedMap(1 -> "two")) + assertEquals(sortedMapSetter.at(0).replace(Some("two"))(sortedMap), immutable.SortedMap(0 -> "two", 1 -> "one")) + assertEquals(sortedMap.applySetter(sortedMapSetter).at(1).replace(Some("two")), immutable.SortedMap(1 -> "two")) + assertEquals( + sortedMap.applySetter(sortedMapSetter).at(0).replace(Some("two")), + immutable.SortedMap(0 -> "two", 1 -> "one") + ) + + val listMap = immutable.ListMap(1 -> "one") + val listMapSetter = Setter.id[immutable.ListMap[Int, String]] + assertEquals(listMapSetter.at(1).replace(Some("two"))(listMap), immutable.ListMap(1 -> "two")) + assertEquals(listMapSetter.at(0).replace(Some("two"))(listMap), immutable.ListMap(1 -> "one", 0 -> "two")) + assertEquals(listMap.applySetter(listMapSetter).at(1).replace(Some("two")), immutable.ListMap(1 -> "two")) + assertEquals( + listMap.applySetter(listMapSetter).at(0).replace(Some("two")), + immutable.ListMap(1 -> "one", 0 -> "two") + ) + + val map = immutable.Map(1 -> "one") + val mapSetter = Setter.id[Map[Int, String]] + assertEquals(mapSetter.at(1).replace(Some("two"))(map), Map(1 -> "two")) + assertEquals(mapSetter.at(0).replace(Some("two"))(map), Map(1 -> "one", 0 -> "two")) + assertEquals(map.applySetter(mapSetter).at(1).replace(Some("two")), Map(1 -> "two")) + assertEquals(map.applySetter(mapSetter).at(0).replace(Some("two")), Map(1 -> "one", 0 -> "two")) + + val set = Set(1) + val setSetter = Setter.id[Set[Int]] + assertEquals(setSetter.at(1).replace(true)(set), Set(1)) + assertEquals(setSetter.at(2).replace(false)(set), Set(1)) + assertEquals(set.applySetter(setSetter).at(1).replace(true), Set(1)) + assertEquals(set.applySetter(setSetter).at(2).replace(false), Set(1)) + } + + test("index") { + val list = List(1) + val listSetter = Setter.id[List[Int]] + assertEquals(listSetter.index(0).replace(2)(list), List(2)) + assertEquals(listSetter.index(1).replace(2)(list), list) + assertEquals(list.applySetter(listSetter).index(0).replace(2), List(2)) + assertEquals(list.applySetter(listSetter).index(1).replace(2), list) + + val lazyList = LazyList(1) + val lazyListSetter = Setter.id[LazyList[Int]] + assertEquals(lazyListSetter.index(0).replace(2)(lazyList), LazyList(2)) + assertEquals(lazyListSetter.index(1).replace(2)(lazyList), lazyList) + assertEquals(lazyList.applySetter(lazyListSetter).index(0).replace(2), LazyList(2)) + assertEquals(lazyList.applySetter(lazyListSetter).index(1).replace(2), lazyList) + + val listMap = immutable.ListMap(1 -> "one") + val listMapSetter = Setter.id[immutable.ListMap[Int, String]] + assertEquals(listMapSetter.index(0).replace("two")(listMap), listMap) + assertEquals(listMapSetter.index(1).replace("two")(listMap), immutable.ListMap(1 -> "two")) + assertEquals(listMap.applySetter(listMapSetter).index(0).replace("two"), listMap) + assertEquals(listMap.applySetter(listMapSetter).index(1).replace("two"), immutable.ListMap(1 -> "two")) + + val map = Map(1 -> "one") + val mapSetter = Setter.id[Map[Int, String]] + assertEquals(mapSetter.index(0).replace("two")(map), map) + assertEquals(mapSetter.index(1).replace("two")(map), Map(1 -> "two")) + assertEquals(map.applySetter(mapSetter).index(0).replace("two"), map) + assertEquals(map.applySetter(mapSetter).index(1).replace("two"), Map(1 -> "two")) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapSetter = Setter.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapSetter.index(0).replace("two")(sortedMap), sortedMap) + assertEquals(sortedMapSetter.index(1).replace("two")(sortedMap), immutable.SortedMap(1 -> "two")) + assertEquals(sortedMap.applySetter(sortedMapSetter).index(0).replace("two"), sortedMap) + assertEquals(sortedMap.applySetter(sortedMapSetter).index(1).replace("two"), immutable.SortedMap(1 -> "two")) + + val vector = Vector(1) + val vectorSetter = Setter.id[Vector[Int]] + assertEquals(vectorSetter.index(0).replace(2)(vector), Vector(2)) + assertEquals(vectorSetter.index(1).replace(2)(vector), vector) + assertEquals(vector.applySetter(vectorSetter).index(0).replace(2), Vector(2)) + assertEquals(vector.applySetter(vectorSetter).index(1).replace(2), vector) + + val chain = Chain.one(1) + val chainSetter = Setter.id[Chain[Int]] + assertEquals(chainSetter.index(0).replace(2)(chain), Chain(2)) + assertEquals(chainSetter.index(1).replace(2)(chain), chain) + assertEquals(chain.applySetter(chainSetter).index(0).replace(2), Chain(2)) + assertEquals(chain.applySetter(chainSetter).index(1).replace(2), chain) + + val nec = NonEmptyChain.one(1) + val necSetter = Setter.id[NonEmptyChain[Int]] + assertEquals(necSetter.index(0).replace(2)(nec), NonEmptyChain(2)) + assertEquals(necSetter.index(1).replace(2)(nec), nec) + assertEquals(nec.applySetter(necSetter).index(0).replace(2), NonEmptyChain(2)) + assertEquals(nec.applySetter(necSetter).index(1).replace(2), nec) + + val nev = NonEmptyVector.one(1) + val nevSetter = Setter.id[NonEmptyVector[Int]] + assertEquals(nevSetter.index(0).replace(2)(nev), NonEmptyVector.one(2)) + assertEquals(nevSetter.index(1).replace(2)(nev), nev) + assertEquals(nev.applySetter(nevSetter).index(0).replace(2), NonEmptyVector.one(2)) + assertEquals(nev.applySetter(nevSetter).index(1).replace(2), nev) + + val nel = NonEmptyList.one(1) + val nelSetter = Setter.id[NonEmptyList[Int]] + assertEquals(nelSetter.index(0).replace(2)(nel), NonEmptyList.one(2)) + assertEquals(nelSetter.index(1).replace(2)(nel), nel) + assertEquals(nel.applySetter(nelSetter).index(0).replace(2), NonEmptyList.one(2)) + assertEquals(nel.applySetter(nelSetter).index(1).replace(2), nel) + } } diff --git a/test/shared/src/test/scala/monocle/TraversalSpec.scala b/test/shared/src/test/scala/monocle/TraversalSpec.scala index 7f54f0361..950b6367c 100644 --- a/test/shared/src/test/scala/monocle/TraversalSpec.scala +++ b/test/shared/src/test/scala/monocle/TraversalSpec.scala @@ -4,11 +4,13 @@ import monocle.law.discipline.{SetterTests, TraversalTests} import monocle.macros.GenLens import org.scalacheck.Arbitrary import org.scalacheck.Arbitrary.arbitrary - import cats.Eq import cats.arrow.{Category, Choice, Compose} +import cats.data.{Chain, NonEmptyChain, NonEmptyList, NonEmptyVector} import cats.syntax.either._ +import scala.collection.immutable + class TraversalSpec extends MonocleSuite { case class Location(latitude: Int, longitude: Int, name: String) @@ -186,4 +188,161 @@ class TraversalSpec extends MonocleSuite { assertEquals(traversal.each.getAll(numbers), List(1, 2, 3, 4)) assertEquals(numbers.applyTraversal(traversal).each.getAll, List(1, 2, 3, 4)) } + + test("at") { + val tuple2 = (1, 2) + val tuple2Traversal = Traversal.id[(Int, Int)] + assertEquals(tuple2Traversal.at(1).getAll(tuple2), List(1)) + assertEquals(tuple2Traversal.at(2).getAll(tuple2), List(2)) + assertEquals(tuple2.applyTraversal(tuple2Traversal).at(1).getAll, List(1)) + assertEquals(tuple2.applyTraversal(tuple2Traversal).at(2).getAll, List(2)) + + val tuple3 = (1, 2, 3) + val tuple3Traversal = Traversal.id[(Int, Int, Int)] + assertEquals(tuple3Traversal.at(1).getAll(tuple3), List(1)) + assertEquals(tuple3Traversal.at(2).getAll(tuple3), List(2)) + assertEquals(tuple3Traversal.at(3).getAll(tuple3), List(3)) + assertEquals(tuple3.applyTraversal(tuple3Traversal).at(1).getAll, List(1)) + assertEquals(tuple3.applyTraversal(tuple3Traversal).at(2).getAll, List(2)) + assertEquals(tuple3.applyTraversal(tuple3Traversal).at(3).getAll, List(3)) + + val tuple4 = (1, 2, 3, 4) + val tuple4Traversal = Traversal.id[(Int, Int, Int, Int)] + assertEquals(tuple4Traversal.at(1).getAll(tuple4), List(1)) + assertEquals(tuple4Traversal.at(2).getAll(tuple4), List(2)) + assertEquals(tuple4Traversal.at(3).getAll(tuple4), List(3)) + assertEquals(tuple4Traversal.at(4).getAll(tuple4), List(4)) + assertEquals(tuple4.applyTraversal(tuple4Traversal).at(1).getAll, List(1)) + assertEquals(tuple4.applyTraversal(tuple4Traversal).at(2).getAll, List(2)) + assertEquals(tuple4.applyTraversal(tuple4Traversal).at(3).getAll, List(3)) + assertEquals(tuple4.applyTraversal(tuple4Traversal).at(4).getAll, List(4)) + + val tuple5 = (1, 2, 3, 4, 5) + val tuple5Traversal = Traversal.id[(Int, Int, Int, Int, Int)] + assertEquals(tuple5Traversal.at(1).getAll(tuple5), List(1)) + assertEquals(tuple5Traversal.at(2).getAll(tuple5), List(2)) + assertEquals(tuple5Traversal.at(3).getAll(tuple5), List(3)) + assertEquals(tuple5Traversal.at(4).getAll(tuple5), List(4)) + assertEquals(tuple5Traversal.at(5).getAll(tuple5), List(5)) + assertEquals(tuple5.applyTraversal(tuple5Traversal).at(1).getAll, List(1)) + assertEquals(tuple5.applyTraversal(tuple5Traversal).at(2).getAll, List(2)) + assertEquals(tuple5.applyTraversal(tuple5Traversal).at(3).getAll, List(3)) + assertEquals(tuple5.applyTraversal(tuple5Traversal).at(4).getAll, List(4)) + assertEquals(tuple5.applyTraversal(tuple5Traversal).at(5).getAll, List(5)) + + val tuple6 = (1, 2, 3, 4, 5, 6) + val tuple6Traversal = Traversal.id[(Int, Int, Int, Int, Int, Int)] + assertEquals(tuple6Traversal.at(1).getAll(tuple6), List(1)) + assertEquals(tuple6Traversal.at(2).getAll(tuple6), List(2)) + assertEquals(tuple6Traversal.at(3).getAll(tuple6), List(3)) + assertEquals(tuple6Traversal.at(4).getAll(tuple6), List(4)) + assertEquals(tuple6Traversal.at(5).getAll(tuple6), List(5)) + assertEquals(tuple6Traversal.at(6).getAll(tuple6), List(6)) + assertEquals(tuple6.applyTraversal(tuple6Traversal).at(1).getAll, List(1)) + assertEquals(tuple6.applyTraversal(tuple6Traversal).at(2).getAll, List(2)) + assertEquals(tuple6.applyTraversal(tuple6Traversal).at(3).getAll, List(3)) + assertEquals(tuple6.applyTraversal(tuple6Traversal).at(4).getAll, List(4)) + assertEquals(tuple6.applyTraversal(tuple6Traversal).at(5).getAll, List(5)) + assertEquals(tuple6.applyTraversal(tuple6Traversal).at(6).getAll, List(6)) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapTraversal = Traversal.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapTraversal.at(1).getAll(sortedMap), List(Some("one"))) + assertEquals(sortedMapTraversal.at(0).getAll(sortedMap), List(None)) + assertEquals(sortedMap.applyTraversal(sortedMapTraversal).at(1).getAll, List(Some("one"))) + assertEquals(sortedMap.applyTraversal(sortedMapTraversal).at(0).getAll, List(None)) + + val listMap = immutable.ListMap(1 -> "one") + val listMapTraversal = Traversal.id[immutable.ListMap[Int, String]] + assertEquals(listMapTraversal.at(1).getAll(listMap), List(Some("one"))) + assertEquals(listMapTraversal.at(0).getAll(listMap), List(None)) + assertEquals(listMap.applyTraversal(listMapTraversal).at(1).getAll, List(Some("one"))) + assertEquals(listMap.applyTraversal(listMapTraversal).at(0).getAll, List(None)) + + val map = immutable.Map(1 -> "one") + val mapTraversal = Traversal.id[Map[Int, String]] + assertEquals(mapTraversal.at(1).getAll(map), List(Some("one"))) + assertEquals(mapTraversal.at(0).getAll(map), List(None)) + assertEquals(map.applyTraversal(mapTraversal).at(1).getAll, List(Some("one"))) + assertEquals(map.applyTraversal(mapTraversal).at(0).getAll, List(None)) + + val set = Set(1) + val setTraversal = Traversal.id[Set[Int]] + assertEquals(setTraversal.at(1).getAll(set), List(true)) + assertEquals(setTraversal.at(0).getAll(set), List(false)) + assertEquals(set.applyTraversal(setTraversal).at(1).getAll, List(true)) + assertEquals(set.applyTraversal(setTraversal).at(0).getAll, List(false)) + } + + test("index") { + val list = List(1) + val listTraversal = Traversal.id[List[Int]] + assertEquals(listTraversal.index(0).getAll(list), List(1)) + assertEquals(listTraversal.index(1).getAll(list), Nil) + assertEquals(list.applyTraversal(listTraversal).index(0).getAll, List(1)) + assertEquals(list.applyTraversal(listTraversal).index(1).getAll, Nil) + + val lazyList = LazyList(1) + val lazyListTraversal = Traversal.id[LazyList[Int]] + assertEquals(lazyListTraversal.index(0).getAll(lazyList), List(1)) + assertEquals(lazyListTraversal.index(1).getAll(lazyList), Nil) + assertEquals(lazyList.applyTraversal(lazyListTraversal).index(0).getAll, List(1)) + assertEquals(lazyList.applyTraversal(lazyListTraversal).index(1).getAll, Nil) + + val listMap = immutable.ListMap(1 -> "one") + val listMapTraversal = Traversal.id[immutable.ListMap[Int, String]] + assertEquals(listMapTraversal.index(0).getAll(listMap), Nil) + assertEquals(listMapTraversal.index(1).getAll(listMap), List("one")) + assertEquals(listMap.applyTraversal(listMapTraversal).index(0).getAll, Nil) + assertEquals(listMap.applyTraversal(listMapTraversal).index(1).getAll, List("one")) + + val map = Map(1 -> "one") + val mapTraversal = Traversal.id[Map[Int, String]] + assertEquals(mapTraversal.index(0).getAll(map), Nil) + assertEquals(mapTraversal.index(1).getAll(map), List("one")) + assertEquals(map.applyTraversal(mapTraversal).index(0).getAll, Nil) + assertEquals(map.applyTraversal(mapTraversal).index(1).getAll, List("one")) + + val sortedMap = immutable.SortedMap(1 -> "one") + val sortedMapTraversal = Traversal.id[immutable.SortedMap[Int, String]] + assertEquals(sortedMapTraversal.index(0).getAll(sortedMap), Nil) + assertEquals(sortedMapTraversal.index(1).getAll(sortedMap), List("one")) + assertEquals(sortedMap.applyTraversal(sortedMapTraversal).index(0).getAll, Nil) + assertEquals(sortedMap.applyTraversal(sortedMapTraversal).index(1).getAll, List("one")) + + val vector = Vector(1) + val vectorTraversal = Traversal.id[Vector[Int]] + assertEquals(vectorTraversal.index(0).getAll(vector), List(1)) + assertEquals(vectorTraversal.index(1).getAll(vector), Nil) + assertEquals(vector.applyTraversal(vectorTraversal).index(0).getAll, List(1)) + assertEquals(vector.applyTraversal(vectorTraversal).index(1).getAll, Nil) + + val chain = Chain.one(1) + val chainTraversal = Traversal.id[Chain[Int]] + assertEquals(chainTraversal.index(0).getAll(chain), List(1)) + assertEquals(chainTraversal.index(1).getAll(chain), Nil) + assertEquals(chain.applyTraversal(chainTraversal).index(0).getAll, List(1)) + assertEquals(chain.applyTraversal(chainTraversal).index(1).getAll, Nil) + + val nec = NonEmptyChain.one(1) + val necTraversal = Traversal.id[NonEmptyChain[Int]] + assertEquals(necTraversal.index(0).getAll(nec), List(1)) + assertEquals(necTraversal.index(1).getAll(nec), Nil) + assertEquals(nec.applyTraversal(necTraversal).index(0).getAll, List(1)) + assertEquals(nec.applyTraversal(necTraversal).index(1).getAll, Nil) + + val nev = NonEmptyVector.one(1) + val nevTraversal = Traversal.id[NonEmptyVector[Int]] + assertEquals(nevTraversal.index(0).getAll(nev), List(1)) + assertEquals(nevTraversal.index(1).getAll(nev), Nil) + assertEquals(nev.applyTraversal(nevTraversal).index(0).getAll, List(1)) + assertEquals(nev.applyTraversal(nevTraversal).index(1).getAll, Nil) + + val nel = NonEmptyList.one(1) + val nelTraversal = Traversal.id[NonEmptyList[Int]] + assertEquals(nelTraversal.index(0).getAll(nel), List(1)) + assertEquals(nelTraversal.index(1).getAll(nel), Nil) + assertEquals(nel.applyTraversal(nelTraversal).index(0).getAll, List(1)) + assertEquals(nel.applyTraversal(nelTraversal).index(1).getAll, Nil) + } }