{-# LANGUAGE TemplateHaskell #-} module Elm.DeriveSpec (spec) where import Elm.Derive import Elm.TyRep import Data.Proxy import Test.Hspec import Data.Char (toLower) data Foo = Foo { f_name :: String , f_blablub :: Int } deriving (Show, Eq) data Bar a = Bar { b_name :: a , b_blablub :: Int , b_tuple :: (Int, String) , b_list :: [Bool] } deriving (Show, Eq) data Change a = Change { _before :: a, _after :: a } data Baz a = Baz1 { _fOo :: Int, _qux :: a } | Baz2 { _bar :: Int, _sTr :: String } | Zob a data Qux a = Qux1 { _quxfoo :: Int, _quxqux :: a } | Qux2 { _quxbar :: Int, _quxstr :: String } data Test a = Test { _t1 :: Change Int , _t2 :: Change a } data SomeOpts a = Okay Int | NotOkay a data Simple = SimpleA | SimpleB deriveElmDef defaultOptions ''Foo deriveElmDef defaultOptions ''Bar deriveElmDef defaultOptions ''SomeOpts deriveElmDef defaultOptions { fieldLabelModifier = drop 1 . map toLower } ''Baz deriveElmDef defaultOptions { fieldLabelModifier = drop 1 . map toLower } ''Test deriveElmDef defaultOptions { fieldLabelModifier = drop 4 . map toLower, sumEncoding = TaggedObject "key" "value" } ''Qux deriveElmDef defaultOptions { constructorTagModifier = drop 6 . map toLower} ''Simple testElm :: ETypeDef testElm = ETypeAlias $ EAlias { ea_name = ETypeName { et_name = "Test" , et_args = [ETVar {tv_name = "a"}] } , ea_fields = [ ("t1",ETyApp (ETyCon (ETCon {tc_name = "Change"})) (ETyCon (ETCon {tc_name = "Int"}))) , ("t2",ETyApp (ETyCon (ETCon {tc_name = "Change"})) (ETyVar (ETVar {tv_name = "a"}))) ] , ea_omit_null = False , ea_newtype = False , ea_unwrap_unary = True } fooElm :: ETypeDef fooElm = ETypeAlias $ EAlias { ea_name = ETypeName { et_name = "Foo" , et_args = [] } , ea_fields = [("f_name",ETyCon (ETCon {tc_name = "String"})),("f_blablub",ETyCon (ETCon {tc_name = "Int"}))] , ea_omit_null = False , ea_newtype = False , ea_unwrap_unary = True } barElm :: ETypeDef barElm = ETypeAlias $ EAlias { ea_name = ETypeName { et_name = "Bar" , et_args = [ETVar {tv_name = "a"}] } , ea_fields = [ ("b_name",ETyVar (ETVar {tv_name = "a"})) , ("b_blablub",ETyCon (ETCon {tc_name = "Int"})) , ("b_tuple",ETyApp (ETyApp (ETyTuple 2) (ETyCon (ETCon {tc_name = "Int"}))) (ETyCon (ETCon {tc_name = "String"}))) , ("b_list",ETyApp (ETyCon (ETCon {tc_name = "List"})) (ETyCon (ETCon {tc_name = "Bool"}))) ] , ea_omit_null = False , ea_newtype = False , ea_unwrap_unary = True } bazElm :: ETypeDef bazElm = ETypeSum $ ESum { es_name = ETypeName {et_name = "Baz", et_args = [ETVar {tv_name = "a"}]} , es_constructors = [ STC "Baz1" "Baz1" (Named [("foo",ETyCon (ETCon {tc_name = "Int"})), ("qux",ETyVar (ETVar {tv_name = "a"}))]) , STC "Baz2" "Baz2" (Named [("bar",ETyCon (ETCon {tc_name = "Int"})), ("str",ETyCon (ETCon {tc_name = "String"}))]) , STC "Zob" "Zob" (Anonymous [ETyVar (ETVar {tv_name = "a"})]) ] , es_type = SumEncoding' ObjectWithSingleField , es_omit_null = False , es_unary_strings = True } quxElm :: ETypeDef quxElm = ETypeSum $ ESum { es_name = ETypeName {et_name = "Qux", et_args = [ETVar {tv_name = "a"}]} , es_constructors = [ STC "Qux1" "Qux1" (Named [("foo",ETyCon (ETCon {tc_name = "Int"})), ("qux",ETyVar (ETVar {tv_name = "a"}))]) , STC "Qux2" "Qux2" (Named [("bar",ETyCon (ETCon {tc_name = "Int"})), ("str",ETyCon (ETCon {tc_name = "String"}))]) ] , es_type = SumEncoding' $ TaggedObject "key" "value" , es_omit_null = False , es_unary_strings = True } someOptsElm :: ETypeDef someOptsElm = ETypeSum $ ESum { es_name = ETypeName { et_name = "SomeOpts" , et_args = [ETVar {tv_name = "a"}] } , es_constructors = [ STC "Okay" "Okay" (Anonymous [ETyCon (ETCon {tc_name = "Int"})]) , STC "NotOkay" "NotOkay" (Anonymous [ETyVar (ETVar {tv_name = "a"})]) ] , es_type = defSumEncoding , es_omit_null = False , es_unary_strings = True } simpleElm :: ETypeDef simpleElm = ETypeSum $ ESum { es_name = ETypeName {et_name = "Simple", et_args = []}, es_constructors = [STC "SimpleA" "a" (Anonymous []),STC "SimpleB" "b" (Anonymous [])] , es_type = SumEncoding' ObjectWithSingleField , es_omit_null = False , es_unary_strings = True } spec :: Spec spec = describe "deriveElmRep" $ it "should produce the correct types" $ do compileElmDef (Proxy :: Proxy Foo) `shouldBe` fooElm compileElmDef (Proxy :: Proxy (Bar a)) `shouldBe` barElm compileElmDef (Proxy :: Proxy (SomeOpts a)) `shouldBe` someOptsElm compileElmDef (Proxy :: Proxy (Baz a)) `shouldBe` bazElm compileElmDef (Proxy :: Proxy (Qux a)) `shouldBe` quxElm compileElmDef (Proxy :: Proxy (Test a)) `shouldBe` testElm compileElmDef (Proxy :: Proxy Simple) `shouldBe` simpleElm