@@ -6,7 +6,9 @@
7{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}
7{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}
9−module Test.TypeRep.MapProperty where
9+module Test.TypeRep.TypeRepMapProperty
10+ ( typeRepMapPropertySpec
11import Prelude hiding (lookup)
13import Prelude hiding (lookup)
@@ -15,43 +17,50 @@ import Data.Semigroup (Semigroup (..))
15import GHC.Exts (fromList)
17import GHC.Exts (fromList)
16import GHC.Stack (HasCallStack)
18import GHC.Stack (HasCallStack)
17import GHC.TypeLits (Nat, SomeNat (..), someNatVal)
19import GHC.TypeLits (Nat, SomeNat (..), someNatVal)
18−import Hedgehog (MonadGen, PropertyT, forAll, property, (===), assert)
20+import Hedgehog (MonadGen, PropertyT, assert, forAll, property, (===))
19−import Test.Tasty (TestName, TestTree)
21+import Test.Hspec (Arg, Expectation, Spec, SpecWith, describe, it)
20−import Test.Tasty.Hedgehog (testProperty)
22+import Test.Hspec.Hedgehog (hedgehog)
22−import Data.TypeRepMap.Internal (TypeRepMap (..), WrapTypeable (..), delete, insert, lookup, member, invariantCheck)
24+import Data.TypeRepMap.Internal (TypeRepMap (..), WrapTypeable (..), delete, insert, invariantCheck,
24import qualified Hedgehog.Gen as Gen
27import qualified Hedgehog.Gen as Gen
25import qualified Hedgehog.Range as Range
28import qualified Hedgehog.Range as Range
27−----------------------------------------------------------------------------
29−----------------------------------------------------------------------------
31−type PropertyTest = [TestTree]
33−prop :: HasCallStack => TestName -> PropertyT IO () -> PropertyTest
31+typeRepMapPropertySpec :: Spec
34−prop testName = pure . testProperty testName . property
32+typeRepMapPropertySpec = describe "TypeRepMap Property tests" $ do
33+ describe "Map modification properties" $ do
39+ describe "Instance Laws" $ do
36----------------------------------------------------------------------------
43----------------------------------------------------------------------------
37-- Map modification properties
44-- Map modification properties
38----------------------------------------------------------------------------
45----------------------------------------------------------------------------
40−test_InsertLookup :: PropertyTest
47+type Property = SpecWith (Arg Expectation)
49+insertLookupSpec :: Property
41−test_InsertLookup = prop "lookup k (insert k v m) == Just v" $ do
50+insertLookupSpec = it "lookup k (insert k v m) == Just v" $ hedgehog $ do
42 m <- forAll genMap
51 m <- forAll genMap
43 WrapTypeable (proxy :: IntProxy n) <- forAll genTF
52 WrapTypeable (proxy :: IntProxy n) <- forAll genTF
44 lookup @n @IntProxy (insert proxy m) === Just proxy
53 lookup @n @IntProxy (insert proxy m) === Just proxy
46−test_InsertInsert :: PropertyTest
55+insertInsertSpec :: Property
47−test_InsertInsert = prop "insert k b . insert k a == insert k b" $ do
56+insertInsertSpec = it "insert k b . insert k a == insert k b" $ hedgehog $ do
48 m <- forAll genMap
57 m <- forAll genMap
49 WrapTypeable a@(IntProxy (proxy :: Proxy n) i) <- forAll genTF
58 WrapTypeable a@(IntProxy (proxy :: Proxy n) i) <- forAll genTF
50 let b = IntProxy proxy (i + 1)
59 let b = IntProxy proxy (i + 1)
51 lookup @n @IntProxy (insert b $ insert a m) === Just b
60 lookup @n @IntProxy (insert b $ insert a m) === Just b
53−test_DeleteMember :: PropertyTest
62+deleteMemberSpec :: Property
54−test_DeleteMember = prop "member k . delete k == False" $ do
63+deleteMemberSpec = it "member k . delete k == False" $ hedgehog $ do
55 m <- forAll genMap
64 m <- forAll genMap
56 WrapTypeable (proxy :: IntProxy n) <- forAll genTF
65 WrapTypeable (proxy :: IntProxy n) <- forAll genTF
57 shouldInsert <- forAll Gen.bool
66 shouldInsert <- forAll Gen.bool
@@ -61,14 +70,14 @@ test_DeleteMember = prop "member k . delete k == False" $ do
62 member @n (delete @n m) === False
71 member @n (delete @n m) === False
64−test_InsertInvariant :: PropertyTest
73+insertInvariantSpec :: Property
65−test_InsertInvariant = prop "invariantCheck (insert k b) == True" $ do
74+insertInvariantSpec = it "invariantCheck (insert k b) == True" $ hedgehog $ do
66 m <- forAll genMap
75 m <- forAll genMap
67 WrapTypeable a <- forAll genTF
76 WrapTypeable a <- forAll genTF
68 assert $ invariantCheck (insert a m)
77 assert $ invariantCheck (insert a m)
70−test_DeleteInvariant :: PropertyTest
79+deleteInvariantSpec :: Property
71−test_DeleteInvariant = prop "invariantCheck (delete k b) == True" $ do
80+deleteInvariantSpec = it "invariantCheck (delete k b) == True" $ hedgehog $ do
72 m <- forAll genMap
81 m <- forAll genMap
73 WrapTypeable (_ :: IntProxy n) <- forAll genTF
82 WrapTypeable (_ :: IntProxy n) <- forAll genTF
74 assert $ invariantCheck (delete @n m)
83 assert $ invariantCheck (delete @n m)
@@ -78,20 +87,21 @@ test_DeleteInvariant = prop "invariantCheck (delete k b) == True" $ do
78----------------------------------------------------------------------------
87----------------------------------------------------------------------------
80#if __GLASGOW_HASKELL__ < 806
89#if __GLASGOW_HASKELL__ < 806
81−-- This newtype is used to compare 'TypeRepMap's using only 'Fingerprint's. It's
90+{- | This newtype is used to compare 'TypeRepMap's using only 'Fingerprint's.
82−-- not a good idea to write such `Eq` instance for `TypeRepMap` itself because
91+It's not a good idea to write such 'Eq' instance for 'TypeRepMap' itself because
83−-- it doesn't compare values so it's not true equality. But this should be
92+it doesn't compare values so it's not true equality. But this should be enough
84−-- enough for tests.
93+for tests.
85newtype FpMap f = FpMap (TypeRepMap f)
95newtype FpMap f = FpMap (TypeRepMap f)
86− deriving newtype (Show, Semigroup, Monoid)
96+ deriving newtype (Show, Semigroup, Monoid)
88instance Eq (FpMap f) where
98instance Eq (FpMap f) where
89 FpMap (TypeRepMap as1 bs1 _ _) == FpMap (TypeRepMap as2 bs2 _ _) =
99 FpMap (TypeRepMap as1 bs1 _ _) == FpMap (TypeRepMap as2 bs2 _ _) =
90 as1 == as2 && bs1 == bs2
100 as1 == as2 && bs1 == bs2
93−test_SemigroupAssoc :: PropertyTest
103+semigroupAssocSpec :: Property
94−test_SemigroupAssoc = prop "x <> (y <> z) == (x <> y) <> z" $ do
104+semigroupAssocSpec = it "x <> (y <> z) == (x <> y) <> z" $ hedgehog $ do
95#if __GLASGOW_HASKELL__ >= 806
105#if __GLASGOW_HASKELL__ >= 806
96 x <- forAll genMap
106 x <- forAll genMap
97 y <- forAll genMap
107 y <- forAll genMap
@@ -101,11 +111,10 @@ test_SemigroupAssoc = prop "x <> (y <> z) == (x <> y) <> z" $ do
101 y <- FpMap <$> forAll genMap
111 y <- FpMap <$> forAll genMap
102 z <- FpMap <$> forAll genMap
112 z <- FpMap <$> forAll genMap
105 (x <> (y <> z)) === ((x <> y) <> z)
114 (x <> (y <> z)) === ((x <> y) <> z)
107−test_MonoidIdentity :: PropertyTest
116+monoidIdentitySpec :: Property
108−test_MonoidIdentity = prop "x <> mempty == mempty <> x == x" $ do
117+monoidIdentitySpec = it "x <> mempty == mempty <> x == x" $ hedgehog $ do
109#if __GLASGOW_HASKELL__ >= 806
118#if __GLASGOW_HASKELL__ >= 806
110 x <- forAll genMap
119 x <- forAll genMap