{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_HADDOCK prune not-home #-}

{- |
Module      : Test.KeyedVals.CheckHandle
Copyright   : (c) 2022 Tim Emiola
Maintainer  : Tim Emiola <adetcorrectlyunbo@emio.la>
SPDX-License-Identifier: BSD3
-}
module Test.KeyedVals.CheckHandle (
  -- * a test fixture
  spec,

  -- * setup/teardown hspec tests
  setupFixture,
  closeFixture,
) where

import qualified Data.Map.Strict as Map
import KeyedVals.Handle
import Test.KeyedVals.Prelude


spec :: SpecWith (Handle IO)
spec :: SpecWith (Handle IO)
spec = do
  forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"with simple values" forall a b. (a -> b) -> a -> b
$ do
    forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should load correctly" forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
loadVal Handle IO
h Val
key1 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. a -> Maybe a
Just Val
simple1

    forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should update correctly" forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
      forall a b. (Show a, Show b) => IO (Either a b) -> Expectation
endsRight_ forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Handle m -> Val -> Val -> m (Either HandleErr ())
saveVal Handle IO
h Val
key1 Val
"changed"
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
loadVal Handle IO
h Val
key1 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. a -> Maybe a
Just Val
"changed"

    forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should delete matching keys correctly " forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
loadVal Handle IO
h Val
key2 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. a -> Maybe a
Just Val
simple2
      forall a. Val -> (Glob -> IO a) -> IO a
withGlobOf Val
"*2" forall a b. (a -> b) -> a -> b
$ \Glob
patt -> do
        forall a b. (Show a, Show b) => IO (Either a b) -> Expectation
endsRight_ forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). Handle m -> Glob -> m (Either HandleErr ())
deleteMatches Handle IO
h Glob
patt
        forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
loadVal Handle IO
h Val
key2 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. Maybe a
Nothing

    forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should delete correctly" forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
      forall (m :: * -> *).
Handle m -> NonEmpty Val -> m (Either HandleErr ())
deleteKeys Handle IO
h (Val
key1 forall a. a -> [a] -> NonEmpty a
:| []) forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` ()
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
loadVal Handle IO
h Val
key1 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. Maybe a
Nothing

  forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"with keyed values" forall a b. (a -> b) -> a -> b
$ do
    let mKey1Of :: Handle m -> Val -> m (Either HandleErr (Maybe Val))
mKey1Of Handle m
h = forall (m :: * -> *).
Handle m -> Val -> Val -> m (Either HandleErr (Maybe Val))
loadFrom Handle m
h Val
mKey1

    forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should load correctly" forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr ValsByKey)
loadKVs Handle IO
h Val
mKey1 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` ValsByKey
d1

    Val -> Natural -> SpecWith (Handle IO)
checkLength Val
mKey1 Natural
4

    forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should update an indexed value correctly" forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
      forall a b. (Show a, Show b) => IO (Either a b) -> Expectation
endsRight_ forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Handle m -> Val -> Val -> Val -> m (Either HandleErr ())
saveTo Handle IO
h Val
mKey1 Val
key1 Val
"changed"
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
mKey1Of Handle IO
h Val
key1 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. a -> Maybe a
Just Val
"changed"

    Val -> Natural -> SpecWith (Handle IO)
checkLength Val
mKey1 Natural
4

    forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should add an indexed value correctly" forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
mKey1Of Handle IO
h Val
"foo" forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. Maybe a
Nothing
      forall a b. (Show a, Show b) => IO (Either a b) -> Expectation
endsRight_ forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Handle m -> Val -> Val -> Val -> m (Either HandleErr ())
saveTo Handle IO
h Val
mKey1 Val
"foo" Val
"bar"
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
mKey1Of Handle IO
h Val
"foo" forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. a -> Maybe a
Just Val
"bar"

    Val -> Natural -> SpecWith (Handle IO)
checkLength Val
mKey1 Natural
5

    forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should delete key-values correctly" forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
      forall a b. (Show a, Show b) => IO (Either a b) -> Expectation
endsRight_ forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Handle m -> Val -> NonEmpty Val -> m (Either HandleErr ())
deleteKeysFrom Handle IO
h Val
mKey1 (Val
key1 forall a. a -> [a] -> NonEmpty a
:| [Val
key2])
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
mKey1Of Handle IO
h Val
"foo" forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. a -> Maybe a
Just Val
"bar"
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
mKey1Of Handle IO
h Val
key1 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. Maybe a
Nothing
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
mKey1Of Handle IO
h Val
key2 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. Maybe a
Nothing

    Val -> Natural -> SpecWith (Handle IO)
