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 = String -> Spec -> Spec forall a. HasCallStack => String -> SpecWith a -> SpecWith a Hspec.describe String "Saturn.Unstable.Type.Element" (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) -> ((Element -> Expectation) -> Property) -> (Element -> Expectation) -> Spec forall b c a. (b -> c) -> (a -> b) -> a -> c . Gen Element -> (Element -> [Element]) -> (Element -> Expectation) -> Property forall a prop. (Show a, Testable prop) => Gen a -> (a -> [a]) -> (a -> prop) -> Property QuickCheck.forAllShrink Gen Element arbitrary Element -> [Element] shrink ((Element -> Expectation) -> Spec) -> (Element -> Expectation) -> Spec forall a b. (a -> b) -> a -> b $ \Element x -> do Parsec Text () Element -> String -> Text -> Either ParseError Element forall s t a. Stream s Identity t => Parsec s () a -> String -> s -> Either ParseError a Parsec.parse Parsec Text () Element forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Element Element.parsec String "" (Builder -> Text Builder.toLazyText (Builder -> Text) -> Builder -> Text forall a b. (a -> b) -> a -> b $ Element -> Builder Element.toBuilder Element x) Either ParseError Element -> Either ParseError Element -> Expectation forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation `Hspec.shouldBe` Element -> Either ParseError Element 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 (Either Range Number -> Element) -> Gen (Either Range Number) -> Gen Element forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen Range -> Gen Number -> Gen (Either Range Number) forall a b. Gen a -> Gen b -> Gen (Either a 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 (Number -> Element) -> [Number] -> [Element] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Either Range Number -> Element Element.fromEither (Either Range Number -> Element) -> (Number -> Either Range Number) -> Number -> Element forall b c a. (b -> c) -> (a -> b) -> a -> c . Number -> Either Range Number forall a b. b -> Either a b Right) [Number lo, Number hi] Right Number _ -> [] in [Element] -> [Element] -> [Element] forall a. Monoid a => a -> a -> a mappend [Element] xs ([Element] -> [Element]) -> (Either Range Number -> [Element]) -> Either Range Number -> [Element] forall b c a. (b -> c) -> (a -> b) -> a -> c . (Either Range Number -> Element) -> [Either Range Number] -> [Element] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Either Range Number -> Element Element.fromEither ([Either Range Number] -> [Element]) -> (Either Range Number -> [Either Range Number]) -> Either Range Number -> [Element] forall b c a. (b -> c) -> (a -> b) -> a -> c . (Range -> [Range]) -> (Number -> [Number]) -> Either Range Number -> [Either Range Number] forall a b. (a -> [a]) -> (b -> [b]) -> Either a b -> [Either a b] 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 (Either Range Number -> [Element]) -> Either Range Number -> [Element] 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] -> Element -> m Element forall a. a -> m a forall (f :: * -> *) a. Applicative f => a -> f a pure (Element -> m Element) -> (Number -> Element) -> Number -> m Element forall b c a. (b -> c) -> (a -> b) -> a -> c . Either Range Number -> Element Element.fromEither (Either Range Number -> Element) -> (Number -> Either Range Number) -> Number -> Element forall b c a. (b -> c) -> (a -> b) -> a -> c . Number -> Either Range Number forall a b. b -> Either a b Right (Number -> m Element) -> Number -> m Element forall a b. (a -> b) -> a -> b $ Word8 -> Number Number.fromWord8 Word8 x [Word8 x, Word8 y] -> Either Range Number -> Element Element.fromEither (Either Range Number -> Element) -> (Range -> Either Range Number) -> Range -> Element forall b c a. (b -> c) -> (a -> b) -> a -> c . Range -> Either Range Number forall a b. a -> Either a b Left (Range -> Element) -> m Range -> m Element forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (Word8, Word8) -> m Range forall (m :: * -> *). MonadFail m => (Word8, Word8) -> m Range RangeSpec.new (Word8 x, Word8 y) [Word8] _ -> String -> m Element forall a. String -> m a forall (m :: * -> *) a. MonadFail m => String -> m a fail (String -> m Element) -> String -> m Element forall a b. (a -> b) -> a -> b $ String "invalid Element: " String -> String -> String forall a. Semigroup a => a -> a -> a <> [Word8] -> String forall a. Show a => a -> String show [Word8] xs