{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Test.VMap where

import qualified Data.List as List
import qualified Data.Map.Strict as Map
import Data.VMap as VMap
import Test.Common

type MapT = Map.Map Char Int

type VMapT = VMap VB VP Char Int

instance
  (Ord k, Vector kv k, Vector vv v, Arbitrary k, Arbitrary v) =>
  Arbitrary (VMap kv vv k v)
  where
  arbitrary :: Gen (VMap kv vv k v)
arbitrary =
    forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
Map k v -> VMap kv vv k v
VMap.fromMap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary

prop_Roundtrip :: (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip :: forall a. (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip VMapT -> a
to a -> VMapT
from VMapT
km = a -> VMapT
from (VMapT -> a
to VMapT
km) forall a. (Eq a, Show a) => a -> a -> Property
=== VMapT
km

prop_AsMapTo ::
  (Show a, Eq a) => (VMapT -> a) -> (MapT -> a) -> VMapT -> Property
prop_AsMapTo :: forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (MapT -> a) -> VMapT -> Property
prop_AsMapTo VMapT -> a
fromVM MapT -> a
fromM VMapT
vm = VMapT -> a
fromVM VMapT
vm forall a. (Eq a, Show a) => a -> a -> Property
=== MapT -> a
fromM (forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> Map k v
toMap VMapT
vm)

prop_AsMapFrom :: (a -> VMapT) -> (a -> MapT) -> a -> Property
prop_AsMapFrom :: forall a. (a -> VMapT) -> (a -> MapT) -> a -> Property
prop_AsMapFrom a -> VMapT
mkVMap a -> MapT
mkMap a
a = forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> Map k v
toMap (a -> VMapT
mkVMap a
a) forall a. (Eq a, Show a) => a -> a -> Property
=== a -> MapT
mkMap a
a

vMapTests :: TestTree
vMapTests :: TestTree
vMapTests =
  String -> [TestTree] -> TestTree
testGroup
    String
"VMap"
    [ String -> [TestTree] -> TestTree
testGroup
        String
"roundtrip"
        [ forall a. Testable a => String -> a -> TestTree
testProperty String
"to/fromAscDistinctList" forall a b. (a -> b) -> a -> b
$
            forall a. (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> [(k, v)]
VMap.toAscList forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromDistinctAscList
        , forall a. Testable a => String -> a -> TestTree
testProperty String
"to/fromAscList" forall a b. (a -> b) -> a -> b
$ forall a. (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> [(k, v)]
VMap.toAscList forall k (kv :: * -> *) (vv :: * -> *) v.
(Eq k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromAscList
        , forall a. Testable a => String -> a -> TestTree
testProperty String
"to/fromList" forall a b. (a -> b) -> a -> b
$ forall a. (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> [(k, v)]
VMap.toAscList forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList
        , forall a. Testable a => String -> a -> TestTree
testProperty String
"to/fromMap" forall a b. (a -> b) -> a -> b
$ forall a. (VMapT -> a) -> (a -> VMapT) -> VMapT -> Property
prop_Roundtrip forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> Map k v
VMap.toMap forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
Map k v -> VMap kv vv k v
VMap.fromMap
        ]
    , String -> [TestTree] -> TestTree
testGroup
        String
"asMap"
        [ forall a. Testable a => String -> a -> TestTree
testProperty String
"fromList" forall a b. (a -> b) -> a -> b
$ forall a. (a -> VMapT) -> (a -> MapT) -> a -> Property
prop_AsMapFrom forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
        , forall a. Testable a => String -> a -> TestTree
testProperty String
"fromAscListWithKey" forall a b. (a -> b) -> a -> b
$ \[(Char, Int)]
xs Fun (Char, Int, Int) Int
f ->
            forall a. (a -> VMapT) -> (a -> MapT) -> a -> Property
prop_AsMapFrom
              (forall k (kv :: * -> *) (vv :: * -> *) v.
(Eq k, Vector kv k, Vector vv v) =>
(k -> v -> v -> v) -> [(k, v)] -> VMap kv vv k v
VMap.fromAscListWithKey (forall a b c d. Fun (a, b, c) d -> a -> b -> c -> d
applyFun3 Fun (Char, Int, Int) Int
f))
              (forall k a. Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a
Map.fromAscListWithKey (forall a b c d. Fun (a, b, c) d -> a -> b -> c -> d
applyFun3 Fun (Char, Int, Int) Int
f))
              (forall b a. Ord b => (a -> b) -> [a] -> [a]
List.sortOn forall a b. (a, b) -> a
fst [(Char, Int)]
xs)
        , forall a. Testable a => String -> a -> TestTree
testProperty String
"fromAscListWithKeyN" forall a b. (a -> b) -> a -> b
$ \Int
n [(Char, Int)]
xs Fun (Char, Int, Int) Int
f ->
            forall a. (a -> VMapT) -> (a -> MapT) -> a -> Property
prop_AsMapFrom
              (forall k (kv :: * -> *) (vv :: * -> *) v.
(Eq k, Vector kv k, Vector vv v) =>
Int -> (k -> v -> v -> v) -> [(k, v)] -> VMap kv vv k v
VMap.fromAscListWithKeyN Int
n (forall a b c d. Fun (a, b, c) d -> a -> b -> c -> d
applyFun3 Fun (Char, Int, Int) Int
f))
              (forall k a. Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a
Map.fromAscListWithKey (forall a b c d. Fun (a, b, c) d -> a -> b -> c -> d
applyFun3 Fun (Char, Int, Int) Int
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> [a] -> [a]
take Int
n)
              (forall b a. Ord b => (a -> b) -> [a] -> [a]
List.sortOn forall a b. (a, b) -> a
fst [(Char, Int)]
xs)
        , forall a. Testable a => String -> a -> TestTree
testProperty String
"toAscList" forall a b. (a -> b) -> a -> b
$ forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (MapT -> a) -> VMapT -> Property
prop_AsMapTo forall (kv :: * -> *) k (vv :: * -> *) v.
(Vector kv k, Vector vv v) =>
VMap kv vv k v -> [(k, v)]
VMap.toAscList forall k a. Map k a -> [(k, a)]
Map.toAscList
        , forall a. Testable a => String -> a -> TestTree
testProperty String
"foldMapWithKey" forall a b. (a -> b) -> a -> b
$ \Fun (Char, Int) String
f ->
            let f' :: Char -> Int -> String
f' Char
k Int
v = forall a b c. Fun (a, b) c -> a -> b -> c
applyFun2 Fun (Char, Int) String
f Char
k Int
v :: String
             in forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (MapT -> a) -> VMapT -> Property
prop_AsMapTo (forall (kv :: * -> *) k (vv :: * -> *) v m.
(Vector kv k, Vector vv v, Monoid m) =>
(k -> v -> m) -> VMap kv vv k v -> m
VMap.foldMapWithKey Char -> Int -> String
f') (forall m k a. Monoid m => (k -> a -> m) -> Map k a -> m
Map.foldMapWithKey Char -> Int -> String
f')
        , forall a. Testable a => String -> a -> TestTree
testProperty String
"lookup" forall a b. (a -> b) -> a -> b
$ \Char
k -> forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (MapT -> a) -> VMapT -> Property
prop_AsMapTo (forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
k -> VMap kv vv k v -> Maybe v
VMap.lookup Char
k) (forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Char
k)
        , forall a. Testable a => String -> a -> TestTree
testProperty String
"lookup (existing)" forall a b. (a -> b) -> a -> b
$ \Char
k Int
v [(Char, Int)]
xs ->
            let xs' :: [(Char, Int)]
xs' = [(Char, Int)]
xs forall a. Semigroup a => a -> a -> a
<> [(Char
k, Int
v)]
             in (forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
k -> VMap kv vv k v -> Maybe v
VMap.lookup Char
k (forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList [(Char, Int)]
xs' :: VMapT) forall a. (Eq a, Show a) => a -> a -> Property
=== forall a. a -> Maybe a
Just Int
v)
                  forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
.&&. (forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Char
k (forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Char, Int)]
xs' :: MapT) forall a. (Eq a, Show a) => a -> a -> Property
=== forall a. a -> Maybe a
Just Int
v)
        , forall a. Testable a => String -> a -> TestTree
testProperty String
"finsWithDefault" forall a b. (a -> b) -> a -> b
$ \Int
d Char
k ->
            forall a.
(Show a, Eq a) =>
(VMapT -> a) -> (MapT -> a) -> VMapT -> Property
prop_AsMapTo (forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
v -> k -> VMap kv vv k v -> v
VMap.findWithDefault Int
d Char
k) (forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault Int
d Char
k)
        , forall a. Testable a => String -> a -> TestTree
testProperty String
"finsWithDefault (existing)" forall a b. (a -> b) -> a -> b
$ \Char
k Int
v [(Char, Int)]
xs ->
            let xs' :: [(Char, Int)]
xs' = [(Char, Int)]
xs forall a. Semigroup a => a -> a -> a
<> [(Char
k, Int
v)]
             in (forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
v -> k -> VMap kv vv k v -> v
VMap.findWithDefault forall a. HasCallStack => a
undefined Char
k (forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
[(k, v)] -> VMap kv vv k v
VMap.fromList [(Char, Int)]
xs' :: VMapT) forall a. (Eq a, Show a) => a -> a -> Property
=== Int
v)
                  forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
.&&. (forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault forall a. HasCallStack => a
undefined Char
k (forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Char, Int)]
xs' :: MapT) forall a. (Eq a, Show a) => a -> a -> Property
=== Int
v)
        ]
    , String -> [Laws] -> TestTree
testLawsGroup
        String
"classes"
        [ forall a. (Eq a, Arbitrary a, Show a) => Proxy a -> Laws
eqLaws (forall {k} (t :: k). Proxy t
Proxy @VMapT)
        , forall a.
(Semigroup a, Eq a, Arbitrary a, Show a) =>
Proxy a -> Laws
semigroupLaws (forall {k} (t :: k). Proxy t
Proxy @VMapT)
        , forall a. (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
monoidLaws (forall {k} (t :: k). Proxy t
Proxy @VMapT)
        , forall a.
(IsList a, Show a, Show (Item a), Arbitrary a, Arbitrary (Item a),
 Eq a) =>
Proxy a -> Laws
isListLaws (forall {k} (t :: k). Proxy t
Proxy @VMapT)
        ]
    ]