2011-06-19 16:32:21 -06:00
|
|
|
package akka.util
|
|
|
|
|
|
|
|
|
|
import org.scalatest.WordSpec
|
|
|
|
|
import org.scalatest.matchers.MustMatchers
|
|
|
|
|
import org.scalatest.BeforeAndAfterAll
|
|
|
|
|
import org.scalatest.prop.Checkers
|
|
|
|
|
import org.scalacheck._
|
|
|
|
|
import org.scalacheck.Arbitrary._
|
|
|
|
|
import org.scalacheck.Prop._
|
|
|
|
|
import org.scalacheck.Gen._
|
|
|
|
|
|
|
|
|
|
class ByteStringSpec extends WordSpec with MustMatchers with Checkers {
|
|
|
|
|
|
|
|
|
|
def genSimpleByteString(min: Int, max: Int) = for {
|
|
|
|
|
n ← choose(min, max)
|
|
|
|
|
b ← Gen.containerOfN[Array, Byte](n, arbitrary[Byte])
|
2012-05-01 18:41:04 +02:00
|
|
|
from ← choose(0, b.length)
|
|
|
|
|
until ← choose(from, b.length)
|
|
|
|
|
} yield ByteString(b).slice(from, until)
|
2011-06-19 16:32:21 -06:00
|
|
|
|
|
|
|
|
implicit val arbitraryByteString: Arbitrary[ByteString] = Arbitrary {
|
|
|
|
|
Gen.sized { s ⇒
|
|
|
|
|
for {
|
|
|
|
|
chunks ← choose(0, s)
|
|
|
|
|
bytes ← listOfN(chunks, genSimpleByteString(1, s / (chunks max 1)))
|
|
|
|
|
} yield (ByteString.empty /: bytes)(_ ++ _)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-01 18:41:04 +02:00
|
|
|
type ByteStringSlice = (ByteString, Int, Int)
|
|
|
|
|
|
|
|
|
|
implicit val arbitraryByteStringSlice: Arbitrary[ByteStringSlice] = Arbitrary {
|
|
|
|
|
for {
|
|
|
|
|
xs ← arbitraryByteString.arbitrary
|
|
|
|
|
from ← choose(0, xs.length)
|
|
|
|
|
until ← choose(from, xs.length)
|
|
|
|
|
} yield (xs, from, until)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def likeVecIt(bs: ByteString)(body: BufferedIterator[Byte] ⇒ Any, strict: Boolean = true): Boolean = {
|
|
|
|
|
val bsIterator = bs.iterator
|
|
|
|
|
val vecIterator = Vector(bs: _*).iterator.buffered
|
|
|
|
|
(body(bsIterator) == body(vecIterator)) &&
|
|
|
|
|
(!strict || (bsIterator.toSeq == vecIterator.toSeq))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def likeVecIts(a: ByteString, b: ByteString)(body: (BufferedIterator[Byte], BufferedIterator[Byte]) ⇒ Any, strict: Boolean = true): Boolean = {
|
|
|
|
|
val (bsAIt, bsBIt) = (a.iterator, b.iterator)
|
|
|
|
|
val (vecAIt, vecBIt) = (Vector(a: _*).iterator.buffered, Vector(b: _*).iterator.buffered)
|
|
|
|
|
(body(bsAIt, bsBIt) == body(vecAIt, vecBIt)) &&
|
|
|
|
|
(!strict || (bsAIt.toSeq, bsBIt.toSeq) == (vecAIt.toSeq, vecBIt.toSeq))
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-19 16:32:21 -06:00
|
|
|
"A ByteString" must {
|
|
|
|
|
"have correct size" when {
|
|
|
|
|
"concatenating" in { check((a: ByteString, b: ByteString) ⇒ (a ++ b).size == a.size + b.size) }
|
|
|
|
|
"dropping" in { check((a: ByteString, b: ByteString) ⇒ (a ++ b).drop(b.size).size == a.size) }
|
|
|
|
|
}
|
|
|
|
|
"be sequential" when {
|
|
|
|
|
"taking" in { check((a: ByteString, b: ByteString) ⇒ (a ++ b).take(a.size) == a) }
|
|
|
|
|
"dropping" in { check((a: ByteString, b: ByteString) ⇒ (a ++ b).drop(a.size) == b) }
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-05-01 18:41:04 +02:00
|
|
|
|
|
|
|
|
"A ByteStringIterator" must {
|
|
|
|
|
"behave like a buffered Vector Iterator" when {
|
|
|
|
|
"concatenating" in { check { (a: ByteString, b: ByteString) ⇒ likeVecIts(a, b) { (a, b) ⇒ (a ++ b).toSeq } } }
|
|
|
|
|
|
|
|
|
|
"calling head" in { check { a: ByteString ⇒ a.isEmpty || likeVecIt(a) { _.head } } }
|
|
|
|
|
"calling next" in { check { a: ByteString ⇒ a.isEmpty || likeVecIt(a) { _.next() } } }
|
|
|
|
|
"calling hasNext" in { check { a: ByteString ⇒ likeVecIt(a) { _.hasNext } } }
|
|
|
|
|
"calling length" in { check { a: ByteString ⇒ likeVecIt(a) { _.length } } }
|
|
|
|
|
"calling duplicate" in { check { a: ByteString ⇒ likeVecIt(a)({ _.duplicate match { case (a, b) ⇒ (a.toSeq, b.toSeq) } }, strict = false) } }
|
|
|
|
|
"calling span" in { check { (a: ByteString, b: Byte) ⇒ likeVecIt(a)({ _.span(_ == b) match { case (a, b) ⇒ (a.toSeq, b.toSeq) } }, strict = false) } }
|
|
|
|
|
"calling takeWhile" in { check { (a: ByteString, b: Byte) ⇒ likeVecIt(a)({ _.takeWhile(_ == b).toSeq }, strict = false) } }
|
|
|
|
|
"calling dropWhile" in { check { (a: ByteString, b: Byte) ⇒ likeVecIt(a) { _.dropWhile(_ == b).toSeq } } }
|
|
|
|
|
"calling indexWhere" in { check { (a: ByteString, b: Byte) ⇒ likeVecIt(a) { _.indexWhere(_ == b) } } }
|
|
|
|
|
"calling indexOf" in { check { (a: ByteString, b: Byte) ⇒ likeVecIt(a) { _.indexOf(b) } } }
|
|
|
|
|
"calling toSeq" in { check { a: ByteString ⇒ likeVecIt(a) { _.toSeq } } }
|
|
|
|
|
"calling foreach" in { check { a: ByteString ⇒ likeVecIt(a) { it ⇒ var acc = 0; it foreach { acc += _ }; acc } } }
|
|
|
|
|
"calling foldLeft" in { check { a: ByteString ⇒ likeVecIt(a) { _.foldLeft(0) { _ + _ } } } }
|
|
|
|
|
"calling toArray" in { check { a: ByteString ⇒ likeVecIt(a) { _.toArray.toSeq } } }
|
|
|
|
|
|
|
|
|
|
"calling slice" in {
|
|
|
|
|
check { slice: ByteStringSlice ⇒
|
|
|
|
|
slice match {
|
|
|
|
|
case (xs, from, until) ⇒ likeVecIt(xs)({
|
|
|
|
|
_.slice(from, until).toSeq
|
|
|
|
|
}, strict = false)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"calling copyToArray" in {
|
|
|
|
|
check { slice: ByteStringSlice ⇒
|
|
|
|
|
slice match {
|
|
|
|
|
case (xs, from, until) ⇒ likeVecIt(xs)({ it ⇒
|
|
|
|
|
val array = Array.ofDim[Byte](xs.length)
|
|
|
|
|
it.slice(from, until).copyToArray(array, from, until)
|
|
|
|
|
array.toSeq
|
|
|
|
|
}, strict = false)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-06-19 16:32:21 -06:00
|
|
|
}
|