-
-
Notifications
You must be signed in to change notification settings - Fork 81
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
Add property tests for the Validation type #216
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,170 @@ | ||||||
{- | ||||||
Copyright: (c) 2016 Stephen Diehl | ||||||
(c) 2016-2018 Serokell | ||||||
(c) 2018-2019 Kowainik | ||||||
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. I believe there's no need to specify everyone here, since it's a brand new module. So this can be just: Copyright: (c) 2019 Kowainik |
||||||
SPDX-License-Identifier: MIT | ||||||
Maintainer: Kowainik <xrom.xkov@gmail.com> | ||||||
-} | ||||||
|
||||||
module Test.Relude.Extra.Validation.Property | ||||||
( validationTestList | ||||||
) where | ||||||
|
||||||
import Relude | ||||||
import Relude.Extra.Validation | ||||||
|
||||||
import Hedgehog (Gen, Group (..), Property, forAll, forAllWith, property, (===)) | ||||||
|
||||||
import qualified Hedgehog.Gen as Gen | ||||||
import qualified Hedgehog.Range as Range | ||||||
|
||||||
validationTestList :: [Group] | ||||||
validationTestList = | ||||||
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. Let's rename |
||||||
[ validationSemigroupProps | ||||||
, validationMonoidProps | ||||||
, validationApplicativeProps | ||||||
, validationAlternativeProps | ||||||
] | ||||||
|
||||||
---------------------------------------------------------------------------- | ||||||
-- Generators | ||||||
---------------------------------------------------------------------------- | ||||||
|
||||||
genFunction :: Gen (Int -> Int) | ||||||
genFunction = Gen.element [(+), (*), const] <*> genSmallInt | ||||||
|
||||||
genSmallInt :: Gen Int | ||||||
genSmallInt = Gen.int (Range.linear (-10) 10) | ||||||
|
||||||
genSmallText :: Gen Text | ||||||
genSmallText = Gen.text (Range.linear 3 10) Gen.unicode | ||||||
|
||||||
asValidation :: Gen a -> Gen (Validation [Text] a) | ||||||
asValidation gen = Gen.choice | ||||||
[ Success <$> gen | ||||||
, Failure <$> Gen.list (Range.linear 1 5) genSmallText | ||||||
] | ||||||
|
||||||
---------------------------------------------------------------------------- | ||||||
-- Property helpers | ||||||
---------------------------------------------------------------------------- | ||||||
|
||||||
checkAssotiativityFor | ||||||
:: (Show a, Eq a) => Gen a -> (a -> a -> a) -> Property | ||||||
checkAssotiativityFor gen op = property $ do | ||||||
a <- forAll gen | ||||||
b <- forAll gen | ||||||
c <- forAll gen | ||||||
a `op` (b `op` c) === (a `op` b) `op` c | ||||||
|
||||||
---------------------------------------------------------------------------- | ||||||
-- Semogroup instance properties | ||||||
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. Minor typo 🙂
Suggested change
|
||||||
---------------------------------------------------------------------------- | ||||||
|
||||||
validationSemigroupProps :: Group | ||||||
validationSemigroupProps = | ||||||
Group "Semigroup instance for Validation property tests" | ||||||
[ ("associativity:", prop_semigroupAssociativity) | ||||||
] | ||||||
|
||||||
prop_semigroupAssociativity :: Property | ||||||
prop_semigroupAssociativity = | ||||||
checkAssotiativityFor (asValidation genSmallText) (<>) | ||||||
|
||||||
---------------------------------------------------------------------------- | ||||||
-- Monoid instance properties | ||||||
---------------------------------------------------------------------------- | ||||||
|
||||||
validationMonoidProps :: Group | ||||||
validationMonoidProps = | ||||||
Group "Monoid instance for Validation property tests" | ||||||
[ ("right identity:", prop_monoidRightIdentity) | ||||||
, ("left identity:", prop_monoidLeftIdentity) | ||||||
] | ||||||
|
||||||
prop_monoidRightIdentity :: Property | ||||||
prop_monoidRightIdentity = property $ do | ||||||
x <- forAll $ asValidation genSmallText | ||||||
x <> mempty === x | ||||||
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. Warning: Monoid law, right identity
Suggested change
|
||||||
|
||||||
prop_monoidLeftIdentity :: Property | ||||||
prop_monoidLeftIdentity = property $ do | ||||||
x <- forAll $ asValidation genSmallText | ||||||
mempty <> x === x | ||||||
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. Warning: Monoid law, left identity
Suggested change
|
||||||
|
||||||
---------------------------------------------------------------------------- | ||||||
-- Applicative instance properties | ||||||
---------------------------------------------------------------------------- | ||||||
|
||||||
validationApplicativeProps :: Group | ||||||
validationApplicativeProps = | ||||||
Group "Applicative instance for Validation property tests" | ||||||
[ ("identity:", prop_applicativeIdentity) | ||||||
, ("composition:", prop_applicativeComposition) | ||||||
, ("homomorphism:", prop_applicativeHomomorphism) | ||||||
, ("interchange:", prop_applicativeInterchange) | ||||||
, ("u *> v == (id <$ u) <*> v", prop_applicativeApplyRight) | ||||||
, ("u <* v == liftA2 const u v", prop_applicativeApplyLeft) | ||||||
] | ||||||
|
||||||
prop_applicativeIdentity :: Property | ||||||
prop_applicativeIdentity = property $ do | ||||||
vx <- forAll $ asValidation genSmallText | ||||||
(pure id <*> vx) === vx | ||||||
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. Suggestion: Use <$>
Suggested change
|
||||||
|
||||||
prop_applicativeComposition :: Property | ||||||
prop_applicativeComposition = property $ do | ||||||
vf <- forAllWith (const "f") $ asValidation genFunction | ||||||
vg <- forAllWith (const "g") $ asValidation genFunction | ||||||
vx <- forAll $ asValidation genSmallInt | ||||||
(pure (.) <*> vf <*> vg <*> vx) === (vf <*> (vg <*> vx)) | ||||||
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. Suggestion: Use <$>
Suggested change
|
||||||
|
||||||
prop_applicativeHomomorphism :: Property | ||||||
prop_applicativeHomomorphism = property $ do | ||||||
f <- forAllWith (const "f") genFunction | ||||||
x <- forAll genSmallInt | ||||||
(pure f <*> (pure x :: Validation [Text] Int)) === pure (f x) | ||||||
chshersh marked this conversation as resolved.
Show resolved
Hide resolved
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. I think this can be written a bit cleaner with type applications
Suggested change
|
||||||
|
||||||
prop_applicativeInterchange :: Property | ||||||
prop_applicativeInterchange = property $ do | ||||||
vf <- forAllWith (const "f") $ asValidation genFunction | ||||||
x <- forAll genSmallInt | ||||||
(vf <*> pure x) === (pure ($ x) <*> vf) | ||||||
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. Suggestion: Use <$>
Suggested change
|
||||||
|
||||||
prop_applicativeApplyRight :: Property | ||||||
prop_applicativeApplyRight = property $ do | ||||||
vy <- forAll $ asValidation genSmallInt | ||||||
vx <- forAll $ asValidation genSmallInt | ||||||
(vy *> vx) === ((id <$ vy) <*> vx) | ||||||
|
||||||
prop_applicativeApplyLeft :: Property | ||||||
prop_applicativeApplyLeft = property $ do | ||||||
vy <- forAll $ asValidation genSmallInt | ||||||
vx <- forAll $ asValidation genSmallInt | ||||||
(vy <* vx) === liftA2 const vy vx | ||||||
|
||||||
---------------------------------------------------------------------------- | ||||||
-- Alternative instance properties | ||||||
---------------------------------------------------------------------------- | ||||||
|
||||||
validationAlternativeProps :: Group | ||||||
validationAlternativeProps = | ||||||
Group "Alternative instance for Validation property tests" | ||||||
[ ("associativity:", prop_alternativeAssociativity) | ||||||
, ("right identity:", prop_alternativeRightIdentity) | ||||||
, ("left identity:", prop_alternativeLeftIdentity) | ||||||
] | ||||||
|
||||||
prop_alternativeAssociativity :: Property | ||||||
prop_alternativeAssociativity = | ||||||
checkAssotiativityFor (asValidation genSmallText) (<|>) | ||||||
|
||||||
prop_alternativeRightIdentity :: Property | ||||||
prop_alternativeRightIdentity = property $ do | ||||||
x <- forAll $ asValidation genSmallText | ||||||
(x <|> empty) === x | ||||||
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. Warning: Alternative law, right identity
Suggested change
|
||||||
|
||||||
prop_alternativeLeftIdentity :: Property | ||||||
prop_alternativeLeftIdentity = property $ do | ||||||
x <- forAll $ asValidation genSmallText | ||||||
(empty <|> x) === x | ||||||
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. Warning: Alternative law, left identity
Suggested change
|
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.
Commas are redundant in module definitions