-
Notifications
You must be signed in to change notification settings - Fork 11
Generalize postcondition
#11
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
Conversation
This allows `postcondition` to return a string explaining the failure, rather than just a `Bool`. This will help with debugging.
This looks very helpful! I used
But having individual failures described by the model itself, good idea! 👍 |
Only issue with this.. it's a breaking change 😄 Version 2.0.0 incoming? 🤔 @abailly |
Re version numbering, as far as the PVP is concerned, version 1.2 would suffice :) |
If you are going to up the version number, might want to hold off, I'm working on some stuff, I may or may not have further PRs :) |
I don't have any fetish with version numbers, they are, well, just numbers, so if this change is immediately useful and breaking then so be it :) Of course, if you have some other stuff coming @edsko it's also fine to wait a bit. |
And thanks a lot for your contribution BTW ! |
postcondition _s Spawn _ _ = True | ||
postcondition s (Register name step) _ res = | ||
postcondition _s Spawn _ _ = checkBool $ True | ||
postcondition s (Register name step) _ res = checkBool $ |
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.
Suggestion: Just fill in an example here? I agree we shouldn't bother with the other branches of the alternative.
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.
Sure, can do! :)
This was already satisfied, it just wasn't visible. Having this visible is useful when building abstractions on top of `StateModel` (which are themselves still polymorphic in the `state` argument).
Having the ability to explain a failing postcondition is a good feature, but I'm not very fond of
It would suggest defining a new type (isomorphic to Backwards compatibility could be saved by adding this functionality in a new method |
Ok, will give that a stab later. |
Out of curiosity, what are you using q-d for @edsko ? |
I'm investigating whether I can use it for lockstep-style testing with q-d instead of q-s-m, so I'm trying to build some infrastructure on top of Now that we're on the topic: if successful, this infrastructure will probably consist of a new module that users can use, that provides a class on top of |
Interesting! I don't see why we would not be interested in your contributions :) BTW, a few people are interested in understanding what are the differences between q-d and q-s-m and it seems your insights would be much appreciated. At the very least, pointing at your blog post could be a good first answer to that question. |
Ok! Will send you a draft once it's done. And yes, people have been asking me the same question, hence the blog post :) |
This is a welcome idea. We have the Also see #12 - we have some breaking changes coming up so I suggest waiting a little bit with merging this PR (after the important suggestion from @UlfNorell) until we've settled the dust on that. |
Yes, I will make that change, and maybe also propose one other (very minor) one. I am nearly done with my experiment, will report back hopefully tomorrow. |
Ok, draft blog post implementing a "lockstep-style testing" abstraction on top of If you guys think that this |
Thanks a lot @edsko. I had a quick look at the blog post and it's really great. This comparison is really useful and I wish you later have the time to investigate the dynamic logic part. The |
Ok, I have pushed another commit that introduces a proper abstraction for postconditions, and I've modified the postcondition in the registry to take advantage of it. Re lockstep, I will wait for the final verdict before submitting a PR on that :) |
I like the Regarding the |
Sure, I can rebase. |
-- | ||
-- When 'postcondition' returns @Just err@, the property will fail, and @err@ will be shown as a | ||
-- counter-example. This is useful to check th implementation produces expected values. | ||
postcondition :: state -> Action state a -> LookUp -> a -> Postcondition |
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 would be much happier with a Assertable
type class here (just like how QuickCheck has Testable
). That way you can return a boolean if you want.
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.
Also, the comment is now obsolete.
. showsPrec appPrec1 y | ||
$ "" | ||
|
||
assertEQ :: (Eq a, Show a) => a -> a -> Postcondition |
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.
Please add infix versions of these operators.
postcondition s (WhereIs name) env mtid = Post.assertEQ mtid $ | ||
(env <$> lookup name (regs s)) | ||
postcondition _s Spawn _ _ = Post.assertSuccess | ||
postcondition s (Register name step) _ res = Post.assertEQ (isRight res) $ |
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.
This is why I want infix operators...
This is getting into bikeshedding territory; there are many ways that this type can be defined. Happy to make changes if there are specific requirements, or happy to leave this to you guys to modify as you see fit, but I'd like to avoid an endless back and forth if we can. |
I understand wanting to avoid endless back and forth - but this PR currently makes the examples more difficult to read so I'm not super comfortable merging it until that's been fixed. In my humble opinion right way to implement new features is not to introduce a skeleton idea and leave it up to the maintainers to "modify as we see fit" - it's to introduce a coherent and complete package. |
Ok, I see. Fair enough. I tried to give you a nice PR and tried to incorporate your suggestions, but if you consider this to be merely a "skeleton idea" where I am leaving the "actual implementation" up to you guys, I see that I am mistaken. My apologies. |
Not yet, will probably be early this week. |
@edsko I'm sorry if I hurt your feelings. I certainly didn't mean to imply that you haven't done useful work here - I just mean that I think there is more we can do with this to make sure we arrive at the right long-term solution that does everything we want. I think the fact that you were willing to pull this thread and start the discussion is great and I really want to include the work you've done in the repo so let's be friends and have an open discussion about the best way to pull it off. And let's perhaps have that discussion over in #15 to avoid it just being an endless series of requested edits to this PR, because I completely agree that such a process is super frustrating! |
@abailly-iohk I have updated the draft blog post as well as my code to be compatible with current |
(I now use |
Blog post is live! https://well-typed.com/blog/2022/09/lockstep-with-quickcheck-dynamic/ Thanks for the assist, and the library. I think lockstep-style testing is much nicer with quickcheck-dynamic/quickcheck-lockstep rather than with quickcheck-state-machine :) |
Thanks a lot @edsko for being our first external contributor and putting in the effort to work on this! I will make sure we reference the blog post in the documentation real quick and spread the word. |
This allows
postcondition
to return a string explaining the failure, rather than just aBool
. This will help with debugging.I didn't bother taking advantage of this in the registry test, just added a function that turns a
Bool
into aMaybe String
.