refined-scalacheck all values discarded
err0r500 opened this issue · 5 comments
Hello,
I couldn't find any documentation about how to use refined-scalacheck and I struggle with refinements when they become a bit too specific (looks like they act as a filter discarding all values)
I'm new to scala and I suspect that the implicit resolution is not what it should be but I couldn't figure out how to make it work.
import org.scalacheck.Properties
import org.scalacheck.Prop.forAll
import eu.timepit.refined.auto.autoUnwrap
import eu.timepit.refined.api.Refined
import eu.timepit.refined.predicates.string.StartsWith
import eu.timepit.refined.scalacheck.string.startsWithArbitrary
import eu.timepit.refined.scalacheck.any.arbitraryFromValidate // <- my main suspect
object StringSpecification extends Properties("String") {
property("startsWith") = forAll { (str: String Refined StartsWith["a"]) =>
str.charAt(0).equals("a")
}
}
// result -> String.startsWith: Gave up after only 0 passed tests. 501 tests were discarded.
Any hint about how I'm supposed to use it ?
It works if you remove the arbitraryFromValidate
import because startsWithArbitrary
is already imported: https://scastie.scala-lang.org/3zOprdJ5R7CRdcckNGfFVQ
If your refinement becomes more complex, you probably won't have luck with arbitraryFromValidate
because - as you already said - it is just a filter that discards not matching values.
thanks @fthomas !
I use scala3 and if I just switch the target from your example, it doesn't compile : https://scastie.scala-lang.org/1J4smLVBQ86ckV9qgvf9pg
with the error :
No given instance of type org.scalacheck.Arbitrary[
eu.timepit.refined.api.Refined[String,
eu.timepit.refined.string.StartsWith[("a" : String)]
]
] was found for parameter a1 of method forAll in object Prop.
I found:
org.scalacheck.Arbitrary.arbContainer2[eu.timepit.refined.api.Refined, String,
eu.timepit.refined.string.StartsWith[("a" : String)]
](
org.scalacheck.Arbitrary.arbContainer2[Tuple2, String,
eu.timepit.refined.string.StartsWith[("a" : String)]
](
org.scalacheck.Arbitrary.arbContainer[([T2] =>> (String, T2)),
eu.timepit.refined.string.StartsWith[("a" : String)]
](
org.scalacheck.Arbitrary.arbContainer[eu.timepit.refined.string.StartsWith
,
("a" : String)](org.scalacheck.Arbitrary.arbEnum[A], ???, ???)
, ???, ???)
, ???, ???)
, ???, ???)
But method arbEnum in trait ArbitraryLowPriority does not match type org.scalacheck.Arbitrary[("a" : String)].
One of the following imports might make progress towards fixing the problem:
import eu.timepit.refined.scalacheck.any.arbitraryFromValidate
import shapeless.~?>.idKeyWitness
import shapeless.~?>.idValueWitness
import shapeless.~?>.witness
That's the reason why I had to add the arbitraryFromValidate
in my example. I guess I'm doing something wrong....
I guess I'm doing something wrong....
No, you are not. I just saw that startsWithArbitrary
still uses shapeless.Witness
but that doesn't work with Scala 3. The Scala 3 version of this instance needs to be changed to use ValueOf
as is done here for example.
ok, I opened a PR for this.
Beware, I'm a 3-day-old scala dev :D
@err0r500 Your fix is has been released in 0.10.2 and your example is working now: https://scastie.scala-lang.org/bdbcLixJRjmP0JyMltq7CA