/* * Copyright 2020 Daniel Spiewak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package parseback.util import org.specs2.mutable._ import org.specs2.ScalaCheck import org.scalacheck._ class CatenableSpec extends Specification with ScalaCheck { import Catenable.{+:, Syntax} import Prop._ "catenable" should { "retain sequence semantics" in { "with left biasing" >> forAll { xs: List[Int] => Catenable(xs: _*).toList mustEqual xs } "without biasing" >> forAll { xs: List[Int] => def convert[A](xs: List[A]): Catenable[A] = { if (xs.isEmpty) { Catenable.empty } else if (xs.length == 1) { Catenable(xs: _*) } else { val (left, right) = xs splitAt (xs.length - 1) convert(left) ++ convert(right) } } convert(xs).toList mustEqual xs } "with right biasing" >> forAll { xs: List[Int] => val c = xs.foldLeft(Catenable.empty[Int]) { (c, i) => c ++ Catenable(i) } c.toList mustEqual xs } } "implement length matching list" in forAll { xs: List[Int] => Catenable(xs: _*).length mustEqual xs.length } "implement isEmpty matching list" in forAll { xs: List[Int] => Catenable(xs: _*).isEmpty mustEqual xs.isEmpty } "implement filter matching list" in forAll { (xs: List[Int], p: Int => Boolean) => val actual = Catenable(xs: _*) filter p toList val expect = xs filter p actual mustEqual expect } "not evaluate the right when unconsing the left" in { var evaluated = false lazy val right: Catenable[Int] = { evaluated = true Catenable.empty } (Catenable(42, 24) ++ right) must beLike { case i +: tail => i mustEqual 42 evaluated must beFalse tail must beLike { case i2 +: tail => i2 mustEqual 24 evaluated must beFalse } } } } }