Skip to content

Commit c1995eb

Browse files
author
Fede Fernández
authored
Arbitrary section (#5)
* Adds Arbitrary section * Includes the tests for arbitrary section
1 parent 3b148d5 commit c1995eb

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package scalachecklib
2+
3+
import org.scalatest.Matchers
4+
import org.scalatest.prop.Checkers
5+
6+
/** ==The `arbitrary` Generator
7+
*
8+
* There is a special generator, `org.scalacheck.Arbitrary.arbitrary`, which generates arbitrary values of any
9+
* supported type.
10+
*
11+
* {{{
12+
* val evenInteger = Arbitrary.arbitrary[Int] suchThat (_ % 2 == 0)
13+
* val squares = for {
14+
* xs <- Arbitrary.arbitrary[List[Int]]
15+
* } yield xs.map(x => x*x)
16+
* }}}
17+
*
18+
* The `arbitrary` generator is the generator used by ScalaCheck when it generates values for ''property'' parameters.
19+
* Most of the times, you have to supply the type of the value to `arbitrary`, like above, since Scala often can't
20+
* infer the type automatically. You can use `arbitrary` for any type that has an implicit `Arbitrary` instance.
21+
* As mentioned earlier, ScalaCheck has default support for common types, but it is also possible to define your own
22+
* implicit `Arbitrary` instances for unsupported types. See the following implicit Arbitrary definition for booleans,
23+
* that comes from the ScalaCheck implementation.
24+
*
25+
* {{{
26+
* implicit lazy val arbBool: Arbitrary[Boolean] = Arbitrary(oneOf(true, false))
27+
* }}}
28+
*
29+
* @param name arbitrary
30+
*/
31+
object ArbitrarySection extends Checkers with Matchers with org.scalaexercises.definitions.Section {
32+
33+
import GeneratorsHelper._
34+
35+
/** Let's see an example where we're defining an `implicit` `arbitrary` instance for `Char`
36+
*/
37+
def implicitArbitraryChar(res0: Seq[Char]) = {
38+
39+
import org.scalacheck.Arbitrary
40+
import org.scalacheck.Gen
41+
import org.scalacheck.Prop.forAll
42+
43+
implicit lazy val myCharArbitrary = Arbitrary(Gen.oneOf('A', 'E', 'I', 'O', 'U'))
44+
45+
val validChars: Seq[Char] = res0
46+
47+
check(forAll { c: Char =>
48+
validChars.contains(c)
49+
})
50+
}
51+
52+
/** This becomes more useful when we're dealing with our own data types.
53+
* We'll use the case class defined in the ''Generators Section'':
54+
*
55+
* {{{
56+
* case class Foo(intValue: Int, charValue: Char)
57+
* }}}
58+
*
59+
* Having an implicit `def` or `val` of our data type in the scope allow us to use the `forAll` method without
60+
* specifying the ''generator''
61+
*/
62+
def implicitArbitraryCaseClass(res0: Boolean) = {
63+
64+
import org.scalacheck.Arbitrary
65+
import org.scalacheck.Gen
66+
import org.scalacheck.Prop.forAll
67+
68+
val fooGen = for {
69+
intValue <- Gen.posNum[Int]
70+
charValue <- Gen.alphaChar
71+
} yield Foo(intValue, charValue)
72+
73+
implicit lazy val myFooArbitrary = Arbitrary(fooGen)
74+
75+
check(forAll { foo: Foo =>
76+
(foo.intValue < 0) == res0 && !foo.charValue.isDigit
77+
})
78+
}
79+
80+
/** The `Arbitrary.arbitrary` method also returns a `Gen` object.
81+
*/
82+
def useArbitraryOnGen(res0: Int) = {
83+
84+
import org.scalacheck.Arbitrary
85+
import org.scalacheck.Gen.listOfN
86+
import org.scalacheck.Prop.forAll
87+
88+
val genEightBytes = listOfN(8, Arbitrary.arbitrary[Byte])
89+
90+
check(forAll(genEightBytes) { list =>
91+
list.size == res0
92+
})
93+
94+
}
95+
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package exercises.scalachecklib
2+
3+
import org.scalacheck.Shapeless._
4+
import org.scalatest.Spec
5+
import org.scalatest.prop.Checkers
6+
import shapeless.HNil
7+
8+
import scalachecklib.ArbitrarySection
9+
10+
class ArbitrarySpec extends Spec with Checkers {
11+
12+
def `implicit arbitrary char` = {
13+
14+
check(
15+
Test.testSuccess(
16+
ArbitrarySection.implicitArbitraryChar _,
17+
Seq('A', 'E', 'I', 'O', 'U') :: HNil
18+
)
19+
)
20+
}
21+
22+
def `implicit arbitrary case class` = {
23+
24+
check(
25+
Test.testSuccess(
26+
ArbitrarySection.implicitArbitraryCaseClass _,
27+
false :: HNil
28+
)
29+
)
30+
}
31+
32+
def `arbitrary on gen` = {
33+
34+
check(
35+
Test.testSuccess(
36+
ArbitrarySection.useArbitraryOnGen _,
37+
8 :: HNil
38+
)
39+
)
40+
}
41+
42+
}

0 commit comments

Comments
 (0)