-
Notifications
You must be signed in to change notification settings - Fork 407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Defer evaluation of Prop
labels
#979
base: main
Are you sure you want to change the base?
Conversation
Also of note, the by-name parameter of
|
debc313
to
d211c81
Compare
Made some changes here to ensure that this is binary compatible, thank you @armanbilge! |
s"average = $avg" |: avg >= 0.49 && avg <= 0.51 | ||
(avg >= 0.49 && avg <= 0.51).labelImpl2(s"average = $avg") |
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.
Oh this is annoying, I wonder if we should move the test suites out of the scalacheck
package.
I know it's very common but I actually think tests in the same package is an anti-pattern because it's not properly exercising the user-facing experience (e.g. you could make publicly source-breaking changes without realizing it).
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 open to it and happy to include it as part of this if there's another package people agree on
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 went ahead and moved all tests to the scalacheck.tests
package. Happy to change or revert it if we discover a better path forward
7ab14ce
to
a6dfec7
Compare
a6dfec7
to
a7217c8
Compare
@mrdziuban thank you for the ping. To be honest, I forgot about your PR a little bit, sorry about that. I'm trying to wrap my head around the proposed changes, so my judgements may or may not be correct, feel free to argue please – I am totally open to change my mind.
That assumes – we're changing the behavior of the existing APIs, aren't we? I am pretty sure there are a lot of tests around that do exactly that, i.e. just use constant strings as a clue. Moreover, there are also labels available for Wrapping up, perhaps (maybe) instead of replacing the existing behavior silently, it would make sense to provide an alternative APIs for lazy labels. I.e. similar to |
@satorg no problem, thanks for taking a look! Yes, this does change the behavior of existing APIs, but in a way that I think will benefit more users than it will hurt.
Perhaps, but in my codebase (and I would guess a number of others) I use the labels to provide debug info so someone looking at a test failure has somewhere to start.
Interesting point. My thinking was that the different behavior made sense because a
I'm not opposed to this and would be willing to implement it if we decide it's the best path forward, I just might suggest using |
So, is this going to be integrated to master in some form? What is the current obstacle to do so? |
@satorg gentle ping, do you have any thoughts on this? |
To my best knowledge, pretty much the same thing – when a test fails: import org.scalacheck._
object LabelsTestApp extends Properties("LabelsTestApp") {
val myIntGen: Gen[Int] = Arbitrary.arbitrary[Int].label("myIntGen")
def myProp(n: Int): Prop = (n % 2) == 1
property("check_it_out") =
Prop.forAllNoShrink(Arbitrary.arbitrary[Int], myIntGen) { (n1: Int, n2: Int) =>
myProp(n1).label("default-gen") || myProp(n2).label("custom-gen")
}
} which results to:
|
My initial idea was to keep the existing functionality intact while add a new one as necessary (i.e. via My assumption was that adding new functionality without changing the existing one has its advantages:
But perhaps the existing functionality in regards to labels can be considered so bad that it might be worth changing anyway... |
The linked PR proposes I'd have to be shown that there is a performance consequence. But I haven't been researching; I just needed to do some scalachecking today. There may be future hiccups or restrictions with right-associative operators in Scala 3. It's not a terrible idea to avoid them. |
I'm cool with |
I've discovered that a bottleneck in my tests is the generation of labels to be displayed if the test fails. I'm using
pprint
like this:and I see in a stack dump that
pprinter
is being called even when the test succeeds.This does a few things to defer evaluation:
Prop.label
,Prop.:|
, andProp.|:
methods that take a by-name parameterProp.label
,Prop.:|
, andProp.|:
with by-value parameters asprivate[scalacheck]
Prop.Result.labels
if the result's status isFailed
orException
-- this ensures the by-name parameter isn't evaluated when the test succeeds