{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Test.Cardano.Data.OMap.StrictSpec where
import Data.OMap.Strict
import Data.Proxy (Proxy (Proxy))
import Data.Sequence.Strict qualified as SSeq
import Data.Set qualified as Set
import Lens.Micro hiding (set)
import Test.Cardano.Data.Arbitrary ()
import Test.Cardano.Ledger.Binary.RoundTrip (roundTripCborSpec)
import Test.Hspec
import Test.Hspec.QuickCheck
import Test.QuickCheck (Arbitrary)
import Test.QuickCheck.Arbitrary (Arbitrary (arbitrary))
import Test.QuickCheck.Classes
import Prelude hiding (elem, filter, lookup, null)
spec :: Spec
spec :: Spec
spec =
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"OMap.Strict" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"membership checks work" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> (OMap Int Int -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"unconsed" ((OMap Int Int -> IO ()) -> Spec)
-> (OMap Int Int -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\(OMap Int Int
m :: OMap Int Int) -> case OMap Int Int
m of
OMap Int Int
Empty -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Int
v :<|: OMap Int Int
_kv -> Int
v Int -> Getting Int Int Int -> Int
forall s a. s -> Getting a s a -> a
^. Getting Int Int Int
forall k v. HasOKey k v => Lens' v k
Lens' Int Int
okeyL Int -> (Int -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` (Int -> OMap Int Int -> Bool
forall k v. Ord k => k -> OMap k v -> Bool
`member` OMap Int Int
m)
String -> (OMap Int Int -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"unsnoced" ((OMap Int Int -> IO ()) -> Spec)
-> (OMap Int Int -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\(OMap Int Int
m :: OMap Int Int) -> case OMap Int Int
m of
OMap Int Int
Empty -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
OMap Int Int
_kv :|>: Int
v -> Int
v Int -> Getting Int Int Int -> Int
forall s a. s -> Getting a s a -> a
^. Getting Int Int Int
forall k v. HasOKey k v => Lens' v k
Lens' Int Int
okeyL Int -> (Int -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` (Int -> OMap Int Int -> Bool
forall k v. Ord k => k -> OMap k v -> Bool
`member` OMap Int Int
m)
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"when cons-ing" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> (OMap Int Int -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"adding a duplicate results in a no-op" ((OMap Int Int -> IO ()) -> Spec)
-> (OMap Int Int -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\(OMap Int Int
m :: OMap Int Int) -> do
case OMap Int Int
m of
OMap Int Int
Empty -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Int
v :<|: OMap Int Int
_kv -> OMap Int Int
m OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int
v Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => v -> OMap k v -> OMap k v
<| OMap Int Int
m
case OMap Int Int
m of
OMap Int Int
Empty -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
OMap Int Int
_kv :|>: Int
v -> OMap Int Int
m OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int
v Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => v -> OMap k v -> OMap k v
<| OMap Int Int
m
String -> ((OMap Int Int, Int) -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"new values get added" (((OMap Int Int, Int) -> IO ()) -> Spec)
-> ((OMap Int Int, Int) -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\((OMap Int Int
m, Int
v) :: (OMap Int Int, Int)) ->
if Int
v Int -> OMap Int Int -> Bool
forall k v. (HasOKey k v, Eq v) => v -> OMap k v -> Bool
`elem` OMap Int Int
m
then Int
v Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => v -> OMap k v -> OMap k v
<| OMap Int Int
m OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMap Int Int
m
else Int
v Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => v -> OMap k v -> OMap k v
<| OMap Int Int
m OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int
v Int -> OMap Int Int -> OMap Int Int
forall k v. (HasOKey k v, Ord k) => v -> OMap k v -> OMap k v
:<|: OMap Int Int
m
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"when snoc-ing" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> (OMap Int Int -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"adding a duplicate results in a no-op" ((OMap Int Int -> IO ()) -> Spec)
-> (OMap Int Int -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\(OMap Int Int
m :: OMap Int Int) -> do
case OMap Int Int
m of
OMap Int Int
Empty -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Int
v :<|: OMap Int Int
_kv -> OMap Int Int
m OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMap Int Int
m OMap Int Int -> Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> v -> OMap k v
|> Int
v
case OMap Int Int
m of
OMap Int Int
Empty -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
OMap Int Int
_kv :|>: Int
v -> OMap Int Int
m OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMap Int Int
m OMap Int Int -> Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> v -> OMap k v
|> Int
v
String -> ((OMap Int Int, Int) -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"new values get added" (((OMap Int Int, Int) -> IO ()) -> Spec)
-> ((OMap Int Int, Int) -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\((OMap Int Int
m, Int
v) :: (OMap Int Int, Int)) ->
if Int
v Int -> OMap Int Int -> Bool
forall k v. (HasOKey k v, Eq v) => v -> OMap k v -> Bool
`elem` OMap Int Int
m
then OMap Int Int
m OMap Int Int -> Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> v -> OMap k v
|> Int
v OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMap Int Int
m
else OMap Int Int
m OMap Int Int -> Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> v -> OMap k v
|> Int
v OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMap Int Int
m OMap Int Int -> Int -> OMap Int Int
forall k v. (HasOKey k v, Ord k) => OMap k v -> v -> OMap k v
:|>: Int
v
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"mappend preserves uniqueness" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> (OMap Int Int -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"mappending with itself should be a no-op" ((OMap Int Int -> IO ()) -> Spec)
-> (OMap Int Int -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\(OMap Int Int
i :: OMap Int Int) -> do
let il :: OMap Int Int
il = OMap Int Int
i OMap Int Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> OMap k v -> OMap k v
|>< OMap Int Int
i
ir :: OMap Int Int
ir = OMap Int Int
i OMap Int Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> OMap k v -> OMap k v
><| OMap Int Int
i
OMap Int Int
il OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMap Int Int
i
OMap Int Int
ir OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMap Int Int
i
OMap Int Int
il OMap Int Int -> (OMap Int Int -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` OMap Int Int -> Bool
forall k v. Ord k => OMap k v -> Bool
invariantHolds'
OMap Int Int
ir OMap Int Int -> (OMap Int Int -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` OMap Int Int -> Bool
forall k v. Ord k => OMap k v -> Bool
invariantHolds'
String -> ((OMap Int Int, OMap Int Int) -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"mappending with duplicates: left-preserving" (((OMap Int Int, OMap Int Int) -> IO ()) -> Spec)
-> ((OMap Int Int, OMap Int Int) -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\((OMap Int Int
i, OMap Int Int
j) :: (OMap Int Int, OMap Int Int)) ->
case OMap Int Int
j of
OMap Int Int
Empty -> OMap Int Int
i OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMap Int Int
i OMap Int Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> OMap k v -> OMap k v
|>< OMap Int Int
j
Int
j' :<|: OMap Int Int
_js -> do
let result :: OMap Int Int
result = OMap Int Int
i OMap Int Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> OMap k v -> OMap k v
|>< OMap Int Int
j
OMap Int Int
result OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` (OMap Int Int
i OMap Int Int -> Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> v -> OMap k v
|> Int
j') OMap Int Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> OMap k v -> OMap k v
|>< OMap Int Int
j
OMap Int Int
result OMap Int Int -> (OMap Int Int -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` OMap Int Int -> Bool
forall k v. Ord k => OMap k v -> Bool
invariantHolds'
String -> ((OMap Int Int, OMap Int Int) -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"mappending with duplicates: right-preserving" (((OMap Int Int, OMap Int Int) -> IO ()) -> Spec)
-> ((OMap Int Int, OMap Int Int) -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\((OMap Int Int
i, OMap Int Int
j) :: (OMap Int Int, OMap Int Int)) ->
case OMap Int Int
i of
OMap Int Int
Empty -> OMap Int Int
i OMap Int Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> OMap k v -> OMap k v
><| OMap Int Int
j OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMap Int Int
j
OMap Int Int
_is :|>: Int
i' -> do
let result :: OMap Int Int
result = OMap Int Int
i OMap Int Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> OMap k v -> OMap k v
><| OMap Int Int
j
OMap Int Int
result OMap Int Int -> OMap Int Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMap Int Int
i OMap Int Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => OMap k v -> OMap k v -> OMap k v
><| (Int
i' Int -> OMap Int Int -> OMap Int Int
forall k v. HasOKey k v => v -> OMap k v -> OMap k v
<| OMap Int Int
j)
OMap Int Int
result OMap Int Int -> (OMap Int Int -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` OMap Int Int -> Bool
forall k v. Ord k => OMap k v -> Bool
invariantHolds'
String -> ((OMap Int Int, Set Int) -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"extractKeys should satisfy membership" (((OMap Int Int, Set Int) -> IO ()) -> Spec)
-> ((OMap Int Int, Set Int) -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\((OMap Int Int
omap, Set Int
set) :: (OMap Int Int, Set.Set Int)) -> do
let result :: (OMap Int Int, Map Int Int)
result = Set Int -> OMap Int Int -> (OMap Int Int, Map Int Int)
forall k v. Ord k => Set k -> OMap k v -> (OMap k v, Map k v)
extractKeys Set Int
set OMap Int Int
omap
(OMap Int Int, Map Int Int)
result (OMap Int Int, Map Int Int)
-> ((OMap Int Int, Map Int Int) -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` ((Int -> Bool) -> OMap Int Int -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int -> Set Int -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.notMember` Set Int
set) (OMap Int Int -> Bool)
-> ((OMap Int Int, Map Int Int) -> OMap Int Int)
-> (OMap Int Int, Map Int Int)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (OMap Int Int, Map Int Int) -> OMap Int Int
forall a b. (a, b) -> a
fst)
(OMap Int Int, Map Int Int)
result (OMap Int Int, Map Int Int)
-> ((OMap Int Int, Map Int Int) -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` ((Int -> Bool) -> Map Int Int -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int -> Set Int -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Int
set) (Map Int Int -> Bool)
-> ((OMap Int Int, Map Int Int) -> Map Int Int)
-> (OMap Int Int, Map Int Int)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (OMap Int Int, Map Int Int) -> Map Int Int
forall a b. (a, b) -> b
snd)
(OMap Int Int, Map Int Int)
result (OMap Int Int, Map Int Int)
-> ((OMap Int Int, Map Int Int) -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` OMap Int Int -> Bool
forall k v. Ord k => OMap k v -> Bool
invariantHolds' (OMap Int Int -> Bool)
-> ((OMap Int Int, Map Int Int) -> OMap Int Int)
-> (OMap Int Int, Map Int Int)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (OMap Int Int, Map Int Int) -> OMap Int Int
forall a b. (a, b) -> a
fst
String -> ((OMap Int Int, Int) -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"filter" (((OMap Int Int, Int) -> IO ()) -> Spec)
-> ((OMap Int Int, Int) -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\((OMap Int Int
omap, Int
i) :: (OMap Int Int, Int)) -> do
let result :: OMap Int Int
result = (Int -> Bool) -> OMap Int Int -> OMap Int Int
forall k v. Ord k => (v -> Bool) -> OMap k v -> OMap k v
filter (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
i) OMap Int Int
omap
OMap Int Int
result OMap Int Int -> (OMap Int Int -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` (Int -> Bool) -> OMap Int Int -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
i)
OMap Int Int
result OMap Int Int -> (OMap Int Int -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` OMap Int Int -> Bool
forall k v. Ord k => OMap k v -> Bool
invariantHolds'
String -> ((OMap Int OMapTest, Int) -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"adjust" (((OMap Int OMapTest, Int) -> IO ()) -> Spec)
-> ((OMap Int OMapTest, Int) -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\((OMap Int OMapTest
omap, Int
i) :: (OMap Int OMapTest, Int)) -> do
let adjustingFn :: OMapTest -> OMapTest
adjustingFn omt :: OMapTest
omt@OMapTest {Int
omSnd :: Int
omSnd :: OMapTest -> Int
omSnd} = OMapTest
omt {omSnd = omSnd + 1}
overwritingAdjustingFn :: OMapTest -> OMapTest
overwritingAdjustingFn omt :: OMapTest
omt@OMapTest {Int
omFst :: Int
omFst :: OMapTest -> Int
omFst} = OMapTest
omt {omFst = omFst + 1}
(OMapTest -> OMapTest)
-> Int -> OMap Int OMapTest -> OMap Int OMapTest
forall k v. HasOKey k v => (v -> v) -> k -> OMap k v -> OMap k v
adjust OMapTest -> OMapTest
adjustingFn Int
i OMap Int OMapTest
omap OMap Int OMapTest -> (OMap Int OMapTest -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` OMap Int OMapTest -> Bool
forall k v. Ord k => OMap k v -> Bool
invariantHolds'
(OMapTest -> OMapTest)
-> Int -> OMap Int OMapTest -> OMap Int OMapTest
forall k v. HasOKey k v => (v -> v) -> k -> OMap k v -> OMap k v
adjust OMapTest -> OMapTest
overwritingAdjustingFn Int
i OMap Int OMapTest
omap OMap Int OMapTest -> (OMap Int OMapTest -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` OMap Int OMapTest -> Bool
forall k v. Ord k => OMap k v -> Bool
invariantHolds'
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"overwriting" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> ((OMap Int OMapTest, OMapTest) -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"cons' - (<||)" (((OMap Int OMapTest, OMapTest) -> IO ()) -> Spec)
-> ((OMap Int OMapTest, OMapTest) -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\((OMap Int OMapTest
omap, OMapTest
i) :: (OMap Int OMapTest, OMapTest)) -> do
let consed :: OMap Int OMapTest
consed = OMapTest
i OMapTest -> OMap Int OMapTest -> OMap Int OMapTest
forall k v. HasOKey k v => v -> OMap k v -> OMap k v
<|| OMap Int OMapTest
omap
k :: Int
k = OMapTest
i OMapTest -> Getting Int OMapTest Int -> Int
forall s a. s -> Getting a s a -> a
^. Getting Int OMapTest Int
forall k v. HasOKey k v => Lens' v k
Lens' OMapTest Int
okeyL
if Int
k Int -> OMap Int OMapTest -> Bool
forall k v. Ord k => k -> OMap k v -> Bool
`member` OMap Int OMapTest
omap
then OMap Int OMapTest
consed OMap Int OMapTest -> OMap Int OMapTest -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` (OMapTest -> OMapTest)
-> Int -> OMap Int OMapTest -> OMap Int OMapTest
forall k v. HasOKey k v => (v -> v) -> k -> OMap k v -> OMap k v
adjust (OMapTest -> OMapTest -> OMapTest
forall a b. a -> b -> a
const OMapTest
i) (OMapTest
i OMapTest -> Getting Int OMapTest Int -> Int
forall s a. s -> Getting a s a -> a
^. Getting Int OMapTest Int
forall k v. HasOKey k v => Lens' v k
Lens' OMapTest Int
okeyL) OMap Int OMapTest
omap
else OMap Int OMapTest
consed OMap Int OMapTest -> OMap Int OMapTest -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMapTest
i OMapTest -> OMap Int OMapTest -> OMap Int OMapTest
forall k v. HasOKey k v => v -> OMap k v -> OMap k v
<| OMap Int OMapTest
omap
String -> ((OMap Int OMapTest, OMapTest) -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"snoc' - (||>)" (((OMap Int OMapTest, OMapTest) -> IO ()) -> Spec)
-> ((OMap Int OMapTest, OMapTest) -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\((OMap Int OMapTest
omap, OMapTest
i) :: (OMap Int OMapTest, OMapTest)) -> do
let snoced :: OMap Int OMapTest
snoced = OMap Int OMapTest
omap OMap Int OMapTest -> OMapTest -> OMap Int OMapTest
forall k v. HasOKey k v => OMap k v -> v -> OMap k v
||> OMapTest
i
k :: Int
k = OMapTest
i OMapTest -> Getting Int OMapTest Int -> Int
forall s a. s -> Getting a s a -> a
^. Getting Int OMapTest Int
forall k v. HasOKey k v => Lens' v k
Lens' OMapTest Int
okeyL
if Int
k Int -> OMap Int OMapTest -> Bool
forall k v. Ord k => k -> OMap k v -> Bool
`member` OMap Int OMapTest
omap
then OMap Int OMapTest
snoced OMap Int OMapTest -> OMap Int OMapTest -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` (OMapTest -> OMapTest)
-> Int -> OMap Int OMapTest -> OMap Int OMapTest
forall k v. HasOKey k v => (v -> v) -> k -> OMap k v -> OMap k v
adjust (OMapTest -> OMapTest -> OMapTest
forall a b. a -> b -> a
const OMapTest
i) (OMapTest
i OMapTest -> Getting Int OMapTest Int -> Int
forall s a. s -> Getting a s a -> a
^. Getting Int OMapTest Int
forall k v. HasOKey k v => Lens' v k
Lens' OMapTest Int
okeyL) OMap Int OMapTest
omap
else OMap Int OMapTest
snoced OMap Int OMapTest -> OMap Int OMapTest -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` OMap Int OMapTest
omap OMap Int OMapTest -> OMapTest -> OMap Int OMapTest
forall k v. HasOKey k v => OMap k v -> v -> OMap k v
|> OMapTest
i
String -> (Set Int -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"fromFoldable preserves order" ((Set Int -> IO ()) -> Spec) -> (Set Int -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\(Set Int
set :: Set.Set Int) -> do
let sseq :: StrictSeq Int
sseq = [Int] -> StrictSeq Int
forall a. [a] -> StrictSeq a
SSeq.fromList ([Int] -> StrictSeq Int) -> [Int] -> StrictSeq Int
forall a b. (a -> b) -> a -> b
$ Set Int -> [Int]
forall a. Set a -> [a]
Set.elems Set Int
set
omap :: OMap Int Int
omap = StrictSeq Int -> OMap Int Int
forall (f :: * -> *) k v.
(Foldable f, HasOKey k v) =>
f v -> OMap k v
fromFoldable StrictSeq Int
sseq
OMap Int Int -> StrictSeq Int
forall k v. Ord k => OMap k v -> StrictSeq v
toStrictSeq OMap Int Int
omap StrictSeq Int -> StrictSeq Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` StrictSeq Int
sseq
OMap Int Int
omap OMap Int Int -> (OMap Int Int -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` OMap Int Int -> Bool
forall k v. Ord k => OMap k v -> Bool
invariantHolds'
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"fromFoldableDuplicates preserves order" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> (Set Int -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"with duplicates" ((Set Int -> IO ()) -> Spec) -> (Set Int -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\(Set Int
set :: Set.Set Int) -> do
let sseq :: StrictSeq Int
sseq = [Int] -> StrictSeq Int
forall a. [a] -> StrictSeq a
SSeq.fromList ([Int] -> StrictSeq Int) -> [Int] -> StrictSeq Int
forall a b. (a -> b) -> a -> b
$ Set Int -> [Int]
forall a. Set a -> [a]
Set.elems Set Int
set
omap :: OMap Int Int
omap = StrictSeq Int -> OMap Int Int
forall (f :: * -> *) k v.
(Foldable f, HasOKey k v) =>
f v -> OMap k v
fromFoldable StrictSeq Int
sseq
result :: (Set Int, OMap Int Int)
result = StrictSeq Int -> (Set Int, OMap Int Int)
forall (f :: * -> *) k v.
(Foldable f, HasOKey k v, Ord v) =>
f v -> (Set v, OMap k v)
fromFoldableDuplicates (StrictSeq Int
sseq StrictSeq Int -> StrictSeq Int -> StrictSeq Int
forall a. StrictSeq a -> StrictSeq a -> StrictSeq a
SSeq.>< StrictSeq Int
sseq)
OMap Int Int -> StrictSeq Int
forall k v. Ord k => OMap k v -> StrictSeq v
toStrictSeq ((Set Int, OMap Int Int) -> OMap Int Int
forall a b. (a, b) -> b
snd (Set Int, OMap Int Int)
result) StrictSeq Int -> StrictSeq Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` StrictSeq Int
sseq
(Set Int, OMap Int Int)
result (Set Int, OMap Int Int) -> (Set Int, OMap Int Int) -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` (Set Int
set, OMap Int Int
omap)
(Set Int, OMap Int Int) -> OMap Int Int
forall a b. (a, b) -> b
snd (Set Int, OMap Int Int)
result OMap Int Int -> (OMap Int Int -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` OMap Int Int -> Bool
forall k v. Ord k => OMap k v -> Bool
invariantHolds'
String -> (Set Int -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"without duplicates" ((Set Int -> IO ()) -> Spec) -> (Set Int -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$
\(Set Int
set :: Set.Set Int) -> do
let sseq :: StrictSeq Int
sseq = [Int] -> StrictSeq Int
forall a. [a] -> StrictSeq a
SSeq.fromList ([Int] -> StrictSeq Int) -> [Int] -> StrictSeq Int
forall a b. (a -> b) -> a -> b
$ Set Int -> [Int]
forall a. Set a -> [a]
Set.elems Set Int
set
omap :: OMap Int Int
omap = StrictSeq Int -> OMap Int Int
forall (f :: * -> *) k v.
(Foldable f, HasOKey k v) =>
f v -> OMap k v
fromFoldable StrictSeq Int
sseq
result :: (Set Int, OMap Int Int)
result = StrictSeq Int -> (Set Int, OMap Int Int)
forall (f :: * -> *) k v.
(Foldable f, HasOKey k v, Ord v) =>
f v -> (Set v, OMap k v)
fromFoldableDuplicates StrictSeq Int
sseq
OMap Int Int -> StrictSeq Int
forall k v. Ord k => OMap k v -> StrictSeq v
toStrictSeq ((Set Int, OMap Int Int) -> OMap Int Int
forall a b. (a, b) -> b
snd (Set Int, OMap Int Int)
result) StrictSeq Int -> StrictSeq Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` StrictSeq Int
sseq
(Set Int, OMap Int Int)
result (Set Int, OMap Int Int) -> (Set Int, OMap Int Int) -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` (Set Int
forall a. Set a
Set.empty, OMap Int Int
omap)
(Set Int, OMap Int Int) -> OMap Int Int
forall a b. (a, b) -> b
snd (Set Int, OMap Int Int)
result OMap Int Int -> (OMap Int Int -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` OMap Int Int -> Bool
forall k v. Ord k => OMap k v -> Bool
invariantHolds'
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"CBOR round-trip" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
forall t. (Show t, Eq t, Arbitrary t, EncCBOR t, DecCBOR t) => Spec
roundTripCborSpec @(OMap Int Int)
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"Typeclass laws" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> IO () -> SpecM (Arg (IO ())) ()
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"Type" (IO () -> SpecM (Arg (IO ())) ())
-> IO () -> SpecM (Arg (IO ())) ()
forall a b. (a -> b) -> a -> b
$
Proxy (OMap Int Int) -> [Proxy (OMap Int Int) -> Laws] -> IO ()
forall a. Proxy a -> [Proxy a -> Laws] -> IO ()
lawsCheckOne
(Proxy (OMap Int Int)
forall {k} (t :: k). Proxy t
Proxy :: Proxy (OMap Int Int))
[ Proxy (OMap Int Int) -> Laws
forall a. (Eq a, Arbitrary a, Show a) => Proxy a -> Laws
eqLaws
, Proxy (OMap Int Int) -> Laws
forall a.
(IsList a, Show a, Show (Item a), Arbitrary a, Arbitrary (Item a),
Eq a) =>
Proxy a -> Laws
isListLaws
, Proxy (OMap Int Int) -> Laws
forall a.
(Semigroup a, Eq a, Arbitrary a, Show a) =>
Proxy a -> Laws
semigroupLaws
, Proxy (OMap Int Int) -> Laws
forall a. (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
monoidLaws
, Proxy (OMap Int Int) -> Laws
forall a.
(Semigroup a, Monoid a, Eq a, Arbitrary a, Show a) =>
Proxy a -> Laws
semigroupMonoidLaws
]
instance HasOKey Int Int where
okeyL :: Lens' Int Int
okeyL = (Int -> Int) -> (Int -> Int -> Int) -> Lens' Int Int
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Int -> Int
forall a. a -> a
id Int -> Int -> Int
forall a b. a -> b -> a
const
data OMapTest = OMapTest {OMapTest -> Int
omFst :: Int, OMapTest -> Int
omSnd :: Int}
deriving (OMapTest -> OMapTest -> Bool
(OMapTest -> OMapTest -> Bool)
-> (OMapTest -> OMapTest -> Bool) -> Eq OMapTest
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: OMapTest -> OMapTest -> Bool
== :: OMapTest -> OMapTest -> Bool
$c/= :: OMapTest -> OMapTest -> Bool
/= :: OMapTest -> OMapTest -> Bool
Eq, Int -> OMapTest -> ShowS
[OMapTest] -> ShowS
OMapTest -> String
(Int -> OMapTest -> ShowS)
-> (OMapTest -> String) -> ([OMapTest] -> ShowS) -> Show OMapTest
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> OMapTest -> ShowS
showsPrec :: Int -> OMapTest -> ShowS
$cshow :: OMapTest -> String
show :: OMapTest -> String
$cshowList :: [OMapTest] -> ShowS
showList :: [OMapTest] -> ShowS
Show, Eq OMapTest
Eq OMapTest =>
(OMapTest -> OMapTest -> Ordering)
-> (OMapTest -> OMapTest -> Bool)
-> (OMapTest -> OMapTest -> Bool)
-> (OMapTest -> OMapTest -> Bool)
-> (OMapTest -> OMapTest -> Bool)
-> (OMapTest -> OMapTest -> OMapTest)
-> (OMapTest -> OMapTest -> OMapTest)
-> Ord OMapTest
OMapTest -> OMapTest -> Bool
OMapTest -> OMapTest -> Ordering
OMapTest -> OMapTest -> OMapTest
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: OMapTest -> OMapTest -> Ordering
compare :: OMapTest -> OMapTest -> Ordering
$c< :: OMapTest -> OMapTest -> Bool
< :: OMapTest -> OMapTest -> Bool
$c<= :: OMapTest -> OMapTest -> Bool
<= :: OMapTest -> OMapTest -> Bool
$c> :: OMapTest -> OMapTest -> Bool
> :: OMapTest -> OMapTest -> Bool
$c>= :: OMapTest -> OMapTest -> Bool
>= :: OMapTest -> OMapTest -> Bool
$cmax :: OMapTest -> OMapTest -> OMapTest
max :: OMapTest -> OMapTest -> OMapTest
$cmin :: OMapTest -> OMapTest -> OMapTest
min :: OMapTest -> OMapTest -> OMapTest
Ord)
instance HasOKey Int OMapTest where
okeyL :: Lens' OMapTest Int
okeyL = (OMapTest -> Int)
-> (OMapTest -> Int -> OMapTest) -> Lens' OMapTest Int
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens OMapTest -> Int
omFst ((OMapTest -> Int -> OMapTest) -> Lens' OMapTest Int)
-> (OMapTest -> Int -> OMapTest) -> Lens' OMapTest Int
forall a b. (a -> b) -> a -> b
$ \OMapTest
om Int
u -> OMapTest
om {omFst = u}
instance Arbitrary OMapTest where
arbitrary :: Gen OMapTest
arbitrary = Int -> Int -> OMapTest
OMapTest (Int -> Int -> OMapTest) -> Gen Int -> Gen (Int -> OMapTest)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Int
forall a. Arbitrary a => Gen a
arbitrary Gen (Int -> OMapTest) -> Gen Int -> Gen OMapTest
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Int
forall a. Arbitrary a => Gen a
arbitrary