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

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]]()
}