{-# LANGUAGE ScopedTypeVariables #-} module SchemaQuickCheck (schemaCGRQuickCheck) where import qualified Data.ByteString as BS import Capnp.Bits (WordCount) import Capnp.Classes (fromStruct) import Capnp.Errors (Error) import Capnp.Message as M import Capnp.TraversalLimit (LimitT, runLimitT) import qualified Capnp.Basics as Basics import qualified Capnp.Gen.Capnp.Schema as Schema import qualified Capnp.Untyped as Untyped -- Testing framework imports import Test.Hspec import Test.QuickCheck -- Schema generation imports import SchemaGeneration import Util -- Schema validation imports import Control.Monad.Catch as C -- Functions to generate valid CGRs generateCGR :: Schema -> IO BS.ByteString generateCGR schema = capnpCompile (show schema) "-" -- Functions to validate CGRs decodeCGR :: BS.ByteString -> IO (WordCount, Int) decodeCGR bytes = do let reader :: Untyped.Struct M.ConstMsg -> LimitT IO Int reader struct = do req :: Schema.CodeGeneratorRequest M.ConstMsg <- fromStruct struct nodes <- Schema.get_CodeGeneratorRequest'nodes req _ <- Schema.get_CodeGeneratorRequest'requestedFiles req return (Basics.length nodes) msg <- M.decode bytes (numNodes, endQuota) <- runLimitT 1024 (Untyped.rootPtr msg >>= reader) return (endQuota, numNodes) -- QuickCheck properties prop_schemaValid :: Schema -> Property prop_schemaValid schema = ioProperty $ do compiled <- generateCGR schema decoded <- try $ decodeCGR compiled return $ case (decoded :: Either Error (WordCount, Int)) of Left _ -> False Right _ -> True schemaCGRQuickCheck :: Spec schemaCGRQuickCheck = describe "generateCGR an decodeCGR agree" $ it "successfully decodes generated schema" $ property $ prop_schemaValid <$> genSchema