packages feed

genvalidity-sydtest-hashable (empty) → 0.0.0.0

raw patch · 5 files changed

+265/−0 lines, 5 filesdep +QuickCheckdep +basedep +genvalidity

Dependencies added: QuickCheck, base, genvalidity, genvalidity-sydtest, genvalidity-sydtest-hashable, hashable, sydtest, validity

Files

+ LICENSE view
@@ -0,0 +1,21 @@+The MIT License (MIT)++Copyright (c) 2020 Tom Sydney Kerckhove++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ genvalidity-sydtest-hashable.cabal view
@@ -0,0 +1,62 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.34.4.+--+-- see: https://github.com/sol/hpack++name:           genvalidity-sydtest-hashable+version:        0.0.0.0+synopsis:       Standard spec's for Hashable instances for sydtest+description:    Standard spec's for Hashable instances for sydtest+category:       Testing+homepage:       https://github.com/NorfairKing/validity#readme+bug-reports:    https://github.com/NorfairKing/validity/issues+author:         Tom Sydney Kerckhove+maintainer:     syd@cs-syd.eu+copyright:      2020 Tom Sydney Kerckhove+license:        MIT+license-file:   LICENSE+build-type:     Simple++source-repository head+  type: git+  location: https://github.com/NorfairKing/validity++library+  exposed-modules:+      Test.Syd.Validity.Hashable+  other-modules:+      Paths_genvalidity_sydtest_hashable+  hs-source-dirs:+      src+  build-depends:+      QuickCheck+    , base >=4.9 && <5+    , genvalidity >=0.5+    , genvalidity-sydtest+    , hashable >=1.2+    , sydtest+    , validity >=0.5+  default-language: Haskell2010++test-suite genvalidity-sydtest-hashable-test+  type: exitcode-stdio-1.0+  main-is: Spec.hs+  other-modules:+      Test.Syd.Validity.HashableSpec+      Paths_genvalidity_sydtest_hashable+  hs-source-dirs:+      test/+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall+  build-tool-depends:+      sydtest-discover:sydtest-discover+  build-depends:+      QuickCheck+    , base >=4.9 && <5+    , genvalidity >=0.7+    , genvalidity-sydtest+    , genvalidity-sydtest-hashable+    , hashable+    , sydtest+    , validity >=0.9+  default-language: Haskell2010
+ src/Test/Syd/Validity/Hashable.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}++-- | Hashable properties+--+-- You will need @TypeApplications@ to use these.+module Test.Syd.Validity.Hashable+  ( hashableSpecOnValid,+    hashableSpecOnInvalid,+    hashableSpec,+    hashableSpecOnArbitrary,+    hashableSpecOnGen,+  )+where++import Control.Monad+import Data.Data+import Data.GenValidity+import Data.Hashable+import Test.QuickCheck+import Test.Syd+import Test.Syd.Validity.Property.Utils+import Test.Syd.Validity.Utils++-- | Standard test spec for properties of Hashable instances for valid values+--+-- Example usage:+--+-- > hashableSpecOnValid @Double+hashableSpecOnValid ::+  forall a.+  (Show a, Eq a, Typeable a, GenValid a, Hashable a) =>+  Spec+hashableSpecOnValid = hashableSpecOnGen @a genValid "valid" shrinkValid++-- | Standard test spec for properties of Hashable instances for invalid values+--+-- Example usage:+--+-- > hashableSpecOnInvalid @Double+hashableSpecOnInvalid ::+  forall a.+  (Show a, Eq a, Typeable a, GenInvalid a, Hashable a) =>+  Spec+hashableSpecOnInvalid = hashableSpecOnGen @a genInvalid "invalid" shrinkInvalid++-- | Standard test spec for properties of Hashable instances for unchecked values+--+-- Example usage:+--+-- > hashableSpec @Int+hashableSpec ::+  forall a.+  (Show a, Eq a, Typeable a, GenUnchecked a, Hashable a) =>+  Spec+hashableSpec = hashableSpecOnGen @a genUnchecked "unchecked" shrinkUnchecked++-- | Standard test spec for properties of Hashable instances for arbitrary values+--+-- Example usage:+--+-- > hashableSpecOnArbitrary @Int+hashableSpecOnArbitrary ::+  forall a.+  (Show a, Eq a, Typeable a, Arbitrary a, Hashable a) =>+  Spec+hashableSpecOnArbitrary = hashableSpecOnGen @a arbitrary "arbitrary" shrink++-- | Standard test spec for properties of Hashable instances for values generated by a given generator (and name for that generator).+--+-- Example usage:+--+-- > hashableSpecOnGen ((* 2) <$> genValid @Int) "even"+hashableSpecOnGen ::+  forall a.+  (Show a, Eq a, Typeable a, Hashable a) =>+  Gen a ->+  String ->+  (a -> [a]) ->+  Spec+hashableSpecOnGen gen = checkGen $ (,) <$> gen <*> gen++-- | Test spec like hashableSpecOnGen but with a special generator+-- | which is documented to generate equal values by (==) most of the time.+checkGen ::+  forall a.+  (Show a, Eq a, Typeable a, Hashable a) =>+  Gen (a, a) ->+  String ->+  (a -> [a]) ->+  Spec+checkGen gen genname s =+  parallel $ do+    let name = nameOf @a+        hashablestr = unwords ["hashWithSalt :: Int ->", name, "-> Int"]+    describe ("Hashable " ++ name) $+      describe hashablestr $+        it+          ( unwords+              [ "satisfies (a == b) => (hashWithSalt n a) ==",+                "(hashWithSalt n b), for every n and for",+                genname,+                name+              ]+          )+          $ let ss (a, b) = (,) <$> s a <*> s b+             in forAllShrink gen ss $ \(a1, a2) ->+                  forAllValid $ \int ->+                    when (a1 == a2) $+                      let h = hashWithSalt int+                       in h a1 `shouldBe` h a2
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF sydtest-discover #-}
+ test/Test/Syd/Validity/HashableSpec.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE TypeApplications #-}++module Test.Syd.Validity.HashableSpec where++import Data.GenValidity+import Data.Hashable+import GHC.Generics+import Test.Syd+import Test.Syd.Validity.Hashable++spec :: Spec+spec = do+  hashableSpecOnValid @Rational+#if MIN_VERSION_hashable(1,3,0)+  hashableSpecOnValid @Double+#endif+  hashableSpec @Int+  hashableSpecOnArbitrary @Int+  hashableSpec @HashableValid++newtype HashableValid+  = HashableValid Int+  deriving (Show, Generic)++hT :: Int -- Number used in the definition of HashableValid+hT = 7++instance Eq HashableValid where+  (==) (HashableValid x) (HashableValid y) = (x `mod` hT) == (y `mod` hT)++instance Hashable HashableValid where+  hashWithSalt n (HashableValid a) = (int ^ expo) `mod` hT+    where+      int = 1 + (a `mod` hT)+      expo = 1 + (n `mod` hT)++instance Validity HashableValid++instance GenValid HashableValid++instance GenUnchecked HashableValid++newtype HashableInvalid+  = HashableInvalid Int+  deriving (Show, Generic)++hF :: Int -- Numbers used in the definition of HashableInvalid+hF = 8++hM :: Int+hM = 3++instance Eq HashableInvalid where+  (==) (HashableInvalid x) (HashableInvalid y) = (x `mod` hF) == (y `mod` hF)++instance Hashable HashableInvalid where+  hashWithSalt n (HashableInvalid a) = (int ^ expo) `mod` hM+    where+      int = 1 + (a `mod` hM)+      expo = 1 + (n `mod` hM)++instance Validity HashableInvalid++instance GenValid HashableInvalid++instance GenUnchecked HashableInvalid