1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
import org.scalacheck.{ ConsoleReporter, Properties }
import org.scalacheck.Prop._
import scala.reflect.internal.util.Collections._
object Test extends Properties("reflect.internal.util.Collections") {
def map2ConserveOld[A <: AnyRef, B](xs: List[A], ys: List[B])(f: (A, B) => A): List[A] =
if (xs.isEmpty || ys.isEmpty) xs
else {
val x1 = f(xs.head, ys.head)
val xs1 = map2Conserve(xs.tail, ys.tail)(f)
if ((x1 eq xs.head) && (xs1 eq xs.tail)) xs
else x1 :: xs1
}
val testfun: (String, Int) => String = { case(x, y) =>
x.toLowerCase + y.toString
}
val testid: (String, Int) => String = { case (x, y) => x }
val prop1_map2Conserve = forAll { (xs: List[String], ys: List[Int]) =>
val res = map2Conserve(xs, ys)(testid)
res eq xs
}
val prop2_map2Conserve = forAll { (xs: List[String], ys: List[Int]) =>
map2Conserve(xs, ys)(testid) == map2ConserveOld(xs, ys)(testid) &&
map2Conserve(xs, ys)(testfun) == map2ConserveOld(xs, ys)(testfun)
}
def checkStackOverflow() {
var xs: List[String] = Nil
var ys: List[Int] = Nil
for (i <- 0 until 250000) {
xs = "X" :: xs
ys = 1 :: ys
}
map2Conserve(xs, ys){ case(x, y) => x.toLowerCase + y.toString }
}
val tests = List(
("map2Conserve(identity)", prop1_map2Conserve),
("map2Conserve == old impl", prop2_map2Conserve)
)
checkStackOverflow()
for {
(label, prop) <- tests
} property(label) = prop
import org.scalacheck.{ Test => STest }
def runTests() =
STest.checkProperties(
STest.Params(testCallback = ConsoleReporter(0)), this)
}
|