checkLength Val
mKey1 Natural
3

    forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should update the key-values correctly" forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
      forall a b. (Show a, Show b) => IO (Either a b) -> Expectation
endsRight_ forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Handle m -> Val -> ValsByKey -> m (Either HandleErr ())
updateKVs Handle IO
h Val
mKey1 ValsByKey
d2
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
mKey1Of Handle IO
h Val
key1 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. a -> Maybe a
Just Val
simple3
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
mKey1Of Handle IO
h Val
key2 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. Maybe a
Nothing
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
mKey1Of Handle IO
h Val
key5 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. a -> Maybe a
Just Val
simple3

    forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should fetch a subset of the key-values correctly" forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
      let want :: ValsByKey
want = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Val
"foo", Val
"bar"), (Val
key5, Val
simple3)]
      forall (m :: * -> *).
Handle m -> Val -> Selection -> m (Either HandleErr ValsByKey)
loadSlice Handle IO
h Val
mKey1 (NonEmpty Val -> Selection
AllOf (Val
"foo" forall a. a -> [a] -> NonEmpty a
:| [Val
key5])) forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` ValsByKey
want

    forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should delete correctly" forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
      forall a b. (Show a, Show b) => IO (Either a b) -> Expectation
endsRight_ forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Handle m -> NonEmpty Val -> m (Either HandleErr ())
deleteKeys Handle IO
h (Val
mKey1 forall a. a -> [a] -> NonEmpty a
:| [])
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr ValsByKey)
loadKVs Handle IO
h Val
mKey1 forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall k a. Map k a
Map.empty
      forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr (Maybe Val))
mKey1Of Handle IO
h Val
"foo" forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` forall a. Maybe a
Nothing

    Val -> Natural -> SpecWith (Handle IO)
checkLength Val
mKey1 Natural
0


setupFixture :: Handle IO -> IO (Handle IO)
setupFixture :: Handle IO -> IO (Handle IO)
setupFixture Handle IO
h = do
  IO (Either HandleErr ()) -> Expectation
orThrowHandleErr forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Handle m -> Val -> Val -> m (Either HandleErr ())
saveVal Handle IO
h Val
key1 Val
simple1
  IO (Either HandleErr ()) -> Expectation
orThrowHandleErr forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Handle m -> Val -> Val -> m (Either HandleErr ())
saveVal Handle IO
h Val
key2 Val
simple2
  IO (Either HandleErr ()) -> Expectation
orThrowHandleErr forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Handle m -> Val -> ValsByKey -> m (Either HandleErr ())
saveKVs Handle IO
h Val
mKey1 ValsByKey
d1
  forall (f :: * -> *) a. Applicative f => a -> f a
pure Handle IO
h


closeFixture :: Handle IO -> IO ()
closeFixture :: Handle IO -> Expectation
closeFixture = forall (m :: * -> *). Handle m -> m ()
close


checkLength :: Key -> Natural -> SpecWith (Handle IO)
checkLength :: Val -> Natural -> SpecWith (Handle IO)
checkLength Val
aKey Natural
n = forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"and the reported length" forall a b. (a -> b) -> a -> b
$ do
  forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should be correct " forall a b. (a -> b) -> a -> b
$ \Handle IO
h -> do
    forall (m :: * -> *).
Handle m -> Val -> m (Either HandleErr Natural)
countKVs Handle IO
h Val
aKey forall a b.
(HasCallStack, Show a, Eq a, Show b, Eq b) =>
IO (Either a b) -> b -> Expectation
`endsRight` Natural
n


key1, key2, key3, key4, key5, mKey1 :: Key
key1 :: Val
key1 = Val
"a-simple-key-1"
key2 :: Val
key2 = Val
"a-simple-key-2"
key3 :: Val
key3 = Val
"another-key-1"
key4 :: Val
key4 = Val
"another_key-2"
key5 :: Val
key5 = Val
"yet-another-key"
mKey1 :: Val
mKey1 = Val
"a-map-key-1"


simple1, simple2, simple3 :: Val
simple1 :: Val
simple1 = Val
"a-simple-value-1"
simple2 :: Val
simple2 = Val
"a-simple-value-2"
simple3 :: Val
simple3 = Val
"a-simple-value-3"


d1, d2 :: ValsByKey
d1 :: ValsByKey
d1 = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Val
key1, Val
simple1), (Val
key2, Val
simple2), (Val
key3, Val
simple1), (Val
key4, Val
simple2)]
d2 :: ValsByKey
d2 = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Val
key1, Val
simple3), (Val
key5, Val
simple3)]