mirror of
https://github.com/zap-proto/haskell.git
synced 2026-10-30 15:05:00 +00:00
104 lines
3.4 KiB
Haskell
104 lines
3.4 KiB
Haskell
{-# LANGUAGE DataKinds #-}
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
{-# LANGUAGE OverloadedLabels #-}
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
{-# LANGUAGE TypeFamilies #-}
|
|
|
|
-- | This module defines a test that tries to walk over the
|
|
-- CodeGeneratorRequest in `tests/data/schema-codegenreq`,
|
|
-- failing if any of the data is not as expected.
|
|
module WalkSchemaCodeGenRequest (walkSchemaCodeGenRequestTest) where
|
|
|
|
import Zap
|
|
( Raw,
|
|
bsToRaw,
|
|
hasField,
|
|
index,
|
|
length,
|
|
parseField,
|
|
readField,
|
|
textBytes,
|
|
)
|
|
import qualified Zap.Gen.Zap.Schema as Schema
|
|
import qualified Zap.Message as M
|
|
import Zap.TraversalLimit (LimitT, evalLimitT, execLimitT)
|
|
import Control.Monad (when)
|
|
import Control.Monad.Trans.Class (lift)
|
|
import qualified Data.ByteString as BS
|
|
import Data.Function ((&))
|
|
import qualified Data.Vector as V
|
|
import Test.Hspec
|
|
import Prelude hiding (length)
|
|
|
|
nodeNames :: V.Vector BS.ByteString
|
|
nodeNames =
|
|
V.fromList
|
|
[ "Import",
|
|
"annotation",
|
|
"Value",
|
|
"Type"
|
|
]
|
|
|
|
-- TODO: This contains a bit of copypasta from some of the untyped tests; should
|
|
-- factor that out.
|
|
walkSchemaCodeGenRequestTest :: Spec
|
|
walkSchemaCodeGenRequestTest =
|
|
describe "Various sanity checks on a known schema CodeGeneratorRequest" $
|
|
it "Should match misc. expectations" $ do
|
|
-- TODO: the above description betrays that this test isn't
|
|
-- especially well defined at a granularity that I(zenhack)
|
|
-- know how to tell hspec about, because there are data
|
|
-- dependencies between conceptual tests (we walk over the
|
|
-- data checking various things as we go).
|
|
--
|
|
-- It would be nice if we could mark off individual checks for
|
|
-- hspec's reporting somehow.
|
|
bytes <- BS.readFile "tests/data/schema-codegenreq"
|
|
root <- evalLimitT maxBound (bsToRaw bytes)
|
|
endQuota <- execLimitT 4096 (reader root)
|
|
endQuota `shouldBe` 3409
|
|
where
|
|
reader :: Raw Schema.CodeGeneratorRequest 'M.Const -> LimitT IO ()
|
|
reader req = do
|
|
nodes <- req & readField #nodes
|
|
requestedFiles <- req & readField #requestedFiles
|
|
lift $ length nodes `shouldBe` 37
|
|
lift $ length requestedFiles `shouldBe` 1
|
|
mapM_ (walkNode nodes) [0, 1 .. 36]
|
|
walkNode nodes i = do
|
|
node <- index i nodes
|
|
-- None of the nodes in the schema have parameters:
|
|
False <- node & hasField #parameters
|
|
-- And none of them are generic:
|
|
False <- node & parseField #isGeneric
|
|
|
|
nameList <- node & readField #displayName
|
|
name <- textBytes nameList
|
|
prefixLen <- parseField #displayNamePrefixLength node
|
|
let baseName = BS.drop (fromIntegral prefixLen) name
|
|
|
|
when (i < V.length nodeNames && baseName /= (nodeNames V.! i)) $
|
|
error "Incorrect name."
|
|
|
|
has <- node & hasField #annotations
|
|
|
|
-- there are two annotations in all of the nodes, at these indicies:
|
|
case (has, i `elem` [4, 9]) of
|
|
(False, False) -> return ()
|
|
(True, True) -> do
|
|
1 <- length <$> readField #annotations node
|
|
return ()
|
|
(False, True) ->
|
|
error $
|
|
"Node at index "
|
|
++ show i
|
|
++ " should have had"
|
|
++ "an annotation."
|
|
(True, False) ->
|
|
error $
|
|
"Node at index "
|
|
++ show i
|
|
++ " should not "
|
|
++ "have had an annotation."
|