-
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
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,12 +5,12 @@ license: Apache-2.0 | |
license-files: | ||
LICENSE | ||
NOTICE | ||
|
||
maintainer: [email protected] | ||
author: Ulf Norell | ||
category: Testing | ||
synopsis: | ||
A library for stateful property-based testing | ||
A library for stateful property-based testing | ||
homepage: | ||
https://github.com/input-output-hk/quickcheck-dynamic#readme | ||
|
||
|
@@ -23,7 +23,7 @@ description: | |
build-type: Simple | ||
extra-doc-files: README.md | ||
extra-source-files: CHANGELOG.md | ||
|
||
source-repository head | ||
type: git | ||
location: https://github.com/input-output-hk/quickcheck-dynamic | ||
|
@@ -58,6 +58,7 @@ library | |
Test.QuickCheck.DynamicLogic.SmartShrinking | ||
Test.QuickCheck.DynamicLogic.Utils | ||
Test.QuickCheck.StateModel | ||
Test.QuickCheck.StateModel.Postcondition | ||
build-depends: | ||
QuickCheck -any, | ||
base >=4.7 && <5, | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
quickcheck-dynamic/src/Test/QuickCheck/StateModel/Postcondition.hs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
-- | Result of evaluation the postcondition | ||
-- | ||
-- See 'Test.QuickCheck.StateModel.postcondition'. | ||
-- | ||
-- Intended for qualified import. | ||
-- | ||
-- > import Test.QuickCheck.StateModel.Postcondition (Postcondition(..)) | ||
-- > import Test.QuickCheck.StateModel.Postcondition qualified as Post | ||
module Test.QuickCheck.StateModel.Postcondition ( | ||
Postcondition(..) | ||
-- * Primitives | ||
, assertSuccess | ||
, assertFailure | ||
, assertRelatedBy | ||
, assertBool | ||
, assertEQ | ||
, assertLE | ||
, assertLT | ||
, assertLeft | ||
, assertRight | ||
-- * Combinators | ||
, and | ||
, all | ||
, map | ||
) where | ||
|
||
import Prelude hiding (and, all, map) | ||
import Prelude qualified | ||
|
||
import Data.Bifunctor (bimap) | ||
import Data.Foldable (toList) | ||
import GHC.Show (appPrec1, showSpace) | ||
|
||
-- | Result of 'postcondition' | ||
newtype Postcondition = Postcondition { getPostcondition :: Either String () } | ||
deriving (Show) | ||
|
||
{------------------------------------------------------------------------------- | ||
Primitives | ||
-------------------------------------------------------------------------------} | ||
|
||
assertSuccess :: Postcondition | ||
assertSuccess = Postcondition $ Right () | ||
|
||
assertFailure :: String -> Postcondition | ||
assertFailure = Postcondition . Left | ||
|
||
assertBool :: String -> Bool -> Postcondition | ||
assertBool _ True = Postcondition $ Right () | ||
assertBool msg False = assertFailure msg | ||
|
||
-- | Assert that two values are related by the given relation | ||
-- | ||
-- The first argument should be a string representation representing the | ||
-- negated relation. For example: | ||
-- | ||
-- > assertEqual = assertRelatedBy "/=" (==) | ||
assertRelatedBy :: Show a => String -> (a -> a -> Bool) -> a -> a -> Postcondition | ||
assertRelatedBy op f x y = Postcondition $ | ||
if f x y | ||
then Right () | ||
else Left $ showsPrec appPrec1 x | ||
. showSpace | ||
. showString op | ||
. showSpace | ||
. showsPrec appPrec1 y | ||
$ "" | ||
|
||
assertEQ :: (Eq a, Show a) => a -> a -> Postcondition | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add infix versions of these operators. |
||
assertEQ = assertRelatedBy "/=" (==) | ||
|
||
assertLT :: (Ord a, Show a) => a -> a -> Postcondition | ||
assertLT = assertRelatedBy ">=" (<) | ||
|
||
assertLE :: (Ord a, Show a) => a -> a -> Postcondition | ||
assertLE = assertRelatedBy ">" (<=) | ||
|
||
assertLeft :: Show b => Either a b -> Postcondition | ||
assertLeft (Left _) = assertSuccess | ||
assertLeft (Right b) = assertFailure $ "Expected Left: " ++ show b | ||
|
||
assertRight :: Show a => Either a b -> Postcondition | ||
assertRight (Right _) = assertSuccess | ||
assertRight (Left a) = assertFailure $ "Expected Right: " ++ show a | ||
|
||
{------------------------------------------------------------------------------- | ||
Combinators | ||
-------------------------------------------------------------------------------} | ||
|
||
map :: (String -> String) -> Postcondition -> Postcondition | ||
map f = Postcondition . bimap f id . getPostcondition | ||
|
||
and :: Foldable t => t Postcondition -> Postcondition | ||
and = Postcondition . sequence_ . Prelude.map getPostcondition . toList | ||
|
||
all :: forall t a. (Foldable t, Show a) => (a -> Postcondition) -> t a -> Postcondition | ||
all f = and . Prelude.map aux . toList | ||
where | ||
aux :: a -> Postcondition | ||
aux a = map (\msg -> show a ++ ": " ++ msg) (f a) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ import Spec.DynamicLogic.Registry | |
import Test.QuickCheck.DynamicLogic.Core | ||
import Test.QuickCheck.StateModel | ||
import Test.QuickCheck.StateModel.IOSim | ||
import Test.QuickCheck.StateModel.Postcondition qualified as Post | ||
|
||
data RegState = RegState | ||
{ tids :: [Var ModelThreadId] | ||
|
@@ -126,15 +127,15 @@ instance StateModel RegState where | |
precondition s (Successful act) = precondition s act | ||
precondition _ _ = True | ||
|
||
postcondition _ Init _ _ = True | ||
postcondition s (WhereIs name) env mtid = | ||
(env <$> lookup name (regs s)) == mtid | ||
postcondition _s Spawn _ _ = True | ||
postcondition s (Register name step) _ res = | ||
positive s (Register name step) == isRight res | ||
postcondition _s (Unregister _name) _ _ = True | ||
postcondition _s (KillThread _) _ _ = True | ||
postcondition _s (Successful (Register _ _)) _ res = isRight res | ||
postcondition _ Init _ _ = Post.assertSuccess | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. This is why I want infix operators... |
||
positive s (Register name step) | ||
postcondition _s (Unregister _name) _ _ = Post.assertSuccess | ||
postcondition _s (KillThread _) _ _ = Post.assertSuccess | ||
postcondition _s (Successful (Register _ _)) _ res = Post.assertRight res | ||
postcondition s (Successful act) env res = postcondition s act env res | ||
|
||
monitoring (_s, s') act _ res = | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 hasTestable
). 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.