module Saturn.Unstable.Type.DaySpec 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.Day as Day
import qualified Saturn.Unstable.Type.FieldSpec as FieldSpec
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.Day" 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 Day
arbitrary Day -> [Day]
shrink
    forall a b. (a -> b) -> a -> b
$ \Day
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 Day
Day.parsec String
"" (Builder -> Text
Builder.toLazyText forall a b. (a -> b) -> a -> b
$ Day -> Builder
Day.toBuilder Day
x)
        forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation
`Hspec.shouldBe` forall a b. b -> Either a b
Right Day
x

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

shrink :: Day.Day -> [Day.Day]
shrink :: Day -> [Day]
shrink = forall a b. (a -> Maybe b) -> [a] -> [b]
Maybe.mapMaybe Field -> Maybe Day
Day.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
. Day -> Field
Day.toField

new :: (MonadFail m) => [[Word.Word8]] -> m Day.Day
new :: forall (m :: * -> *). MonadFail m => [[Word8]] -> m Day
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 Day: " 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 Day
Day.fromField Field
field