module Saturn.Unstable.Type.ElementSpec where import qualified Data.Text.Lazy.Builder as Builder import qualified Data.Word as Word import qualified Saturn.Unstable.Type.Element as Element import qualified Saturn.Unstable.Type.Number as Number import qualified Saturn.Unstable.Type.NumberSpec as NumberSpec import qualified Saturn.Unstable.Type.Range as Range import qualified Saturn.Unstable.Type.RangeSpec as RangeSpec 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.Element" 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 Element arbitrary Element -> [Element] shrink forall a b. (a -> b) -> a -> b $ \Element 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 Element Element.parsec String "" (Builder -> Text Builder.toLazyText forall a b. (a -> b) -> a -> b $ Element -> Builder Element.toBuilder Element x) forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation `Hspec.shouldBe` forall a b. b -> Either a b Right Element x arbitrary :: QuickCheck.Gen Element.Element arbitrary :: Gen Element arbitrary = Either Range Number -> Element Element.fromEither forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall (f :: * -> * -> *) a b. Arbitrary2 f => Gen a -> Gen b -> Gen (f a b) QuickCheck.liftArbitrary2 Gen Range RangeSpec.arbitrary Gen Number NumberSpec.arbitrary shrink :: Element.Element -> [Element.Element] shrink :: Element -> [Element] shrink Element element = let xs :: [Element] xs = case Element -> Either Range Number Element.toEither Element element of Left Range range -> let (Number lo, Number hi) = Range -> (Number, Number) Range.toTuple Range range in forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Either Range Number -> Element Element.fromEither forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a b. b -> Either a b Right) [Number lo, Number hi] Right Number _ -> [] in forall a. Monoid a => a -> a -> a mappend [Element] xs forall b c a. (b -> c) -> (a -> b) -> a -> c . forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Either Range Number -> Element Element.fromEither forall b c a. (b -> c) -> (a -> b) -> a -> c . forall (f :: * -> * -> *) a b. Arbitrary2 f => (a -> [a]) -> (b -> [b]) -> f a b -> [f a b] QuickCheck.liftShrink2 Range -> [Range] RangeSpec.shrink Number -> [Number] NumberSpec.shrink forall a b. (a -> b) -> a -> b $ Element -> Either Range Number Element.toEither Element element new :: (MonadFail m) => [Word.Word8] -> m Element.Element new :: forall (m :: * -> *). MonadFail m => [Word8] -> m Element new [Word8] xs = case [Word8] xs of [Word8 x] -> forall (f :: * -> *) a. Applicative f => a -> f a pure forall b c a. (b -> c) -> (a -> b) -> a -> c . Either Range Number -> Element Element.fromEither forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a b. b -> Either a b Right forall a b. (a -> b) -> a -> b $ Word8 -> Number Number.fromWord8 Word8 x [Word8 x, Word8 y] -> Either Range Number -> Element Element.fromEither forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a b. a -> Either a b Left forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall (m :: * -> *). MonadFail m => (Word8, Word8) -> m Range RangeSpec.new (Word8 x, Word8 y) [Word8] _ -> forall (m :: * -> *) a. MonadFail m => String -> m a fail forall a b. (a -> b) -> a -> b $ String "invalid Element: " forall a. Semigroup a => a -> a -> a <> forall a. Show a => a -> String show [Word8] xs