packages feed

aeson-schemas-1.3.2: test/Tests/SchemaQQ/TH.hs

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Tests.SchemaQQ.TH where

import Control.DeepSeq (deepseq)
import Data.Aeson (FromJSON, ToJSON)
import Foreign.C (CBool(..))
import Language.Haskell.TH.Quote (QuasiQuoter(..))
import Language.Haskell.TH.TestUtils
    (MockedMode(..), QMode(..), QState(..), loadNames, runTestQ, runTestQErr)

import Data.Aeson.Schema (schema, showSchema)
import TestUtils (mkExpQQ)
import TestUtils.DeepSeq ()

type UserSchema = [schema| { name: Text } |]
type ExtraSchema = [schema| { extra: Text } |]
type ExtraSchema2 = [schema| { extra: Maybe Text } |]

newtype Status = Status Int
  deriving (Show,FromJSON,ToJSON)

-- | The type referenced here should not be imported in SchemaQQ.hs nor included in 'knownNames'.
type SchemaWithHiddenImport = [schema| { a: CBool } |]
deriving instance ToJSON CBool
deriving instance FromJSON CBool

-- Compile above types before reifying
$(return [])

type WithUser = [schema| { user: #UserSchema } |]

-- Compile above types before reifying
$(return [])

qState :: QState 'FullyMocked
qState = QState
  { mode = MockQ
  , knownNames =
      [ ("Status", ''Status)
      , ("UserSchema", ''UserSchema)
      , ("ExtraSchema", ''ExtraSchema)
      , ("ExtraSchema2", ''ExtraSchema2)
      , ("Tests.SchemaQQ.TH.UserSchema", ''UserSchema)
      , ("Tests.SchemaQQ.TH.ExtraSchema", ''ExtraSchema)
      , ("SchemaWithHiddenImport", ''SchemaWithHiddenImport)
      , ("WithUser", ''WithUser)
      , ("Int", ''Int)
      ]
  , reifyInfo = $(loadNames
      [ ''UserSchema
      , ''ExtraSchema
      , ''ExtraSchema2
      , ''SchemaWithHiddenImport
      , ''WithUser
      , ''Int
      ]
    )
  }

-- | A quasiquoter for generating the string representation of a schema.
--
-- Also runs the `schema` quasiquoter at runtime, to get coverage information.
schemaRep :: QuasiQuoter
schemaRep = mkExpQQ $ \s ->
  let schemaType = quoteType schema s
  in [| runTestQ qState (quoteType schema s) `deepseq` showSchema @ $schemaType |]

schemaErr :: QuasiQuoter
schemaErr = mkExpQQ $ \s -> [| runTestQErr qState (quoteType schema s) |]