You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
3.0 KiB
102 lines
3.0 KiB
package green.thisfieldwas.embracingnondeterminism.data
|
|
|
|
import green.thisfieldwas.embracingnondeterminism.util.Laws
|
|
import org.scalacheck.Arbitrary
|
|
import org.scalacheck.Arbitrary.arbitrary
|
|
import org.scalatest.Inside
|
|
import org.scalatest.matchers.should.Matchers
|
|
import org.scalatest.wordspec.AnyWordSpec
|
|
|
|
class NonEmptyChainSpec extends AnyWordSpec with Matchers with Inside {
|
|
|
|
"NonEmptyChain" can {
|
|
"prepend" which {
|
|
"prepends a chain to the start of another chain" in {
|
|
val prefix = NonEmptyChain(1, 2, 3)
|
|
val suffix = NonEmptyChain(4, 5, 6)
|
|
(suffix.prepend(prefix).toSeq should contain).theSameElementsAs(Seq(1, 2, 3, 4, 5, 6))
|
|
}
|
|
}
|
|
"append" which {
|
|
"appends a chain to the end of another chain" in {
|
|
val prefix = NonEmptyChain(1, 2, 3)
|
|
val suffix = NonEmptyChain(4, 5, 6)
|
|
(prefix.append(suffix).toSeq should contain).theSameElementsAs(Seq(1, 2, 3, 4, 5, 6))
|
|
}
|
|
}
|
|
"cons" which {
|
|
"prepends a value to the start of the chain" in {
|
|
val newHead = 1
|
|
val chain = NonEmptyChain(2, 3)
|
|
(chain.cons(newHead).toSeq should contain).theSameElementsAs(Seq(1, 2, 3))
|
|
}
|
|
}
|
|
"head" which {
|
|
"gets the first value in the chain" in {
|
|
val chain = NonEmptyChain(1, 2, 3, 4)
|
|
chain.head shouldBe 1
|
|
}
|
|
}
|
|
"tail" which {
|
|
"gets all but the first value in the chain" when {
|
|
"there are more than one value in the chain" in {
|
|
val chain = NonEmptyChain(1, 2, 3, 4)
|
|
inside(chain.tail) { case Some(tail) =>
|
|
(tail.toSeq should contain).theSameElementsAs(Seq(2, 3, 4))
|
|
}
|
|
}
|
|
"there is only one value in the chain" in {
|
|
val chain = NonEmptyChain(1)
|
|
inside(chain.tail) { case None => }
|
|
}
|
|
}
|
|
}
|
|
"length" which {
|
|
"gets the number of values in the chain" in {
|
|
val chain = NonEmptyChain(1, 2, 3, 4, 5)
|
|
chain.length shouldBe 5
|
|
}
|
|
}
|
|
"toSeq" which {
|
|
"creates a Scala Seq from the values in the chain" in {
|
|
import NonEmptyChain._
|
|
val messyChain = Append(
|
|
Append(
|
|
Singleton("apple"),
|
|
Singleton("banana"),
|
|
),
|
|
Append(
|
|
Singleton("orange"),
|
|
Append(
|
|
Singleton("pineapple"),
|
|
Append(
|
|
Singleton("pickle"),
|
|
Singleton("apricot"),
|
|
),
|
|
),
|
|
),
|
|
)
|
|
(messyChain.toSeq should contain).theSameElementsAs(
|
|
Seq(
|
|
"apple",
|
|
"banana",
|
|
"orange",
|
|
"pineapple",
|
|
"pickle",
|
|
"apricot",
|
|
)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class NonEmptyChainLaws extends Laws with SemigroupLaws {
|
|
|
|
import LiftedGens.nonEmptyChainLiftedGen
|
|
|
|
implicit def arbitraryNonEmptyChain[A: Arbitrary]: Arbitrary[NonEmptyChain[A]] =
|
|
Arbitrary(nonEmptyChainLiftedGen.lift(arbitrary[A]))
|
|
|
|
checkSemigroupLaws[NonEmptyChain[Int]]()
|
|
}
|
|
|