module Hydra.ContestationPeriodSpec where

import Hydra.Prelude hiding (label)

import Data.Time (secondsToNominalDiffTime)
import Hydra.ContestationPeriod (ContestationPeriod, fromNominalDiffTime)
import Test.Hspec (Spec, describe)
import Test.Hspec.QuickCheck (prop)
import Test.QuickCheck (getNonPositive, getPositive, (===))
import Test.QuickCheck.Instances.Time ()

spec :: Spec
spec :: Spec
spec = do
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"fromNominalDiffTime" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> (Positive NominalDiffTime -> Bool) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"works for diff times > 0" ((Positive NominalDiffTime -> Bool) -> Spec)
-> (Positive NominalDiffTime -> Bool) -> Spec
forall a b. (a -> b) -> a -> b
$
      Maybe ContestationPeriod -> Bool
forall a. Maybe a -> Bool
isJust (Maybe ContestationPeriod -> Bool)
-> (Positive NominalDiffTime -> Maybe ContestationPeriod)
-> Positive NominalDiffTime
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NominalDiffTime -> Maybe ContestationPeriod
forall (m :: * -> *).
MonadFail m =>
NominalDiffTime -> m ContestationPeriod
fromNominalDiffTime (NominalDiffTime -> Maybe ContestationPeriod)
-> (Positive NominalDiffTime -> NominalDiffTime)
-> Positive NominalDiffTime
-> Maybe ContestationPeriod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Positive NominalDiffTime -> NominalDiffTime
forall a. Positive a -> a
getPositive

    String -> (NonPositive NominalDiffTime -> Bool) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"fails for diff times <= 0" ((NonPositive NominalDiffTime -> Bool) -> Spec)
-> (NonPositive NominalDiffTime -> Bool) -> Spec
forall a b. (a -> b) -> a -> b
$
      Maybe ContestationPeriod -> Bool
forall a. Maybe a -> Bool
isNothing (Maybe ContestationPeriod -> Bool)
-> (NonPositive NominalDiffTime -> Maybe ContestationPeriod)
-> NonPositive NominalDiffTime
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NominalDiffTime -> Maybe ContestationPeriod
forall (m :: * -> *).
MonadFail m =>
NominalDiffTime -> m ContestationPeriod
fromNominalDiffTime (NominalDiffTime -> Maybe ContestationPeriod)
-> (NonPositive NominalDiffTime -> NominalDiffTime)
-> NonPositive NominalDiffTime
-> Maybe ContestationPeriod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonPositive NominalDiffTime -> NominalDiffTime
forall a. NonPositive a -> a
getNonPositive

    String -> (Positive Pico -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"rounds to 1 second" ((Positive Pico -> Property) -> Spec)
-> (Positive Pico -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ \Positive Pico
n ->
      let subSecond :: Pico
subSecond = Positive Pico -> Pico
forall a. Positive a -> a
getPositive Positive Pico
n Pico -> Pico -> Pico
forall a. Fractional a => a -> a -> a
/ Pico
100 -- Definitely < 1 second
       in NominalDiffTime -> Maybe ContestationPeriod
forall (m :: * -> *).
MonadFail m =>
NominalDiffTime -> m ContestationPeriod
fromNominalDiffTime (Pico -> NominalDiffTime
secondsToNominalDiffTime Pico
subSecond)
            Maybe ContestationPeriod -> Maybe ContestationPeriod -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== (NominalDiffTime -> Maybe ContestationPeriod
forall (m :: * -> *).
MonadFail m =>
NominalDiffTime -> m ContestationPeriod
fromNominalDiffTime NominalDiffTime
1 :: Maybe ContestationPeriod)