module Test.TypeSpec.Core
(
TypeSpec (..)
, type EvalExpectation
, PrettyTypeSpec(..)
, prettyIndentation
, module ReExport
)
where
import Data.Proxy
import Test.TypeSpec.Internal.Either ()
import Test.TypeSpec.Internal.Apply
import Test.TypeSpec.Internal.Result as ReExport
import Text.PrettyPrint
data TypeSpec expectation where
Valid :: (Try (EvalExpectation expectation) ~ expectation)
=> TypeSpec expectation
Invalid :: (DontTry (EvalExpectation expectation))
=> TypeSpec expectation
type family EvalExpectation (expectation :: k) :: Result k
type instance EvalExpectation '(a, b) =
Pair'' <$> EvalExpectation a <*> EvalExpectation b
type instance EvalExpectation '[] = OK '[]
type instance EvalExpectation (expectation ': rest) =
Cons'' <$> EvalExpectation expectation <*> EvalExpectation rest
class PrettyTypeSpec (t :: k) where
prettyTypeSpec :: proxy t -> Doc
instance PrettyTypeSpec t => Show (TypeSpec t) where
show px@Valid =
render
$ hang (text "Valid:") 5 (prettyTypeSpec px)
show px@Invalid =
render
$ hang (text "Invalid:") 5 (prettyTypeSpec px)
prettyIndentation :: Int
prettyIndentation = 2
instance
( PrettyTypeSpec expectation1
, PrettyTypeSpec expectation2 )
=> PrettyTypeSpec '(expectation1, expectation2)
where
prettyTypeSpec _ =
prettyTypeSpec pe1 <+> prettyTypeSpec pe2
where pe1 = Proxy :: Proxy expectation1
pe2 = Proxy :: Proxy expectation2
instance
PrettyTypeSpec '[]
where
prettyTypeSpec _ = empty
instance
( PrettyTypeSpec expectation
, PrettyTypeSpec rest )
=> PrettyTypeSpec (expectation ': rest)
where
prettyTypeSpec _ =
(prettyTypeSpec pe1) <+> (prettyTypeSpec pe2)
where pe1 = Proxy :: Proxy expectation
pe2 = Proxy :: Proxy rest