purescript-typeable/test/Main.purs
Anupam Jain f3dd0c0fb1 Reduce dependence on the internal dictionary passing mechanism
Part of this work was done by @the-dr-lazy in
https://github.com/ajnsit/purescript-typeable/pull/3.

GOOD:
Now there is no more dependence on dictionaries being passed as function
arguments at runtime.

BAD:
1. However, we still depend on the dictionaries being stable at runtime.
2. We now also assume that the output of the new function `makeTag` will
never be cached.
2023-07-06 20:51:50 +05:30

72 lines
2.7 KiB
Haskell

module Test.Main where
import Prelude
import Control.Monad.Error.Class (class MonadThrow)
import Data.Either (Either)
import Data.Typeable (class Tagged, TypeRep, eqTypeRep, makeTag, typeRep, typeRepFromVal)
import Effect (Effect)
import Effect.Aff (launchAff_)
import Effect.Exception (Error)
import Test.Person (Person, typeArrPerson, typePerson)
import Test.Spec (describe, it)
import Test.Spec.Assertions (shouldEqual)
import Test.Spec.Reporter.Console (consoleReporter)
import Test.Spec.Runner (runSpec)
foreign import clog :: forall a. a -> Effect Unit
assert :: forall m. MonadThrow Error m => Boolean -> m Unit
assert = shouldEqual true
deny :: forall m. MonadThrow Error m => Boolean -> m Unit
deny = shouldEqual false
main :: Effect Unit
main = do
launchAff_ $ runSpec [ consoleReporter ] do
describe "Typeable" do
it "can handle primitives" do
deny $ eqTypeRep (typeRep :: _ Int) (typeRep :: _ Char)
it "can handle unsaturated types" do
assert $ eqTypeRep (typeRep :: _ Array) (typeRep :: _ Array)
assert $ eqTypeRep (typeRep :: _ Optional) (typeRep :: _ Optional)
deny $ eqTypeRep (typeRep :: _ (Optional Int)) (typeRep :: _ (Optional Char))
it "can handle mixed arity" do
deny $ eqTypeRep (typeRep :: _ Array) (typeRep :: _ Person)
it "can handle user defined data types" do
assert $ eqTypeRep (typeRep :: _ Person) typePerson
assert $ eqTypeRep (typeRep :: _ Person) (typeRep :: _ Person)
it "can distinguish between distinct types with matching fields" do
deny $ eqTypeRep (typeRep :: _ Person) (typeRep :: _ Person2)
it "can handle nested types" do
assert $ eqTypeRep (typeRep :: _ (Either Int Person)) (typeRep :: _ (Either Int Person))
assert $ eqTypeRep (typeRep :: _ (Array Person)) typeArrPerson
deny $ eqTypeRep (typeRep :: _ (Array Person2)) typeArrPerson
it "can handle bare records" do
assert $ eqTypeRep typeRecord (typeRep :: _ { name :: String, age :: Int })
it "can generate type reps from values" do
assert $ eqTypeRep (typeRep :: _ (Optional Int)) (typeRepFromVal (Some 1))
deny $ eqTypeRep (typeRep :: _ (Optional Person)) (typeRepFromVal (Some 1))
where
typeRecord :: TypeRep { age :: Int, name :: String }
typeRecord = typeRep
-- -- A data type without a typeable instance
-- data Break
-- -- The following should not compile since Break does not have a typeable instance
-- typeRecordBreak :: TypeRep {break::Break, name::String}
-- typeRecordBreak = typeRep
newtype Person2 = Person2 { name :: String, location :: String }
instance tagPerson2 :: Tagged Person2 where
tag = makeTag unit
data Optional a = None | Some a
instance tagOptional :: Tagged Optional where
tag = makeTag unit