module Saturn.Unstable.Type.HourSpec where

import qualified Data.Maybe as Maybe
import qualified Data.Text.Lazy.Builder as Builder
import qualified Data.Word as Word
import qualified Saturn.Unstable.Type.FieldSpec as FieldSpec
import qualified Saturn.Unstable.Type.Hour as Hour
import qualified Test.Hspec as Hspec
import qualified Test.QuickCheck as QuickCheck
import qualified Text.Parsec as Parsec

spec :: Hspec.Spec
spec :: Spec
spec = forall a. HasCallStack => String -> SpecWith a -> SpecWith a
Hspec.describe String
"Saturn.Unstable.Type.Hour" forall a b. (a -> b) -> a -> b
$ do
  forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
Hspec.it String
"round trips"
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
QuickCheck.forAllShrink Gen Hour
arbitrary Hour -> [Hour]
shrink
    forall a b. (a -> b) -> a -> b
$ \Hour
x -> do
      forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
Parsec.parse forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Hour
Hour.parsec String
"" (Builder -> Text
Builder.toLazyText forall a b. (a -> b) -> a -> b
$ Hour -> Builder
Hour.toBuilder Hour
x)
        forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation
`Hspec.shouldBe` forall a b. b -> Either a b
Right Hour
x

arbitrary :: QuickCheck.Gen Hour.Hour
arbitrary :: Gen Hour
arbitrary = forall a b. Gen a -> (a -> Maybe b) -> Gen b
QuickCheck.suchThatMap Gen Field
FieldSpec.arbitrary Field -> Maybe Hour
Hour.fromField

shrink :: Hour.Hour -> [Hour.Hour]
shrink :: Hour -> [Hour]
shrink = forall a b. (a -> Maybe b) -> [a] -> [b]
Maybe.mapMaybe Field -> Maybe Hour
Hour.fromField forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field -> [Field]
FieldSpec.shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hour -> Field
Hour.toField

new :: (MonadFail m) => [[Word.Word8]] -> m Hour.Hour
new :: forall (m :: * -> *). MonadFail m => [[Word8]] -> m Hour
new [[Word8]]
xs = do
  Field
field <- forall (m :: * -> *). MonadFail m => [[Word8]] -> m Field
FieldSpec.new [[Word8]]
xs
  forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"invalid Hour: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show [[Word8]]
xs) forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Field -> Maybe Hour
Hour.fromField Field
field