summaryrefslogtreecommitdiff
path: root/test/files/scalacheck
diff options
context:
space:
mode:
Diffstat (limited to 'test/files/scalacheck')
-rw-r--r--test/files/scalacheck/CheckCollections.scala52
-rw-r--r--test/files/scalacheck/CheckEither.scala36
-rw-r--r--test/files/scalacheck/Ctrie.scala66
-rw-r--r--test/files/scalacheck/HashTrieSplit.scala47
-rw-r--r--test/files/scalacheck/ReflectionExtractors.scala52
-rw-r--r--test/files/scalacheck/Unrolled.scala6
-rw-r--r--test/files/scalacheck/array-new.scala2
-rw-r--r--test/files/scalacheck/array-old.scala6
-rw-r--r--test/files/scalacheck/avl.scala10
-rw-r--r--test/files/scalacheck/list.scala2
-rw-r--r--test/files/scalacheck/parallel-collections/IntOperators.scala2
-rw-r--r--test/files/scalacheck/parallel-collections/PairOperators.scala42
-rw-r--r--test/files/scalacheck/parallel-collections/PairValues.scala2
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelArrayCheck.scala19
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelArrayTest.scala2
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelArrayViewCheck.scala22
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala31
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelHashMapCheck.scala31
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelHashSetCheck.scala33
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelHashTrieCheck.scala48
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelIterableCheck.scala131
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelMapCheck1.scala6
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelRangeCheck.scala26
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelSeqCheck.scala60
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelSetCheck.scala6
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelVectorCheck.scala24
-rw-r--r--test/files/scalacheck/parallel-collections/pc.scala71
-rw-r--r--test/files/scalacheck/primitive-eqeq.scala10
-rw-r--r--test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala295
-rw-r--r--test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala453
-rw-r--r--test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala290
-rw-r--r--test/files/scalacheck/quasiquotes/DeprecationProps.scala52
-rw-r--r--test/files/scalacheck/quasiquotes/ErrorProps.scala213
-rw-r--r--test/files/scalacheck/quasiquotes/ForProps.scala70
-rw-r--r--test/files/scalacheck/quasiquotes/LiftableProps.scala174
-rw-r--r--test/files/scalacheck/quasiquotes/PatternConstructionProps.scala36
-rw-r--r--test/files/scalacheck/quasiquotes/PatternDeconstructionProps.scala44
-rw-r--r--test/files/scalacheck/quasiquotes/QuasiquoteProperties.scala120
-rw-r--r--test/files/scalacheck/quasiquotes/RuntimeErrorProps.scala75
-rw-r--r--test/files/scalacheck/quasiquotes/TermConstructionProps.scala313
-rw-r--r--test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala249
-rw-r--r--test/files/scalacheck/quasiquotes/Test.scala19
-rw-r--r--test/files/scalacheck/quasiquotes/TypeConstructionProps.scala42
-rw-r--r--test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala78
-rw-r--r--test/files/scalacheck/quasiquotes/TypecheckedProps.scala215
-rw-r--r--test/files/scalacheck/quasiquotes/UnliftableProps.scala166
-rw-r--r--test/files/scalacheck/range.scala48
-rw-r--r--test/files/scalacheck/redblack.scala213
-rw-r--r--test/files/scalacheck/redblacktree.scala14
-rw-r--r--test/files/scalacheck/substringTests.scala4
-rw-r--r--test/files/scalacheck/t2460.scala5
-rw-r--r--test/files/scalacheck/t4147.scala (renamed from test/files/scalacheck/si4147.scala)7
-rw-r--r--test/files/scalacheck/treeset.scala3
53 files changed, 3436 insertions, 607 deletions
diff --git a/test/files/scalacheck/CheckCollections.scala b/test/files/scalacheck/CheckCollections.scala
new file mode 100644
index 0000000000..329d505b47
--- /dev/null
+++ b/test/files/scalacheck/CheckCollections.scala
@@ -0,0 +1,52 @@
+import org.scalacheck.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
+}
diff --git a/test/files/scalacheck/CheckEither.scala b/test/files/scalacheck/CheckEither.scala
index 4e8480d72e..48f732a22d 100644
--- a/test/files/scalacheck/CheckEither.scala
+++ b/test/files/scalacheck/CheckEither.scala
@@ -1,25 +1,23 @@
-import org.scalacheck.{ Arbitrary, ConsoleReporter, Prop, Properties }
+import org.scalacheck.{ Arbitrary, Prop, Properties }
import org.scalacheck.Arbitrary.{arbitrary, arbThrowable}
import org.scalacheck.Gen.oneOf
-import org.scalacheck.util.StdRand
import org.scalacheck.Prop._
-import org.scalacheck.Test.{Params, check}
-import org.scalacheck.ConsoleReporter.testStatsEx
+import org.scalacheck.Test.check
import Function.tupled
object Test extends Properties("Either") {
- implicit def arbitraryEither[X, Y](implicit xa: Arbitrary[X], ya: Arbitrary[Y]): Arbitrary[Either[X, Y]] =
+ implicit def arbitraryEither[X, Y](implicit xa: Arbitrary[X], ya: Arbitrary[Y]): Arbitrary[Either[X, Y]] =
Arbitrary[Either[X, Y]](oneOf(arbitrary[X].map(Left(_)), arbitrary[Y].map(Right(_))))
- val prop_either1 = forAll((n: Int) => Left(n).fold(x => x, b => error("fail")) == n)
+ val prop_either1 = forAll((n: Int) => Left(n).fold(x => x, b => sys.error("fail")) == n)
- val prop_either2 = forAll((n: Int) => Right(n).fold(a => error("fail"), x => x) == n)
+ val prop_either2 = forAll((n: Int) => Right(n).fold(a => sys.error("fail"), x => x) == n)
val prop_swap = forAll((e: Either[Int, Int]) => e match {
case Left(a) => e.swap.right.get == a
case Right(b) => e.swap.left.get == b
})
-
+
val prop_isLeftRight = forAll((e: Either[Int, Int]) => e.isLeft != e.isRight)
object CheckLeftProjection {
@@ -35,7 +33,7 @@ object Test extends Properties("Either") {
val prop_exists = forAll((e: Either[Int, Int]) =>
e.left.exists(_ % 2 == 0) == (e.isLeft && e.left.get % 2 == 0))
-
+
val prop_flatMapLeftIdentity = forAll((e: Either[Int, Int], n: Int, s: String) => {
def f(x: Int) = if(x % 2 == 0) Left(s) else Right(s)
Left(n).left.flatMap(f(_)) == f(n)})
@@ -115,7 +113,7 @@ object Test extends Properties("Either") {
}
val prop_Either_left = forAll((n: Int) => Left(n).left.get == n)
-
+
val prop_Either_right = forAll((n: Int) => Right(n).right.get == n)
val prop_Either_joinLeft = forAll((e: Either[Either[Int, Int], Int]) => e match {
@@ -128,12 +126,12 @@ object Test extends Properties("Either") {
case Right(ee) => e.joinRight == ee
})
- val prop_Either_reduce = forAll((e: Either[Int, Int]) =>
+ val prop_Either_reduce = forAll((e: Either[Int, Int]) =>
e.merge == (e match {
case Left(a) => a
case Right(a) => a
}))
-
+
/** Hard to believe I'm "fixing" a test to reflect B before A ... */
val prop_Either_cond = forAll((c: Boolean, a: Int, b: Int) =>
Either.cond(c, a, b) == (if(c) Right(a) else Left(b)))
@@ -168,20 +166,14 @@ object Test extends Properties("Either") {
("Right.prop_seq", CheckRightProjection.prop_seq),
("Right.prop_option", CheckRightProjection.prop_option),
("prop_Either_left", prop_Either_left),
- ("prop_Either_right", prop_Either_right),
+ ("prop_Either_right", prop_Either_right),
("prop_Either_joinLeft", prop_Either_joinLeft),
- ("prop_Either_joinRight", prop_Either_joinRight),
- ("prop_Either_reduce", prop_Either_reduce),
+ ("prop_Either_joinRight", prop_Either_joinRight),
+ ("prop_Either_reduce", prop_Either_reduce),
("prop_Either_cond", prop_Either_cond)
)
-
+
for ((label, prop) <- tests) {
property(label) = prop
}
-
- import org.scalacheck.{ Test => STest }
-
- def runTests() = {
- STest.checkProperties(STest.Params(testCallback = ConsoleReporter(0)), this)
- }
}
diff --git a/test/files/scalacheck/Ctrie.scala b/test/files/scalacheck/Ctrie.scala
index 736bf938bc..714f1c3b09 100644
--- a/test/files/scalacheck/Ctrie.scala
+++ b/test/files/scalacheck/Ctrie.scala
@@ -17,21 +17,21 @@ case class Wrap(i: Int) {
/** A check mainly oriented towards checking snapshot correctness.
*/
object Test extends Properties("concurrent.TrieMap") {
-
+
/* generators */
-
+
val sizes = choose(0, 200000)
-
+
val threadCounts = choose(2, 16)
-
+
val threadCountsAndSizes = for {
p <- threadCounts
sz <- sizes
} yield (p, sz);
-
-
+
+
/* helpers */
-
+
def inParallel[T](totalThreads: Int)(body: Int => T): Seq[T] = {
val threads = for (idx <- 0 until totalThreads) yield new Thread {
setName("ParThread-" + idx)
@@ -44,11 +44,11 @@ object Test extends Properties("concurrent.TrieMap") {
res
}
}
-
+
threads foreach (_.start())
threads map (_.result)
}
-
+
def spawn[T](body: =>T): { def get: T } = {
val t = new Thread {
setName("SpawnThread")
@@ -66,7 +66,7 @@ object Test extends Properties("concurrent.TrieMap") {
}
}
}
-
+
def elementRange(threadIdx: Int, totalThreads: Int, totalElems: Int): Range = {
val sz = totalElems
val idx = threadIdx
@@ -76,7 +76,7 @@ object Test extends Properties("concurrent.TrieMap") {
val end = start + elems
(start until end)
}
-
+
def hasGrown[K, V](last: Map[K, V], current: Map[K, V]) = {
(last.size <= current.size) && {
last forall {
@@ -84,7 +84,7 @@ object Test extends Properties("concurrent.TrieMap") {
}
}
}
-
+
object err {
var buffer = new StringBuilder
def println(a: AnyRef) = buffer.append(a.toString).append("\n")
@@ -94,16 +94,16 @@ object Test extends Properties("concurrent.TrieMap") {
clear()
}
}
-
-
+
+
/* properties */
-
+
property("concurrent growing snapshots") = forAll(threadCounts, sizes) {
(numThreads, numElems) =>
val p = 3 //numThreads
val sz = 102 //numElems
val ct = new TrieMap[Wrap, Int]
-
+
// checker
val checker = spawn {
def check(last: Map[Wrap, Int], iterationsLeft: Int): Boolean = {
@@ -115,23 +115,23 @@ object Test extends Properties("concurrent.TrieMap") {
}
check(ct.readOnlySnapshot(), 500)
}
-
+
// fillers
inParallel(p) {
idx =>
elementRange(idx, p, sz) foreach (i => ct.update(Wrap(i), i))
}
-
+
// wait for checker to finish
val growing = true//checker.get
-
+
val ok = growing && ((0 until sz) forall {
case i => ct.get(Wrap(i)) == Some(i)
})
-
+
ok
}
-
+
property("update") = forAll(sizes) {
(n: Int) =>
val ct = new TrieMap[Int, Int]
@@ -140,52 +140,52 @@ object Test extends Properties("concurrent.TrieMap") {
case i => ct(i) == i
}
}
-
+
property("concurrent update") = forAll(threadCountsAndSizes) {
case (p, sz) =>
val ct = new TrieMap[Wrap, Int]
-
+
inParallel(p) {
idx =>
for (i <- elementRange(idx, p, sz)) ct(Wrap(i)) = i
}
-
+
(0 until sz) forall {
case i => ct(Wrap(i)) == i
}
}
-
-
+
+
property("concurrent remove") = forAll(threadCounts, sizes) {
(p, sz) =>
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(Wrap(i)) = i
-
+
inParallel(p) {
idx =>
for (i <- elementRange(idx, p, sz)) ct.remove(Wrap(i))
}
-
+
(0 until sz) forall {
case i => ct.get(Wrap(i)) == None
}
}
-
-
+
+
property("concurrent putIfAbsent") = forAll(threadCounts, sizes) {
(p, sz) =>
val ct = new TrieMap[Wrap, Int]
-
+
val results = inParallel(p) {
idx =>
elementRange(idx, p, sz) find (i => ct.putIfAbsent(Wrap(i), i) != None)
}
-
+
(results forall (_ == None)) && ((0 until sz) forall {
case i => ct.get(Wrap(i)) == Some(i)
})
}
-
+
}
diff --git a/test/files/scalacheck/HashTrieSplit.scala b/test/files/scalacheck/HashTrieSplit.scala
deleted file mode 100644
index 908c878f54..0000000000
--- a/test/files/scalacheck/HashTrieSplit.scala
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-import collection._
-
-
-
-
-// checks whether hash tries split their iterators correctly
-// even after some elements have been traversed
-object Test {
- def main(args: Array[String]) {
- doesSplitOk
- }
-
- def doesSplitOk = {
- val sz = 2000
- var ht = new parallel.immutable.ParHashMap[Int, Int]
- // println("creating trie")
- for (i <- 0 until sz) ht += ((i + sz, i))
- // println("created trie")
- for (n <- 0 until (sz - 1)) {
- // println("---------> n = " + n)
- val pit = ht.splitter
- val pit2 = ht.splitter
- var i = 0
- while (i < n) {
- pit.next
- pit2.next
- i += 1
- }
- // println("splitting")
- val pits = pit.split
- val fst = pits(0).toSet
- val snd = pits(1).toSet
- val orig = pit2.toSet
- if (orig.size != (fst.size + snd.size) || orig != (fst ++ snd)) {
- println("Original: " + orig)
- println("First: " + fst)
- println("Second: " + snd)
- assert(false)
- }
- }
- }
-}
diff --git a/test/files/scalacheck/ReflectionExtractors.scala b/test/files/scalacheck/ReflectionExtractors.scala
new file mode 100644
index 0000000000..a2615feb3e
--- /dev/null
+++ b/test/files/scalacheck/ReflectionExtractors.scala
@@ -0,0 +1,52 @@
+import org.scalacheck._
+import Prop._
+import Gen._
+import Arbitrary._
+
+import scala.reflect.runtime.universe._
+import Flag._
+
+object Test extends Properties("reflection extractors") {
+
+ val genFlag = oneOf(
+ TRAIT, INTERFACE, MUTABLE, MACRO, DEFERRED, ABSTRACT, FINAL, SEALED,
+ IMPLICIT, LAZY, OVERRIDE, PRIVATE, PROTECTED, LOCAL, CASE, ABSOVERRIDE,
+ BYNAMEPARAM, PARAM, COVARIANT, CONTRAVARIANT, DEFAULTPARAM, PRESUPER,
+ DEFAULTINIT
+ )
+ val genModifiers =
+ for(flag <- genFlag; privateWithin <- genName)
+ yield Modifiers(flag, privateWithin, Nil)
+ val genTermName = for(name <- arbitrary[String]) yield TermName(name)
+ val genTypeName = for(name <- arbitrary[String]) yield TypeName(name)
+ val genName = oneOf(genTermName, genTypeName)
+
+ implicit val arbTermName: Arbitrary[TermName] = Arbitrary(genTermName)
+ implicit val arbTypeName: Arbitrary[TypeName] = Arbitrary(genTypeName)
+ implicit val arbName: Arbitrary[Name] = Arbitrary(genName)
+ implicit val arbMods: Arbitrary[Modifiers] = Arbitrary(genModifiers)
+
+ property("extract term name") = forAll { (name: TermName) =>
+ val TermName(s) = name
+ s == name.toString
+ }
+
+ property("extract type name") = forAll { (name: TypeName) =>
+ val TypeName(s) = name
+ s == name.toString
+ }
+
+ property("extract term or type name") = forAll { (name: Name) =>
+ name match {
+ case TermName(s) => s == name.toString
+ case TypeName(s) => s == name.toString
+ }
+ }
+
+ property("extract modifiers") = forAll { (mods: Modifiers) =>
+ val Modifiers(flags, priv, annots) = mods
+ flags == mods.flags &&
+ priv == mods.privateWithin &&
+ annots == mods.annotations
+ }
+} \ No newline at end of file
diff --git a/test/files/scalacheck/Unrolled.scala b/test/files/scalacheck/Unrolled.scala
index 8067a44501..34604b8667 100644
--- a/test/files/scalacheck/Unrolled.scala
+++ b/test/files/scalacheck/Unrolled.scala
@@ -5,7 +5,7 @@ import Gen._
import collection.mutable.UnrolledBuffer
object Test extends Properties("UnrolledBuffer") {
-
+
property("concat size") = forAll { (l1: List[Int], l2: List[Int]) =>
val u1 = new UnrolledBuffer[Int]
u1 ++= l1
@@ -15,12 +15,12 @@ object Test extends Properties("UnrolledBuffer") {
u1 concat u2
totalsz == u1.size
}
-
+
property("adding") = forAll { (l: List[Int]) =>
val u = new UnrolledBuffer[Int]
u ++= l
u == l
}
-
+
}
diff --git a/test/files/scalacheck/array-new.scala b/test/files/scalacheck/array-new.scala
index e13a47a5d5..d8c69ead78 100644
--- a/test/files/scalacheck/array-new.scala
+++ b/test/files/scalacheck/array-new.scala
@@ -1,4 +1,4 @@
-import scala.reflect.{ClassTag, classTag}
+import scala.reflect.ClassTag // new style: use ClassTag
import org.scalacheck._
import Prop._
import Gen._
diff --git a/test/files/scalacheck/array-old.scala b/test/files/scalacheck/array-old.scala
index f262bc6320..03c0217180 100644
--- a/test/files/scalacheck/array-old.scala
+++ b/test/files/scalacheck/array-old.scala
@@ -11,7 +11,7 @@ object Test extends Properties("Array") {
*/
implicit def arbArray[T](implicit a: Arbitrary[T], m: Manifest[T]): Arbitrary[Array[T]] =
Arbitrary(containerOf[List,T](arbitrary[T]) map (_.toArray))
-
+
val arrGen: Gen[Array[_]] = oneOf(
arbitrary[Array[Int]],
arbitrary[Array[Array[Int]]],
@@ -20,7 +20,7 @@ object Test extends Properties("Array") {
arbitrary[Array[Boolean]],
arbitrary[Array[AnyVal]]
)
-
+
// inspired by #1857 and #2352
property("eq/ne") = forAll(arrGen, arrGen) { (c1, c2) =>
(c1 eq c2) || (c1 ne c2)
@@ -32,6 +32,6 @@ object Test extends Properties("Array") {
val arr = Array.ofDim[String](i1, i2, i3)
val flattened = arr flatMap (x => x) flatMap (x => x)
flattened.length == i1 * i2 * i3
- }
+ }
}
diff --git a/test/files/scalacheck/avl.scala b/test/files/scalacheck/avl.scala
index af79ad49e3..4cfacaf407 100644
--- a/test/files/scalacheck/avl.scala
+++ b/test/files/scalacheck/avl.scala
@@ -2,14 +2,12 @@ import org.scalacheck.Gen
import org.scalacheck.Prop.forAll
import org.scalacheck.Properties
-import util.logging.ConsoleLogger
-
package scala.collection.mutable {
/**
* Property of an AVL Tree : Any node of the tree has a balance value beetween in [-1; 1]
*/
- abstract class AVLTreeTest(name: String) extends Properties(name) with ConsoleLogger {
+ abstract class AVLTreeTest(name: String) extends Properties(name) {
def `2^`(n: Int) = (1 to n).fold(1)((a, b) => b*2)
@@ -54,7 +52,7 @@ package scala.collection.mutable {
} yield {
// selected mustn't be in elements already
val list = makeAllBalancedTree(elements.sorted.distinct.map(_*2))
- (selected*2+1, list)
+ (selected*2+1, list)
}
def genInputDelete: org.scalacheck.Gen[(Int, List[AVLTree[Int]])] = for {
@@ -65,7 +63,7 @@ package scala.collection.mutable {
} yield {
// selected must be in elements already
val list = makeAllBalancedTree(e)
- (e(selected), list)
+ (e(selected), list)
}
}
@@ -78,7 +76,7 @@ package scala.collection.mutable {
}
def setup(invariant: AVLTree[Int] => Boolean) = forAll(genInput) {
- case (selected: Int, trees: List[AVLTree[Int]]) =>
+ case (selected: Int, trees: List[AVLTree[Int]]) =>
trees.map(tree => invariant(tree)).fold(true)((a, b) => a && b)
}
diff --git a/test/files/scalacheck/list.scala b/test/files/scalacheck/list.scala
index 4e1cf1fc80..5f6de95237 100644
--- a/test/files/scalacheck/list.scala
+++ b/test/files/scalacheck/list.scala
@@ -12,7 +12,7 @@ object Test extends Properties("List") {
property("startsWith/take") = forAll { (xs: List[Int], count: Int) => xs startsWith (xs take count) }
property("endsWith/takeRight") = forAll { (xs: List[Int], count: Int) => xs endsWith (xs takeRight count) }
property("fill") = forAll(choose(1, 100)) { count =>
- forAll { (x: Int) =>
+ forAll { (x: Int) =>
val xs = List.fill(count)(x)
(xs.length == count) && (xs.distinct == List(x))
}
diff --git a/test/files/scalacheck/parallel-collections/IntOperators.scala b/test/files/scalacheck/parallel-collections/IntOperators.scala
index 5c997962ba..4a74b91da8 100644
--- a/test/files/scalacheck/parallel-collections/IntOperators.scala
+++ b/test/files/scalacheck/parallel-collections/IntOperators.scala
@@ -106,7 +106,7 @@ trait IntSeqOperators extends IntOperators with SeqOperators[Int] {
List(4, 5, 6, 7, 8, 9, 10),
List(4, 5, 6, 7, 8, 9, 0),
List(-4, -3, -2, -1)
- )
+ )
}
diff --git a/test/files/scalacheck/parallel-collections/PairOperators.scala b/test/files/scalacheck/parallel-collections/PairOperators.scala
index 4711e21c34..fe851114be 100644
--- a/test/files/scalacheck/parallel-collections/PairOperators.scala
+++ b/test/files/scalacheck/parallel-collections/PairOperators.scala
@@ -7,76 +7,76 @@ import scala.collection.parallel._
trait PairOperators[K, V] extends Operators[(K, V)] {
def koperators: Operators[K]
def voperators: Operators[V]
-
+
private def zipPredicates(kps: List[K => Boolean], vps: List[V => Boolean]): List[((K, V)) => Boolean] = for {
(kp, vp) <- koperators.countPredicates zip voperators.countPredicates
} yield new Function1[(K, V), Boolean] {
def apply(kv: (K, V)) = kp(kv._1) && vp(kv._2)
}
-
+
/* operators */
-
+
def reduceOperators = for {
(kop, vop) <- koperators.reduceOperators zip voperators.reduceOperators
} yield new Function2[(K, V), (K, V), (K, V)] {
def apply(kv1: (K, V), kv2: (K, V)) = (kop(kv1._1, kv2._1), vop(kv1._2, kv2._2))
}
-
+
def countPredicates = zipPredicates(koperators.countPredicates, voperators.countPredicates)
-
+
def forallPredicates = zipPredicates(koperators.forallPredicates, voperators.forallPredicates)
-
+
def existsPredicates = zipPredicates(koperators.existsPredicates, voperators.existsPredicates)
-
+
def findPredicates = zipPredicates(koperators.findPredicates, voperators.findPredicates)
-
+
def mapFunctions = for {
(km, vm) <- koperators.mapFunctions zip voperators.mapFunctions
} yield new Function1[(K, V), (K, V)] {
def apply(kv: (K, V)) = (km(kv._1), vm(kv._2))
}
-
+
def partialMapFunctions = for {
(kpm, vpm) <- koperators.partialMapFunctions zip voperators.partialMapFunctions
} yield new PartialFunction[(K, V), (K, V)] {
def isDefinedAt(kv: (K, V)) = kpm.isDefinedAt(kv._1) && vpm.isDefinedAt(kv._2)
def apply(kv: (K, V)) = (kpm(kv._1), vpm(kv._2))
}
-
+
def flatMapFunctions = for {
(kfm, vfm) <- koperators.flatMapFunctions zip voperators.flatMapFunctions
} yield new Function1[(K, V), Traversable[(K, V)]] {
def apply(kv: (K, V)) = kfm(kv._1).toIterable zip vfm(kv._2).toIterable
}
-
+
def filterPredicates = zipPredicates(koperators.filterPredicates, voperators.filterPredicates)
-
+
def filterNotPredicates = filterPredicates
-
+
def partitionPredicates = filterPredicates
-
+
def takeWhilePredicates = zipPredicates(koperators.takeWhilePredicates, voperators.takeWhilePredicates)
-
+
def dropWhilePredicates = takeWhilePredicates
-
+
def spanPredicates = takeWhilePredicates
-
+
def foldArguments = for {
((kinit, kop), (vinit, vop)) <- koperators.foldArguments zip voperators.foldArguments
} yield ((kinit, vinit), new Function2[(K, V), (K, V), (K, V)] {
def apply(kv1: (K, V), kv2: (K, V)) = (kop(kv1._1, kv2._1), vop(kv1._2, kv2._2))
})
-
+
def addAllTraversables = for {
(kt, vt) <- koperators.addAllTraversables zip voperators.addAllTraversables
} yield kt.toIterable zip vt.toIterable
-
+
def newArray(sz: Int) = new Array[(K, V)](sz)
-
+
def groupByFunctions = (koperators.groupByFunctions zip voperators.groupByFunctions) map {
opt => { (p: (K, V)) => (opt._1(p._1), opt._2(p._2)) }
}
-
+
}
diff --git a/test/files/scalacheck/parallel-collections/PairValues.scala b/test/files/scalacheck/parallel-collections/PairValues.scala
index 5007c4598b..864dad2425 100644
--- a/test/files/scalacheck/parallel-collections/PairValues.scala
+++ b/test/files/scalacheck/parallel-collections/PairValues.scala
@@ -17,7 +17,7 @@ import org.scalacheck.Arbitrary._
trait PairValues[K, V] {
def kvalues: Seq[Gen[K]]
def vvalues: Seq[Gen[V]]
-
+
def values = for {
kg <- kvalues
vg <- vvalues
diff --git a/test/files/scalacheck/parallel-collections/ParallelArrayCheck.scala b/test/files/scalacheck/parallel-collections/ParallelArrayCheck.scala
index a01c8c7dbe..691a3e961e 100644
--- a/test/files/scalacheck/parallel-collections/ParallelArrayCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelArrayCheck.scala
@@ -17,22 +17,25 @@ import scala.collection.parallel.ops._
abstract class ParallelArrayCheck[T](tp: String) extends ParallelSeqCheck[T]("ParArray[" + tp + "]") {
// ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2)
// ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2)
-
+
type CollType = ParArray[T]
-
+
def isCheckingViews = false
-
+
def hasStrictOrder = true
+ def tasksupport: TaskSupport
+
def ofSize(vals: Seq[Gen[T]], sz: Int) = {
val a = new mutable.ArrayBuffer[T](sz)
val gen = vals(rnd.nextInt(vals.size))
for (i <- 0 until sz) a += sample(gen)
a
}
-
+
def fromSeq(a: Seq[T]) = {
val pa = new ParArray[T](a.size)
+ pa.tasksupport = tasksupport
var i = 0
for (elem <- a.toList) {
pa(i) = elem
@@ -40,20 +43,20 @@ abstract class ParallelArrayCheck[T](tp: String) extends ParallelSeqCheck[T]("Pa
}
pa
}
-
+
property("array mappings must be equal") = forAll(collectionPairs) { case (t, coll) =>
val results = for ((f, ind) <- mapFunctions.zipWithIndex)
yield ("op index: " + ind) |: t.map(f) == coll.map(f)
results.reduceLeft(_ && _)
}
-
+
}
-object IntParallelArrayCheck extends ParallelArrayCheck[Int]("Int") with IntSeqOperators with IntValues {
+class IntParallelArrayCheck(val tasksupport: TaskSupport) extends ParallelArrayCheck[Int]("Int") with IntSeqOperators with IntValues {
override def instances(vals: Seq[Gen[Int]]) = oneOf(super.instances(vals), sized { sz =>
(0 until sz).toArray.toSeq
- }, sized { sz =>
+ }, sized { sz =>
(-sz until 0).toArray.toSeq
})
}
diff --git a/test/files/scalacheck/parallel-collections/ParallelArrayTest.scala b/test/files/scalacheck/parallel-collections/ParallelArrayTest.scala
index 680f6e1d28..db2b1ea01e 100644
--- a/test/files/scalacheck/parallel-collections/ParallelArrayTest.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelArrayTest.scala
@@ -15,7 +15,7 @@
// /**
// * this currently passes, but do we want it to?
-// * does it have meaning to have an empty parallel array?
+// * does it have meaning to have an empty parallel array?
// */
// new ParallelArray(0)
// ()
diff --git a/test/files/scalacheck/parallel-collections/ParallelArrayViewCheck.scala b/test/files/scalacheck/parallel-collections/ParallelArrayViewCheck.scala
index d2a8fa7c22..9805e2644f 100644
--- a/test/files/scalacheck/parallel-collections/ParallelArrayViewCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelArrayViewCheck.scala
@@ -24,18 +24,18 @@
// extends ParallelSeqCheck[T]("ParallelSeqView[" + tp + ", ParallelArray[" + tp + "]]") {
// // ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2)
// // ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2)
-
+
// type CollType = ParallelSeqView[T, ParallelArray[T], ArraySeq[T]]
-
+
// def isCheckingViews = true
-
+
// def instances(vals: Seq[Gen[T]]): Gen[Seq[T]] = sized { sz =>
// val a = new ArrayBuffer[T](sz)
// val gen = vals(rnd.nextInt(vals.size))
// for (i <- 0 until sz) a += sample(gen)
// a
// }
-
+
// def fromSeq(a: Seq[T]) = {
// val pa = new ParallelArray[T](a.size)
// var i = 0
@@ -45,13 +45,13 @@
// }
// pa.view
// }
-
+
// property("forces must be equal") = forAll(collectionPairs) { case (s, coll) =>
// val smodif = (s ++ s).reverse.take(s.length).reverse.zip(s).drop(s.length / 2)
// val cmodif = (coll ++ s).reverse.take(s.length).reverse.zip(s).drop(s.length / 2).force
// smodif == cmodif
// }
-
+
// }
@@ -68,18 +68,18 @@
// extends ParallelSeqCheck[T]("ParallelSeqView[" + tp + "], ParallelArray[" + tp + "].++.patch.reverse.take.reverse") {
// ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2)
// ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2)
-
+
// type CollType = collection.parallel.ParallelSeq[T]
-
+
// def isCheckingViews = true
-
+
// def instances(vals: Seq[Gen[T]]): Gen[Seq[T]] = sized { sz =>
// val a = new ArrayBuffer[T](sz)
// val gen = vals(rnd.nextInt(vals.size))
// for (i <- 0 until sz) a += sample(gen)
// a
// }
-
+
// def fromSeq(a: Seq[T]) = {
// val pa = new ParallelArray[T](a.size)
// var i = 0
@@ -91,7 +91,7 @@
// val original = modified.take(modified.length / 2).reverse
// original
// }
-
+
// }
diff --git a/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala b/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala
index e141c398fd..cf15afb3b9 100644
--- a/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala
@@ -18,22 +18,25 @@ import scala.collection.parallel.ops._
abstract class ParallelConcurrentTrieMapCheck[K, V](tp: String) extends ParallelMapCheck[K, V]("mutable.ParConcurrentTrieMap[" + tp + "]") {
// ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2)
// ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2)
-
+
type CollType = ParTrieMap[K, V]
-
+
def isCheckingViews = false
-
+
def hasStrictOrder = false
- def ofSize(vals: Seq[Gen[(K, V)]], sz: Int) = {
+ def tasksupport: TaskSupport
+
+ def ofSize(vals: Seq[Gen[(K, V)]], sz: Int) = {
val ct = new concurrent.TrieMap[K, V]
val gen = vals(rnd.nextInt(vals.size))
for (i <- 0 until sz) ct += sample(gen)
ct
}
-
+
def fromTraversable(t: Traversable[(K, V)]) = {
val pct = new ParTrieMap[K, V]
+ pct.tasksupport = tasksupport
var i = 0
for (kv <- t.toList) {
pct += kv
@@ -41,33 +44,33 @@ abstract class ParallelConcurrentTrieMapCheck[K, V](tp: String) extends Parallel
}
pct
}
-
+
}
-object IntIntParallelConcurrentTrieMapCheck extends ParallelConcurrentTrieMapCheck[Int, Int]("Int, Int")
+class IntIntParallelConcurrentTrieMapCheck(val tasksupport: TaskSupport) extends ParallelConcurrentTrieMapCheck[Int, Int]("Int, Int")
with PairOperators[Int, Int]
with PairValues[Int, Int]
{
def intvalues = new IntValues {}
def kvalues = intvalues.values
def vvalues = intvalues.values
-
+
val intoperators = new IntOperators {}
def voperators = intoperators
def koperators = intoperators
-
+
override def printDataStructureDebugInfo(ds: AnyRef) = ds match {
case pm: ParTrieMap[k, v] =>
println("Mutable parallel ctrie")
case _ =>
println("could not match data structure type: " + ds.getClass)
}
-
+
override def checkDataStructureInvariants(orig: Traversable[(Int, Int)], ds: AnyRef) = ds match {
// case pm: ParHashMap[k, v] if 1 == 0 => // disabled this to make tests faster
// val invs = pm.brokenInvariants
-
+
// val containsall = (for ((k, v) <- orig) yield {
// if (pm.asInstanceOf[ParHashMap[Int, Int]].get(k) == Some(v)) true
// else {
@@ -75,8 +78,8 @@ with PairValues[Int, Int]
// false
// }
// }).foldLeft(true)(_ && _)
-
-
+
+
// if (invs.isEmpty) containsall
// else {
// println("Invariants broken:\n" + invs.mkString("\n"))
@@ -84,7 +87,7 @@ with PairValues[Int, Int]
// }
case _ => true
}
-
+
}
diff --git a/test/files/scalacheck/parallel-collections/ParallelHashMapCheck.scala b/test/files/scalacheck/parallel-collections/ParallelHashMapCheck.scala
index 0152b1b435..34b3f33de2 100644
--- a/test/files/scalacheck/parallel-collections/ParallelHashMapCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelHashMapCheck.scala
@@ -17,22 +17,25 @@ import scala.collection.parallel.ops._
abstract class ParallelHashMapCheck[K, V](tp: String) extends ParallelMapCheck[K, V]("mutable.ParHashMap[" + tp + "]") {
// ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2)
// ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2)
-
+
type CollType = ParHashMap[K, V]
-
+
def isCheckingViews = false
-
+
def hasStrictOrder = false
- def ofSize(vals: Seq[Gen[(K, V)]], sz: Int) = {
+ def tasksupport: TaskSupport
+
+ def ofSize(vals: Seq[Gen[(K, V)]], sz: Int) = {
val hm = new mutable.HashMap[K, V]
val gen = vals(rnd.nextInt(vals.size))
for (i <- 0 until sz) hm += sample(gen)
hm
}
-
+
def fromTraversable(t: Traversable[(K, V)]) = {
val phm = new ParHashMap[K, V]
+ phm.tasksupport = tasksupport
var i = 0
for (kv <- t.toList) {
phm += kv
@@ -40,33 +43,33 @@ abstract class ParallelHashMapCheck[K, V](tp: String) extends ParallelMapCheck[K
}
phm
}
-
+
}
-object IntIntParallelHashMapCheck extends ParallelHashMapCheck[Int, Int]("Int, Int")
+class IntIntParallelHashMapCheck(val tasksupport: TaskSupport) extends ParallelHashMapCheck[Int, Int]("Int, Int")
with PairOperators[Int, Int]
with PairValues[Int, Int]
{
def intvalues = new IntValues {}
def kvalues = intvalues.values
def vvalues = intvalues.values
-
+
val intoperators = new IntOperators {}
def voperators = intoperators
def koperators = intoperators
-
+
override def printDataStructureDebugInfo(ds: AnyRef) = ds match {
case pm: ParHashMap[k, v] =>
println("Mutable parallel hash map\n" + pm.hashTableContents.debugInformation)
case _ =>
println("could not match data structure type: " + ds.getClass)
}
-
+
override def checkDataStructureInvariants(orig: Traversable[(Int, Int)], ds: AnyRef) = ds match {
// case pm: ParHashMap[k, v] if 1 == 0 => // disabled this to make tests faster
// val invs = pm.brokenInvariants
-
+
// val containsall = (for ((k, v) <- orig) yield {
// if (pm.asInstanceOf[ParHashMap[Int, Int]].get(k) == Some(v)) true
// else {
@@ -74,8 +77,8 @@ with PairValues[Int, Int]
// false
// }
// }).foldLeft(true)(_ && _)
-
-
+
+
// if (invs.isEmpty) containsall
// else {
// println("Invariants broken:\n" + invs.mkString("\n"))
@@ -83,7 +86,7 @@ with PairValues[Int, Int]
// }
case _ => true
}
-
+
}
diff --git a/test/files/scalacheck/parallel-collections/ParallelHashSetCheck.scala b/test/files/scalacheck/parallel-collections/ParallelHashSetCheck.scala
index a0a6d1ae5e..91de2472a7 100644
--- a/test/files/scalacheck/parallel-collections/ParallelHashSetCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelHashSetCheck.scala
@@ -17,34 +17,37 @@ import scala.collection.parallel.ops._
abstract class ParallelHashSetCheck[T](tp: String) extends ParallelSetCheck[T]("mutable.ParHashSet[" + tp + "]") {
// ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2)
// ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2)
-
+
type CollType = ParHashSet[T]
-
+
def isCheckingViews = false
-
+
def hasStrictOrder = false
- def ofSize(vals: Seq[Gen[T]], sz: Int) = {
+ def tasksupport: TaskSupport
+
+ def ofSize(vals: Seq[Gen[T]], sz: Int) = {
val hm = new mutable.HashSet[T]
val gen = vals(rnd.nextInt(vals.size))
for (i <- 0 until sz) hm += sample(gen)
hm
}
-
+
def fromTraversable(t: Traversable[T]) = {
- val phm = new ParHashSet[T]
+ val phs = new ParHashSet[T]
+ phs.tasksupport = tasksupport
var i = 0
for (kv <- t.toList) {
- phm += kv
+ phs += kv
i += 1
}
- phm
+ phs
}
-
+
}
-object IntParallelHashSetCheck extends ParallelHashSetCheck[Int]("Int")
+class IntParallelHashSetCheck(val tasksupport: TaskSupport) extends ParallelHashSetCheck[Int]("Int")
with IntOperators
with IntValues
{
@@ -54,12 +57,12 @@ with IntValues
case _ =>
println("could not match data structure type: " + ds.getClass)
}
-
+
override def checkDataStructureInvariants(orig: Traversable[Int], ds: AnyRef) = ds match {
// case pm: ParHashSet[t] if 1 == 0 =>
// // for an example of how not to write code proceed below
// val invs = pm.brokenInvariants
-
+
// val containsall = (for (elem <- orig) yield {
// if (pm.asInstanceOf[ParHashSet[Int]](elem) == true) true
// else {
@@ -69,8 +72,8 @@ with IntValues
// false
// }
// }).foldLeft(true)(_ && _)
-
-
+
+
// if (invs.isEmpty) {
// if (!containsall) println(pm.debugInformation)
// containsall
@@ -80,7 +83,7 @@ with IntValues
// }
case _ => true
}
-
+
}
diff --git a/test/files/scalacheck/parallel-collections/ParallelHashTrieCheck.scala b/test/files/scalacheck/parallel-collections/ParallelHashTrieCheck.scala
index 3a2893f48a..9e29be5429 100644
--- a/test/files/scalacheck/parallel-collections/ParallelHashTrieCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelHashTrieCheck.scala
@@ -17,22 +17,25 @@ import scala.collection.parallel.ops._
abstract class ParallelHashMapCheck[K, V](tp: String) extends ParallelMapCheck[K, V]("immutable.ParHashMap[" + tp + "]") {
// ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2)
// ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2)
-
+
type CollType = ParHashMap[K, V]
-
+
def isCheckingViews = false
-
+
def hasStrictOrder = false
-
+
+ def tasksupport: TaskSupport
+
def ofSize(vals: Seq[Gen[(K, V)]], sz: Int) = {
var hm = new immutable.HashMap[K, V]
val gen = vals(rnd.nextInt(vals.size))
for (i <- 0 until sz) hm += sample(gen)
hm
}
-
+
def fromTraversable(t: Traversable[(K, V)]) = {
var phm = new ParHashMap[K, V]
+ phm.tasksupport = tasksupport
var i = 0
for (kv <- t.toList) {
phm += kv
@@ -40,22 +43,22 @@ abstract class ParallelHashMapCheck[K, V](tp: String) extends ParallelMapCheck[K
}
phm
}
-
+
}
-object IntIntParallelHashMapCheck extends ParallelHashMapCheck[Int, Int]("Int, Int")
+class IntIntParallelHashMapCheck(val tasksupport: TaskSupport) extends ParallelHashMapCheck[Int, Int]("Int, Int")
with PairOperators[Int, Int]
with PairValues[Int, Int]
{
def intvalues = new IntValues {}
def kvalues = intvalues.values
def vvalues = intvalues.values
-
+
val intoperators = new IntOperators {}
def voperators = intoperators
def koperators = intoperators
-
+
override def printDataStructureDebugInfo(ds: AnyRef) = ds match {
case pm: ParHashMap[k, v] =>
pm.printDebugInfo
@@ -69,48 +72,51 @@ with PairValues[Int, Int]
abstract class ParallelHashSetCheck[T](tp: String) extends ParallelSetCheck[T]("immutable.ParHashSet[" + tp + "]") {
// ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2)
// ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2)
-
+
type CollType = ParHashSet[T]
-
+
def isCheckingViews = false
-
+
def hasStrictOrder = false
-
+
+ def tasksupport: TaskSupport
+
def ofSize(vals: Seq[Gen[T]], sz: Int) = {
var hm = new immutable.HashSet[T]
val gen = vals(rnd.nextInt(vals.size))
for (i <- 0 until sz) hm += sample(gen)
hm
}
-
+
def fromTraversable(t: Traversable[T]) = {
- var phm = new ParHashSet[T]
+ var phs = new ParHashSet[T]
+ phs.tasksupport = tasksupport
var i = 0
for (kv <- t.toList) {
- phm += kv
+ phs += kv
i += 1
}
- phm
+ phs
}
-
+
override def printDataStructureDebugInfo(ds: AnyRef) = ds match {
case pm: ParHashSet[t] =>
println("Parallel hash set")
case _ =>
println("could not match data structure type: " + ds.getClass)
}
-
+
}
-object IntParallelHashSetCheck extends ParallelHashSetCheck[Int]("Int")
+class IntParallelHashSetCheck(val tasksupport: TaskSupport) extends ParallelHashSetCheck[Int]("Int")
with IntOperators
with IntValues
{
def intvalues = new IntValues {}
def kvalues = intvalues.values
def vvalues = intvalues.values
-
+
override def printDataStructureDebugInfo(ds: AnyRef) = ds match {
case pm: ParHashMap[k, v] =>
pm.printDebugInfo
diff --git a/test/files/scalacheck/parallel-collections/ParallelIterableCheck.scala b/test/files/scalacheck/parallel-collections/ParallelIterableCheck.scala
index e3f8778bca..774d6f428b 100644
--- a/test/files/scalacheck/parallel-collections/ParallelIterableCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelIterableCheck.scala
@@ -16,14 +16,14 @@ import scala.collection.parallel._
abstract class ParallelIterableCheck[T](collName: String) extends Properties(collName) with Operators[T] {
type CollType <: ParIterable[T]
-
+
def values: Seq[Gen[T]]
def ofSize(vals: Seq[Gen[T]], sz: Int): Iterable[T]
def fromTraversable(t: Traversable[T]): CollType
def isCheckingViews: Boolean
def hasStrictOrder: Boolean
-
-
+
+
def instances(vals: Seq[Gen[T]]): Gen[Iterable[T]] = oneOf(
sized(
sz =>
@@ -31,46 +31,46 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
),
for (sz <- choose(1000, 2000)) yield ofSize(vals, sz),
for (sz <- choose(4000, 4001)) yield ofSize(vals, sz),
- for (sz <- choose(10000, 10001)) yield ofSize(vals, sz)
+ for (sz <- choose(10000, 10001)) yield ofSize(vals, sz)
)
-
+
// used to check if constructed collection is valid
def checkDataStructureInvariants(orig: Traversable[T], cf: AnyRef) = {
// can be overriden in subclasses
true
}
-
+
def printDataStructureDebugInfo(cf: AnyRef) {
// can be overridden in subclasses
}
-
+
val rnd = new scala.util.Random
-
+
def sample(gen: Gen[T]): T = {
var s = gen.sample
while (s == None) s = gen.sample
s.get
}
-
+
def sampleValue: T = sample(values(rnd.nextInt(values.length)))
-
+
def collectionPairs = for (inst <- instances(values)) yield (inst, fromTraversable(inst))
-
+
def collectionPairsWithLengths = for (inst <- instances(values); s <- choose(0, inst.size))
yield (inst, fromTraversable(inst), s)
-
+
def collectionPairsWith2Indices = for (
inst <- instances(values);
f <- choose(0, inst.size);
s <- choose(0, inst.size))
yield (inst, fromTraversable(inst), f, s)
-
- def collectionTriplets = for (inst <- instances(values);
+
+ def collectionTriplets = for (inst <- instances(values);
updStart <- choose(0, inst.size); howMany <- choose(0, inst.size)) yield {
val modif = inst.toSeq.patch(updStart, inst.toSeq, howMany)
(inst, fromTraversable(inst), modif)
}
-
+
def areEqual(t1: GenTraversable[T], t2: GenTraversable[T]) = if (hasStrictOrder) {
t1 == t2 && t2 == t1
} else (t1, t2) match { // it is slightly delicate what `equal` means if the order is not strict
@@ -81,14 +81,14 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
i1s == i2s && i2s == i1s
case _ => t1 == t2 && t2 == t1
}
-
+
def printDebugInfo(coll: ParIterableLike[_, _, _]) {
println("Collection debug info: ")
coll.printDebugBuffer
println("Task debug info: ")
println(coll.tasksupport.debugMessages.mkString("\n"))
}
-
+
def printComparison(t: Traversable[_], coll: ParIterable[_], tf: Traversable[_], cf: ParIterable[_], ind: Int) {
printDebugInfo(coll)
println("Operator: " + ind)
@@ -108,7 +108,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
println("tf == cf - " + (tf == cf))
println("cf == tf - " + (cf == tf))
}
-
+
property("reductions must be equal for assoc. operators") = forAll(collectionPairs) { case (t, coll) =>
if (t.size != 0) {
val results = for ((op, ind) <- reduceOperators.zipWithIndex) yield {
@@ -126,7 +126,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
results.reduceLeft(_ && _)
} else "has size 0" |: true
}
-
+
property("counts must be equal") = forAll(collectionPairs) { case (t, coll) =>
val results = for ((pred, ind) <- countPredicates.zipWithIndex) yield {
val tc = t.count(pred)
@@ -142,19 +142,19 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
}
results.reduceLeft(_ && _)
}
-
+
property("forall must be equal") = forAll(collectionPairs) { case (t, coll) =>
val results = for ((pred, ind) <- forallPredicates.zipWithIndex)
yield ("op index: " + ind) |: t.forall(pred) == coll.forall(pred)
results.reduceLeft(_ && _)
}
-
+
property("exists must be equal") = forAll(collectionPairs) { case (t, coll) =>
val results = for ((pred, ind) <- existsPredicates.zipWithIndex)
yield ("op index: " + ind) |: t.exists(pred) == coll.exists(pred)
results.reduceLeft(_ && _)
}
-
+
property("both must find or not find an element") = forAll(collectionPairs) { case (t, coll) =>
val results = for ((pred, ind) <- findPredicates.zipWithIndex) yield {
val ft = t.find(pred)
@@ -163,7 +163,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
}
results.reduceLeft(_ && _)
}
-
+
property("mappings must be equal") = forAll(collectionPairs) { case (t, coll) =>
val results = for ((f, ind) <- mapFunctions.zipWithIndex) yield {
val ms = t.map(f)
@@ -184,7 +184,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
}
results.reduceLeft(_ && _)
}
-
+
property("collects must be equal") = forAll(collectionPairs) { case (t, coll) =>
val results = for ((f, ind) <- partialMapFunctions.zipWithIndex) yield {
val ps = t.collect(f)
@@ -200,12 +200,12 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
}
results.reduceLeft(_ && _)
}
-
+
property("flatMaps must be equal") = forAll(collectionPairs) { case (t, coll) =>
(for ((f, ind) <- flatMapFunctions.zipWithIndex)
yield ("op index: " + ind) |: areEqual(t.flatMap(f), coll.flatMap(f))).reduceLeft(_ && _)
}
-
+
property("filters must be equal") = forAll(collectionPairs) { case (t, coll) =>
(for ((p, ind) <- filterPredicates.zipWithIndex) yield {
val tf = t.filter(p)
@@ -234,7 +234,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
("op index: " + ind) |: tf == cf && cf == tf && invs
}).reduceLeft(_ && _)
}
-
+
property("filterNots must be equal") = forAll(collectionPairs) { case (t, coll) =>
(for ((p, ind) <- filterNotPredicates.zipWithIndex) yield {
val tf = t.filterNot(p)
@@ -243,7 +243,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
("op index: " + ind) |: tf == cf && cf == tf
}).reduceLeft(_ && _)
}
-
+
if (!isCheckingViews) property("partitions must be equal") = forAll(collectionPairs) { case (t, coll) =>
(for ((p, ind) <- partitionPredicates.zipWithIndex) yield {
val tpart = t.partition(p)
@@ -257,15 +257,15 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
("op index: " + ind) |: tpart == cpart
}).reduceLeft(_ && _)
}
-
+
if (hasStrictOrder) property("takes must be equal") = forAll(collectionPairsWithLengths) { case (t, coll, n) =>
("take " + n + " elements") |: t.take(n) == coll.take(n)
}
-
+
if (hasStrictOrder) property("drops must be equal") = forAll(collectionPairsWithLengths) { case (t, coll, n) =>
("drop " + n + " elements") |: t.drop(n) == coll.drop(n)
}
-
+
if (hasStrictOrder) property("slices must be equal") = forAll(collectionPairsWith2Indices)
{ case (t, coll, fr, slicelength) =>
val from = if (fr < 0) 0 else fr
@@ -289,7 +289,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
}
("slice from " + from + " until " + until) |: tsl == collsl
}
-
+
if (hasStrictOrder) property("splits must be equal") = forAll(collectionPairsWithLengths) { case (t, coll, n) =>
val tspl = t.splitAt(n)
val cspl = coll.splitAt(n)
@@ -302,7 +302,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
}
("splitAt " + n) |: tspl == cspl
}
-
+
if (hasStrictOrder) property("takeWhiles must be equal") = forAll(collectionPairs) { case (t, coll) =>
(for ((pred, ind) <- takeWhilePredicates.zipWithIndex) yield {
val tt = t.takeWhile(pred)
@@ -317,7 +317,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
("operator " + ind) |: tt == ct
}).reduceLeft(_ && _)
}
-
+
if (hasStrictOrder) property("spans must be equal") = forAll(collectionPairs) { case (t, coll) =>
(for ((pred, ind) <- spanPredicates.zipWithIndex) yield {
val tsp = t.span(pred)
@@ -335,13 +335,13 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
("operator " + ind) |: tsp == csp
}).reduceLeft(_ && _)
}
-
+
if (hasStrictOrder) property("dropWhiles must be equal") = forAll(collectionPairs) { case (t, coll) =>
(for ((pred, ind) <- dropWhilePredicates.zipWithIndex) yield {
("operator " + ind) |: t.dropWhile(pred) == coll.dropWhile(pred)
}).reduceLeft(_ && _)
}
-
+
property("folds must be equal for assoc. operators") = forAll(collectionPairs) { case (t, coll) =>
(for (((first, op), ind) <- foldArguments.zipWithIndex) yield {
val tres = t.foldLeft(first)(op)
@@ -356,34 +356,39 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
("operator " + ind) |: tres == cres
}).reduceLeft(_ && _)
}
-
+
property("++s must be equal") = forAll(collectionTriplets) { case (t, coll, colltoadd) =>
- val toadd = colltoadd
- val tr = t ++ toadd.iterator
- val cr = coll ++ toadd.iterator
- if (!areEqual(tr, cr)) {
- println("from: " + t)
- println("and: " + coll.iterator.toList)
- println("adding: " + toadd)
- println(tr.toList)
- println(cr.iterator.toList)
- }
- ("adding " |: areEqual(tr, cr)) &&
- (for ((trav, ind) <- (addAllTraversables).zipWithIndex) yield {
- val tadded = t ++ trav
- val cadded = coll ++ collection.parallel.mutable.ParArray(trav.toSeq: _*)
- if (!areEqual(tadded, cadded)) {
- println("----------------------")
+ try {
+ val toadd = colltoadd
+ val tr = t ++ toadd.iterator
+ val cr = coll ++ toadd.iterator
+ if (!areEqual(tr, cr)) {
println("from: " + t)
- println("and: " + coll)
- println("adding: " + trav)
- println(tadded)
- println(cadded)
+ println("and: " + coll.iterator.toList)
+ println("adding: " + toadd)
+ println(tr.toList)
+ println(cr.iterator.toList)
}
- ("traversable " + ind) |: areEqual(tadded, cadded)
- }).reduceLeft(_ && _)
+ ("adding " |: areEqual(tr, cr)) &&
+ (for ((trav, ind) <- (addAllTraversables).zipWithIndex) yield {
+ val tadded = t ++ trav
+ val cadded = coll ++ collection.parallel.mutable.ParArray(trav.toSeq: _*)
+ if (!areEqual(tadded, cadded)) {
+ println("----------------------")
+ println("from: " + t)
+ println("and: " + coll)
+ println("adding: " + trav)
+ println(tadded)
+ println(cadded)
+ }
+ ("traversable " + ind) |: areEqual(tadded, cadded)
+ }).reduceLeft(_ && _)
+ } catch {
+ case e: java.lang.Exception =>
+ throw e
+ }
}
-
+
if (hasStrictOrder) property("copies to array must be equal") = forAll(collectionPairs) { case (t, coll) =>
val tarr = newArray(t.size)
val collarr = newArray(coll.size)
@@ -397,7 +402,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
}
tarr.toSeq == collarr.toSeq
}
-
+
if (hasStrictOrder) property("scans must be equal") = forAll(collectionPairs) {
case (t, coll) =>
(for (((first, op), ind) <- foldArguments.zipWithIndex) yield {
@@ -413,7 +418,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
("operator " + ind) |: tscan == cscan && cscan == tscan
}).reduceLeft(_ && _)
}
-
+
property("groupBy must be equal") = forAll(collectionPairs) {
case (t, coll) =>
(for ((f, ind) <- groupByFunctions.zipWithIndex) yield {
@@ -429,7 +434,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
("operator " + ind) |: tgroup == cgroup && cgroup == tgroup
}).reduceLeft(_ && _)
}
-
+
}
diff --git a/test/files/scalacheck/parallel-collections/ParallelMapCheck1.scala b/test/files/scalacheck/parallel-collections/ParallelMapCheck1.scala
index b6af8f41bd..d4643e7f2c 100644
--- a/test/files/scalacheck/parallel-collections/ParallelMapCheck1.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelMapCheck1.scala
@@ -16,15 +16,15 @@ import scala.collection.parallel._
abstract class ParallelMapCheck[K, V](collname: String) extends ParallelIterableCheck[(K, V)](collname) {
type CollType <: ParMap[K, V]
-
+
property("gets iterated keys") = forAll(collectionPairs) {
case (t, coll) =>
val containsT = for ((k, v) <- t) yield (coll.get(k) == Some(v))
val containsSelf = coll.map { case (k, v) => coll.get(k) == Some(v) }
("Par contains elements of seq map" |: containsT.forall(_ == true)) &&
("Par contains elements of itself" |: containsSelf.forall(_ == true))
- }
-
+ }
+
}
diff --git a/test/files/scalacheck/parallel-collections/ParallelRangeCheck.scala b/test/files/scalacheck/parallel-collections/ParallelRangeCheck.scala
index 3c6a35d8f1..f490d9490a 100644
--- a/test/files/scalacheck/parallel-collections/ParallelRangeCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelRangeCheck.scala
@@ -17,18 +17,18 @@ import scala.collection.parallel.ops._
-object ParallelRangeCheck extends ParallelSeqCheck[Int]("ParallelRange[Int]") with ops.IntSeqOperators {
+class ParallelRangeCheck(val tasksupport: TaskSupport) extends ParallelSeqCheck[Int]("ParallelRange[Int]") with ops.IntSeqOperators {
// ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2)
// ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2)
-
+
type CollType = collection.parallel.ParSeq[Int]
-
+
def hasStrictOrder = true
-
+
def isCheckingViews = false
-
+
def ofSize(vals: Seq[Gen[Int]], sz: Int) = unsupported
-
+
override def instances(vals: Seq[Gen[Int]]): Gen[Seq[Int]] = sized { start =>
sized { end =>
sized { step =>
@@ -36,22 +36,26 @@ object ParallelRangeCheck extends ParallelSeqCheck[Int]("ParallelRange[Int]") wi
}
}
}
-
+
def fromSeq(a: Seq[Int]) = a match {
- case r: Range => ParRange(r.start, r.end, r.step, false)
+ case r: Range =>
+ val pr = ParRange(r.start, r.end, r.step, false)
+ pr.tasksupport = tasksupport
+ pr
case _ =>
val pa = new parallel.mutable.ParArray[Int](a.length)
+ pa.tasksupport = tasksupport
for (i <- 0 until a.length) pa(i) = a(i)
pa
}
-
+
override def traversable2Seq(t: Traversable[Int]): Seq[Int] = t match {
case r: Range => r
case _ => t.toSeq
}
-
+
def values = Seq(choose(-100, 100))
-
+
}
diff --git a/test/files/scalacheck/parallel-collections/ParallelSeqCheck.scala b/test/files/scalacheck/parallel-collections/ParallelSeqCheck.scala
index dd897412ae..3f8a8ad4f5 100644
--- a/test/files/scalacheck/parallel-collections/ParallelSeqCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelSeqCheck.scala
@@ -16,13 +16,13 @@ import scala.collection.parallel._
abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableCheck[T](collName) with SeqOperators[T] {
-
+
type CollType <: collection.parallel.ParSeq[T]
-
+
def ofSize(vals: Seq[Gen[T]], sz: Int): Seq[T]
def fromSeq(s: Seq[T]): CollType
-
+
override def instances(vals: Seq[Gen[T]]): Gen[Seq[T]] = oneOf(
sized(
sz =>
@@ -31,17 +31,17 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
for (sz <- choose(1000, 2000)) yield ofSize(vals, sz)
)
-
+
def fromTraversable(t: Traversable[T]) = fromSeq(traversable2Seq(t))
def traversable2Seq(t: Traversable[T]): Seq[T] = {
if (t.isInstanceOf[Iterable[_]]) t.asInstanceOf[Iterable[T]].iterator.toList else t.toList
}
-
+
override def collectionPairs: Gen[(Seq[T], CollType)] = for (inst <- instances(values)) yield (inst, fromSeq(inst))
-
+
override def collectionPairsWithLengths: Gen[(Seq[T], CollType, Int)] =
for (inst <- instances(values); s <- choose(0, inst.size)) yield (inst, fromSeq(inst), s);
-
+
def collectionPairsWithModifiedWithLengths: Gen[(Seq[T], CollType, ParSeq[T], Int)] =
for (inst <- instances(values); s <- choose(0, inst.size);
updateStart <- choose(0, inst.size); howMany <- choose(0, inst.size)) yield {
@@ -49,31 +49,31 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
val parcollmodif = fromSeq(modifySlightly(inst, updateStart, howMany))
(inst, parcoll, parcollmodif, s)
}
-
+
def collectionPairsWithModified: Gen[(Seq[T], CollType, ParSeq[T])] =
for (inst <- instances(values); updateStart <- choose(0, inst.size); howMany <- choose(0, inst.size)) yield {
val parcoll = fromSeq(inst)
val parcollmodif = fromSeq(modifySlightly(inst, updateStart, howMany))
(inst, parcoll, parcollmodif)
}
-
+
def collectionPairsWithSliced: Gen[(Seq[T], CollType, ParSeq[T])] =
for (inst <- instances(values); sliceStart <- choose(0, inst.size); howMany <- choose(0, inst.size)) yield {
val parcoll = fromSeq(inst)
val parcollsliced = fromSeq(inst.slice(sliceStart, sliceStart + howMany))
(inst, parcoll, parcollsliced)
}
-
+
def collectionTripletsWith2Indices: Gen[(Seq[T], CollType, Seq[T], Int, Int)] =
for (inst <- instances(values); f <- choose(0, inst.size); s <- choose(0, inst.size - f);
third <- instances(values); sliceStart <- choose(0, inst.size); howMany <- choose(0, inst.size)) yield {
(inst, fromSeq(inst), inst.slice(sliceStart, sliceStart + howMany), f, s)
}
-
+
private def modifySlightly(coll: Seq[T], updateStart: Int, howMany: Int) = {
coll.patch(updateStart, coll, howMany)
}
-
+
property("segmentLengths must be equal") = forAll(collectionPairsWithLengths) { case (s, coll, len) =>
(for ((pred, ind) <- segmentLengthPredicates.zipWithIndex) yield {
val slen = s.segmentLength(pred, if (len < 0) 0 else len)
@@ -87,13 +87,13 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
("operator " + ind) |: slen == clen
}).reduceLeft(_ && _)
}
-
+
property("prefixLengths must be equal") = forAll(collectionPairs) { case (s, coll) =>
(for ((pred, ind) <- segmentLengthPredicates.zipWithIndex) yield {
("operator " + ind) |: s.prefixLength(pred) == coll.prefixLength(pred)
}).reduceLeft(_ && _)
}
-
+
property("indexWheres must be equal") = forAll(collectionPairsWithLengths) { case (s, coll, len) =>
(for ((pred, ind) <- indexWherePredicates.zipWithIndex) yield {
val sind = s.indexWhere(pred, len)
@@ -108,7 +108,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
("operator " + ind) |: sind == cind
}).reduceLeft(_ && _)
}
-
+
property("lastIndexWheres must be equal") = forAll(collectionPairsWithLengths) { case (s, coll, len) =>
(for ((pred, ind) <- lastIndexWherePredicates.zipWithIndex) yield {
val end = if (len >= s.size) s.size - 1 else len
@@ -117,7 +117,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
("operator " + ind) |: sind == cind
}).reduceLeft(_ && _)
}
-
+
property("reverses must be equal") = forAll(collectionPairs) { case (s, coll) =>
(s.length == 0 && s.getClass == classOf[collection.immutable.Range]) ||
{
@@ -132,13 +132,13 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
sr == cr
}
}
-
+
property("reverseMaps must be equal") = forAll(collectionPairs) { case (s, coll) =>
(for ((f, ind) <- reverseMapFunctions.zipWithIndex) yield {
("operator " + ind) |: s.reverseMap(f) == coll.reverseMap(f)
}).reduceLeft(_ && _)
}
-
+
property("sameElements must be equal") = forAll(collectionPairsWithModifiedWithLengths) {
case (s, coll, collmodif, len) =>
val pos = if (len < 0) 0 else len
@@ -170,7 +170,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
("collection " + ind) |: sres == pres
}).reduceLeft(_ && _)
}
-
+
property("startsWiths must be equal") = forAll(collectionPairsWithModifiedWithLengths) {
case (s, coll, collmodif, len) =>
val pos = if (len < 0) 0 else len
@@ -194,7 +194,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
("seq " + sq) |: ss == cs
}).reduceLeft(_ && _)
}
-
+
property("endsWiths must be equal") = forAll(collectionPairsWithModified) {
case (s, coll, collmodif) =>
("ends with self" |: s.endsWith(s) == coll.endsWith(s)) &&
@@ -213,18 +213,18 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
("seq " + sq) |: sew == cew
}).reduceLeft(_ && _)
}
-
+
property("unions must be equal") = forAll(collectionPairsWithModified) { case (s, coll, collmodif) =>
("modified" |: s.union(collmodif.seq) == coll.union(collmodif)) &&
("empty" |: s.union(Nil) == coll.union(fromSeq(Nil)))
}
-
+
// This is failing with my views patch: array index out of bounds in the array iterator.
// Couldn't see why this and only this was impacted, could use a second pair of eyes.
- //
+ //
// This was failing because some corner cases weren't added to the patch method in ParSeqLike.
// Curiously, this wasn't detected before.
- //
+ //
if (!isCheckingViews) property("patches must be equal") = forAll(collectionTripletsWith2Indices) {
case (s, coll, pat, from, repl) =>
("with seq" |: s.patch(from, pat, repl) == coll.patch(from, pat, repl)) &&
@@ -232,7 +232,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
("with empty" |: s.patch(from, Nil, repl) == coll.patch(from, fromSeq(Nil), repl)) &&
("with one" |: (s.length == 0 || s.patch(from, List(s(0)), 1) == coll.patch(from, fromSeq(List(coll(0))), 1)))
}
-
+
if (!isCheckingViews) property("updates must be equal") = forAll(collectionPairsWithLengths) { case (s, coll, len) =>
val pos = if (len >= s.length) s.length - 1 else len
if (s.length > 0) {
@@ -247,15 +247,15 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
"from first" |: (supd == cupd)
} else "trivially" |: true
}
-
+
property("prepends must be equal") = forAll(collectionPairs) { case (s, coll) =>
s.length == 0 || s(0) +: s == coll(0) +: coll
}
-
+
property("appends must be equal") = forAll(collectionPairs) { case (s, coll) =>
s.length == 0 || s :+ s(0) == coll :+ coll(0)
}
-
+
property("padTos must be equal") = forAll(collectionPairsWithLengths) { case (s, coll, len) =>
val someValue = sampleValue
val sdoub = s.padTo(len * 2, someValue)
@@ -269,14 +269,14 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
("smaller" |: s.padTo(len / 2, someValue) == coll.padTo(len / 2, someValue)) &&
("bigger" |: sdoub == cdoub)
}
-
+
property("corresponds must be equal") = forAll(collectionPairsWithModified) { case (s, coll, modified) =>
val modifcut = modified.toSeq.slice(0, modified.length)
("self" |: s.corresponds(s)(_ == _) == coll.corresponds(coll)(_ == _)) &&
("modified" |: s.corresponds(modified.seq)(_ == _) == coll.corresponds(modified)(_ == _)) &&
("modified2" |: s.corresponds(modifcut)(_ == _) == coll.corresponds(modifcut)(_ == _))
}
-
+
}
diff --git a/test/files/scalacheck/parallel-collections/ParallelSetCheck.scala b/test/files/scalacheck/parallel-collections/ParallelSetCheck.scala
index 4211abbd16..56f7832fed 100644
--- a/test/files/scalacheck/parallel-collections/ParallelSetCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelSetCheck.scala
@@ -16,15 +16,15 @@ import scala.collection.parallel._
abstract class ParallelSetCheck[T](collname: String) extends ParallelIterableCheck[T](collname) {
type CollType <: ParSet[T]
-
+
property("gets iterated keys") = forAll(collectionPairs) {
case (t, coll) =>
val containsT = for (elem <- t) yield (coll.contains(elem))
val containsSelf = for (elem <- coll) yield (coll.contains(elem))
("Par contains elements of seq map" |: containsT.forall(_ == true)) &&
("Par contains elements of itself" |: containsSelf.forall(_ == true))
- }
-
+ }
+
}
diff --git a/test/files/scalacheck/parallel-collections/ParallelVectorCheck.scala b/test/files/scalacheck/parallel-collections/ParallelVectorCheck.scala
index e4bb588fa7..bbebd51919 100644
--- a/test/files/scalacheck/parallel-collections/ParallelVectorCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelVectorCheck.scala
@@ -17,37 +17,43 @@ import scala.collection.parallel.ops._
import immutable.Vector
import immutable.VectorBuilder
+import scala.collection.parallel.TaskSupport
+
abstract class ParallelVectorCheck[T](tp: String) extends collection.parallel.ParallelSeqCheck[T]("ParVector[" + tp + "]") {
// ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2)
// ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2)
-
+
type CollType = ParVector[T]
-
+
def isCheckingViews = false
-
+
def hasStrictOrder = true
+ def tasksupport: TaskSupport
+
def ofSize(vals: Seq[Gen[T]], sz: Int) = {
val vb = new immutable.VectorBuilder[T]()
val gen = vals(rnd.nextInt(vals.size))
for (i <- 0 until sz) vb += sample(gen)
vb.result
}
-
+
def fromSeq(a: Seq[T]) = {
- val pa = ParVector.newCombiner[T]
- for (elem <- a.toList) pa += elem
- pa.result
+ val pc = ParVector.newCombiner[T]
+ for (elem <- a.toList) pc += elem
+ val pv = pc.result
+ pv.tasksupport = tasksupport
+ pv
}
-
+
}
-object IntParallelVectorCheck extends ParallelVectorCheck[Int]("Int") with IntSeqOperators with IntValues {
+class IntParallelVectorCheck(val tasksupport: TaskSupport) extends ParallelVectorCheck[Int]("Int") with IntSeqOperators with IntValues {
override def instances(vals: Seq[Gen[Int]]) = oneOf(super.instances(vals), sized { sz =>
(0 until sz).toArray.toSeq
}, sized { sz =>
diff --git a/test/files/scalacheck/parallel-collections/pc.scala b/test/files/scalacheck/parallel-collections/pc.scala
index 0a91977da0..a3c1df4054 100644
--- a/test/files/scalacheck/parallel-collections/pc.scala
+++ b/test/files/scalacheck/parallel-collections/pc.scala
@@ -1,42 +1,58 @@
-
-
-
+/*
+ * scalac: -deprecation
+ * scalacheck: -workers 1 -minSize 0 -maxSize 4000 -minSuccessfulTests 5
+ */
import org.scalacheck._
-
import scala.collection.parallel._
+// package here to be able access the package-private implementation and shutdown the pool
+package scala {
-class ParCollProperties extends Properties("Parallel collections") {
- /* Collections */
-
- // parallel arrays
- include(mutable.IntParallelArrayCheck)
-
- // parallel ranges
- include(immutable.ParallelRangeCheck)
+ class ParCollProperties extends Properties("Parallel collections") {
- // parallel immutable hash maps (tries)
- include(immutable.IntIntParallelHashMapCheck)
+ def includeAllTestsWith(support: TaskSupport) {
+ // parallel arrays with default task support
+ include(new mutable.IntParallelArrayCheck(support))
+
+ // parallel ranges
+ include(new immutable.ParallelRangeCheck(support))
+
+ // parallel immutable hash maps (tries)
+ include(new immutable.IntIntParallelHashMapCheck(support))
+
+ // parallel immutable hash sets (tries)
+ include(new immutable.IntParallelHashSetCheck(support))
+
+ // parallel mutable hash maps (tables)
+ include(new mutable.IntIntParallelHashMapCheck(support))
+
+ // parallel ctrie
+ include(new mutable.IntIntParallelConcurrentTrieMapCheck(support))
+
+ // parallel mutable hash sets (tables)
+ include(new mutable.IntParallelHashSetCheck(support))
+
+ // parallel vectors
+ include(new immutable.IntParallelVectorCheck(support))
+ }
- // parallel immutable hash sets (tries)
- include(immutable.IntParallelHashSetCheck)
+ includeAllTestsWith(defaultTaskSupport)
- // parallel mutable hash maps (tables)
- include(mutable.IntIntParallelHashMapCheck)
-
- // parallel ctrie
- include(mutable.IntIntParallelConcurrentTrieMapCheck)
-
- // parallel mutable hash sets (tables)
- include(mutable.IntParallelHashSetCheck)
+ val ec = scala.concurrent.ExecutionContext.fromExecutorService(java.util.concurrent.Executors.newFixedThreadPool(5))
+ val ectasks = new collection.parallel.ExecutionContextTaskSupport(ec)
+ includeAllTestsWith(ectasks)
+
+ // no post test hooks in scalacheck, so cannot do:
+ // ec.shutdown()
- // parallel vectors
- include(immutable.IntParallelVectorCheck)
+ }
+
}
-object Test {
+object Test extends scala.ParCollProperties {
+ /*
def main(args: Array[String]) {
val pc = new ParCollProperties
org.scalacheck.Test.checkProperties(
@@ -51,4 +67,5 @@ object Test {
pc
)
}
+ */
}
diff --git a/test/files/scalacheck/primitive-eqeq.scala b/test/files/scalacheck/primitive-eqeq.scala
index a783805e46..60fe63c207 100644
--- a/test/files/scalacheck/primitive-eqeq.scala
+++ b/test/files/scalacheck/primitive-eqeq.scala
@@ -4,7 +4,7 @@ import Gen._
object Test extends Properties("==") {
def equalObjectsEqualHashcodes(x: Any, y: Any) = (x != y) || (x == y && x.## == y.##)
-
+
// ticket #2087
property("short/char") = forAll { (x: Short) => {
val ch: Char = x.toChar
@@ -14,15 +14,15 @@ object Test extends Properties("==") {
property("symmetry") = forAll { (x: AnyVal, y: AnyVal) => (x == y) == (y == x) }
property("transitivity") = forAll { (x: AnyVal, y: AnyVal, z: AnyVal) => x != y || y != z || x == z }
-
- property("##") = forAll {
+
+ property("##") = forAll {
(x: Short) => {
val anyvals = List(x.toByte, x.toChar, x, x.toInt, x.toLong, x.toFloat, x.toDouble, BigInt(x), BigDecimal(x))
val shortAndLarger = anyvals drop 2
val result = (
- ((anyvals, anyvals).zipped forall equalObjectsEqualHashcodes) &&
- ((shortAndLarger, shortAndLarger).zipped forall (_ == _)) &&
+ ((anyvals, anyvals).zipped forall equalObjectsEqualHashcodes) &&
+ ((shortAndLarger, shortAndLarger).zipped forall (_ == _)) &&
((shortAndLarger, shortAndLarger).zipped forall ((x, y) => (x: Any) == (y: Any)))
)
result
diff --git a/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala b/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala
new file mode 100644
index 0000000000..7bd37140a7
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala
@@ -0,0 +1,295 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, internal._, Flag._
+
+trait ArbitraryTreesAndNames {
+ def smallList[T](size: Int, g: Gen[T]) = {
+ val n: Int = choose(0, size / 2 + 1).sample match {
+ case Some(i) => i
+ case None => 0
+ }
+ containerOfN[List, T](n, g)
+ }
+
+ def shortIdent(len: Int) =
+ for(name <- identifier)
+ yield if(name.length <= len) name
+ else name.substring(0, len - 1)
+
+ def genTermName = for(name <- shortIdent(8)) yield TermName(name)
+ def genTypeName = for(name <- shortIdent(8)) yield TypeName(name)
+ def genName = oneOf(genTermName, genTypeName)
+
+ def genFlagSet = oneOf(
+ TRAIT, INTERFACE, MUTABLE, MACRO,
+ DEFERRED, ABSTRACT, FINAL, SEALED,
+ IMPLICIT, LAZY, OVERRIDE, PRIVATE,
+ PROTECTED, LOCAL, CASE, ABSOVERRIDE,
+ BYNAMEPARAM, PARAM, COVARIANT, CONTRAVARIANT,
+ DEFAULTPARAM, PRESUPER, DEFAULTINIT
+ )
+
+ def genModifiers = for(flagset <- genFlagSet) yield Modifiers(flagset)
+
+ def genConstant =
+ for(value <- oneOf(arbitrary[Byte], arbitrary[Short], arbitrary[Char],
+ arbitrary[Int], arbitrary[Long], arbitrary[Float],
+ arbitrary[Double], arbitrary[Boolean], arbitrary[String]))
+ yield Constant(value)
+
+ def genAnnotated(size: Int, argGen: Int => Gen[Tree]) =
+ for(annot <- genTree(size - 1); arg <- argGen(size - 1))
+ yield Annotated(annot, arg)
+
+ def genAlternative(size: Int): Gen[Alternative] =
+ for(trees <- smallList(size, genTree(size - 1)))
+ yield Alternative(trees)
+
+ def genAppliedTypeTree(size: Int) =
+ for(tpt <- genTree(size - 1) if tpt.isType;
+ args <- smallList(size, genTree(size - 1)))
+ yield AppliedTypeTree(tpt, args)
+
+ def genApply(size: Int) =
+ for(fun <- genTree(size - 1);
+ args <- smallList(size, genTree(size - 1)))
+ yield Apply(fun, args)
+
+ def genAssign(size: Int) =
+ for(lhs <- genTree(size - 1); rhs <- genTree(size - 1))
+ yield Assign(lhs, rhs)
+
+ def genAssignOrNamedArg(size: Int) =
+ for(lhs <- genTree(size - 1); rhs <- genTree(size - 1))
+ yield AssignOrNamedArg(lhs, rhs)
+
+ def genBind(size: Int, nameGen: Gen[Name]) =
+ for(name <- nameGen; body <- genTree(size - 1))
+ yield Bind(name, body)
+
+ def genBlock(size: Int) =
+ for(stats <- smallList(size, genTree(size - 1)); expr <- genTree(size - 1))
+ yield Block(stats, expr)
+
+ def genCaseDef(size: Int) =
+ for(pat <- genTree(size - 1); guard <- genTree(size - 1); body <- genTree(size - 1))
+ yield CaseDef(pat, guard, body)
+
+ def genClassDef(size: Int) =
+ for(mods <- genModifiers; name <- genTypeName;
+ tparams <- smallList(size, genTypeDef(size - 1));
+ impl <- genTemplate(size - 1))
+ yield ClassDef(mods, name, tparams, impl)
+
+ def genCompoundTypeTree(size: Int) =
+ for(templ <- genTemplate(size - 1))
+ yield CompoundTypeTree(templ)
+
+ def genDefDef(size: Int) =
+ for(mods <- genModifiers; name <- genTermName;
+ tpt <- genTree(size -1); rhs <- genTree(size - 1);
+ tparams <- smallList(size, genTypeDef(size - 1));
+ vparamss <- smallList(size, smallList(size, genValDef(size - 1))))
+ yield DefDef(mods, name, tparams, vparamss, tpt, rhs)
+
+ def genExistentialTypeTree(size: Int) =
+ for(tpt <- genTree(size - 1); where <- smallList(size, oneOf(genValDef(size - 1), genTypeDef(size - 1))))
+ yield ExistentialTypeTree(tpt, where)
+
+ def genFunction(size: Int) =
+ for(vparams <- smallList(size, genValDef(size - 1)); body <- genTree(size - 1))
+ yield Function(vparams, body)
+
+ def genIdent(nameGen: Gen[Name] = genName) =
+ for(name <- nameGen) yield Ident(name)
+
+ def genIf(size: Int) =
+ for(cond <- genTree(size - 1); thenp <- genTree(size - 1); elsep <- genTree(size - 1))
+ yield If(cond, thenp, elsep)
+
+ def genImport(size: Int) =
+ for(expr <- genTree(size - 1); selectors <- smallList(size, genImportSelector(size - 1)))
+ yield Import(expr, selectors)
+
+ def genImportSelector(size: Int) =
+ for(name <- genName; namePos <- arbitrary[Int]; rename <- genName; renamePos <- arbitrary[Int])
+ yield ImportSelector(name, namePos, rename, renamePos)
+
+ def genTemplate(size: Int) =
+ for(parents <- smallList(size, genTree(size - 1));
+ self <- genValDef(size - 1);
+ body <- smallList(size, genTree(size - 1)))
+ yield Template(parents, self, body)
+
+ def genLabelDef(size: Int) =
+ for(name <- genTermName; params <- smallList(size, genIdent()); rhs <- genTree(size - 1))
+ yield LabelDef(name, params, rhs)
+
+ def genLiteral =
+ for(const <- genConstant) yield Literal(const)
+
+ def genMatch(size: Int) =
+ for(selector <- genTree(size - 1); cases <- smallList(size, genCaseDef(size - 1)))
+ yield Match(selector, cases)
+
+ def genModuleDef(size: Int) =
+ for(mods <- genModifiers; name <- genTermName; impl <- genTemplate(size - 1))
+ yield ModuleDef(mods, name, impl)
+
+ def genNew(size: Int) =
+ for(tpt <- genTree(size - 1))
+ yield New(tpt)
+
+ def genRefTree(size: Int) =
+ oneOf(genSelect(size), genIdent(), genSelectFromTypeTree(size))
+
+ def genPackageDef(size: Int) =
+ for(reftree <- genRefTree(size - 1); stats <- smallList(size, genTree(size - 1)))
+ yield PackageDef(reftree, stats)
+
+ def genTypeSelect(size: Int) =
+ for(qual <- genTree(size - 1); name <- genTypeName)
+ yield Select(qual, name)
+
+ def genSelect(size: Int, nameGen: Gen[Name] = genName) =
+ for(qual <- genTree(size - 1); name <- nameGen)
+ yield Select(qual, name)
+
+ def genSelectFromTypeTree(size: Int) =
+ for(qual <- genTreeIsType(size - 1); name <- genTypeName)
+ yield SelectFromTypeTree(qual, name)
+
+ def genReferenceToBoxed(size: Int) =
+ for(ident <- genIdent())
+ yield ReferenceToBoxed(ident)
+
+ def genReturn(size: Int) =
+ for(expr <- genTree(size - 1))
+ yield Return(expr)
+
+ def genSingletonTypeTree(size: Int) =
+ for(expr <- genTree(size - 1))
+ yield SingletonTypeTree(expr)
+
+ def genStar(size: Int) =
+ for(expr <- genTree(size - 1))
+ yield Star(expr)
+
+ def genSuper(size: Int) =
+ for(qual <- genTree(size - 1); mix <- genTypeName)
+ yield Super(qual, mix)
+
+ def genThis(size: Int) =
+ for(qual <- genTypeName)
+ yield This(qual)
+
+ def genThrow(size: Int) =
+ for(expr <- genTree(size - 1))
+ yield Throw(expr)
+
+ def genTry(size: Int) =
+ for(block <- genTree(size - 1);
+ catches <- smallList(size, genCaseDef(size - 1));
+ finalizer <- genTree(size - 1))
+ yield Try(block, catches, finalizer)
+
+ def genTypeApply(size: Int) =
+ for(fun <- genTreeIsTerm(size - 1); args <- smallList(size, genTree(size - 1)))
+ yield TypeApply(fun, args)
+
+ def genTypeBoundsTree(size: Int) =
+ for(lo <- genTree(size - 1); hi <- genTree(size - 1))
+ yield TypeBoundsTree(lo, hi)
+
+ def genTypeDef(size: Int): Gen[TypeDef] =
+ for(mods <- genModifiers; name <- genTypeName;
+ tparams <- smallList(size, genTypeDef(size - 1)); rhs <- genTree(size - 1))
+ yield TypeDef(mods, name, tparams, rhs)
+
+ def genTypeTree: Gen[TypeTree] = TypeTree()
+
+ def genTyped(size: Int) =
+ for(expr <- genTree(size - 1); tpt <- genTree(size - 1))
+ yield Typed(expr, tpt)
+
+ def genUnApply(size: Int) =
+ for(fun <- genTree(size - 1); args <- smallList(size, genTree(size - 1)))
+ yield UnApply(fun, args)
+
+ def genValDef(size: Int) =
+ for(mods <- genModifiers; name <- genTermName;
+ tpt <- genTree(size - 1); rhs <- genTree(size - 1))
+ yield ValDef(mods, name, tpt, rhs)
+
+ def genTree(size: Int): Gen[Tree] =
+ if (size <= 1) oneOf(EmptyTree: Gen[Tree], genTreeIsTerm(size), genTreeIsType(size))
+ else oneOf(genTree(1),
+ // these trees are neither terms nor types
+ genPackageDef(size - 1), genModuleDef(size - 1),
+ genCaseDef(size - 1), genDefDef(size - 1),
+ genTypeDef(size - 1), genTemplate(size - 1),
+ genClassDef(size - 1), genValDef(size - 1),
+ genImport(size - 1))
+
+ def genTreeIsTerm(size: Int): Gen[Tree] =
+ if (size <= 1) oneOf(genLiteral, genIdent(genTermName))
+ else oneOf(genTreeIsTerm(1), genBind(size - 1, genTermName),
+ genAnnotated(size - 1, genTreeIsTerm), genSelect(size - 1, genTermName),
+ genAlternative(size - 1), genApply(size - 1), genAssign(size - 1),
+ genAssignOrNamedArg(size - 1), genBlock(size - 1), genFunction(size - 1),
+ genIf(size - 1), genLabelDef(size - 1), genMatch(size - 1), genNew(size - 1),
+ genReturn(size - 1), genStar(size - 1), genSuper(size - 1), genThis(size - 1),
+ genThrow(size - 1), genTry(size - 1), genTypeApply(size - 1),
+ genTyped(size - 1), genUnApply(size - 1))
+
+ def genTreeIsType(size: Int): Gen[Tree] =
+ if (size <= 1) genIdent(genTypeName)
+ else oneOf(genTreeIsType(1), genAnnotated(size - 1, genTreeIsType),
+ genBind(size - 1, genTypeName), genSelect(size - 1, genTypeName),
+ genSingletonTypeTree(size - 1), genSelectFromTypeTree(size - 1),
+ genExistentialTypeTree(size - 1), genCompoundTypeTree(size - 1),
+ genAppliedTypeTree(size - 1), genTypeBoundsTree(size - 1))
+
+ /* These are marker types that allow to write tests that
+ * depend specificly on Trees that are terms or types.
+ * They are transparently tranformed to trees through
+ * implicit conversions and liftables for quasiquotes.
+ */
+
+ case class TreeIsTerm(tree: Tree) { require(tree.isTerm, showRaw(tree)) }
+ case class TreeIsType(tree: Tree) { require(tree.isType, showRaw(tree)) }
+
+ def genTreeIsTermWrapped(size: Int) =
+ for(tit <- genTreeIsTerm(size)) yield TreeIsTerm(tit)
+
+ def genTreeIsTypeWrapped(size: Int) =
+ for(tit <- genTreeIsType(size)) yield TreeIsType(tit)
+
+ implicit val liftTreeIsTerm = Liftable[TreeIsTerm] { _.tree }
+ implicit val liftTreeIsType = Liftable[TreeIsType] { _.tree }
+ implicit def treeIsTerm2tree(tit: TreeIsTerm): Tree = tit.tree
+ implicit def treeIsType2tree(tit: TreeIsType): Tree = tit.tree
+
+ implicit val arbConstant: Arbitrary[Constant] = Arbitrary(genConstant)
+ implicit val arbModifiers: Arbitrary[Modifiers] = Arbitrary(genModifiers)
+ implicit val arbTermName: Arbitrary[TermName] = Arbitrary(genTermName)
+ implicit val arbTypeName: Arbitrary[TypeName] = Arbitrary(genTypeName)
+ implicit val arbName: Arbitrary[Name] = Arbitrary(genName)
+
+ // Trees generators are bound by this size to make
+ // generation times shorter and less memory hungry.
+ // TODO: is there any better solution?
+ val maxTreeSize = 5
+
+ def arbitrarySized[T](gen: Int => Gen[T]) =
+ Arbitrary(sized(s => gen(s.min(maxTreeSize))))
+
+ implicit val arbLiteral: Arbitrary[Literal] = Arbitrary(genLiteral)
+ implicit val arbIdent: Arbitrary[Ident] = Arbitrary(genIdent())
+ implicit val arbValDef: Arbitrary[ValDef] = arbitrarySized(genValDef)
+ implicit val arbDefDef: Arbitrary[DefDef] = arbitrarySized(genDefDef)
+ implicit val arbTypeDef: Arbitrary[TypeDef] = arbitrarySized(genTypeDef)
+ implicit val arbBind: Arbitrary[Bind] = arbitrarySized(genBind(_, genName))
+ implicit val arbTree: Arbitrary[Tree] = arbitrarySized(genTree)
+ implicit val arbTreeIsTerm: Arbitrary[TreeIsTerm] = arbitrarySized(genTreeIsTermWrapped)
+ implicit val arbTreeIsType: Arbitrary[TreeIsType] = arbitrarySized(genTreeIsTypeWrapped)
+} \ No newline at end of file
diff --git a/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala b/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala
new file mode 100644
index 0000000000..fd810674f5
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala
@@ -0,0 +1,453 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport.ScalaDot
+
+object DefinitionConstructionProps
+ extends QuasiquoteProperties("definition construction")
+ with ClassConstruction
+ with TraitConstruction
+ with TypeDefConstruction
+ with ValDefConstruction
+ with PatDefConstruction
+ with DefConstruction
+ with PackageConstruction
+ with ImportConstruction {
+
+ val x: Tree = q"val x: Int"
+ property("SI-6842 a1") = test { assertEqAst(q"def f($x) = 0", "def f(x: Int) = 0") }
+ property("SI-6842 a2") = test { assertEqAst(q"class C($x)", "class C(val x: Int)") }
+ property("SI-6842 a3") = test { assertEqAst(q"class C { $x => }", "class C { x: Int => }") }
+ property("SI-6842 a4") = test { assertEqAst(q"trait B { $x => }", "trait B { x: Int => }") }
+ property("SI-6842 a5") = test { assertEqAst(q"object A { $x => }", "object A { x: Int => }") }
+
+ val t: Tree = q"type T"
+ property("SI-6842 b1") = test { assertEqAst(q"def f[$t] = 0", "def f[T] = 0") }
+ property("SI-6842 b2") = test { assertEqAst(q"class C[$t]", "class C[T]") }
+ property("SI-6842 b3") = test { assertEqAst(q"trait B[$t]", "trait B[T]") }
+}
+
+trait ClassConstruction { self: QuasiquoteProperties =>
+ val anyRef = ScalaDot(TypeName("AnyRef"))
+ val emtpyConstructor =
+ DefDef(Modifiers(), termNames.CONSTRUCTOR, List(),
+ List(List()), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(()))))
+ def classWith(name: TypeName, parents: List[Tree] = List(anyRef), body: List[DefDef] = Nil) =
+ ClassDef(
+ Modifiers(), name, List(),
+ Template(parents, emptyValDef, emtpyConstructor :: body))
+
+ property("construct case class") = test {
+ val params = q"val x: Int" :: q"val y: Int" :: Nil
+ val name = TypeName("Point")
+ assertEqAst(q"$CASE class $name(..$params)", "case class Point(x: Int, y: Int)")
+ }
+
+ property("case class bare param") = test {
+ assertEqAst(q"$CASE class Point(x: Int, y: Int)", "case class Point(private[this] val x: Int, private[this] val y: Int)")
+ }
+
+ property("generate default constructors automatically") = test {
+ val parents = List.empty[Tree]
+ assertEqAst(q"class Foo extends ..$parents", "class Foo")
+ }
+
+ property("unquote term name into class") = forAll { (rname: TypeName) =>
+ // add prefix to avoid failure in case rname is keyword
+ val name = TypeName("prefix$" + rname)
+ eqAst(q"class $name", "class " + name.toString)
+ }
+
+ property("unquote method into class") = forAll { (name: TypeName, method: DefDef) =>
+ q"class $name { $method }" ≈ classWith(name, body = List(method))
+ }
+
+ property("unquote members into class") = forAll { (name: TypeName, defs: List[DefDef], extra: DefDef) =>
+ q"""class $name {
+ ..$defs
+ $extra
+ }""" ≈ classWith(name, body = defs :+ extra)
+ }
+
+ property("unquote type name into class parents") = forAll { (name: TypeName, parent: TypeName) =>
+ q"class $name extends $parent" ≈ classWith(name, parents = List(Ident(parent)))
+ }
+
+ property("param flags are consistent with raw code") = test {
+ val pubx = q"val x: Int"
+ val privx = q"private[this] val x: Int"
+ assertEqAst(q" class C(x: Int)", " class C(x: Int) ")
+ assertEqAst(q"case class C(x: Int)", "case class C(x: Int) ")
+ assertEqAst(q" class C($pubx) ", " class C(val x: Int) ")
+ assertEqAst(q"case class C($pubx) ", "case class C(x: Int) ")
+ assertEqAst(q" class C($privx)", " class C(x: Int) ")
+ assertEqAst(q"case class C($privx)", "case class C(private[this] val x: Int)")
+ }
+
+ property("SI-8333") = test {
+ assertEqAst(q"{ $NoMods class C }", "{ class C }")
+ }
+
+ property("SI-8332") = test {
+ val args = q"val a: Int; val b: Int"
+ assertEqAst(q"class C(implicit ..$args)", "class C(implicit val a: Int, val b: Int)")
+ }
+
+ property("SI-8451: inline secondary constructors") = test {
+ assertEqAst(q"class C(x: Int) { def this() = this(0) }", "class C(x: Int) { def this() = this(0) }")
+ }
+
+ property("SI-8451: unquoted secondary constructors") = test {
+ val secondaryCtor = q"def this() = this(0)"
+ assertEqAst(q"class C(x: Int) { $secondaryCtor }", "class C(x: Int) { def this() = this(0) }")
+ }
+}
+
+trait TraitConstruction { self: QuasiquoteProperties =>
+ property("unquote name into trait def") = test {
+ val Foo = TypeName("Foo")
+ assert(q"trait $Foo" ≈ q"trait Foo")
+ }
+
+ property("unquote type params into trait def") = test {
+ val tparams = q"type A" :: q"type B" :: Nil
+ assert(q"trait Foo[..$tparams]" ≈ q"trait Foo[A, B]")
+ }
+
+ property("unquote defs into trait body") = test {
+ val body = q"def foo" :: q"val bar: Baz" :: Nil
+ assert(q"trait Foo { ..$body }" ≈ q"trait Foo { def foo; val bar: Baz }")
+ }
+
+ property("unquote parents into trait") = test {
+ val parents = tq"A" :: tq"B" :: Nil
+ assert(q"trait Foo extends ..$parents" ≈ q"trait Foo extends A with B")
+ }
+
+ property("unquote early valdef into trait") = test {
+ val x = q"val x: Int = 1"
+ assertEqAst(q"trait T extends { $x } with Any", "trait T extends { val x: Int = 1} with Any")
+ }
+
+ property("construct trait with early valdef") = test {
+ assertEqAst(q"trait T extends { val x: Int = 1 } with Any", "trait T extends { val x: Int = 1 } with Any")
+ }
+
+ property("unquote defs into early block") = test {
+ val defs = q"val x: Int = 0" :: q"type Foo = Bar" :: Nil
+ assert(q"trait T extends { ..$defs } with Bippy" ≈
+ q"trait T extends { val x: Int = 0; type Foo = Bar} with Bippy")
+ }
+
+ property("fail on splicing of non-valid early tree") = test {
+ val defn = q"def x: Int = 0"
+ assertThrows[IllegalArgumentException] { q"trait T extends { $defn } with Bar" }
+ }
+}
+
+trait TypeDefConstruction { self: QuasiquoteProperties =>
+ property("unquote type name into typedef") = forAll { (name1: TypeName, name2: TypeName) =>
+ q"type $name1 = $name2" ≈ TypeDef(Modifiers(), name1, List(), Ident(name2))
+ }
+
+ property("unquote type names into type bounds") = forAll { (T1: TypeName, T2: TypeName, T3: TypeName) =>
+ q"type $T1 >: $T2 <: $T3" ≈
+ TypeDef(
+ Modifiers(DEFERRED), T1, List(),
+ TypeBoundsTree(Ident(T2), Ident(T3)))
+ }
+
+ property("unquote trees names into type bounds") = forAll { (T: TypeName, t1: Tree, t2: Tree) =>
+ q"type $T >: $t1 <: $t2" ≈
+ TypeDef(
+ Modifiers(DEFERRED), T, List(),
+ TypeBoundsTree(t1, t2))
+ }
+
+ property("unquote tparams into typedef (1)") = forAll { (T: TypeName, targs: List[TypeDef], t: Tree) =>
+ q"type $T[..$targs] = $t" ≈ TypeDef(Modifiers(), T, targs, t)
+ }
+
+ property("unquote tparams into typedef (2)") = forAll { (T: TypeName, targs1: List[TypeDef], targs2: List[TypeDef], t: Tree) =>
+ q"type $T[..$targs1, ..$targs2] = $t" ≈ TypeDef(Modifiers(), T, targs1 ++ targs2, t)
+ }
+
+ property("unquote tparams into typedef (3)") = forAll { (T: TypeName, targ: TypeDef, targs: List[TypeDef], t: Tree) =>
+ q"type $T[$targ, ..$targs] = $t" ≈ TypeDef(Modifiers(), T, targ :: targs, t)
+ }
+
+ property("unquote typename into typedef with default bounds") = forAll { (T1: TypeName, T2: TypeName, t: Tree) =>
+ q"type $T1[$T2 >: Any <: Nothing] = $t" ≈
+ TypeDef(
+ Modifiers(), T1,
+ List(TypeDef(
+ Modifiers(PARAM), T2,
+ List(),
+ TypeBoundsTree(
+ Ident(TypeName("Any")),
+ Ident(TypeName("Nothing"))))),
+ t)
+ }
+
+ property("unquote type names into compound type tree") = forAll { (T: TypeName, A: TypeName, B: TypeName) =>
+ q"type $T = $A with $B" ≈
+ TypeDef(
+ Modifiers(), T, List(),
+ CompoundTypeTree(
+ Template(List(Ident(A), Ident(B)), ValDef(Modifiers(PRIVATE), termNames.WILDCARD, TypeTree(), EmptyTree), List())))
+ }
+
+ property("unquote trees into existential type tree") = forAll {
+ (T1: TypeName, T2: TypeName, X: TypeName, Lo: TypeName, Hi: TypeName) =>
+
+ q"type $T1 = $T2[$X] forSome { type $X >: $Lo <: $Hi }" ≈
+ TypeDef(
+ Modifiers(), T1, List(),
+ ExistentialTypeTree(
+ AppliedTypeTree(Ident(T2), List(Ident(X))),
+ List(
+ TypeDef(Modifiers(DEFERRED), X, List(), TypeBoundsTree(Ident(Lo), Ident(Hi))))))
+ }
+
+ property("unquote tree into singleton type tree") = forAll { (name: TypeName, t: Tree) =>
+ q"type $name = $t.type" ≈ q"type $name = ${SingletonTypeTree(t)}"
+ }
+
+ property("unquote into applied type tree") = forAll { (T1: TypeName, T2: TypeName, args: List[Tree]) =>
+ q"type $T1 = $T2[..$args]" ≈
+ TypeDef(Modifiers(), T1, List(),
+ if(args.nonEmpty) AppliedTypeTree(Ident(T2), args) else Ident(T2))
+ }
+}
+
+trait ValDefConstruction { self: QuasiquoteProperties =>
+ property("unquote into val") = forAll { (name: TermName, tpt: Tree, rhs: Tree) =>
+ q"val $name: $tpt = $rhs" ≈ ValDef(Modifiers(), name, tpt, rhs)
+ }
+
+ property("unquote into var") = forAll { (name: TermName, tpt: Tree, rhs: Tree) =>
+ q"var $name: $tpt = $rhs" ≈ ValDef(Modifiers(MUTABLE), name, tpt, rhs)
+ }
+
+ // left tree is not a pattern due to Si-8211
+ property("SI-8202") = test {
+ assertEqAst(q"val (x: Int) = 1", "val x: Int = 1")
+ }
+}
+
+trait PatDefConstruction { self: QuasiquoteProperties =>
+ property("unquote pattern into pat def") = test {
+ val pat = pq"(a, b)"
+ assertEqAst(q"val $pat = (1, 2)", "val (a, b) = (1, 2)")
+ val tpt = tq"(Int, Int)"
+ assertEqAst(q"val $pat: $tpt = (1, 2)", "val (a, b): (Int, Int) = (1, 2)")
+ }
+
+ property("unquote pattern into pat def within other pattern (1)") = test {
+ val pat = pq"(a, b)"
+ assertEqAst(q"val Foo($pat) = Foo((1, 2))", "val Foo((a, b)) = Foo((1, 2))")
+ val tpt = tq"Foo"
+ assertEqAst(q"val Foo($pat): $tpt = Foo((1, 2))", "val Foo((a, b)): Foo = Foo((1, 2))")
+ }
+
+ property("unquote patterns into pat def within other pattern (2)") = test {
+ val pat1 = pq"(a, b)"; val pat2 = pq"(c, d)"
+ assertEqAst(q"val ($pat1, $pat2) = ((1, 2), (3, 4))", "val ((a, b), (c, d)) = ((1, 2), (3, 4))")
+ val tpt = tq"((Int, Int), (Int, Int))"
+ assertEqAst(q"val ($pat1, $pat2): $tpt = ((1, 2), (3, 4))", "val ((a, b), (c, d)): ((Int, Int), (Int, Int)) = ((1, 2), (3, 4))")
+ }
+
+ property("unquote pattern without free vars into pat def") = test {
+ val pat = pq"((1, 2), 3)"
+ assertEqAst(q"val $pat = ((1, 2), 3)", "{ val ((1, 2), 3) = ((1, 2), 3) }")
+ val tpt = tq"((Int, Int), Int)"
+ assertEqAst(q"val $pat: $tpt = ((1, 2), 3)","{ val ((1, 2), 3): ((Int, Int), Int) = ((1, 2), 3) }")
+ }
+
+ // won't result into pattern match due to SI-8211
+ property("unquote typed pat into pat def") = test {
+ val pat = pq"x: Int"
+ assertEqAst(q"val $pat = 2", "{ val x: Int = 2 }")
+ }
+}
+
+trait MethodConstruction { self: QuasiquoteProperties =>
+ property("unquote paramss into defdef") = test {
+ val paramss = List(q"val x: Int") :: List(q"val y: Int = 1") :: Nil
+ assert(q"def foo(...$paramss)" ≈ parse("def foo(x: Int)(y: Int = 1)"))
+ }
+
+ property("unquote tparams into defdef") = test {
+ val tparams = q"type A" :: q"type B <: Bippy" :: Nil
+ assert(q"def foo[..$tparams]" ≈ parse("def foo[A, B <: Bippy]"))
+ }
+
+ def assertSameAnnots(tree: {def mods: Modifiers}, annots: List[Tree]) =
+ assert(tree.mods.annotations ≈ annots,
+ s"${tree.mods.annotations} =/= ${annots}")
+
+ def assertSameAnnots(tree1: {def mods: Modifiers}, tree2: {def mods: Modifiers}) =
+ assert(tree1.mods.annotations ≈ tree2.mods.annotations,
+ s"${tree1.mods.annotations} =/= ${tree2.mods.annotations}")
+
+ property("unquote type name into annotation") = test {
+ val name = TypeName("annot")
+ assertSameAnnots(q"@$name def foo", List(q"new $name"))
+ }
+
+ property("unquote ident into annotation") = test {
+ val name = TypeName("annot")
+ val ident = Ident(name)
+ assertSameAnnots(q"@$ident def foo", List(q"new $name"))
+ }
+
+ property("unquote idents into annotation") = test {
+ val idents = List(Ident(TypeName("annot1")), Ident(TypeName("annot2")))
+ assertSameAnnots(q"@..$idents def foo",
+ idents.map { ident => Apply(Select(New(ident), termNames.CONSTRUCTOR), List()) })
+ }
+
+ property("unquote constructor calls into annotation") = test {
+ val ctorcalls = List(q"new a1", q"new a2")
+ assertSameAnnots(q"@..$ctorcalls def foo", ctorcalls)
+ }
+
+ property("unquote multiple annotations (1)") = test {
+ val annot1 = q"new a1"
+ val annot2 = q"new a2"
+ val res = q"@$annot1 @$annot2 def foo"
+ assertSameAnnots(res, List(annot1, annot2))
+ }
+
+ property("unquote multiple annotations (2)") = test {
+ val annot1 = q"new a1"
+ val annots = List(q"new a2", q"new a3")
+ val res = q"@$annot1 @..$annots def foo"
+ assertSameAnnots(res, annot1 :: annots)
+ }
+
+ property("unquote annotations with arguments (1)") = test {
+ val a = q"new a(x)"
+ assertSameAnnots(q"@$a def foo", q"@a(x) def foo")
+ }
+
+ property("unquote annotations with arguments (2)") = test {
+ val a = TypeName("a")
+ assertSameAnnots(q"@$a(x) def foo", q"@a(x) def foo")
+ }
+
+ property("unquote annotations with arguments (3") = test {
+ val a = Ident(TypeName("a"))
+ assertSameAnnots(q"@$a(x) def foo", q"@a(x) def foo")
+ }
+
+ property("unquote improper tree into annot") = test {
+ val t = tq"Foo[Baz]"
+ assertThrows[IllegalArgumentException] {
+ q"@$t def foo"
+ }
+ }
+
+ property("can't unquote annotations with arguments specificed twice") = test {
+ val a = q"new a(x)"
+ assertThrows[IllegalArgumentException] {
+ q"@$a(y) def foo"
+ }
+ }
+
+ property("unquote annotation with targs") = test {
+ val a = q"new Foo[A, B]"
+ assertEqAst(q"@$a def foo", "@Foo[A,B] def foo")
+ }
+
+ property("unquote annotation with multiple argument lists") = test {
+ val a = q"new Foo(a)(b)"
+ assertEqAst(q"@$a def foo", "@Foo(a)(b) def foo")
+ }
+}
+
+trait PackageConstruction { self: QuasiquoteProperties =>
+ property("unquote select into package name") = test {
+ val name = q"foo.bar"
+ assertEqAst(q"package $name { }", "package foo.bar { }")
+ }
+
+ property("splce name into package name") = test{
+ val name = TermName("bippy")
+ assertEqAst(q"package $name { }", "package bippy { }")
+ }
+
+ property("unquote members into package body") = test {
+ val members = q"class C" :: q"object O" :: Nil
+ assertEqAst(q"package foo { ..$members }", "package foo { class C; object O }")
+ }
+
+ property("unquote illegal members into package body") = test {
+ val f = q"def f"
+ assertThrows[IllegalArgumentException] { q"package foo { $f }" }
+ val v = q"val v = 0"
+ assertThrows[IllegalArgumentException] { q"package foo { $v }" }
+ val expr = q"x + 1"
+ assertThrows[IllegalArgumentException] { q"package foo { $expr }" }
+ }
+
+ property("unquote name into package object") = test {
+ val foo = TermName("foo")
+ assertEqAst(q"package object $foo", "package object foo")
+ }
+
+ property("unquote parents into package object") = test {
+ val parents = tq"a" :: tq"b" :: Nil
+ assertEqAst(q"package object foo extends ..$parents",
+ "package object foo extends a with b")
+ }
+
+ property("unquote members into package object") = test {
+ val members = q"def foo" :: q"val x = 1" :: Nil
+ assertEqAst(q"package object foo { ..$members }",
+ "package object foo { def foo; val x = 1 }")
+ }
+
+ property("unquote early def into package object") = test {
+ val edefs = q"val x = 1" :: q"type I = Int" :: Nil
+ assertEqAst(q"package object foo extends { ..$edefs } with Any",
+ "package object foo extends { val x = 1; type I = Int } with Any")
+ }
+}
+
+trait DefConstruction { self: QuasiquoteProperties =>
+ property("construct implicit args (1)") = test {
+ val x = q"val x: Int"
+ assertEqAst(q"def foo(implicit $x) = x", "def foo(implicit x: Int) = x")
+ }
+
+ property("construct implicit args (2)") = test {
+ val xs = q"val x1: Int" :: q"val x2: Long" :: Nil
+ assertEqAst(q"def foo(implicit ..$xs) = x1 + x2", "def foo(implicit x1: Int, x2: Long) = x1 + x2")
+ }
+}
+
+trait ImportConstruction { self: QuasiquoteProperties =>
+ property("construct wildcard import") = test {
+ val sel = pq"_"
+ assert(q"import foo.$sel" ≈ q"import foo._")
+ }
+
+ property("construct named import") = test {
+ val sel = pq"bar"
+ assert(q"import foo.$sel" ≈ q"import foo.bar")
+ }
+
+ property("construct renaming import") = test {
+ val sel = pq"bar -> baz"
+ assert(q"import foo.$sel" ≈ q"import foo.{bar => baz}")
+ }
+
+ property("construct unimport import") = test {
+ val sels = pq"poison -> _" :: pq"_" :: Nil
+ assert(q"import foo.{..$sels}" ≈ q"import foo.{poison => _, _}")
+ }
+
+ property("construct mixed import") = test {
+ val sels = pq"a -> b" :: pq"c -> _" :: pq"_" :: Nil
+ assert(q"import foo.{..$sels}" ≈ q"import foo.{a => b, c => _, _}")
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala
new file mode 100644
index 0000000000..2c0e100b5a
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala
@@ -0,0 +1,290 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport.SyntacticClassDef
+
+object DefinitionDeconstructionProps
+ extends QuasiquoteProperties("definition deconstruction")
+ with TraitDeconstruction
+ with ClassDeconstruction
+ with ObjectDeconstruction
+ with ModsDeconstruction
+ with ValVarDeconstruction
+ with DefDeconstruction
+ with PackageDeconstruction
+ with ImportDeconstruction
+
+trait TraitDeconstruction { self: QuasiquoteProperties =>
+ property("exhaustive trait matcher") = test {
+ def matches(line: String) {
+ val q"""$mods trait $name[..$targs]
+ extends { ..$early } with ..$parents { $self => ..$body }""" = parse(line)
+ }
+ matches("trait Foo")
+ matches("trait Foo[T]")
+ matches("trait Foo { def bar }")
+ matches("trait Foo extends Bar with Baz")
+ matches("trait Foo { self: Bippy => val x: Int = 1}")
+ matches("trait Foo extends { val early: Int = 1 } with Bar { val late = early }")
+ matches("private[Gap] trait Foo")
+ }
+}
+
+trait ObjectDeconstruction { self: QuasiquoteProperties =>
+ property("exhaustive object matcher") = test {
+ def matches(line: String) = {
+ val q"""$mods object $name extends { ..$early } with ..$parents { $self => ..$body }""" = parse(line)
+ }
+ matches("object Foo")
+ matches("object Foo extends Bar[T]")
+ matches("object Foo extends { val early: T = v } with Bar")
+ matches("object Foo extends Foo { selfy => body }")
+ matches("private[Bippy] object Foo extends Bar with Baz")
+ }
+}
+
+trait ClassDeconstruction { self: QuasiquoteProperties =>
+ property("class without params") = test {
+ val q"class $name { ..$body }" = q"class Foo { def bar = 3 }"
+ assert(body ≈ List(q"def bar = 3"))
+ }
+
+ property("class constructor") = test {
+ val q"class $name(...$argss)" = q"class Foo(x: Int)(y: Int)"
+ assert(argss.length == 2)
+ }
+
+ property("class parents") = test {
+ val q"class $name extends ..$parents" = q"class Foo extends Bar with Blah"
+ assert(parents ≈ List(tq"Bar", tq"Blah"))
+ }
+
+ property("class selfdef") = test {
+ val q"class $name { $self => }" = q"class Foo { self: T => }"
+ assert(self.name ≈ TermName("self") && self.tpt ≈ tq"T")
+ }
+
+ property("class tparams") = test {
+ val q"class $name[..$tparams]" = q"class Foo[A, B]"
+ assert(tparams.map { _.name } == List(TypeName("A"), TypeName("B")))
+ }
+
+ property("deconstruct bare case class") = test {
+ val q"$mods class $name(..$args) extends ..$parents" = q"case class Foo(x: Int)"
+ }
+
+ property("exhaustive class matcher") = test {
+ def matches(line: String) {
+ val tree = parse(line)
+ val q"""$classMods0 class $name0[..$targs0] $ctorMods0(...$argss0)
+ extends { ..$early0 } with ..$parents0 { $self0 => ..$body0 }""" = tree
+ val q"""$classMods1 class $name1[..$targs1] $ctorMods1(...$argss1)(implicit ..$impl)
+ extends { ..$early1 } with ..$parents1 { $self1 => ..$body1 }""" = tree
+ }
+ matches("class Foo")
+ matches("class Foo[T]")
+ matches("class Foo[T] @annot")
+ matches("class Foo extends Bar with Baz")
+ matches("class Foo { body }")
+ matches("class Foo extends { val early = 0 } with Any")
+ matches("abstract class Foo")
+ matches("private[Baz] class Foo")
+ matches("class Foo(first: A)(second: B)")
+ matches("class Foo(first: A) extends Bar(first) with Baz")
+ matches("class Foo private (first: A) { def bar }")
+ matches("class Foo { self => bar(self) }")
+ matches("case class Foo(x: Int)")
+ }
+
+ property("SI-7979") = test {
+ val PARAMACCESSOR = (1 << 29).toLong.asInstanceOf[FlagSet]
+ assertThrows[MatchError] {
+ val SyntacticClassDef(_, _, _, _, _, _, _, _, _) =
+ ClassDef(
+ Modifiers(), TypeName("Foo"), List(),
+ Template(
+ List(Select(Ident(TermName("scala")), TypeName("AnyRef"))),
+ noSelfType,
+ List(
+ //ValDef(Modifiers(PRIVATE | LOCAL | PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree),
+ DefDef(Modifiers(), termNames.CONSTRUCTOR, List(), List(List(ValDef(Modifiers(PARAM | PARAMACCESSOR), TermName("x"),
+ Ident(TypeName("Int")), EmptyTree))), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(())))))))
+ }
+ }
+
+ property("SI-8332") = test {
+ val q"class C(implicit ..$args)" = q"class C(implicit i: I, j: J)"
+ val q"$imods val i: I" :: q"$jmods val j: J" :: Nil = args
+ assert(imods.hasFlag(IMPLICIT))
+ assert(jmods.hasFlag(IMPLICIT))
+ }
+}
+
+trait ModsDeconstruction { self: QuasiquoteProperties =>
+ property("deconstruct mods") = test {
+ val mods = Modifiers(IMPLICIT | PRIVATE, TermName("foobar"), Nil)
+ val q"$mods0 def foo" = q"$mods def foo"
+ assert(mods0 ≈ mods)
+ }
+
+ property("@$annot def foo") = forAll { (annotName: TypeName) =>
+ val q"@$annot def foo" = q"@$annotName def foo"
+ annot ≈ Apply(Select(New(Ident(annotName)), termNames.CONSTRUCTOR), List())
+ }
+
+ property("@$annot(..$args) def foo") = forAll { (annotName: TypeName, tree: Tree) =>
+ val q"@$annot(..$args) def foo" = q"@$annotName($tree) def foo"
+ annot ≈ Ident(annotName) && args ≈ List(tree)
+ }
+
+ property("@..$annots def foo") = test {
+ val a = q"new a"
+ val b = q"new b"
+ val q"@..$annots def foo" = q"@$a @$b def foo"
+ annots ≈ List(a, b)
+ }
+
+ property("@$annot @..$annots def foo") = test {
+ val a = q"new a"
+ val b = q"new b"
+ val c = q"new c"
+ val q"@$first @..$rest def foo" = q"@$a @$b @$c def foo"
+ assert(first ≈ a)
+ assert(rest ≈ List(b, c))
+ }
+
+ property("@..$anots @$annot def foo") = test {
+ val a = q"new a"
+ val b = q"new b"
+ val c = q"new c"
+ val q"@..$init @$last def foo" = q"@$a @$b @$c def foo"
+ assert(init ≈ List(a, b))
+ assert(last ≈ c)
+ }
+}
+
+trait ValVarDeconstruction { self: QuasiquoteProperties =>
+ property("exhaustive val matcher") = test {
+ def matches(line: String) { val q"$mods val $name: $tpt = $rhs" = parse(line) }
+ matches("val x: Int")
+ matches("val x: Int = 1")
+ matches("lazy val x: Int = 1")
+ matches("implicit val x = 1")
+ assertThrows[MatchError] { matches("var x = 1") }
+ }
+
+ property("exhaustive var matcher") = test {
+ def matches(line: String) { val q"$mods var $name: $tpt = $rhs" = parse(line) }
+ matches("var x: Int")
+ matches("var x: Int = 1")
+ matches("var x = 1")
+ assertThrows[MatchError] { matches("val x = 1") }
+ }
+}
+
+trait PackageDeconstruction { self: QuasiquoteProperties =>
+ property("exhaustive package matcher") = test {
+ def matches(line: String) { val q"package $name { ..$body }" = parse(line) }
+ matches("package foo { }")
+ matches("package foo { class C }")
+ matches("package foo.bar { }")
+ matches("package bippy.bongo { object A; object B }")
+ matches("package bippy { package bongo { object O } }")
+ }
+
+ property("exhaustive package object matcher") = test {
+ def matches(line: String) {
+ val q"package object $name extends { ..$early } with ..$parents { $self => ..$body }" = parse(line)
+ }
+ matches("package object foo")
+ matches("package object foo { def baz }")
+ matches("package object foo { self => }")
+ matches("package object foo extends mammy with daddy { def baz }")
+ matches("package object foo extends { val early = 1 } with daddy")
+ assertThrows[MatchError] { matches("object foo") }
+ }
+}
+
+trait DefDeconstruction { self: QuasiquoteProperties =>
+ property("exhaustive def matcher") = test {
+ def matches(line: String) = {
+ val t = parse(line)
+ val q"$mods0 def $name0[..$targs0](...$argss0): $restpe0 = $body0" = t
+ val q"$mods1 def $name1[..$targs1](...$argss1)(implicit ..$impl1): $restpe1 = $body1" = t
+ }
+ matches("def foo = foo")
+ matches("implicit def foo: Int = 2")
+ matches("def foo[T](x: T): T = x")
+ matches("def foo[A: B] = implicitly[B[A]]")
+ matches("private def foo = 0")
+ matches("def foo[A <% B] = null")
+ matches("def foo(one: One)(two: Two) = (one, two)")
+ matches("def foo[T](args: T*) = args.toList")
+ }
+
+ property("extract implicit arg list (1)") = test {
+ val q"def foo(...$argss)(implicit ..$impl)" = q"def foo(x: Int)(implicit y: Int)"
+ assert(impl ≈ List(q"${Modifiers(IMPLICIT | PARAM)} val y: Int"))
+ }
+
+ property("extract implicit arg list (2)") = test {
+ val q"def foo(...$argss)(implicit ..$impl)" = q"def foo(x: Int)"
+ assert(impl.isEmpty)
+ }
+
+ property("SI-8451") = test {
+ val q"def this(..$params) = this(..$args)" = q"def this(x: Int) = this(0)"
+ assert(params ≈ List(q"${Modifiers(PARAM)} val x: Int"))
+ assert(args ≈ List(q"0"))
+ }
+}
+
+trait ImportDeconstruction { self: QuasiquoteProperties =>
+ property("exhaustive import matcher") = test {
+ def matches(line: String) = {
+ val q"import $ref.{..$sels}" = parse(line)
+ }
+ matches("import foo.bar")
+ matches("import foo.{bar, baz}")
+ matches("import foo.{a => b, c => d}")
+ matches("import foo.{poision => _, _}")
+ matches("import foo.bar.baz._")
+ }
+
+ property("extract import binding") = test {
+ val q"import $_.$sel" = q"import foo.bar"
+ val pq"bar" = sel
+ }
+
+ property("extract import wildcard") = test {
+ val q"import $_.$sel" = q"import foo._"
+ val pq"_" = sel
+ }
+
+ property("extract import rename") = test {
+ val q"import $_.$sel" = q"import foo.{bar => baz}"
+ val pq"bar -> baz" = sel
+ val pq"$left -> $right" = sel
+ val pq"bar" = left
+ val pq"baz" = right
+ }
+
+ property("extract import unimport") = test {
+ val q"import $_.$sel" = q"import foo.{bar => _}"
+ val pq"bar -> _" = sel
+ val pq"$left -> $right" = sel
+ val pq"bar" = left
+ val pq"_" = right
+ }
+
+ property("unquote names into import selector") = forAll {
+ (expr: Tree, plain: TermName, oldname: TermName, newname: TermName, discard: TermName) =>
+
+ val Import(expr1, List(
+ ImportSelector(plain11, _, plain12, _),
+ ImportSelector(oldname1, _, newname1, _),
+ ImportSelector(discard1, _, wildcard, _))) =
+ q"import $expr.{$plain, $oldname => $newname, $discard => _}"
+
+ expr1 ≈ expr && plain11 == plain12 && plain12 == plain &&
+ oldname1 == oldname && newname1 == newname && discard1 == discard && wildcard == termNames.WILDCARD
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/DeprecationProps.scala b/test/files/scalacheck/quasiquotes/DeprecationProps.scala
new file mode 100644
index 0000000000..8e1601cf9d
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/DeprecationProps.scala
@@ -0,0 +1,52 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._
+
+object DeprecationProps extends QuasiquoteProperties("deprecation") {
+ val tname = TypeName("Foo")
+ val tpt = tq"Foo"
+ val tpe = typeOf[Int]
+ val sym = tpe.typeSymbol.asType
+ val argss = List(q"x") :: List(q"y") :: Nil
+ val args = q"x" :: q"y" :: Nil
+
+ property("new tpt argss") = test {
+ assert(q"new $tpt(...$argss)" ≈ New(tpt, argss))
+ }
+
+ property("new tpe args") = test {
+ assert(q"new $tpe(..$args)" ≈ New(tpe, args: _*))
+ }
+
+ property("new tpe args") = test {
+ assert(q"new ${sym.toType}(..$args)" ≈ New(sym, args: _*))
+ }
+
+ property("apply sym args") = test {
+ assert(q"$sym(..$args)" ≈ Apply(sym, args: _*))
+ }
+
+ property("applyconstructor") = test {
+ assert(q"new $tpt(..$args)" ≈ ApplyConstructor(tpt, args))
+ }
+
+ property("super sym name") = test {
+ assert(q"$sym.super[$tname].x".qualifier ≈ Super(sym, tname))
+ }
+
+ property("throw tpe args") = test {
+ assert(q"throw new $tpe(..$args)" ≈ Throw(tpe, args: _*))
+ }
+
+ property("casedef pat body") = test {
+ val pat = pq"foo"
+ val body = q"bar"
+ assert(cq"$pat => $body" ≈ CaseDef(pat, body))
+ }
+
+ property("try body cases") = test {
+ val cases = (pq"a", q"b") :: (pq"c", q"d") :: Nil
+ val newcases = cases.map { case (pat, body) => cq"$pat => $body" }
+ val body = q"foo"
+ assert(q"try $body catch { case ..$newcases }" ≈ Try(body, cases: _*))
+ }
+} \ No newline at end of file
diff --git a/test/files/scalacheck/quasiquotes/ErrorProps.scala b/test/files/scalacheck/quasiquotes/ErrorProps.scala
new file mode 100644
index 0000000000..2cba07abf2
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/ErrorProps.scala
@@ -0,0 +1,213 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+
+object ErrorProps extends QuasiquoteProperties("errors") {
+ property("can't extract two .. rankinalities in a row") = fails(
+ "Can't extract with .. here",
+ """
+ val xs = List(q"x1", q"x2")
+ val q"f(..$xs1, ..$xs2)" = xs
+ """)
+
+ property("can't unquote with given rank") = fails(
+ "Can't unquote List[StringBuilder], consider using .. or providing an implicit instance of Liftable[List[StringBuilder]]",
+ """
+ import java.lang.StringBuilder
+ val xs: List[StringBuilder] = Nil
+ q"$xs"
+ """)
+
+ property("unquote typename into typedef with default bounds") = fails(
+ "reflect.runtime.universe.Name expected but reflect.runtime.universe.TypeDef found",
+ """
+ val T1 = TypeName("T1")
+ val T2 = q"type T"
+ val t = EmptyTree
+ q"type $T1[$T2 >: _root_.scala.Any <: _root_.scala.Nothing] = $t" ≈
+ TypeDef(Modifiers(), T1, List(T2), t)
+ """)
+
+ property("can't unquote annotations with ... rank") = fails(
+ "Can't unquote with ... here",
+ """
+ val annots = List(List(q"Foo"))
+ q"@...$annots def foo"
+ """)
+
+ property("only literal string arguments") = fails(
+ "Quasiquotes can only be used with literal strings",
+ """
+ val s: String = "foo"
+ StringContext(s).q()
+ """)
+
+ property("don't know how to unquote inside of strings") = fails(
+ "Don't know how to unquote here",
+ """
+ val x: Tree = EmptyTree
+ StringContext("\"", "\"").q(x)
+ """)
+
+ property("non-liftable type ..") = fails(
+ "Can't unquote List[StringBuilder] with .., consider omitting the dots or providing an implicit instance of Liftable[StringBuilder]",
+ """
+ import java.lang.StringBuilder
+ val bazs = List(new StringBuilder)
+ q"f(..$bazs)"
+ """)
+
+ property("non-liftable type ...") = fails(
+ "Can't unquote List[List[StringBuilder]] with .., consider using ... or providing an implicit instance of Liftable[StringBuilder]",
+ """
+ import java.lang.StringBuilder
+ val bazs = List(List(new StringBuilder))
+ q"f(..$bazs)"
+ """)
+
+ property("use .. rank or provide liftable") = fails(
+ "Can't unquote List[StringBuilder], consider using .. or providing an implicit instance of Liftable[List[StringBuilder]]",
+ """
+ import java.lang.StringBuilder
+ val lst: List[StringBuilder] = Nil
+ q"f($lst)"
+ """)
+
+ property("use ... rank or provide liftable") = fails(
+ "Can't unquote List[List[StringBuilder]], consider using ... or providing an implicit instance of Liftable[List[List[StringBuilder]]]",
+ """
+ import java.lang.StringBuilder
+ val xs: List[List[StringBuilder]] = Nil
+ q"$xs"
+ """)
+
+ property("not liftable or natively supported") = fails(
+ "Can't unquote StringBuilder, consider providing an implicit instance of Liftable[StringBuilder]",
+ """
+ import java.lang.StringBuilder
+ val sb = new StringBuilder
+ q"f($sb)"
+ """)
+
+ property("can't unquote with ... rank here") = fails(
+ "Can't unquote with ... here",
+ """
+ val lst: List[List[Tree]] = Nil; val t = EmptyTree
+ q"f(...$lst, $t)"
+ """)
+
+ property("name expected") = fails(
+ "reflect.runtime.universe.Name expected but reflect.runtime.universe.Tree found",
+ """
+ val t = EmptyTree
+ q"class $t"
+ """)
+
+ property("flags or mods expected") = fails(
+ "reflect.runtime.universe.FlagSet or reflect.runtime.universe.Modifiers expected but reflect.runtime.universe.Tree found",
+ """
+ val t = EmptyTree
+ q"$t def foo"
+ """)
+
+ property("cant unquote flags together with mods") = fails(
+ "Can't unquote flags together with modifiers, consider merging flags into modifiers",
+ """
+ val f = Flag.IMPLICIT; val m = NoMods
+ q"$f $m def foo"
+ """)
+
+ property("can't unquote mods with annots") = fails(
+ "Can't unquote modifiers together with annotations, consider merging annotations into modifiers",
+ """
+ val m = NoMods
+ q"@annot $m def foo"
+ """)
+
+ property("can't unquote modifiers with inline flags") = fails(
+ "Can't unquote modifiers together with flags, consider merging flags into modifiers",
+ """
+ val m = NoMods
+ q"$m implicit def foo"
+ """)
+
+ property("can't unquote multiple mods") = fails(
+ "Can't unquote multiple modifiers, consider merging them into a single modifiers instance",
+ """
+ val m1 = NoMods; val m2 = NoMods
+ q"$m1 $m2 def foo"
+ """)
+
+ property("can't extract mods with annots") = fails(
+ "Can't extract modifiers together with annotations, consider extracting just modifiers",
+ """
+ val q"@$annot $mods def foo" = EmptyTree
+ """)
+
+ property("can't extract multiple mods") = fails(
+ "Can't extract multiple modifiers together, consider extracting a single modifiers instance",
+ """
+ val q"$m1 $m2 def foo" = EmptyTree
+ """)
+
+ property("can't unquote values of Null") = fails(
+ "Can't unquote Null, bottom type values often indicate programmer mistake",
+ """
+ val n = null
+ q"$n"
+ """)
+
+ property("can't unquote values of Nothing") = fails(
+ "Can't unquote Nothing, bottom type values often indicate programmer mistake",
+ """
+ def n = ???
+ q"$n"
+ """)
+
+ property("SI-8211: check unbound placeholder paremeters") = fails(
+ "unbound placeholder parameter",
+ """
+ q"_"
+ """)
+
+ property("SI-8211: check unbound wildcard types") = fails(
+ "unbound wildcard type",
+ """
+ tq"_"
+ """)
+
+ property("SI-8420: don't crash on splicing of non-unliftable native type (1)") = fails(
+ "Can't unquote List[reflect.runtime.universe.Symbol] with .., consider omitting the dots or providing an implicit instance of Liftable[reflect.runtime.universe.Symbol]",
+ """
+ val l: List[Symbol] = Nil
+ q"f(..$l)"
+ """)
+
+ property("SI-8420: don't crash on splicing of non-unliftable native type (2)") = fails(
+ "Can't unquote List[reflect.runtime.universe.FlagSet] with .., consider omitting the dots or providing an implicit instance of Liftable[reflect.runtime.universe.FlagSet]",
+ """
+ val l: List[FlagSet] = Nil
+ q"f(..$l)"
+ """)
+
+ property("SI-8420: don't crash on splicing of non-unliftable native type (3)") = fails(
+ "Can't unquote List[reflect.runtime.universe.Modifiers] with .., consider omitting the dots or providing an implicit instance of Liftable[reflect.runtime.universe.Modifiers]",
+ """
+ val l: List[Modifiers] = Nil
+ q"f(..$l)"
+ """)
+
+ property("SI-8451 construction: disallow everything except for constructor calls in secondary constructor bodies") = fails(
+ "'this' expected but unquotee found",
+ """
+ val rhs1 = q"this(0)"
+ val ctor1 = q"def this(x: Int) = $rhs1"
+ """)
+
+ property("SI-8451 deconstruction: disallow everything except for constructor calls in secondary constructor bodies") = fails(
+ "'this' expected but unquotee found",
+ """
+ val q"def this(..$params) = $rhs2" = q"def this(x: Int) = this(0)"
+ """)
+
+ // // Make sure a nice error is reported in this case
+ // { import Flag._; val mods = NoMods; q"lazy $mods val x: Int" }
+}
diff --git a/test/files/scalacheck/quasiquotes/ForProps.scala b/test/files/scalacheck/quasiquotes/ForProps.scala
new file mode 100644
index 0000000000..b14d345edd
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/ForProps.scala
@@ -0,0 +1,70 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport._
+
+object ForProps extends QuasiquoteProperties("for") {
+ case class ForEnums(val value: List[Tree])
+
+ def genSimpleBind: Gen[Bind] =
+ for(name <- genTermName)
+ yield pq"$name @ _"
+
+ def genForFilter: Gen[Tree] =
+ for(cond <- genIdent(genTermName))
+ yield fq"if $cond"
+
+ def genForFrom: Gen[Tree] =
+ for(lhs <- genSimpleBind; rhs <- genIdent(genTermName))
+ yield fq"$lhs <- $rhs"
+
+ def genForEq: Gen[Tree] =
+ for(lhs <- genSimpleBind; rhs <- genIdent(genTermName))
+ yield fq"$lhs = $rhs"
+
+ def genForEnums(size: Int): Gen[ForEnums] =
+ for(first <- genForFrom; rest <- listOfN(size, oneOf(genForFrom, genForFilter, genForEq)))
+ yield new ForEnums(first :: rest)
+
+ implicit val arbForEnums: Arbitrary[ForEnums] = arbitrarySized(genForEnums)
+
+ property("construct-reconstruct for") = forAll { (enums: ForEnums, body: Tree) =>
+ val SyntacticFor(recoveredEnums, recoveredBody) = SyntacticFor(enums.value, body)
+ recoveredEnums ≈ enums.value && recoveredBody ≈ body
+ }
+
+ property("construct-reconstruct for-yield") = forAll { (enums: ForEnums, body: Tree) =>
+ val SyntacticForYield(recoveredEnums, recoveredBody) = SyntacticForYield(enums.value, body)
+ recoveredEnums ≈ enums.value && recoveredBody ≈ body
+ }
+
+ val abcde = List(fq"a <-b", fq"if c", fq"d = e")
+ val foobarbaz = pq"foo @ Bar(baz)"
+ val fv = q"f(v)"
+
+ property("construct/deconstruct for loop with fq") = test {
+ val for0 = q"for(..$abcde) $fv"
+ assertEqAst(for0, "for(a <- b; if c; d = e) f(v)")
+ val q"for(..$enums) $body" = for0
+ assert(enums ≈ abcde)
+ assert(body ≈ fv)
+ }
+
+ property("construct/deconstruct valfrom with fq") = test {
+ assert(fq"$foobarbaz <- $fv" ≈ fq"foo @ Bar(baz) <- f(v)")
+ val fq"$lhs <- $rhs" = fq"$foobarbaz <- $fv"
+ assert(lhs ≈ foobarbaz)
+ assert(rhs ≈ fv)
+ }
+
+ property("construct/deconstruct valeq with fq") = test {
+ assert(fq"$foobarbaz = $fv" ≈ fq"foo @ Bar(baz) = f(v)")
+ val fq"$lhs = $rhs" = fq"$foobarbaz = $fv"
+ assert(lhs ≈ foobarbaz)
+ assert(rhs ≈ fv)
+ }
+
+ property("construct/deconstruct filter with fq") = test {
+ assert(fq"if $fv" ≈ fq"if f(v)")
+ val fq"if $cond" = fq"if $fv"
+ assert(cond ≈ fv)
+ }
+} \ No newline at end of file
diff --git a/test/files/scalacheck/quasiquotes/LiftableProps.scala b/test/files/scalacheck/quasiquotes/LiftableProps.scala
new file mode 100644
index 0000000000..a4c57ac359
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/LiftableProps.scala
@@ -0,0 +1,174 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._
+
+object LiftableProps extends QuasiquoteProperties("liftable") {
+ property("unquote byte") = test {
+ val c: Byte = 0
+ assert(q"$c" ≈ Literal(Constant(c)))
+ assert(q"${0: Byte}" ≈ Literal(Constant(c)))
+ }
+
+ property("unquote short") = test {
+ val c: Short = 0
+ assert(q"$c" ≈ Literal(Constant(c)))
+ assert(q"${0: Short}" ≈ Literal(Constant(c)))
+ }
+
+ property("unquote char") = test {
+ val c: Char = 'c'
+ assert(q"$c" ≈ Literal(Constant(c)))
+ assert(q"${'c'}" ≈ Literal(Constant(c)))
+ }
+
+ property("unquote int") = test {
+ val c: Int = 0
+ assert(q"$c" ≈ Literal(Constant(c)))
+ assert(q"${0: Int}" ≈ Literal(Constant(c)))
+ }
+
+ property("unquote long") = test {
+ val c: Long = 0
+ assert(q"$c" ≈ Literal(Constant(c)))
+ assert(q"${0: Long}" ≈ Literal(Constant(c)))
+ }
+
+ property("unquote float") = test {
+ val c: Float = 0.0f
+ assert(q"$c" ≈ Literal(Constant(c)))
+ assert(q"${0.0f: Float}" ≈ Literal(Constant(c)))
+ }
+
+ property("unquote double") = test {
+ val c: Double = 0.0
+ assert(q"$c" ≈ Literal(Constant(c)))
+ assert(q"${0.0: Double}" ≈ Literal(Constant(c)))
+ }
+
+ property("unquote boolean") = test {
+ val c: Boolean = false
+ assert(q"$c" ≈ Literal(Constant(c)))
+ assert(q"${true}" ≈ Literal(Constant(true)))
+ assert(q"${false}" ≈ Literal(Constant(false)))
+ }
+
+ property("unquote string") = test {
+ val c: String = "s"
+ assert(q"$c" ≈ Literal(Constant(c)))
+ assert(q"${"s"}" ≈ Literal(Constant(c)))
+ }
+
+ property("unquote unit") = test {
+ val c: Unit = ()
+ assert(q"$c" ≈ Literal(Constant(c)))
+ assert(q"${()}" ≈ Literal(Constant(c)))
+ }
+
+ property("lift symbol") = test {
+ val s = rootMirror.staticClass("scala.Int")
+ assert(q"$s" ≈ Ident(s))
+ }
+
+ property("lift type") = test {
+ val tpe = rootMirror.staticClass("scala.Int").toType
+ assert(q"$tpe" ≈ TypeTree(tpe))
+ }
+
+ property("lift type tag") = test {
+ val tag = TypeTag.Int
+ assert(q"$tag" ≈ TypeTree(tag.tpe))
+ }
+
+ property("lift weak type tag") = test {
+ val tag = WeakTypeTag.Int
+ assert(q"$tag" ≈ TypeTree(tag.tpe))
+ }
+
+ property("lift constant") = test {
+ val const = Constant(0)
+ assert(q"$const" ≈ q"0")
+ }
+
+ val immutable = q"$scalapkg.collection.immutable"
+
+ property("lift list variants") = test {
+ val lst = List(1, 2)
+ assert(q"$lst" ≈ q"$immutable.List(1, 2)")
+ assert(q"f(..$lst)" ≈ q"f(1, 2)")
+ val llst = List(List(1), List(2))
+ assert(q"f(..$llst)" ≈ q"f($immutable.List(1), $immutable.List(2))")
+ assert(q"f(...$llst)" ≈ q"f(1)(2)")
+ }
+
+ property("lift list of tree") = test {
+ val lst = List(q"a", q"b")
+ assert(q"$lst" ≈ q"$immutable.List(a, b)")
+ }
+
+ property("lift tuple") = test {
+ assert(q"${(1, 2)}" ≈ q"(1, 2)")
+ assert(q"${(1, 2, 3)}" ≈ q"(1, 2, 3)")
+ assert(q"${(1, 2, 3, 4)}" ≈ q"(1, 2, 3, 4)")
+ assert(q"${(1, 2, 3, 4, 5)}" ≈ q"(1, 2, 3, 4, 5)")
+ assert(q"${(1, 2, 3, 4, 5, 6)}" ≈ q"(1, 2, 3, 4, 5, 6)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7)}" ≈ q"(1, 2, 3, 4, 5, 6, 7)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)")
+ assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)")
+ }
+
+ property("lift nil") = test {
+ val nil = Nil
+ assert(q"$nil" ≈ q"scala.collection.immutable.Nil")
+ }
+
+ property("lift some") = test {
+ val some1 = Some(1)
+ assert(q"$some1" ≈ q"scala.Some(1)")
+ val some2: Option[Int] = Some(1)
+ assert(q"$some2" ≈ q"scala.Some(1)")
+ }
+
+ property("lift none") = test {
+ val none1 = None
+ assert(q"$none1" ≈ q"scala.None")
+ val none2: Option[Int] = None
+ assert(q"$none2" ≈ q"scala.None")
+ }
+
+ property("lift left") = test {
+ val left1 = Left(1)
+ assert(q"$left1" ≈ q"scala.util.Left(1)")
+ val left2: Left[Int, Int] = Left(1)
+ assert(q"$left2" ≈ q"scala.util.Left(1)")
+ val left3: Either[Int, Int] = Left(1)
+ assert(q"$left3" ≈ q"scala.util.Left(1)")
+ }
+
+ property("lift right") = test {
+ val right1 = Right(1)
+ assert(q"$right1" ≈ q"scala.util.Right(1)")
+ val right2: Right[Int, Int] = Right(1)
+ assert(q"$right2" ≈ q"scala.util.Right(1)")
+ val right3: Either[Int, Int] = Right(1)
+ assert(q"$right3" ≈ q"scala.util.Right(1)")
+ }
+
+ property("lift xml comment") = test {
+ implicit val liftXmlComment = Liftable[xml.Comment] { comment =>
+ q"new _root_.scala.xml.Comment(${comment.commentText})"
+ }
+ assert(q"${xml.Comment("foo")}" ≈ q"<!--foo-->")
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/PatternConstructionProps.scala b/test/files/scalacheck/quasiquotes/PatternConstructionProps.scala
new file mode 100644
index 0000000000..7ed95fa984
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/PatternConstructionProps.scala
@@ -0,0 +1,36 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._
+
+object PatternConstructionProps extends QuasiquoteProperties("pattern construction") {
+ property("unquote bind") = forAll { (bind: Bind) =>
+ pq"$bind" ≈ bind
+ }
+
+ property("unquote name into bind") = forAll { (name: TermName) =>
+ pq"$name" ≈ Bind(name, Ident(termNames.WILDCARD))
+ }
+
+ property("unquote name and tree into bind") = forAll { (name: TermName, tree: Tree) =>
+ pq"$name @ $tree" ≈ Bind(name, tree)
+ }
+
+ property("unquote type name into typed") = forAll { (name: TypeName) =>
+ pq"_ : $name" ≈ Typed(Ident(termNames.WILDCARD), Ident(name))
+ }
+
+ property("unquote tree into typed") = forAll { (typ: Tree) =>
+ pq"_ : $typ" ≈ Typed(Ident(termNames.WILDCARD), typ)
+ }
+
+ property("unquote into apply") = forAll { (pat: Tree, subpat: Tree) =>
+ pq"$pat($subpat)" ≈ Apply(pat, List(subpat))
+ }
+
+ property("unquote into casedef") = forAll { (pat: Tree, cond: Tree, body: Tree) =>
+ cq"$pat if $cond => $body" ≈ CaseDef(pat, cond, body)
+ }
+
+ property("unquote into alternative") = forAll { (first: Tree, rest: List[Tree]) =>
+ pq"$first | ..$rest" ≈ Alternative(first :: rest)
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/PatternDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/PatternDeconstructionProps.scala
new file mode 100644
index 0000000000..ad3266bcec
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/PatternDeconstructionProps.scala
@@ -0,0 +1,44 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._
+
+object PatternDeconstructionProps extends QuasiquoteProperties("pattern deconstruction") {
+ property("extract bind") = forAll { (bind: Bind) =>
+ val pq"$bind0" = pq"$bind"
+ bind0 ≈ bind
+ }
+
+ property("extract bind and subpattern") = forAll { (name: TermName, subp: Tree) =>
+ val pq"$name0 @ $subp0" = pq"$name @ $subp"
+ name0 ≈ name && subp0 ≈ subp
+ }
+
+ property("extract typed") = forAll { (typ: Tree) =>
+ val pq"_ : $typ0" = pq"_ : $typ"
+ typ0 ≈ typ
+ }
+
+ property("extract apply") = forAll { (pat: Tree, subpat: Tree) =>
+ val pq"$pat0($subpat0)" = pq"$pat($subpat)"
+ pat0 ≈ pat && subpat0 ≈ subpat
+ }
+
+ property("extract apply many") = forAll { (pat: Tree, subpats: List[Tree]) =>
+ val pq"$pat0(..$subpats0)" = pq"$pat(..$subpats)"
+ pat0 ≈ pat && subpats0 ≈ subpats
+ }
+
+ property("extract apply last") = forAll { (pat: Tree, subpats: List[Tree], subpatlast: Tree) =>
+ val pq"$pat0(..$subpats0, $subpatlast0)" = pq"$pat(..$subpats, $subpatlast)"
+ pat0 ≈ pat && subpats0 ≈ subpats && subpatlast0 ≈ subpatlast
+ }
+
+ property("extract casedef") = forAll { (pat: Tree, cond: Tree, body: Tree) =>
+ val cq"$pat0 if $cond0 => $body0" = cq"$pat if $cond => $body"
+ pat0 ≈ pat && cond0 ≈ cond && body0 ≈ body
+ }
+
+ property("extract alternative") = forAll { (first: Tree, rest: List[Tree]) =>
+ val pq"$first1 | ..$rest1" = pq"$first | ..$rest"
+ first1 ≈ first && rest1 ≈ rest
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/QuasiquoteProperties.scala b/test/files/scalacheck/quasiquotes/QuasiquoteProperties.scala
new file mode 100644
index 0000000000..6132244227
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/QuasiquoteProperties.scala
@@ -0,0 +1,120 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.reflect.runtime.currentMirror
+import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport.setSymbol
+
+class QuasiquoteProperties(name: String) extends Properties(name) with ArbitraryTreesAndNames with Helpers
+
+trait Helpers {
+ /** Runs a code block and returns proof confirmation
+ * if no exception has been thrown while executing code
+ * block. This is useful for simple one-off tests.
+ */
+ def test[T](block: => T) =
+ Prop { params =>
+ block
+ Result(Prop.Proof)
+ }
+
+ object simplify extends Transformer {
+ object SimplifiedName {
+ val st = scala.reflect.runtime.universe.asInstanceOf[scala.reflect.internal.SymbolTable]
+ val FreshName = new st.FreshNameExtractor
+ def unapply[T <: Name](name: T): Option[T] = name.asInstanceOf[st.Name] match {
+ case FreshName(prefix) =>
+ Some((if (name.isTermName) TermName(prefix) else TypeName(prefix)).asInstanceOf[T])
+ }
+ }
+
+ override def transform(tree: Tree): Tree = tree match {
+ case Ident(SimplifiedName(name)) => Ident(name)
+ case ValDef(mods, SimplifiedName(name), tpt, rhs) => ValDef(mods, name, transform(tpt), transform(rhs))
+ case Bind(SimplifiedName(name), rhs) => Bind(name, rhs)
+ case _ =>
+ super.transform(tree)
+ }
+
+ def apply(tree: Tree): Tree = transform(tree)
+ }
+
+ implicit class TestSimilarTree(tree1: Tree) {
+ def ≈(tree2: Tree) = simplify(tree1).equalsStructure(simplify(tree2))
+ }
+
+ implicit class TestSimilarListTree(lst: List[Tree]) {
+ def ≈(other: List[Tree]) = (lst.length == other.length) && lst.zip(other).forall { case (t1, t2) => t1 ≈ t2 }
+ }
+
+ implicit class TestSimilarListListTree(lst: List[List[Tree]]) {
+ def ≈(other: List[List[Tree]]) = (lst.length == other.length) && lst.zip(other).forall { case (l1, l2) => l1 ≈ l2 }
+ }
+
+ implicit class TestSimilarName(name: Name) {
+ def ≈(other: Name) = name == other
+ }
+
+ implicit class TestSimilarMods(mods: Modifiers) {
+ def ≈(other: Modifiers) = (mods.flags == other.flags) && (mods.privateWithin ≈ other.privateWithin) && (mods.annotations ≈ other.annotations)
+ }
+
+ def assertThrows[T <: AnyRef](f: => Any)(implicit manifest: Manifest[T]): Unit = {
+ val clazz = manifest.runtimeClass.asInstanceOf[Class[T]]
+ val thrown =
+ try {
+ f
+ false
+ } catch {
+ case u: Throwable =>
+ if (!clazz.isAssignableFrom(u.getClass))
+ assert(false, s"wrong exception: $u")
+ true
+ }
+ if(!thrown)
+ assert(false, "exception wasn't thrown")
+ }
+
+ def assertEqAst(tree: Tree, code: String) = assert(eqAst(tree, code))
+ def eqAst(tree: Tree, code: String) = tree ≈ parse(code)
+
+ val toolbox = currentMirror.mkToolBox()
+ val parse = toolbox.parse(_)
+ val compile = toolbox.compile(_)
+ val eval = toolbox.eval(_)
+
+ def typecheck(tree: Tree) = toolbox.typecheck(tree)
+
+ def typecheckTyp(tree: Tree) = {
+ val q"type $_ = $res" = typecheck(q"type T = $tree")
+ res
+ }
+
+ def typecheckPat(tree: Tree) = {
+ val q"$_ match { case $res => }" = typecheck(q"((): Any) match { case $tree => }")
+ res
+ }
+
+ def fails(msg: String, block: String) = {
+ def result(ok: Boolean, description: String = "") = {
+ val status = if (ok) Prop.Proof else Prop.False
+ val labels = if (description != "") Set(description) else Set.empty[String]
+ Prop { new Prop.Result(status, Nil, Set.empty, labels) }
+ }
+ try {
+ compile(parse(s"""
+ object Wrapper extends Helpers {
+ import scala.reflect.runtime.universe._
+ $block
+ }
+ """))
+ result(false, "given code doesn't fail to typecheck")
+ } catch {
+ case ToolBoxError(emsg, _) =>
+ if (!emsg.contains(msg))
+ result(false, s"error message '${emsg}' is not the same as expected '$msg'")
+ else
+ result(true)
+ }
+ }
+
+ val scalapkg = setSymbol(Ident(TermName("scala")), definitions.ScalaPackage)
+}
diff --git a/test/files/scalacheck/quasiquotes/RuntimeErrorProps.scala b/test/files/scalacheck/quasiquotes/RuntimeErrorProps.scala
new file mode 100644
index 0000000000..a3b6137f68
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/RuntimeErrorProps.scala
@@ -0,0 +1,75 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._
+
+object RuntimeErrorProps extends QuasiquoteProperties("errors") {
+ def testFails[T](block: =>T) = test {
+ assertThrows[IllegalArgumentException] {
+ block
+ }
+ }
+
+ property("default param anon function") = testFails {
+ val param = q"val x: Int = 1"
+ q"{ $param => x + 1 }"
+ }
+
+ property("non-casedef case") = testFails {
+ val x = q"x"
+ q"foo match { case $x }"
+ }
+
+ property("non-new annotation") = testFails {
+ val annot = q"foo"
+ q"@$annot def foo"
+ }
+
+ property("non-valdef param") = testFails {
+ val param = q"foo"
+ q"def foo($param)"
+ }
+
+ property("non-valdef class param") = testFails {
+ val param = q"foo"
+ q"class Foo($param)"
+ }
+
+ property("non-typedef type param") = testFails {
+ val tparam = tq"T"
+ q"class C[$tparam]"
+ }
+
+ property("non-definition refine stat") = testFails {
+ val stat = q"foo"
+ tq"Foo { $stat }"
+ }
+
+ property("non-definition early def") = testFails {
+ val stat = q"foo"
+ q"class Foo extends { $stat } with Bar"
+ }
+
+ property("type apply for definition") = testFails {
+ val defn = q"def foo"
+ q"$defn[foo]"
+ }
+
+ property("non-val selftype") = testFails {
+ val foo = q"foo"
+ q"class Foo { $foo => }"
+ }
+
+ property("for empty enums") = testFails {
+ val enums = List.empty[Tree]
+ q"for(..$enums) 0"
+ }
+
+ property("for starts with non-from enum") = testFails {
+ val enums = fq"foo = bar" :: Nil
+ q"for(..$enums) 0"
+ }
+
+ property("for inlalid enum") = testFails {
+ val enums = q"foo" :: Nil
+ q"for(..$enums) 0"
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/TermConstructionProps.scala b/test/files/scalacheck/quasiquotes/TermConstructionProps.scala
new file mode 100644
index 0000000000..45392de582
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/TermConstructionProps.scala
@@ -0,0 +1,313 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._
+
+object TermConstructionProps extends QuasiquoteProperties("term construction") {
+ property("unquote single tree return tree itself") = forAll { (t: Tree) =>
+ q"$t" ≈ t
+ }
+
+ property("unquote trees into if expression") = forAll { (t1: Tree, t2: Tree, t3: Tree) =>
+ q"if($t1) $t2 else $t3" ≈ If(t1, t2, t3)
+ }
+
+ property("unquote trees into ascriptiopn") = forAll { (t1: Tree, t2: Tree) =>
+ q"$t1 : $t2" ≈ Typed(t1, t2)
+ }
+
+ property("unquote trees into apply") = forAll { (t1: Tree, t2: Tree, t3: Tree) =>
+ q"$t1($t2, $t3)" ≈ Apply(t1, List(t2, t3))
+ }
+
+ property("unquote trees with .. rank into apply") = forAll { (ts: List[Tree]) =>
+ q"f(..$ts)" ≈ Apply(q"f", ts)
+ }
+
+ property("unquote iterable into apply") = forAll { (trees: List[Tree]) =>
+ val itrees: Iterable[Tree] = trees
+ q"f(..$itrees)" ≈ Apply(q"f", trees)
+ }
+
+ property("unquote trees with ... rank into apply") = forAll { (ts1: List[Tree], ts2: List[Tree]) =>
+ val argss = List(ts1, ts2)
+ q"f(...$argss)" ≈ Apply(Apply(q"f", ts1), ts2)
+ }
+
+ property("unquote term name into assign") = forAll { (name: TermName, t: Tree) =>
+ q"$name = $t" ≈ Assign(Ident(name), t)
+ }
+
+ property("unquote trees into block") = forAll { (t1: Tree, t2: Tree, t3: Tree) =>
+ blockInvariant(q"""{
+ $t1
+ $t2
+ $t3
+ }""", List(t1, t2, t3))
+ }
+
+
+ property("unquote tree into new") = forAll { (tree: Tree) =>
+ q"new $tree" ≈ Apply(Select(New(tree), termNames.CONSTRUCTOR), List())
+ }
+
+ property("unquote tree into return") = forAll { (tree: Tree) =>
+ q"return $tree" ≈ Return(tree)
+ }
+
+ property("unquote a list of arguments") = forAll { (fun: Tree, args: List[Tree]) =>
+ q"$fun(..$args)" ≈ Apply(fun, args)
+ }
+
+ property("unquote list and non-list fun arguments") = forAll { (fun: Tree, arg1: Tree, arg2: Tree, args: List[Tree]) =>
+ q"$fun(..$args, $arg1, $arg2)" ≈ Apply(fun, args ++ List(arg1) ++ List(arg2)) &&
+ q"$fun($arg1, ..$args, $arg2)" ≈ Apply(fun, List(arg1) ++ args ++ List(arg2)) &&
+ q"$fun($arg1, $arg2, ..$args)" ≈ Apply(fun, List(arg1) ++ List(arg2) ++ args)
+ }
+
+ property("unquote into new") = forAll { (name: TypeName, body: List[Tree]) =>
+ q"new $name { ..$body }" ≈
+ q"""{
+ final class $$anon extends $name {
+ ..$body
+ }
+ new $$anon
+ }"""
+ }
+
+ property("unquote type name into this") = forAll { (T: TypeName) =>
+ q"$T.this" ≈ This(T)
+ }
+
+ property("unquote tree into throw") = forAll { (t: Tree) =>
+ q"throw $t" ≈ Throw(t)
+ }
+
+ property("unquote trees into type apply") = forAll { (fun: TreeIsTerm, types: List[Tree]) =>
+ q"$fun[..$types]" ≈ (if (types.nonEmpty) TypeApply(fun, types) else fun)
+ }
+
+ property("unquote trees into while loop") = forAll { (cond: Tree, body: Tree) =>
+ val LabelDef(_, List(), If(cond1, Block(List(body1), Apply(_, List())), Literal(Constant(())))) = q"while($cond) $body"
+ body1 ≈ body && cond1 ≈ cond
+ }
+
+ property("unquote trees into do while loop") = forAll { (cond: Tree, body: Tree) =>
+ val LabelDef(_, List(), Block(List(body1), If(cond1, Apply(_, List()), Literal(Constant(()))))) = q"do $body while($cond)"
+ body1 ≈ body && cond1 ≈ cond
+ }
+
+ def blockInvariant(quote: Tree, trees: List[Tree]) =
+ quote ≈ (trees match {
+ case Nil => q"{}"
+ case _ :+ last if !last.isTerm => Block(trees, q"()")
+ case head :: Nil => head
+ case init :+ last => Block(init, last)
+ })
+
+ property("unquote list of trees into block (1)") = forAll { (trees: List[Tree]) =>
+ blockInvariant(q"{ ..$trees }", trees)
+ }
+
+ property("unquote list of trees into block (2)") = forAll { (trees1: List[Tree], trees2: List[Tree]) =>
+ blockInvariant(q"{ ..$trees1 ; ..$trees2 }", trees1 ++ trees2)
+ }
+
+ property("unquote list of trees into block (3)") = forAll { (trees: List[Tree], tree: Tree) =>
+ blockInvariant(q"{ ..$trees; $tree }", trees :+ tree)
+ }
+
+ property("unquote term into brackets") = test {
+ val a = q"a"
+ assert(q"($a)" ≈ a)
+ }
+
+ property("unquote terms into tuple") = test {
+ val a1 = q"a1"
+ val a2 = q"a2"
+ val as = List(a1, a2)
+ assert(q"(..$as)" ≈ q"scala.Tuple2($a1, $a2)")
+ assert(q"(a0, ..$as)" ≈ q"scala.Tuple3(a0, $a1, $a2)")
+ }
+
+ property("unquote empty list into tuple") = test {
+ val empty = List[Tree]()
+ assert(q"(..$empty)" ≈ q"()")
+ }
+
+ property("unquote single element list into tuple") = test {
+ val xs = q"x" :: Nil
+ assert(q"(..$xs)" ≈ xs.head)
+ }
+
+ property("function param flags are the same") = test {
+ val xy = q"val x: A" :: q"val y: B" :: Nil
+ assertEqAst(q"(..$xy) => x + y", "(x: A, y: B) => x + y")
+ }
+
+ property("anonymous functions don't support default values") = test {
+ val x = q"val x: Int = 1"
+ assertThrows[IllegalArgumentException] { q"($x) => x" }
+ }
+
+ property("assign variable") = test {
+ val v = q"v"
+ val value = q"foo"
+ assertEqAst(q"$v = $value", "v = foo")
+ }
+
+ property("assign update 1") = test {
+ val v = q"v"
+ val args = q"1" :: q"2" :: Nil
+ val value = q"foo"
+ assertEqAst(q"$v(..$args) = $value", "v(1, 2) = foo")
+ }
+
+ property("assign update 2") = test {
+ val a = q"v(0)"
+ val value = q"foo"
+ assertEqAst(q"$a = $value", "v(0) = foo")
+ }
+
+ property("assign or named arg") = test {
+ val assignx = q"x = 1"
+ assertEqAst(q"f($assignx)", "f(x = 1)")
+ }
+
+ property("fresh names are regenerated at each evaluation") = test {
+ def plusOne = q"{ _ + 1 }"
+ assert(!plusOne.equalsStructure(plusOne))
+ def whileTrue = q"while(true) false"
+ assert(!whileTrue.equalsStructure(whileTrue))
+ def withEvidence = q"def foo[T: X]"
+ assert(!withEvidence.equalsStructure(withEvidence))
+ }
+
+ property("make sure inference doesn't infer any") = test {
+ val l1 = List(q"foo")
+ val l2 = List(q"bar")
+ val baz = q"baz"
+ assert(q"f(..${l1 ++ l2})" ≈ q"f(foo, bar)")
+ assert(q"f(..${l1 ++ l2}, $baz)" ≈ q"f(foo, bar, baz)")
+ assert(q"f(${if (true) q"a" else q"b"})" ≈ q"f(a)")
+ }
+
+ property("unquote iterable of non-parametric type") = test {
+ object O extends Iterable[Tree] { def iterator = List(q"foo").iterator }
+ q"f(..$O)"
+ }
+
+ property("SI-8016") = test {
+ val xs = q"1" :: q"2" :: Nil
+ assertEqAst(q"..$xs", "{1; 2}")
+ assertEqAst(q"{..$xs}", "{1; 2}")
+ }
+
+ property("SI-6842") = test {
+ val cases: List[Tree] = cq"a => b" :: cq"_ => c" :: Nil
+ assertEqAst(q"1 match { case ..$cases }", "1 match { case a => b case _ => c }")
+ assertEqAst(q"try 1 catch { case ..$cases }", "try 1 catch { case a => b case _ => c }")
+ }
+
+ property("SI-8009") = test {
+ q"`foo`".asInstanceOf[reflect.internal.SymbolTable#Ident].isBackquoted
+ }
+
+ property("SI-8148") = test {
+ val q"($a, $b) => $_" = q"_ + _"
+ assert(a.name != b.name)
+ }
+
+ property("SI-7275 a") = test {
+ val t = q"stat1; stat2"
+ assertEqAst(q"..$t", "{stat1; stat2}")
+ }
+
+ property("SI-7275 b") = test {
+ def f(t: Tree) = q"..$t"
+ assertEqAst(f(q"stat1; stat2"), "{stat1; stat2}")
+ }
+
+ property("SI-7275 c1") = test {
+ object O
+ implicit val liftO = Liftable[O.type] { _ => q"foo; bar" }
+ assertEqAst(q"f(..$O)", "f(foo, bar)")
+ }
+
+ property("SI-7275 c2") = test {
+ object O
+ implicit val liftO = Liftable[O.type] { _ => q"{ foo; bar }; { baz; bax }" }
+ assertEqAst(q"f(...$O)", "f(foo, bar)(baz, bax)")
+ }
+
+ property("SI-7275 d") = test {
+ val l = q"a; b" :: q"c; d" :: Nil
+ assertEqAst(q"f(...$l)", "f(a, b)(c, d)")
+ val l2: Iterable[Tree] = l
+ assertEqAst(q"f(...$l2)", "f(a, b)(c, d)")
+ }
+
+ property("SI-7275 e") = test {
+ val t = q"{ a; b }; { c; d }"
+ assertEqAst(q"f(...$t)", "f(a, b)(c, d)")
+ }
+
+ property("SI-7275 e2") = test {
+ val t = q"{ a; b }; c; d"
+ assertEqAst(q"f(...$t)", "f(a, b)(c)(d)")
+ }
+
+ property("remove synthetic unit") = test {
+ val q"{ ..$stats1 }" = q"{ def x = 2 }"
+ assert(stats1 ≈ List(q"def x = 2"))
+ val q"{ ..$stats2 }" = q"{ class X }"
+ assert(stats2 ≈ List(q"class X"))
+ val q"{ ..$stats3 }" = q"{ type X = Int }"
+ assert(stats3 ≈ List(q"type X = Int"))
+ val q"{ ..$stats4 }" = q"{ val x = 2 }"
+ assert(stats4 ≈ List(q"val x = 2"))
+ }
+
+ property("don't remove user-defined unit") = test {
+ val q"{ ..$stats }" = q"{ def x = 2; () }"
+ assert(stats ≈ List(q"def x = 2", q"()"))
+ }
+
+ property("empty-tree is not a block") = test {
+ assertThrows[MatchError] {
+ val q"{ ..$stats1 }" = q" "
+ }
+ }
+
+ property("empty block is synthetic unit") = test {
+ val q"()" = q"{}"
+ val q"{..$stats}" = q"{}"
+ assert(stats.isEmpty)
+ assertEqAst(q"{..$stats}", "{}")
+ assertEqAst(q"{..$stats}", "()")
+ }
+
+ property("consistent variable order") = test {
+ val q"$a = $b = $c = $d = $e = $f = $g = $h = $k = $l" = q"a = b = c = d = e = f = g = h = k = l"
+ assert(a ≈ q"a" && b ≈ q"b" && c ≈ q"c" && d ≈ q"d" && e ≈ q"e" && g ≈ q"g" && h ≈ q"h" && k ≈ q"k" && l ≈ q"l")
+ }
+
+ property("SI-8385 a") = test {
+ assertEqAst(q"(foo.x = 1)(2)", "(foo.x = 1)(2)")
+ }
+
+ property("SI-8385 b") = test {
+ assertEqAst(q"(() => ())()", "(() => ())()")
+ }
+
+ property("match scrutinee may not be empty") = test {
+ assertThrows[IllegalArgumentException] {
+ val scrutinee = q""
+ val cases = List(cq"_ =>")
+ q"$scrutinee match { case ..$cases }"
+ }
+ }
+
+ property("construct partial function") = test {
+ val cases = List(cq"a => b", cq"c => d")
+ assertEqAst(q"{ case ..$cases }", "{ case a => b case c => d }")
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala
new file mode 100644
index 0000000000..49ffaff630
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala
@@ -0,0 +1,249 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._
+
+object TermDeconstructionProps extends QuasiquoteProperties("term deconstruction") {
+ property("f(..x) = f") = test {
+ // see SI-8008
+ assertThrows[MatchError] {
+ val q"f(..$args)" = q"f"
+ }
+ }
+
+ property("f(x)") = forAll { (x: Tree) =>
+ val q"f($x1)" = q"f($x)"
+ x1 ≈ x
+ }
+
+ property("f(..xs)") = forAll { (x1: Tree, x2: Tree) =>
+ val q"f(..$xs)" = q"f($x1, $x2)"
+ xs ≈ List(x1, x2)
+ }
+
+ property("f(y, ..ys)") = forAll { (x1: Tree, x2: Tree, x3: Tree) =>
+ val q"f($y, ..$ys)" = q"f($x1, $x2, $x3)"
+ y ≈ x1 && ys ≈ List(x2, x3)
+ }
+
+ property("f(y1, y2, ..ys)") = forAll { (x1: Tree, x2: Tree, x3: Tree) =>
+ val q"f($y1, $y2, ..$ys)" = q"f($x1, $x2, $x3)"
+ y1 ≈ x1 && y2 ≈ x2 && ys ≈ List(x3)
+ }
+
+ property("f(y1, ..ys, yn)") = forAll { (x1: Tree, x2: Tree, x3: Tree, x4: Tree) =>
+ val q"f($y1, ..$ys, $yn)" = q"f($x1, $x2, $x3, $x4)"
+ y1 ≈ x1 && ys ≈ List(x2, x3) && yn ≈ x4
+ }
+
+ property("f(..ys, y_{n-1}, y_n)") = forAll { (x1: Tree, x2: Tree, x3: Tree, x4: Tree) =>
+ val q"f(..$ys, $yn1, $yn)" = q"f($x1, $x2, $x3, $x4)"
+ ys ≈ List(x1, x2) && yn1 ≈ x3 && yn ≈ x4
+ }
+
+ property("f(...xss)") = forAll { (x1: Tree, x2: Tree) =>
+ val q"f(...$xss)" = q"f($x1)($x2)"
+ xss ≈ List(List(x1), List(x2))
+ }
+
+ property("f(...$xss)(..$last)") = forAll { (x1: Tree, x2: Tree, x3: Tree) =>
+ val q"f(...$xss)(..$last)" = q"f($x1)($x2)($x3)"
+ xss ≈ List(List(x1), List(x2)) && last ≈ List(x3)
+ }
+
+ property("f(...$xss)(..$lastinit, $lastlast)") = forAll { (x1: Tree, x2: Tree, x3: Tree, x4: Tree) =>
+ val q"f(...$xss)(..$lastinit, $lastlast)" = q"f($x1)($x2, $x3, $x4)"
+ xss ≈ List(List(x1)) && lastinit ≈ List(x2, x3) && lastlast ≈ x4
+ }
+
+ property("f(...xss) = f") = forAll { (x1: Tree, x2: Tree) =>
+ val q"f(...$xss)" = q"f"
+ xss ≈ List()
+ }
+
+ property("deconstruct unit as tuple") = test {
+ val q"(..$xs)" = q"()"
+ assert(xs.isEmpty)
+ }
+
+ property("deconstruct tuple") = test {
+ val q"(..$xs)" = q"(a, b)"
+ assert(xs ≈ List(q"a", q"b"))
+ }
+
+ property("deconstruct tuple mixed") = test {
+ val q"($first, ..$rest)" = q"(a, b, c)"
+ assert(first ≈ q"a")
+ assert(rest ≈ List(q"b", q"c"))
+ }
+
+ property("deconstruct tuple last element") = test {
+ val q"($first, ..$rest, $last)" = q"(a, b, c, d)"
+ assert(first ≈ q"a")
+ assert(rest ≈ List(q"b", q"c"))
+ assert(last ≈ q"d")
+ }
+
+ property("deconstruct expr as tuple") = test {
+ val q"(..$elems)" = q"foo"
+ assert(elems ≈ List(q"foo"))
+ }
+
+ property("deconstruct cases") = test {
+ val q"$x match { case ..$cases }" = q"x match { case 1 => case 2 => }"
+ assert(x ≈ q"x")
+ assert(cases ≈ List(cq"1 =>", cq"2 =>"))
+ }
+
+ property("deconstruct splitting last case") = test {
+ val q"$_ match { case ..$cases case $last }" = q"x match { case 1 => case 2 => case 3 => }"
+ assert(cases ≈ List(cq"1 =>", cq"2 =>"))
+ assert(last ≈ cq"3 =>")
+ }
+
+ property("deconstruct block") = test {
+ val q"{ ..$xs }" = q"{ x1; x2; x3 }"
+ assert(xs ≈ List(q"x1", q"x2", q"x3"))
+ }
+
+ property("deconstruct last element of a block") = test {
+ val q"{ ..$xs; $x }" = q"x1; x2; x3; x4"
+ assert(xs ≈ List(q"x1", q"x2", q"x3"))
+ assert(x ≈ q"x4")
+ }
+
+ property("exhaustive function matcher") = test {
+ def matches(line: String) { val q"(..$args) => $body" = parse(line) }
+ matches("() => bippy")
+ matches("(y: Y) => y oh y")
+ matches("(x: X, y: Y) => x and y")
+ }
+
+ property("exhaustive new pattern") = test {
+ def matches(line: String) {
+ val q"new { ..$early } with $name[..$targs](...$vargss) with ..$mixin { $self => ..$body }" = parse(line)
+ }
+ matches("new foo")
+ matches("new foo { body }")
+ matches("new foo[t]")
+ matches("new foo(x)")
+ matches("new foo[t](x)")
+ matches("new foo[t](x) { body }")
+ matches("new foo with bar")
+ matches("new foo with bar { body }")
+ matches("new { anonymous }")
+ matches("new { val early = 1 } with Parent[Int] { body }")
+ matches("new Foo { selfie => }")
+ }
+
+ property("exhaustive assign pattern") = test {
+ def matches(tree: Tree) { val q"$rhs = $lhs" = tree }
+ matches(parse("left = right"))
+ matches(parse("arr(1) = 2"))
+ matches(AssignOrNamedArg(EmptyTree, EmptyTree))
+ }
+
+ property("deconstruct update 1") = test {
+ val q"$obj(..$args) = $value" = q"foo(bar) = baz"
+ assert(obj ≈ q"foo")
+ assert(args ≈ List(q"bar"))
+ assert(value ≈ q"baz")
+ }
+
+ property("deconstruct update 2") = test {
+ val q"$left = $value" = q"foo(bar) = baz"
+ assert(left ≈ q"foo(bar)")
+ assert(value ≈ q"baz")
+ }
+
+ property("deconstruct while loop") = test {
+ val q"while($cond) $body" = parse("while(cond) body")
+ assert(cond ≈ q"cond")
+ assert(body ≈ q"body")
+ }
+
+ property("deconstruct do while loop") = test {
+ val q"do $body while($cond)" = parse("do body while(cond)")
+ assert(cond ≈ q"cond")
+ assert(body ≈ q"body")
+ }
+
+ property("deconstruct anonymous function with placeholders") = test {
+ val q"{ $f(_) }" = q"{ foo(_) }"
+ assert(f ≈ q"foo")
+ val q"{ _.$member }" = q"{ _.foo }"
+ assert(member ≈ TermName("foo"))
+ val q"{ _ + $x }" = q"{ _ + x }"
+ assert(x ≈ q"x")
+ val q"{ _ * _ }" = q"{ _ * _ }"
+ }
+
+ property("si-8275 a") = test {
+ val cq"_ => ..$stats" = cq"_ => foo; bar"
+ assert(stats ≈ List(q"foo", q"bar"))
+ }
+
+ property("si-8275 b") = test {
+ val cq"_ => ..$init; $last" = cq"_ => a; b; c"
+ assert(init ≈ List(q"a", q"b"))
+ assert(last ≈ q"c")
+ }
+
+ property("si-8275 c") = test {
+ val cq"_ => ..$stats" = cq"_ =>"
+ assert(stats.isEmpty)
+ assertEqAst(q"{ case _ => ..$stats }", "{ case _ => }")
+ }
+
+ property("can't flatten type into block") = test {
+ assertThrows[IllegalArgumentException] {
+ val tpt = tq"List[Int]"
+ q"..$tpt; ()"
+ }
+ }
+
+ property("term select doesn't match type select") = test {
+ assertThrows[MatchError] {
+ val q"$qual.$name" = tq"foo.bar"
+ }
+ }
+
+ property("type application doesn't match applied type") = test {
+ assertThrows[MatchError] {
+ val q"$f[..$targs]" = tq"foo[bar]"
+ }
+ }
+
+ property("match doesn't match partial function") = test {
+ assertThrows[MatchError] {
+ val q"$_ match { case ..$_ }" = q"{ case _ => }"
+ }
+ }
+
+ property("deconstruct partial function") = test {
+ val q"{ case ..$cases }" = q"{ case a => b case c => d }"
+ val List(cq"a => b", cq"c => d") = cases
+ }
+
+ property("SI-8350 `new C` and `new C()` are equivalent") = test {
+ val q"new C" = q"new C()"
+ val q"new C()" = q"new C"
+ }
+
+ property("SI-8350 new applications extracted only for non-empty ctor calls") = test{
+ val q"new $c1" = q"new C()"
+ assert(c1 ≈ tq"C")
+ val q"new $c2" = q"new C(x)"
+ assert(c2 ≈ q"${tq"C"}(x)")
+ }
+
+ property("SI-8350 original test case") = test {
+ val q"new ..$parents" = q"new Foo with Bar"
+ assert(parents ≈ List(tq"Foo", tq"Bar"))
+ }
+
+ property("SI-8387 new is not an application") = test {
+ val `new` = q"new F(x)"
+ val q"$f(...$argss)" = `new`
+ assert(f ≈ `new`)
+ assert(argss.isEmpty)
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/Test.scala b/test/files/scalacheck/quasiquotes/Test.scala
new file mode 100644
index 0000000000..7a26fa4923
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/Test.scala
@@ -0,0 +1,19 @@
+import org.scalacheck._
+
+object Test extends Properties("quasiquotes") {
+ include(TermConstructionProps)
+ include(TermDeconstructionProps)
+ include(TypeConstructionProps)
+ include(TypeDeconstructionProps)
+ include(PatternConstructionProps)
+ include(PatternDeconstructionProps)
+ include(LiftableProps)
+ include(UnliftableProps)
+ include(ErrorProps)
+ include(RuntimeErrorProps)
+ include(DefinitionConstructionProps)
+ include(DefinitionDeconstructionProps)
+ include(DeprecationProps)
+ include(ForProps)
+ include(TypecheckedProps)
+}
diff --git a/test/files/scalacheck/quasiquotes/TypeConstructionProps.scala b/test/files/scalacheck/quasiquotes/TypeConstructionProps.scala
new file mode 100644
index 0000000000..27ad4c50e9
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/TypeConstructionProps.scala
@@ -0,0 +1,42 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport.ScalaDot
+
+object TypeConstructionProps extends QuasiquoteProperties("type construction") {
+ property("bare idents contain type names") = test {
+ tq"x" ≈ Ident(TypeName("x"))
+ }
+
+ property("unquote type names into AppliedTypeTree") = forAll { (name1: TypeName, name2: TypeName) =>
+ tq"$name1[$name2]" ≈ AppliedTypeTree(Ident(name1), List(Ident(name2)))
+ }
+
+ property("tuple type") = test {
+ val empty = List[Tree]()
+ val ts = List(tq"t1", tq"t2")
+ assert(tq"(..$empty)" ≈ ScalaDot(TypeName("Unit")))
+ assert(tq"(..$ts)" ≈ tq"scala.Tuple2[t1, t2]")
+ assert(tq"(t0, ..$ts)" ≈ tq"scala.Tuple3[t0, t1, t2]")
+ }
+
+ property("single-element tuple type") = test {
+ val ts = q"T" :: Nil
+ assert(tq"(..$ts)" ≈ ts.head)
+ }
+
+ property("refined type") = test {
+ val stats = q"def foo" :: q"val x: Int" :: q"type Y = String" :: Nil
+ assert(tq"T { ..$stats }" ≈ tq"T { def foo; val x: Int; type Y = String }")
+ }
+
+ property("function type") = test {
+ val argtpes = tq"A" :: tq"B" :: Nil
+ val restpe = tq"C"
+ assert(tq"..$argtpes => $restpe" ≈ tq"(A, B) => C")
+ }
+
+ property("empty tq") = test {
+ val tt: TypeTree = tq""
+ assert(tt.tpe == null)
+ assert(tt.original == null)
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala
new file mode 100644
index 0000000000..7572b27b52
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala
@@ -0,0 +1,78 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._
+
+object TypeDeconstructionProps extends QuasiquoteProperties("type deconstruction") {
+ property("ident(type name)") = forAll { (name: TypeName) =>
+ val t = Ident(name)
+ val tq"$t1" = t
+ t1 ≈ t
+ }
+
+ property("applied type tree") = forAll { (name1: TypeName, name2: TypeName) =>
+ val tq"$a[$b]" = AppliedTypeTree(Ident(name1), List(Ident(name2)))
+ a ≈ Ident(name1) && b ≈ Ident(name2)
+ }
+
+ property("tuple type (1)") = test {
+ val tq"(..$empty)" = tq"_root_.scala.Unit"
+ assert(empty.isEmpty)
+ }
+
+ property("tuple type (2)") = test {
+ val tq"(..$ts)" = tq"(t1, t2)"
+ assert(ts ≈ List(tq"t1", tq"t2"))
+ }
+
+ property("tuple type (3)") = test {
+ val tq"($head, ..$tail)" = tq"(t0, t1, t2)"
+ assert(head ≈ tq"t0")
+ assert(tail ≈ List(tq"t1", tq"t2"))
+ }
+
+ property("tuple type (4)") = test {
+ val tq"(..$init, $last)" = tq"(t0, t1, t2)"
+ assert(init ≈ List(tq"t0", tq"t1"))
+ assert(last ≈ tq"t2")
+ }
+
+ property("tuple type (5)") = test {
+ val tq"(..$ts)" = tq"T"
+ assert(ts ≈ List(tq"T"))
+ }
+
+ property("refined type") = test {
+ val tq"T { ..$stats }" = tq"T { def foo; val x: Int; type Y = String }"
+ assert(stats ≈ List(q"def foo", q"val x: Int", q"type Y = String"))
+ }
+
+ property("function type (1)") = test {
+ val tq"..$argtpes => $restpe" = tq"(A, B) => C"
+ assert(argtpes ≈ List(tq"A", tq"B"))
+ assert(restpe ≈ tq"C")
+ }
+
+ property("function type (2)") = test {
+ val tq"(..$argtpes, $arglast) => $restpe" = tq"(A, B, C) => D"
+ assert(argtpes ≈ List(tq"A", tq"B"))
+ assert(arglast ≈ tq"C")
+ assert(restpe ≈ tq"D")
+ }
+
+ property("match empty type tree") = test {
+ val tq"" = TypeTree()
+ // matches because type tree isn't syntactic without original
+ val tq"" = tq"${typeOf[Int]}"
+ }
+
+ property("type select doesn't match term select") = test {
+ assertThrows[MatchError] {
+ val tq"$qual.$name" = q"foo.bar"
+ }
+ }
+
+ property("applied type doesn't match type appliction") = test {
+ assertThrows[MatchError] {
+ val tq"$tpt[..$tpts]" = q"foo[bar]"
+ }
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala
new file mode 100644
index 0000000000..f84df269ca
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala
@@ -0,0 +1,215 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport._
+
+object TypecheckedProps extends QuasiquoteProperties("typechecked")
+ with TypecheckedTypes {
+ property("tuple term") = test {
+ val q"(..$elements)" = typecheck(q"(1, 2)")
+ assert(elements ≈ List(q"1", q"2"))
+ }
+
+ property("for/for-yield") = test {
+ val enums = fq"x <- xs" :: fq"x1 = x + 1" :: fq"if x1 % 2 == 0" :: Nil
+ val body = q"x1"
+ val xs = q"val xs = List(1, 2, 3)"
+ val q"$_; for(..$enums0) yield $body0" = typecheck(q"$xs; for(..$enums) yield $body")
+ assert(enums0 ≈ enums)
+ assert(body0 ≈ body)
+ val q"$_; for(..$enums1) $body1" = typecheck(q"$xs; for(..$enums) $body")
+ assert(enums1 ≈ enums)
+ assert(body1 ≈ body)
+ }
+
+ property("for .filter instead of .withFilter") = test {
+ val enums = fq"foo <- new Foo" :: fq"if foo != null" :: Nil
+ val body = q"foo"
+ val q"$_; for(..$enums1) yield $body1" = typecheck(q"""
+ class Foo { def map(f: Any => Any) = this; def withFilter(cond: Any => Boolean) = this }
+ for(..$enums) yield $body
+ """)
+ assert(enums1 ≈ enums)
+ assert(body1 ≈ body)
+ }
+
+ property("extract UnApply (1)") = test {
+ val q"object $_ { $_; $_; $m }" = typecheck(q"""
+ object Test {
+ class Cell(val x: Int)
+ object Cell { def unapply(c: Cell) = Some(c.x) }
+ new Cell(0) match { case Cell(v) => v }
+ }
+ """)
+ val q"$_ match { case $f(..$args) => $_ }" = m
+ assert(f ≈ pq"Test.this.Cell")
+ assert(args ≈ List(pq"v"))
+ }
+
+ property("extract UnApply (2)") = test {
+ val q"object $_ { $_; $m }" = typecheck(q"""
+ object Test {
+ case class Cell(val x: Int)
+ new Cell(0) match { case Cell(v) => v }
+ }
+ """)
+ val q"$_ match { case ${f: TypeTree}(..$args) => $_ }" = m
+ assert(f.original ≈ pq"Test.this.Cell")
+ assert(args ≈ List(pq"v"))
+ }
+
+ property("extract inferred val type") = test {
+ val typechecked = typecheck(q"val x = 42")
+ val q"val x = 42" = typechecked
+ val q"val x: ${tq""} = 42" = typechecked
+ val q"val x: ${t: Type} = 42" = typechecked
+ }
+
+ property("class with param (1)") = test {
+ val paramName = TermName("x")
+ val q"class $_($param)" = typecheck(q"class Test(val $paramName: Int)")
+
+ assert(param.name == paramName)
+ }
+
+ property("class with param (2)") = test {
+ val paramName = TermName("y")
+ val q"{class $_($param)}" = typecheck(q"class Test(val $paramName: Int = 3)")
+
+ assert(param.name == paramName)
+ assert(param.rhs ≈ q"3")
+ }
+
+ property("class with params") = test {
+ val pName1 = TermName("x1")
+ val pName2 = TermName("x2")
+ val q"{class $_($param1)(..$params2)}" = typecheck(q"class Test(val x0: Float)(val $pName1: Int = 3, $pName2: String)")
+
+ val List(p1, p2, _*) = params2
+
+ assert(p1.name == pName1)
+ assert(p2.name == pName2)
+ assert(params2.size == 2)
+ }
+
+ property("implicit class") = test {
+ val clName = TypeName("Test")
+ val paramName = TermName("x")
+ val q"{implicit class $name($param)}" = typecheck(q"implicit class $clName(val $paramName: String)")
+
+ assert(name == clName)
+ assert(param.name == paramName)
+ }
+
+ property("block with lazy") = test {
+ val lazyName = TermName("x")
+ val lazyRhsVal = 42
+ val lazyRhs = Literal(Constant(lazyRhsVal))
+ val q"{lazy val $pname = $rhs}" = typecheck(q"{lazy val $lazyName = $lazyRhsVal}")
+
+ assert(pname == lazyName)
+ assert(rhs ≈ lazyRhs)
+ }
+
+ property("class with lazy") = test {
+ val clName = TypeName("Test")
+ val paramName = TermName("x")
+ val q"class $name{lazy val $pname = $_}" = typecheck(q"class $clName {lazy val $paramName = 42}")
+
+ assert(name == clName)
+ assert(pname == paramName)
+ }
+
+ property("case class with object") = test {
+ val defName = TermName("z")
+ val defRhsVal = 42
+ val defRhs = Literal(Constant(defRhsVal))
+ val q"object $_{ $_; object $_ extends ..$_ {def $name = $rhs} }" =
+ typecheck(q"""
+ object Test{
+ case class C(x: Int) { def y = x };
+ object C { def $defName = $defRhsVal }
+ }""")
+
+ assert(name == defName)
+ assert(rhs ≈ defRhs)
+ }
+
+ property("partial function") = test {
+ val q"{ case ..$cases }: $ascr" = typecheck(q"{ case 1 => () }: PartialFunction[Int, Unit]")
+ assert(cases ≈ q"{ case 1 => () }".cases)
+ }
+}
+
+trait TypecheckedTypes { self: QuasiquoteProperties =>
+ property("type ident") = test {
+ val q"$_; type $_ = $tpt" = typecheck(q"class C; type T = C")
+ val tq"C" = tpt
+ }
+
+ property("type select") = test {
+ val tq"scala.Int" = typecheckTyp(tq"Int")
+ }
+
+ property("this type select") = test {
+ val q"class $_ { $_; type $_ = $tpt }" = typecheck(q"class C { type A = Int; type B = this.A }")
+ val tq"this.$name" = tpt
+ val TypeName("A") = name
+ }
+
+ property("super type select") = test {
+ val q"$_; class $_ extends $_ { type $_ = $tpt }" =
+ typecheck(q"class C1 { type A = Int }; class C2 extends C1 { type B = super[C1].A }")
+ val tq"$empty.super[$c1].$a" = tpt
+ val TypeName("") = empty
+ val TypeName("C1") = c1
+ val TypeName("A") = a
+ }
+
+ property("applied type") = test {
+ val tt = typecheckTyp(tq"Map[Int, Int]")
+ val tq"$tpt[..$tpts]" = tt
+ val tq"scala.this.Predef.Map" = tpt
+ val List(tq"scala.Int", tq"scala.Int") = tpts
+ }
+
+ property("tuple type") = test {
+ val tq"(..$els0)" = typecheckTyp(tq"Unit")
+ assert(els0.isEmpty)
+ val tq"(..$els1)" = typecheckTyp(tq"(Int, Int)")
+ val List(tq"scala.Int", tq"scala.Int") = els1
+ }
+
+ property("function type") = test {
+ val tq"(..$argtpes) => $restpe" = typecheckTyp(tq"(Int, Int) => Int")
+ val List(tq"scala.Int", tq"scala.Int") = argtpes
+ val tq"scala.Int" = restpe
+ }
+
+ property("compound type") = test {
+ val tq"..$parents { ..$defns }" = typecheckTyp(tq"Int { def x: Int }")
+ val List(tq"Int") = parents
+ val List(q"def x: Int") = defns
+ }
+
+ property("singleton type") = test {
+ val tq"$ref.type" = typecheckTyp(tq"scala.Predef.type")
+ val q"scala.Predef" = ref
+ }
+
+ property("type projection") = test {
+ val tq"$tpt#$name" = typecheckTyp(tq"({ type T = Int })#T")
+ val TypeName("T") = name
+ val tq"{ type T = Int }" = tpt
+ }
+
+ property("annotated type") = test {
+ val tq"$tpt @$annot" = typecheckTyp(tq"Int @unchecked")
+ val tq"scala.Int" = tpt
+ val tq"unchecked" = annot
+ }
+
+ property("existential type") = test {
+ val tq"$tpt forSome { ..$defns }" = typecheckTyp(tq"T forSome { type T }")
+ val tq"T" = tpt
+ val q"type T" :: Nil = defns
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/UnliftableProps.scala b/test/files/scalacheck/quasiquotes/UnliftableProps.scala
new file mode 100644
index 0000000000..659b18edab
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/UnliftableProps.scala
@@ -0,0 +1,166 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._
+
+object UnliftableProps extends QuasiquoteProperties("unliftable") {
+ property("unlift name") = test {
+ val termname0 = TermName("foo")
+ val typename0 = TypeName("foo")
+ val q"${termname1: TermName}" = Ident(termname0)
+ assert(termname1 == termname0)
+ val q"${typename1: TypeName}" = Ident(typename0)
+ assert(typename1 == typename0)
+ val q"${name1: Name}" = Ident(termname0)
+ assert(name1 == termname0)
+ val q"${name2: Name}" = Ident(typename0)
+ assert(name2 == typename0)
+ }
+
+ property("unlift type") = test {
+ val q"${tpe: Type}" = TypeTree(typeOf[Int])
+ assert(tpe =:= typeOf[Int])
+ }
+
+ property("unlift constant") = test {
+ val q"${const: Constant}" = Literal(Constant("foo"))
+ assert(const == Constant("foo"))
+ }
+
+ property("unlift char") = test {
+ val q"${c: Char}" = Literal(Constant('0'))
+ assert(c.isInstanceOf[Char] && c == '0')
+ }
+
+ property("unlift byte") = test {
+ val q"${b: Byte}" = Literal(Constant(0: Byte))
+ assert(b.isInstanceOf[Byte] && b == 0)
+ }
+
+ property("unlift short") = test {
+ val q"${s: Short}" = Literal(Constant(0: Short))
+ assert(s.isInstanceOf[Short] && s == 0)
+ }
+
+ property("unlift int") = test {
+ val q"${i: Int}" = Literal(Constant(0: Int))
+ assert(i.isInstanceOf[Int] && i == 0)
+ }
+
+ property("unlift long") = test {
+ val q"${l: Long}" = Literal(Constant(0L: Long))
+ assert(l.isInstanceOf[Long] && l == 0L)
+ }
+
+ property("unlift float") = test {
+ val q"${f: Float}" = Literal(Constant(0.0f: Float))
+ assert(f.isInstanceOf[Float] && f == 0.0f)
+ }
+
+ property("unlift double") = test {
+ val q"${d: Double}" = Literal(Constant(0.0: Double))
+ assert(d.isInstanceOf[Double] && d == 0.0)
+ }
+
+ property("unlift bool") = test {
+ val q"${b: Boolean}" = q"true"
+ assert(b.isInstanceOf[Boolean] && b == true)
+ }
+
+ property("unlift string") = test {
+ val q"${s: String}" = q""" "foo" """
+ assert(s.isInstanceOf[String] && s == "foo")
+ }
+
+ property("unlift scala.symbol") = test {
+ val q"${s: scala.Symbol}" = q"'foo"
+ assert(s.isInstanceOf[scala.Symbol] && s == 'foo)
+ }
+
+ implicit def unliftList[T: Unliftable]: Unliftable[List[T]] = Unliftable {
+ case q"scala.collection.immutable.List(..$args)" if args.forall { implicitly[Unliftable[T]].unapply(_).nonEmpty } =>
+ val ut = implicitly[Unliftable[T]]
+ args.flatMap { ut.unapply(_) }
+ }
+
+ property("unlift list (1)") = test {
+ val orig = List(1, 2)
+ val q"${l1: List[Int]}" = q"$orig" // q"List(1, 2)"
+ assert(l1 == orig)
+ val q"f(..${l2: List[Int]})" = q"f(..$orig)" // q"f(1, 2)
+ assert(l2 == orig)
+ }
+
+ property("unlift list (2)") = test {
+ val orig2 = List(List(1, 2), List(3))
+ val q"f(${l3: List[List[Int]]})" = q"f($orig2)" // q"f(List(List(1, 2), List(3)))
+ assert(l3 == orig2)
+ val q"f(..${l4: List[List[Int]]})" = q"f(..$orig2)" // q"f(List(1, 2), List(3))"
+ assert(l4 == orig2)
+ val q"f(...${l5: List[List[Int]]})" = q"f(...$orig2)" // q"f(1, 2)(3)
+ assert(l5 == orig2)
+ }
+
+ property("don't unlift non-tree unquotee (1)") = test {
+ val q"${a: TermName}.${b: TermName}" = q"a.b"
+ assert(a == TermName("a"))
+ assert(b == TermName("b"))
+ }
+
+ property("don't unlift non-tree unquotee (2)") = test {
+ val q"${mods: Modifiers} def foo" = q"def foo"
+ assert(mods == Modifiers(DEFERRED))
+ }
+
+ property("unlift tuple") = test {
+ val q"${t2: (Int, Int)}" = q"(1, 2)"
+ val q"${t3: (Int, Int, Int)}" = q"(1, 2, 3)"
+ val q"${t4: (Int, Int, Int, Int)}" = q"(1, 2, 3, 4)"
+ val q"${t5: (Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5)"
+ val q"${t6: (Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6)"
+ val q"${t7: (Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7)"
+ val q"${t8: (Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8)"
+ val q"${t9: (Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9)"
+ val q"${t10: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)"
+ val q"${t11: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)"
+ val q"${t12: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)"
+ val q"${t13: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)"
+ val q"${t14: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)"
+ val q"${t15: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)"
+ val q"${t16: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)"
+ val q"${t17: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)"
+ val q"${t18: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)"
+ val q"${t19: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)"
+ val q"${t20: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)"
+ val q"${t21: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)"
+ val q"${t22: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)"
+ // assert(t1 == Tuple1(1))
+ assert(t2 == (1, 2))
+ assert(t3 == (1, 2, 3))
+ assert(t4 == (1, 2, 3, 4))
+ assert(t5 == (1, 2, 3, 4, 5))
+ assert(t6 == (1, 2, 3, 4, 5, 6))
+ assert(t7 == (1, 2, 3, 4, 5, 6, 7))
+ assert(t8 == (1, 2, 3, 4, 5, 6, 7, 8))
+ assert(t9 == (1, 2, 3, 4, 5, 6, 7, 8, 9))
+ assert(t10 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
+ assert(t11 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11))
+ assert(t12 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
+ assert(t13 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13))
+ assert(t14 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14))
+ assert(t15 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15))
+ assert(t16 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16))
+ assert(t17 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17))
+ assert(t18 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18))
+ assert(t19 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19))
+ assert(t20 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20))
+ assert(t21 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21))
+ assert(t22 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22))
+ }
+
+ property("unlift xml comment") = test {
+ implicit val unliftXmlComment = Unliftable[xml.Comment] {
+ case q"new _root_.scala.xml.Comment(${value: String})" => xml.Comment(value)
+ }
+ val q"${comment: xml.Comment}" = q"<!--foo-->"
+ assert(comment.commentText == "foo")
+ }
+}
diff --git a/test/files/scalacheck/range.scala b/test/files/scalacheck/range.scala
index 72979115be..493083a51f 100644
--- a/test/files/scalacheck/range.scala
+++ b/test/files/scalacheck/range.scala
@@ -30,7 +30,7 @@ abstract class RangeTest(kind: String) extends Properties("Range "+kind) {
def myGen: Gen[Range]
def genReasonableSizeRange = oneOf(genArbitraryRange, genBoundaryRange)
-
+
def genArbitraryRange = for {
start <- choose(Int.MinValue, Int.MaxValue)
end <- choose(Int.MinValue, Int.MaxValue)
@@ -56,7 +56,7 @@ abstract class RangeTest(kind: String) extends Properties("Range "+kind) {
} yield if (start < end) Range(start, end, step) else Range(start, end, -step)
def genRangeByOne = oneOf(genRangeOpenByOne, genRangeClosedByOne)
-
+
def genRangeOpenByOne = for {
r <- oneOf(genSmallRange, genBoundaryRange)
if (r.end.toLong - r.start.toLong).abs <= 10000000L
@@ -127,6 +127,47 @@ abstract class RangeTest(kind: String) extends Properties("Range "+kind) {
(visited == expectedSize(r)) :| str(r)
}
+ property("sum") = forAll(myGen) { r =>
+// println("----------")
+// println("sum "+str(r))
+ val rSum = r.sum
+ val expected = r.length match {
+ case 0 => 0
+ case 1 => r.head
+ case _ => ((r.head + r.last).toLong * r.length / 2).toInt
+ }
+// println("size: " + r.length)
+// println("expected: " + expected)
+// println("obtained: " + rSum)
+
+ (rSum == expected) :| str(r)
+ }
+
+/* checks that sum respects custom Numeric */
+ property("sumCustomNumeric") = forAll(myGen) { r =>
+ val mod = 65536
+ object mynum extends Numeric[Int] {
+ def plus(x: Int, y: Int): Int = (x + y) % mod
+ override def zero = 0
+
+ def fromInt(x: Int): Int = ???
+ def minus(x: Int, y: Int): Int = ???
+ def negate(x: Int): Int = ???
+ def times(x: Int, y: Int): Int = ???
+ def toDouble(x: Int): Double = ???
+ def toFloat(x: Int): Float = ???
+ def toInt(x: Int): Int = ((x % mod) + mod * 2) % mod
+ def toLong(x: Int): Long = ???
+ def compare(x: Int, y: Int): Int = ???
+ }
+
+ val rSum = r.sum(mynum)
+ val expected = mynum.toInt(r.sum)
+
+ (rSum == expected) :| str(r)
+ }
+
+
property("length") = forAll(myGen suchThat (r => expectedSize(r).toInt == expectedSize(r))) { r =>
// println("length "+str(r))
(r.length == expectedSize(r)) :| str(r)
@@ -224,7 +265,8 @@ object TooLargeRange extends Properties("Too Large Range") {
property("Too large range throws exception") = forAll(genTooLargeStart) { start =>
try {
val r = Range.inclusive(start, Int.MaxValue, 1)
- println("how here? r = " + r.toString)
+ val l = r.length
+ println("how here? length = " + l + ", r = " + r.toString)
false
}
catch { case _: IllegalArgumentException => true }
diff --git a/test/files/scalacheck/redblack.scala b/test/files/scalacheck/redblack.scala
deleted file mode 100644
index bbc6504f58..0000000000
--- a/test/files/scalacheck/redblack.scala
+++ /dev/null
@@ -1,213 +0,0 @@
-import org.scalacheck._
-import Prop._
-import Gen._
-
-/*
-Properties of a Red & Black Tree:
-
-A node is either red or black.
-The root is black. (This rule is used in some definitions and not others. Since the
-root can always be changed from red to black but not necessarily vice-versa this
-rule has little effect on analysis.)
-All leaves are black.
-Both children of every red node are black.
-Every simple path from a given node to any of its descendant leaves contains the same number of black nodes.
-*/
-
-abstract class RedBlackTest extends Properties("RedBlack") {
- def minimumSize = 0
- def maximumSize = 5
-
- object RedBlackTest extends scala.collection.immutable.RedBlack[String] {
- def isSmaller(x: String, y: String) = x < y
- }
-
- import RedBlackTest._
-
- def nodeAt[A](tree: Tree[A], n: Int): Option[(String, A)] = if (n < tree.iterator.size && n >= 0)
- Some(tree.iterator.drop(n).next)
- else
- None
-
- def treeContains[A](tree: Tree[A], key: String) = tree.iterator.map(_._1) contains key
-
- def mkTree(level: Int, parentIsBlack: Boolean = false, label: String = ""): Gen[Tree[Int]] =
- if (level == 0) {
- value(Empty)
- } else {
- for {
- oddOrEven <- choose(0, 2)
- tryRed = oddOrEven.sample.get % 2 == 0 // work around arbitrary[Boolean] bug
- isRed = parentIsBlack && tryRed
- nextLevel = if (isRed) level else level - 1
- left <- mkTree(nextLevel, !isRed, label + "L")
- right <- mkTree(nextLevel, !isRed, label + "R")
- } yield {
- if (isRed)
- RedTree(label + "N", 0, left, right)
- else
- BlackTree(label + "N", 0, left, right)
- }
- }
-
- def genTree = for {
- depth <- choose(minimumSize, maximumSize + 1)
- tree <- mkTree(depth)
- } yield tree
-
- type ModifyParm
- def genParm(tree: Tree[Int]): Gen[ModifyParm]
- def modify(tree: Tree[Int], parm: ModifyParm): Tree[Int]
-
- def genInput: Gen[(Tree[Int], ModifyParm, Tree[Int])] = for {
- tree <- genTree
- parm <- genParm(tree)
- } yield (tree, parm, modify(tree, parm))
-}
-
-trait RedBlackInvariants {
- self: RedBlackTest =>
-
- import RedBlackTest._
-
- def rootIsBlack[A](t: Tree[A]) = t.isBlack
-
- def areAllLeavesBlack[A](t: Tree[A]): Boolean = t match {
- case Empty => t.isBlack
- case ne: NonEmpty[_] => List(ne.left, ne.right) forall areAllLeavesBlack
- }
-
- def areRedNodeChildrenBlack[A](t: Tree[A]): Boolean = t match {
- case RedTree(_, _, left, right) => List(left, right) forall (t => t.isBlack && areRedNodeChildrenBlack(t))
- case BlackTree(_, _, left, right) => List(left, right) forall areRedNodeChildrenBlack
- case Empty => true
- }
-
- def blackNodesToLeaves[A](t: Tree[A]): List[Int] = t match {
- case Empty => List(1)
- case BlackTree(_, _, left, right) => List(left, right) flatMap blackNodesToLeaves map (_ + 1)
- case RedTree(_, _, left, right) => List(left, right) flatMap blackNodesToLeaves
- }
-
- def areBlackNodesToLeavesEqual[A](t: Tree[A]): Boolean = t match {
- case Empty => true
- case ne: NonEmpty[_] =>
- (
- blackNodesToLeaves(ne).distinct.size == 1
- && areBlackNodesToLeavesEqual(ne.left)
- && areBlackNodesToLeavesEqual(ne.right)
- )
- }
-
- def orderIsPreserved[A](t: Tree[A]): Boolean =
- t.iterator zip t.iterator.drop(1) forall { case (x, y) => isSmaller(x._1, y._1) }
-
- def setup(invariant: Tree[Int] => Boolean) = forAll(genInput) { case (tree, parm, newTree) =>
- invariant(newTree)
- }
-
- property("root is black") = setup(rootIsBlack)
- property("all leaves are black") = setup(areAllLeavesBlack)
- property("children of red nodes are black") = setup(areRedNodeChildrenBlack)
- property("black nodes are balanced") = setup(areBlackNodesToLeavesEqual)
- property("ordering of keys is preserved") = setup(orderIsPreserved)
-}
-
-object TestInsert extends RedBlackTest with RedBlackInvariants {
- import RedBlackTest._
-
- override type ModifyParm = Int
- override def genParm(tree: Tree[Int]): Gen[ModifyParm] = choose(0, tree.iterator.size + 1)
- override def modify(tree: Tree[Int], parm: ModifyParm): Tree[Int] = tree update (generateKey(tree, parm), 0)
-
- def generateKey(tree: Tree[Int], parm: ModifyParm): String = nodeAt(tree, parm) match {
- case Some((key, _)) => key.init.mkString + "MN"
- case None => nodeAt(tree, parm - 1) match {
- case Some((key, _)) => key.init.mkString + "RN"
- case None => "N"
- }
- }
-
- property("update adds elements") = forAll(genInput) { case (tree, parm, newTree) =>
- treeContains(newTree, generateKey(tree, parm))
- }
-}
-
-object TestModify extends RedBlackTest {
- import RedBlackTest._
-
- def newValue = 1
- override def minimumSize = 1
- override type ModifyParm = Int
- override def genParm(tree: Tree[Int]): Gen[ModifyParm] = choose(0, tree.iterator.size)
- override def modify(tree: Tree[Int], parm: ModifyParm): Tree[Int] = nodeAt(tree, parm) map {
- case (key, _) => tree update (key, newValue)
- } getOrElse tree
-
- property("update modifies values") = forAll(genInput) { case (tree, parm, newTree) =>
- nodeAt(tree,parm) forall { case (key, _) =>
- newTree.iterator contains (key, newValue)
- }
- }
-}
-
-object TestDelete extends RedBlackTest with RedBlackInvariants {
- import RedBlackTest._
-
- override def minimumSize = 1
- override type ModifyParm = Int
- override def genParm(tree: Tree[Int]): Gen[ModifyParm] = choose(0, tree.iterator.size)
- override def modify(tree: Tree[Int], parm: ModifyParm): Tree[Int] = nodeAt(tree, parm) map {
- case (key, _) => tree delete key
- } getOrElse tree
-
- property("delete removes elements") = forAll(genInput) { case (tree, parm, newTree) =>
- nodeAt(tree, parm) forall { case (key, _) =>
- !treeContains(newTree, key)
- }
- }
-}
-
-object TestRange extends RedBlackTest with RedBlackInvariants {
- import RedBlackTest._
-
- override type ModifyParm = (Option[Int], Option[Int])
- override def genParm(tree: Tree[Int]): Gen[ModifyParm] = for {
- from <- choose(0, tree.iterator.size)
- to <- choose(0, tree.iterator.size) suchThat (from <=)
- optionalFrom <- oneOf(Some(from), None, Some(from)) // Double Some(n) to get around a bug
- optionalTo <- oneOf(Some(to), None, Some(to)) // Double Some(n) to get around a bug
- } yield (optionalFrom, optionalTo)
-
- override def modify(tree: Tree[Int], parm: ModifyParm): Tree[Int] = {
- val from = parm._1 flatMap (nodeAt(tree, _) map (_._1))
- val to = parm._2 flatMap (nodeAt(tree, _) map (_._1))
- tree range (from, to)
- }
-
- property("range boundaries respected") = forAll(genInput) { case (tree, parm, newTree) =>
- val from = parm._1 flatMap (nodeAt(tree, _) map (_._1))
- val to = parm._2 flatMap (nodeAt(tree, _) map (_._1))
- ("lower boundary" |: (from forall ( key => newTree.iterator.map(_._1) forall (key <=)))) &&
- ("upper boundary" |: (to forall ( key => newTree.iterator.map(_._1) forall (key >))))
- }
-
- property("range returns all elements") = forAll(genInput) { case (tree, parm, newTree) =>
- val from = parm._1 flatMap (nodeAt(tree, _) map (_._1))
- val to = parm._2 flatMap (nodeAt(tree, _) map (_._1))
- val filteredTree = (tree.iterator
- .map(_._1)
- .filter(key => from forall (key >=))
- .filter(key => to forall (key <))
- .toList)
- filteredTree == newTree.iterator.map(_._1).toList
- }
-}
-
-object Test extends Properties("RedBlack") {
- include(TestInsert)
- include(TestModify)
- include(TestDelete)
- include(TestRange)
-}
-
diff --git a/test/files/scalacheck/redblacktree.scala b/test/files/scalacheck/redblacktree.scala
index bc7f92aa1b..871444a4b8 100644
--- a/test/files/scalacheck/redblacktree.scala
+++ b/test/files/scalacheck/redblacktree.scala
@@ -205,22 +205,22 @@ package scala.collection.immutable.redblacktree {
filteredTree == keysIterator(newTree).toList
}
}
-
+
object TestDrop extends RedBlackTreeTest with RedBlackTreeInvariants {
import RB._
-
+
override type ModifyParm = Int
override def genParm(tree: Tree[String, Int]): Gen[ModifyParm] = choose(0, iterator(tree).size)
override def modify(tree: Tree[String, Int], parm: ModifyParm): Tree[String, Int] = drop(tree, parm)
-
+
property("drop") = forAll(genInput) { case (tree, parm, newTree) =>
iterator(tree).drop(parm).toList == iterator(newTree).toList
}
}
-
+
object TestTake extends RedBlackTreeTest with RedBlackTreeInvariants {
import RB._
-
+
override type ModifyParm = Int
override def genParm(tree: Tree[String, Int]): Gen[ModifyParm] = choose(0, iterator(tree).size)
override def modify(tree: Tree[String, Int], parm: ModifyParm): Tree[String, Int] = take(tree, parm)
@@ -229,7 +229,7 @@ package scala.collection.immutable.redblacktree {
iterator(tree).take(parm).toList == iterator(newTree).toList
}
}
-
+
object TestSlice extends RedBlackTreeTest with RedBlackTreeInvariants {
import RB._
@@ -239,7 +239,7 @@ package scala.collection.immutable.redblacktree {
to <- choose(from, iterator(tree).size)
} yield (from, to)
override def modify(tree: Tree[String, Int], parm: ModifyParm): Tree[String, Int] = slice(tree, parm._1, parm._2)
-
+
property("slice") = forAll(genInput) { case (tree, parm, newTree) =>
iterator(tree).slice(parm._1, parm._2).toList == iterator(newTree).toList
}
diff --git a/test/files/scalacheck/substringTests.scala b/test/files/scalacheck/substringTests.scala
index a48356e1fa..76260b9dd2 100644
--- a/test/files/scalacheck/substringTests.scala
+++ b/test/files/scalacheck/substringTests.scala
@@ -6,11 +6,11 @@ object Test extends Properties("String") {
property("endsWith") = Prop.forAll((a: String, b: String) => (a+b).endsWith(b))
- property("concat") = Prop.forAll((a: String, b: String) =>
+ property("concat") = Prop.forAll((a: String, b: String) =>
(a+b).length >= a.length && (a+b).length >= b.length
)
- property("substring") = Prop.forAll((a: String, b: String) =>
+ property("substring") = Prop.forAll((a: String, b: String) =>
(a+b).substring(a.length) == b
)
diff --git a/test/files/scalacheck/t2460.scala b/test/files/scalacheck/t2460.scala
index 196b43789f..ab2911447a 100644
--- a/test/files/scalacheck/t2460.scala
+++ b/test/files/scalacheck/t2460.scala
@@ -1,6 +1,5 @@
import org.scalacheck.Prop.forAll
import org.scalacheck.Properties
-import org.scalacheck.ConsoleReporter.testStatsEx
import org.scalacheck.{Test => SCTest}
import org.scalacheck.Gen
@@ -25,8 +24,4 @@ object Test extends Properties("Regex : Ticket 2460") {
("numberOfGroup", numberOfGroup),
("nameOfGroup", nameOfGroup)
)
-
- /*tests foreach {
- case (name, p) => testStatsEx(name, SCTest.check(p))
- }*/
}
diff --git a/test/files/scalacheck/si4147.scala b/test/files/scalacheck/t4147.scala
index 1453440ef1..72f6e9afd5 100644
--- a/test/files/scalacheck/si4147.scala
+++ b/test/files/scalacheck/t4147.scala
@@ -1,8 +1,6 @@
-import org.scalacheck.Prop.forAll
+import org.scalacheck.Prop.{forAll, throws}
import org.scalacheck.Properties
-import org.scalacheck.ConsoleReporter.testStatsEx
import org.scalacheck.Gen
-import org.scalacheck.ConsoleReporter
import collection.mutable
@@ -64,4 +62,7 @@ object Test extends Properties("Mutable TreeSet") {
view.filter(_ < 50) == Set[Int]() && view.filter(_ >= 150) == Set[Int]()
}
}
+
+ property("ordering must not be null") =
+ throws(classOf[NullPointerException])(mutable.TreeSet.empty[Int](null))
}
diff --git a/test/files/scalacheck/treeset.scala b/test/files/scalacheck/treeset.scala
index 98e38c8219..4b9b77dd7e 100644
--- a/test/files/scalacheck/treeset.scala
+++ b/test/files/scalacheck/treeset.scala
@@ -149,4 +149,7 @@ object Test extends Properties("TreeSet") {
val result = subject.foldLeft(subject)((acc, elt) => acc - elt)
result.isEmpty
}
+
+ property("ordering must not be null") =
+ throws(classOf[NullPointerException])(TreeSet.empty[Int](null))
}