module Saturn.Unstable.Type.WeekdaySpec 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.Weekday as Weekday
import qualified Test.Hspec as Hspec
import qualified Test.QuickCheck as QuickCheck
import qualified Text.Parsec as Parsec

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

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

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

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