packages feed

genvalidity-hspec-hashable (empty) → 0.0.0.0

raw patch · 8 files changed

+274/−0 lines, 8 filesdep +QuickCheckdep +basedep +doctestsetup-changed

Dependencies added: QuickCheck, base, doctest, genvalidity, genvalidity-hspec, genvalidity-hspec-hashable, genvalidity-property, hashable, hspec, hspec-core, validity

Files

+ LICENSE view
@@ -0,0 +1,21 @@+The MIT License (MIT)++Copyright (c) 2017 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.
+ README.md view
@@ -0,0 +1,1 @@+This code provides the means to test the laws of the typeclass Hashable for any instance.
+ Setup.hs view
@@ -0,0 +1,3 @@+import Distribution.Simple++main = defaultMain
+ genvalidity-hspec-hashable.cabal view
@@ -0,0 +1,64 @@+name:                genvalidity-hspec-hashable+version:             0.0.0.0+synopsis:            Standard spec's for Hashable instances+description:         Standard spec's for Hashable instances+homepage:            https://github.com/NorfairKing/validity+license:             MIT+license-file:        LICENSE+author:              Nick Van den Broeck+maintainer:          syd.kerckhove@gmail.com+copyright:           2017 Tom Sydney Kerckhove+category:            Testing+build-type:          Simple+extra-source-files:  README.md+cabal-version:       >=1.10++source-repository head+    type: git+    location: https://github.com/NorfairKing/validity++library+    exposed-modules:+        Test.Validity.Hashable+    build-depends:+        base >= 4.9 && <5,+        validity >=0.3 && <0.4,+        genvalidity-hspec >=0.3 && <0.5,+        genvalidity >=0.3 && <0.4,+        genvalidity-property >= 0.0 && < 0.1,+        hspec >=2.2 && <2.5,+        hashable >= 1.2 && < 1.3,+        QuickCheck -any+    default-language: Haskell2010+    hs-source-dirs: src++test-suite genvalidity-hspec-hashable-doctests+    type: exitcode-stdio-1.0+    main-is: DocTest.hs+    build-depends:+        base -any,+        doctest >=0.11 && <0.12,+        hashable >= 1.2 && < 1.3,+        genvalidity-hspec-hashable -any,+        QuickCheck -any+    default-language: Haskell2010+    hs-source-dirs: test+    ghc-options: -threaded++test-suite genvalidity-hspec-hashable-test+    type: exitcode-stdio-1.0+    main-is: Spec.hs+    build-depends:+        base -any,+        genvalidity >=0.3 && <0.4,+        genvalidity-hspec -any,+        genvalidity-hspec-hashable -any,+        hashable >= 1.2 && < 1.3,+        hspec,+        hspec-core,+        QuickCheck+    default-language: Haskell2010+    hs-source-dirs: test/+    other-modules:+        Test.Validity.HashableSpec+    ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
+ src/Test/Validity/Hashable.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE AllowAmbiguousTypes #-}++-- | Hashable properties+--+-- You will need @TypeApplications@ to use these.+module Test.Validity.Hashable+    ( hashableSpecOnValid+    , hashableSpecOnInvalid+    , hashableSpec+    , hashableSpecOnArbitrary+    , hashableSpecOnGen+    ) where++import Data.Data+import Data.Hashable+import Control.Monad+import Test.Validity.Utils++import Data.GenValidity++import Test.Hspec+import Test.QuickCheck++-- | 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"++-- | 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"++-- | 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"++-- | 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"++-- | 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 -> Spec+hashableSpecOnGen gen genname = checkGen gen2 genname+                                    where gen2 = (,) <$> 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 -> Spec+checkGen gen genname = parallel $ do+        let name = nameOf @a+            hashablestr = (unwords+                            ["hashWithSalt :: Int ->"+                            , name+                            , "-> Int"])+        describe ("Hashable " ++ name) $ do+            describe hashablestr $ do+                it+                    (unwords+                         [ "satisfies (a == b) => (hashWithSalt n a) =="+                         ,"(hashWithSalt n b), for every n and for"+                         , genname+                         , name+                         ]) $+                    forAll gen $ \(a1, a2) ->+                        forAll arbitrary $ \int ->+                            when (a1 == a2) $+                                let hash = hashWithSalt int+                                in hash a1 `shouldBe` hash a2++++
+ test/DocTest.hs view
@@ -0,0 +1,4 @@+import Test.DocTest++main :: IO ()+main = doctest ["-isrc", "src", "-XTypeApplications"]
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ test/Test/Validity/HashableSpec.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE DeriveGeneric #-}++-- | Standard 'Spec's for 'Hashable' instances.+--+-- You will need @TypeApplications@ to use these.+module Test.Validity.HashableSpec where++import Test.Hspec+import Data.Hashable+import Test.Validity.Utils+import GHC.Generics++import Data.GenValidity+import Test.Validity.Hashable++spec :: Spec+spec = do+    hashableSpecOnValid @Double+    hashableSpec @Int+    hashableSpecOnArbitrary @Int+    hashableSpec @HashableValid+    failsBecause ("Two equal elements aren't hashed to the same value!") $+        hashableSpec @HashableInvalid++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++