serokell-util 0.1.3.2 → 0.1.3.3
raw patch · 5 files changed
+120/−2 lines, 5 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Serokell.Arbitrary: instance Test.QuickCheck.Arbitrary.Arbitrary Serokell.Util.Verify.VerificationRes
+ Serokell.Util.Lens: packM :: WrappedM m => m a -> UnwrappedM m a
+ Serokell.Util.Lens: unpackM :: WrappedM m => UnwrappedM m a -> m a
+ Serokell.Util.Verify: instance GHC.Classes.Eq Serokell.Util.Verify.VerificationRes
- Serokell.Util.Lens: class Monad m => WrappedM m where type UnwrappedM m :: * -> * where {
+ Serokell.Util.Lens: class Monad m => WrappedM m where type UnwrappedM m :: * -> * _WrappedM = iso packM unpackM packM = view _WrappedM unpackM = view _UnwrappedM where {
Files
- serokell-util.cabal +2/−1
- src/Serokell/Arbitrary.hs +15/−0
- src/Serokell/Util/Lens.hs +8/−0
- src/Serokell/Util/Verify.hs +1/−1
- test/Test/Serokell/Util/VerifySpec.hs +94/−0
serokell-util.cabal view
@@ -1,5 +1,5 @@ name: serokell-util-version: 0.1.3.2+version: 0.1.3.3 synopsis: General-purpose functions by Serokell homepage: https://github.com/serokell/serokell-util license: MIT@@ -109,6 +109,7 @@ Test.Serokell.Util.CommonSpec Test.Serokell.Util.ByteStringSpec Test.Serokell.Util.TextSpec+ Test.Serokell.Util.VerifySpec Spec type: exitcode-stdio-1.0 build-depends: aeson >= 0.11.0.0 && < 1.0.0.0
src/Serokell/Arbitrary.hs view
@@ -19,7 +19,12 @@ import Serokell.Data.Variant.Variant (Variant (..)) import qualified Serokell.Util.Base64 as S+import qualified Serokell.Util.Verify as V +------------------------------------------------------------------------------------------+-- Serokell.Data.Variant+------------------------------------------------------------------------------------------+ instance Arbitrary S.JsonByteString where arbitrary = S.JsonByteString <$> (arbitrary :: Gen BS.ByteString) @@ -89,3 +94,13 @@ -- Lengths of keys and vals may not match and so we would get less -- constructors due to truncation, but we don't care. return $ VarMap $ H.fromList $ zip keys vals++------------------------------------------------------------------------------------------+-- Serokell.Util.Verify+------------------------------------------------------------------------------------------++instance Arbitrary V.VerificationRes where+ arbitrary = oneof $+ [ pure V.VerSuccess+ , V.VerFailure <$> arbitrary+ ]
src/Serokell/Util/Lens.hs view
@@ -34,7 +34,15 @@ -- | Similar to `Wrapped`, but for `Monad`s. class Monad m => WrappedM m where type UnwrappedM m :: * -> *+ _WrappedM :: L.Iso' (m a) (UnwrappedM m a)+ _WrappedM = L.iso packM unpackM++ packM :: m a -> UnwrappedM m a+ packM = L.view _WrappedM++ unpackM :: UnwrappedM m a -> m a+ unpackM = L.view _UnwrappedM _UnwrappedM :: WrappedM m => L.Iso' (UnwrappedM m a) (m a) _UnwrappedM = L.from _WrappedM
src/Serokell/Util/Verify.hs view
@@ -35,7 +35,7 @@ data VerificationRes = VerSuccess | VerFailure ![T.Text]- deriving (Show)+ deriving (Eq, Show) isVerSuccess :: VerificationRes -> Bool isVerSuccess VerSuccess = True
+ test/Test/Serokell/Util/VerifySpec.hs view
@@ -0,0 +1,94 @@+module Test.Serokell.Util.VerifySpec+ ( spec+ ) where++import Test.Hspec (Expectation, Spec, describe, it, shouldBe)+import Test.Hspec.QuickCheck (prop)+import Test.QuickCheck (Property, (===), (==>))+import Test.QuickCheck.Instances ()++import Data.Semigroup ((<>))+import qualified Data.Text as T (Text)++import Serokell.Arbitrary ()+import qualified Serokell.Util.Verify as V++spec :: Spec+spec =+ describe "Verify" $ do+ describe "isVerSuccess" $+ prop description_isVerSuccess isVerSuccessWorks+ describe "isVerSuccess" $+ prop description_isVerFailure isVerFailureWorks+ describe "Monoid VerificationRes" $+ prop description_verificationResIsMonoid verificationResIsMonoid+ describe "verifyGeneric" $ do+ it "verifyGeneric of an empty string always succeeds"+ (V.verifyGeneric [] `shouldBe` V.VerSuccess)+ prop description_verifyGeneric verifyGenericWorks+ prop description_verifyGenericMessageOrder verifyGenericMessageOrder+ where+ description_isVerSuccess =+ "A successful verification should yield True, and an unsuccessful one should\+ \ yield False"+ description_isVerFailure =+ "An unsuccessful verification should yield True, and an unsuccessful one should\+ \ yield False"+ description_verificationResIsMonoid =+ "The set of verification results with the concatenation operation defined in the\+ \ Serokell.Util.Verify module forms a monoid"+ description_verifyGeneric =+ "A list of predicates with a single failure yields a failed verification, and a\+ \ list of predicates with no failures yields a successful verification"+ description_verifyGenericMessageOrder =+ "Error messages in a predicate list are taken from left to right"++isVerSuccessWorks :: V.VerificationRes -> Expectation+isVerSuccessWorks v = case v of+ V.VerSuccess -> V.isVerSuccess v `shouldBe` True+ V.VerFailure _ -> V.isVerSuccess v `shouldBe` False++-- | The property+-- `isVerFailure = not . isVerSuccess`+-- should hold for all v in VerificationRes+isVerFailureWorks :: V.VerificationRes -> Property+isVerFailureWorks v = (not . V.isVerSuccess $ v) === V.isVerFailure v++verificationResIsMonoid+ :: V.VerificationRes+ -> V.VerificationRes+ -> V.VerificationRes+ -> Bool+verificationResIsMonoid v1 v2 v3 =+ let isAssociative =+ let assoc1 = (v1 <> v2) <> v3+ assoc2 = v1 <> (v2 <> v3)+ in assoc1 == assoc2+ hasIdentity =+ let id1 = mempty <> v1+ id2 = v1 <> mempty+ in (v1 == id1) && (v1 == id2)+ in isAssociative && hasIdentity++-- | The function `verifyGeneric` must have the following properties+-- (any (not . fst) l :: [(Bool, a)]) iff (isVerFailure . verifyGeneric) l+-- (all (identity . fst) l :: [(Bool, a)]) iff (isVerSuccess . verifyGeneric) l++verifyGenericWorks :: [(Bool, T.Text)] -> Bool+verifyGenericWorks l =+ let someFailure = any (not . fst) l+ allSuccess = not someFailure+ in (someFailure == (V.isVerFailure . V.verifyGeneric $ l)) &&+ (allSuccess == (V.isVerSuccess . V.verifyGeneric $ l))++-- | This property checks that the error messages in a list of predicates are collected+-- from left to right.++verifyGenericMessageOrder :: [(Bool, T.Text)] -> Property+verifyGenericMessageOrder l =+ let someFailure = any (not . fst) l+ msgList = foldr (\(b, err) accList ->+ if not b then err : accList+ else accList) [] l+ in someFailure ==>+ ((V.VerFailure msgList) == V.verifyGeneric l)