module Saturn.Unstable.Type.NumberSpec where

import qualified Data.Text.Lazy.Builder as Builder
import qualified Saturn.Unstable.Type.Number as Number
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.Number" (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)
-> ((Number -> Expectation) -> Property)
-> (Number -> Expectation)
-> Spec
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Gen Number
-> (Number -> [Number]) -> (Number -> Expectation) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
QuickCheck.forAllShrink Gen Number
arbitrary Number -> [Number]
shrink
    ((Number -> Expectation) -> Spec)
-> (Number -> Expectation) -> Spec
forall a b. (a -> b) -> a -> b
$ \Number
x -> do
      Parsec Text () Number -> String -> Text -> Either ParseError Number
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
Parsec.parse Parsec Text () Number
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Number
Number.parsec String
"" (Builder -> Text
Builder.toLazyText (Builder -> Text) -> Builder -> Text
forall a b. (a -> b) -> a -> b
$ Number -> Builder
Number.toBuilder Number
x)
        Either ParseError Number -> Either ParseError Number -> Expectation
forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation
`Hspec.shouldBe` Number -> Either ParseError Number
forall a b. b -> Either a b
Right Number
x

arbitrary :: QuickCheck.Gen Number.Number
arbitrary :: Gen Number
arbitrary = Word8 -> Number
Number.fromWord8 (Word8 -> Number) -> Gen Word8 -> Gen Number
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word8
forall a. Arbitrary a => Gen a
QuickCheck.arbitrary

shrink :: Number.Number -> [Number.Number]
shrink :: Number -> [Number]
shrink = (Word8 -> Number) -> [Word8] -> [Number]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Word8 -> Number
Number.fromWord8 ([Word8] -> [Number]) -> (Number -> [Word8]) -> Number -> [Number]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> [Word8]
forall a. Arbitrary a => a -> [a]
QuickCheck.shrink (Word8 -> [Word8]) -> (Number -> Word8) -> Number -> [Word8]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Number -> Word8
Number.toWord8