7

I am trying out ScalaCheck for the first time and I want to generate an ordered array of Ints.

I read the documentation and did some search but I didn't find a way to do it.

Can someone shed some light on this?

Thanks

rmorais
  • 229
  • 1
  • 5

1 Answers1

7

I assume you want an arbitrary array of integers that's been sorted, right? If that's the case, you can use either of the following approaches to get a Gen[Array[Int]]:

val genIntArray = Gen.containerOf[Array, Int](
  Gen.chooseNum(Int.MinValue, Int.MaxValue)
)

Or:

val genIntArray = implicitly[Arbitrary[Array[Int]]].arbitrary

You can then use map to modify the generator to sort its results:

 val genSortedIntArray = genIntArray.map(_.sorted)

Now you can run genSortedIntArray.sample.get a few times to convince yourself that the result is a sorted array of random integers.

If you want an Arbitrary for sorted arrays of integers, it's best to define a wrapper instead of hiding the default Arbitrary[Array[Int]]. For example, you could write the following:

case class SortedIntArray(value: Array[Int]) extends AnyVal

object SortedIntArray {
  implicit val arb: Arbitrary[SortedIntArray] = Arbitrary(
    genSortedIntArray.map(SortedIntArray(_))
  )
}

And then:

forAll { (a: SortedIntArray) =>
  confirmThatMyFunctionOnSortedIntArraysWorks(a.value)
}
Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • When using specialized generators like this, I think it is better to avoid Arbitrary all together. You can just use your generator directly: forAll(genSortedIntArray) { a => ... }. It might be a matter of taste, however. – Rickard Nilsson Mar 16 '15 at 08:49