Is this a bug in ScalaTest
It demonstrates the limits of method overloading.
In an article on selfless traits, Bill Venners describes this pattern as a workaround for these sorts of naming collisions.
In your case, one overload is preferred because it is defined in a "derived class".
(I think; I'm not a user of these test frameworks and one of the sources is generated, etc, so testing this was not a simple matter of firing up sbt and looking at code.)
(Edit: the scaladoc says you're supposed to import Inspectors._
. Maybe you expected to inherit it with Matchers
because it also suggests importing its companion, though that doesn't work for me offhandily. If you did import Inspectors._
, you can't actually induce an overload by importing the name.)
(Edit: to explain the naming bit: see the beginning of Ch 2 of the spec, where it says that bindings of names have precedences, and names you inherit have higher precedence than names you import.)
Anyway, one solution is to remix-in Inspectors
as shown below.
The other solution is to import the method with a rename:
import Inspectors.{ forAll => iforAll }
It's useful to try options "-Xprint:typer", "-Xlog-implicit-conversions" to see what's happening. In your case, your collection is promoted to a "constant gen" by an implicit view Gen.value
in ScalaCheck 1.10.
import org.scalatest._
import org.scalatest.prop._
//class MySpec extends FeatureSpec with Matchers with GeneratorDrivenPropertyChecks
class MySpec extends FeatureSpec with Matchers with GeneratorDrivenPropertyChecks with Inspectors {
case class Foo(id: Int)
val items = 1 to 10 map (Foo.apply(_))
forAll(items) { x => Console println x.id }
}
object Test extends App {
case class Foo(id: Int)
val items = 1 to 10 map (Foo.apply(_))
val sut = new MySpec
sut.forAll(items) { x => Console println x.id }
//sut.forAll[Foo](items) { x => Console println x.i }
}
Some debug output:
/*
[info] /home/apm/projects/skala-unit-tests/src/test/scala/maqi/MySpec.scala:15: inferred view from scala.collection.immutable.IndexedSeq[maqi.Test.Foo] to org.scalacheck.Gen[?] = scalacheck.this.Gen.value[scala.collection.immutable.IndexedSeq[maqi.Test.Foo]]:(x: scala.collection.immutable.IndexedSeq[maqi.Test.Foo])org.scalacheck.Gen[scala.collection.immutable.IndexedSeq[maqi.Test.Foo]]
> test
[info] Compiling 3 Scala sources to /home/apm/projects/skala-unit-tests/target/scala-2.10/test-classes...
[error] /home/apm/projects/skala-unit-tests/src/test/scala/maqi/MySpec.scala:16: overloaded method value forAll with alternatives:
[error] (genAndNameA: (org.scalacheck.Gen[maqi.Test.Foo], String),configParams: maqi.Test.sut.PropertyCheckConfigParam*)(fun: maqi.Test.Foo => Unit)(implicit config: maqi.Test.sut.PropertyCheckConfig, implicit shrA: org.scalacheck.Shrink[maqi.Test.Foo])Unit <and>
[error] (genA: org.scalacheck.Gen[maqi.Test.Foo],configParams: maqi.Test.sut.PropertyCheckConfigParam*)(fun: maqi.Test.Foo => Unit)(implicit config: maqi.Test.sut.PropertyCheckConfig, implicit shrA: org.scalacheck.Shrink[maqi.Test.Foo])Unit <and>
[error] (nameA: String,configParams: maqi.Test.sut.PropertyCheckConfigParam*)(fun: maqi.Test.Foo => Unit)(implicit config: maqi.Test.sut.PropertyCheckConfig, implicit arbA: org.scalacheck.Arbitrary[maqi.Test.Foo], implicit shrA: org.scalacheck.Shrink[maqi.Test.Foo])Unit <and>
[error] (fun: maqi.Test.Foo => Unit)(implicit config: maqi.Test.sut.PropertyCheckConfig, implicit arbA: org.scalacheck.Arbitrary[maqi.Test.Foo], implicit shrA: org.scalacheck.Shrink[maqi.Test.Foo])Unit
[error] cannot be applied to (scala.collection.immutable.IndexedSeq[maqi.Test.Foo])
[error] sut.forAll[Foo](items) { x => Console println x.i }
[error] ^
*/