dhall-1.42.3: tests/Dhall/Test/TH.hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
module Dhall.Test.TH where
import Control.Exception (throwIO)
import Data.Either.Validation (Validation (..))
import Data.Time (TimeOfDay (..), TimeZone (..), fromGregorian)
import Dhall.TH (HaskellType (..))
import Test.Tasty (TestTree)
import qualified Data.Text
import qualified Dhall
import qualified Dhall.TH
import qualified Test.Tasty as Tasty
import qualified Test.Tasty.HUnit as Tasty.HUnit
Dhall.TH.makeHaskellTypeFromUnion "T" "./tests/th/example.dhall"
deriving instance Eq T
deriving instance Show T
Dhall.TH.makeHaskellTypes
[ MultipleConstructors "Department" "./tests/th/Department.dhall"
, SingleConstructor "Employee" "MakeEmployee" "./tests/th/Employee.dhall"
, SingleConstructor "TimeExample" "TimeExample" "./tests/th/Time.dhall"
]
deriving instance Eq Department
deriving instance Show Department
deriving instance Eq Employee
deriving instance Show Employee
deriving instance Eq TimeExample
deriving instance Show TimeExample
Dhall.TH.makeHaskellTypes
[ SingleConstructor "Bar" "MakeBar" "(./tests/th/issue2066.dhall).Bar"
, SingleConstructor "Foo" "MakeFoo" "(./tests/th/issue2066.dhall).Foo"
, MultipleConstructors "Qux" "(./tests/th/issue2066.dhall).Qux"
]
deriving instance Eq Bar
deriving instance Show Bar
deriving instance Eq Foo
deriving instance Show Foo
deriving instance Eq Qux
deriving instance Show Qux
tests :: TestTree
tests = Tasty.testGroup "Template Haskell" [ makeHaskellTypeFromUnion ]
makeHaskellTypeFromUnion :: TestTree
makeHaskellTypeFromUnion = Tasty.HUnit.testCase "makeHaskellTypeFromUnion" $ do
t0 <- Dhall.input Dhall.auto "let T = ./tests/th/example.dhall in T.A { x = True, y = [ \"ABC\" ] }"
Tasty.HUnit.assertEqual "" t0 A{ x = True, y = [ "ABC" ] }
t1 <- Dhall.input Dhall.auto "let T = ./tests/th/example.dhall in T.B (Some [ 1 ])"
Tasty.HUnit.assertEqual "" t1 (B (Just [ 1 ]))
t2 <- Dhall.input Dhall.auto "let T = ./tests/th/example.dhall in T.C"
Tasty.HUnit.assertEqual "" t2 C
employee <- Dhall.input Dhall.auto "let Department = ./tests/th/Department.dhall in { name = \"John\", department = Department.Marketing }"
Tasty.HUnit.assertEqual "" employee MakeEmployee{ name = "John", department = Marketing }
qux <- Dhall.input Dhall.auto "let T = ./tests/th/issue2066.dhall in T.Qux.Foo { foo = +2, bar = { baz = +3 } }"
Tasty.HUnit.assertEqual "" qux (Foo MakeFoo{ foo = 2, bar = MakeBar{ baz = 3 } })
timex <- Dhall.input Dhall.auto "let T = ./tests/th/Time.dhall in { txTime = 21:12:00, txDate = 1976-04-01, txTimeZone = +05:00 } : T"
Tasty.HUnit.assertEqual "" timex TimeExample { txTime = tod, txDate = day, txTimeZone = tz}
where
tod = TimeOfDay { todHour = 21, todMin = 12, todSec = 0 }
day = fromGregorian 1976 4 1
tz = TimeZone { timeZoneMinutes = 300, timeZoneSummerOnly = False, timeZoneName = "" }
Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions
{ Dhall.TH.constructorModifier = ("My" <>)
, Dhall.TH.fieldModifier = ("my" <>) . Data.Text.toTitle
})
[ MultipleConstructors "MyT" "./tests/th/example.dhall"
, MultipleConstructors "MyDepartment" "./tests/th/Department.dhall"
, SingleConstructor "MyEmployee" "Employee" "./tests/th/Employee.dhall"
]
deriving instance Eq MyT
deriving instance Eq MyDepartment
deriving instance Eq MyEmployee
deriving instance Show MyT
deriving instance Show MyDepartment
deriving instance Show MyEmployee
Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions
{ Dhall.TH.constructorModifier = ("My" <>)
, Dhall.TH.fieldModifier = ("my" <>) . Data.Text.toTitle
, Dhall.TH.generateFromDhallInstance = False
, Dhall.TH.generateToDhallInstance = False
})
[ SingleConstructor "MyHKSingle" "HKSingle" "./tests/th/HigherKindSingle.dhall"
, MultipleConstructors "MyHKUnion" "./tests/th/HigherKindUnion.dhall"
]
type MyHKSingle_ = MyHKSingle Maybe Int
type MyHKUnion_ = MyHKUnion Bool Int
deriving instance Eq MyHKSingle_
deriving instance Show MyHKSingle_
deriving instance Dhall.Generic MyHKSingle_
instance Dhall.FromDhall MyHKSingle_
instance Dhall.ToDhall MyHKSingle_
deriving instance Eq MyHKUnion_
deriving instance Show MyHKUnion_
deriving instance Dhall.Generic MyHKUnion_
instance Dhall.FromDhall MyHKUnion_
instance Dhall.ToDhall MyHKUnion_
testMakeHaskellTypesWith :: TestTree
testMakeHaskellTypesWith = Tasty.HUnit.testCase "makeHaskellTypesWith" $ do
let text0 = "let T = ./tests/th/example.dhall in T.A { x = True, y = [] : List Text }"
ref0 = MyA{ myX = True, myY = [] }
myTest text0 ref0
let text1 = "let T = ./tests/th/example.dhall in T.B (None (List Natural))"
ref1 = MyB Nothing
myTest text1 ref1
let text2 = "let T = ./tests/th/example.dhall in T.C"
ref2 = MyC
myTest text2 ref2
let textDepartment = "let T = ./tests/th/Department.dhall in T.Sales"
refDepartment = MySales
myTest textDepartment refDepartment
let textEmployee = "let T = ./tests/th/Department.dhall in T.Sales"
refEmployee = MyEmployee{ myName = "", myDepartment = MySales }
myTest textEmployee refEmployee
let textHKSingle = "let T = (./tests/th/HigherKindSingle.dhall) Optional Int in T { foo = +1, bar = Some +2, bam = \"\" }"
refHKSingle = MyHKSingle { myFoo = 1, myBar = Just 2, myBam = "" } :: MyHKSingle_
myTest textHKSingle refHKSingle
let textHKUnion0 = "let T = (./tests/th/HigherKindUnion.dhall) Bool Int in T.Foo True"
refHKUnion0 = MyFoo True :: MyHKUnion_
myTest textHKUnion0 refHKUnion0
let textHKUnion1 = "let T = (./tests/th/HigherKindUnion.dhall) Bool Int in T.Bar +1"
refHKUnion1 = MyBar 1 :: MyHKUnion_
myTest textHKUnion1 refHKUnion1
where
myTest text ref = do
expr <- Dhall.inputExpr text
t <- case Dhall.extract Dhall.auto expr of
Failure e -> throwIO e
Success t -> return t
Tasty.HUnit.assertEqual "" t ref
Tasty.HUnit.assertEqual "" expr $ Dhall.embed Dhall.inject ref
Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions
{ Dhall.TH.constructorModifier = ("NoFromDhall" <>)
, Dhall.TH.fieldModifier = ("noFromDhall" <>) . Data.Text.toTitle
, Dhall.TH.generateFromDhallInstance = False
})
[ MultipleConstructors "NoFromDhallT" "./tests/th/example.dhall"
]
instance Dhall.FromDhall NoFromDhallT
Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions
{ Dhall.TH.constructorModifier = ("NoToDhall" <>)
, Dhall.TH.fieldModifier = ("noToDhall" <>) . Data.Text.toTitle
, Dhall.TH.generateToDhallInstance = False
})
[ MultipleConstructors "NoToDhallT" "./tests/th/example.dhall"
]
instance Dhall.ToDhall NoToDhallT
Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions
{ Dhall.TH.constructorModifier = ("NoInstances" <>)
, Dhall.TH.fieldModifier = ("noInstances" <>) . Data.Text.toTitle
, Dhall.TH.generateFromDhallInstance = False
, Dhall.TH.generateToDhallInstance = False
})
[ MultipleConstructors "NoInstancesT" "./tests/th/example.dhall"
]
deriving instance Dhall.Generic NoInstancesT
instance Dhall.FromDhall NoInstancesT
instance Dhall.ToDhall NoInstancesT
Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions
{ Dhall.TH.constructorModifier = ("Strict" <>)
, Dhall.TH.fieldModifier = ("strict" <>) . Data.Text.toTitle
, Dhall.TH.makeStrict = True
})
[ MultipleConstructors "StrictFields" "./tests/th/example.dhall"
]