-
Notifications
You must be signed in to change notification settings - Fork 406
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Deprecate forAll with Gens #444
Conversation
@@ -806,6 +806,7 @@ object Prop { | |||
|
|||
/** Universal quantifier for an explicit generator. Shrinks failed arguments | |||
* with the default shrink function for the type */ | |||
@deprecated("Use 'forAllNoShrink', shrinking will be disabled for Gen by default in the next release", "1.14.1") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suck with useful error messages. Suggestions welcome for what might be more appropriate/useful/readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned in #440, it would be better to provide users with forAllShrink
, since forAllNoShrink
does not provide shrinking.
This requires adding all the same arities of forAllShrink(Gen)
as exist for forAll(Gen)
. This would probably end up needing to be released as 1.15.0.
The wording of the deprecation should probably be something like, "Shrink will be disabled when given explicit Gen, use forAllShrink instead", giving:
[warn] method forAll in object Prop is deprecated (since 1.15.0):
[warn] Shrink will be disabled when given explicit Gen, use forAllShrink instead
@@ -24,7 +24,7 @@ object PropSpecification extends Properties("Prop") { | |||
|
|||
property("Prop.==> undecided") = forAll { p1: Prop => | |||
val g = oneOf(falsified,undecided) | |||
forAll(g) { p2 => | |||
forAllNoShrink(g) { p2 => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that you've defined forAllShrink(Gen)
, you could use it in the test suite. But it would be better to just minimize the changes in the PR, by keeping forAll(Gen)
in the tests. The deprecation warnings for forAll(Gen)
are non-fatal in the test suite, anyway.
@@ -163,7 +163,7 @@ sealed abstract class Gen[+T] extends Serializable { self => | |||
if (lhs == rhs) Prop.proved(prms) else Prop.falsified(prms) | |||
} | |||
|
|||
def !=[U](g: Gen[U]) = Prop.forAll(this)(r => Prop.forAll(g)(_ != r)) | |||
def !=[U](g: Gen[U]) = Prop.forAllNoShrink(this)(r => Prop.forAllNoShrink(g)(_ != r)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that you've defined it, you can use forAllShrink
. Otherwise, you're changing the semantics of !=
.
@@ -215,7 +215,7 @@ trait Commands { | |||
final def property(threadCount: Int = 1, maxParComb: Int = 1000000): Prop = { | |||
val suts = collection.mutable.Map.empty[AnyRef,(State,Option[Sut])] | |||
|
|||
Prop.forAll(actions(threadCount, maxParComb)) { as => | |||
Prop.forAllNoShrink(actions(threadCount, maxParComb)) { as => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, you can use forAllShrink
. Otherwise, you're changing the implementation. Additionally, there is a Shrink[Actions]
in scope.
f5c3563
to
3bf4d72
Compare
Thanks @ashawley, sorry some of that was a little sloppy. |
@@ -163,7 +163,7 @@ sealed abstract class Gen[+T] extends Serializable { self => | |||
if (lhs == rhs) Prop.proved(prms) else Prop.falsified(prms) | |||
} | |||
|
|||
def !=[U](g: Gen[U]) = Prop.forAll(this)(r => Prop.forAll(g)(_ != r)) | |||
def !=[U](g: Gen[U]) = Prop.forAllShrink(this)(r => Prop.forAllNoShrink(g)(_ != r)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You fixed one, but theres a second one that needs to be forAllShrink
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies, I completely didn't see that. Updated
011cbd7
to
8aa8e2e
Compare
@@ -806,16 +907,18 @@ object Prop { | |||
|
|||
/** Universal quantifier for an explicit generator. Shrinks failed arguments | |||
* with the default shrink function for the type */ | |||
@deprecated("Use 'forAllNoShrink', shrinking will be disabled for Gen, use forAllShrink instead", "1.14.1") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The deprecation message still needs tweaking. As I suggested, it should be
Shrink will be disabled with explicit Gen, use forAllShrink instead
The version number should be 1.15.0
, not 1.14.1
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how strict ScalaCheck is with semver, but I understand you increment the minor version when there is either new functionality or new deprecations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not necessary to suggest forAllNoShrink
, because that's what forAll
will effectively become.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tone of the deprecation message could be less commanding. Users could assume they have to migrate to forAllShrink
. It's really their choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ashawley Thanks, I wasn't paying close enough attention (again). I've just used your full/original suggestion and updated the version number. I've updated the PR. Sorry for the confusion and wasted time.
@ashawley do you have merge and release permissions? I'm wondering if I should weigh in on the changes you're suggesting or not. |
I don't, but hopefully you'd weigh in regardless. |
5993f71
to
848a47f
Compare
I don't support deprecating shrinking with an explicit generator. I'd rather see it fixed, but in the absence of a fix, @charleso has made a valid argument that it should be disabled by default. My concern of not providing an opt-in for shrinking via Thanks for doing this! |
Concerning Rickard's original question in #440:
This deprecation warning for
We could try to either massage the deprecation message or jam in more information. Any suggestions to the wording are welcome, but it has diminishing returns. I'd wager there needs to be a comprehensive release notes about this. The release that subsequently removes shrinking should follow closely behind the release that does deprecation. That would avoid confusing new users from the deprecation warning. |
Hi @ashawley Thanks for taking the time to review this PR. My sincere apologies for doing this but I'm going to close the PR. It was originally as a Proof Of Concept and to help communicate one of the options for "fixing" (for some definition) for `forAll (as part of #440 ). I wont deny it, ScalaCheck is in a tough spot. There is an extremely commonly used function that is behaving in an (arguably) unexpected fashion. By changing the semantics are we breaking compatibility? Honestly I don't think the there is a Right Answer. I just know that personally I'm going to feel extremely responsible if we merge this PR and, as you 100% correctly point out, "New users are going to write their first property test using I'm more than happy if @rickynils, yourself, or another maintainer want to re-open and merge this PR, but I don't want to be seen as the person who was responsible for 1000 deprecation warnings for (in my opinion) a behaviour they didn't realise they were getting. I still think that #440 is the right approach in this situation. Let's just change the behaviour. The worst that can happen is that users get slightly more unhelpful failure cases, but that are true positives. The alternatives are:
I'm really not trying to push you to merge/support #440, I suspect you won't and I'm not trying to have that argument again. I'm just not comfortable with #444 (this PR) and don't want to have my name associated with potentially pissing off lots of people "fixing" something. Thanks again though, I really mean that, and sorry for dragging out a PR I wasn't really comfortable with in the first place. |
Ok, we can resurrect the branch if we need to. I actually agree that there probably isn't much advantage to this approach of deprecating. It's probably better to just migrate over in #444. We still have a lot of the same issues with #444, but it will be less confusing than pushing a release with deprecation warnings. |
I'm wondering what y'all would think about making shrink/noshrink a boolean parameter. Is there an easy way to turn shrinking on and off? Like if I have a test suite and I want to turn shrinking on and off for the whole suite. For instance, perhaps I'm still working on the instance of Shrink for my type and want to turn it on or off in a simple way. I'm convincing myself this isn't a good idea, since |
@rickynils @dwijnand
Sorry if this gets confusing pretty quickly. This is one option for the first change to ScalaCheck to deprecate the forAll Gen functions, but leave the behaviour. Is it what you had in mind?
EDIT: This is based on the original disabling of Shrinking on #440