{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# OPTIONS_GHC -Wno-unused-top-binds #-} {-# OPTIONS_GHC -Wno-unused-imports #-} module Property ( propertyTests ) where import Data.Either (either, isRight) import qualified Data.Graph.Inductive as G import Data.Text (Text) import Hedgehog (Gen, Property, (===)) import qualified Hedgehog as Hog import Hedgehog.Function (Arg, Vary) import qualified Hedgehog.Function as Hog import qualified Hedgehog.Gen as Hog import qualified Hedgehog.Range as Hog import Parser (parserTests) import Test.Tasty import Test.Tasty.Hedgehog import Text.Parsec import VeriFuzz import VeriFuzz.Result import VeriFuzz.Verilog.Lex import VeriFuzz.Verilog.Parser randomDAG' :: Gen Circuit randomDAG' = Hog.resize 30 randomDAG acyclicGraph :: Property acyclicGraph = Hog.property $ do xs <- Hog.forAllWith (const "") randomDAG' Hog.assert $ simp xs where simp g = (== G.noNodes (getCircuit g)) . sum . fmap length . G.scc . getCircuit $ g type GenFunctor f a b c = ( Functor f , Show (f a) , Show a, Arg a, Vary a , Show b, Arg b, Vary b , Show c , Eq (f c) , Show (f c) ) mapCompose :: forall f a b c . GenFunctor f a b c => (forall x . Gen x -> Gen (f x)) -> Gen a -> Gen b -> Gen c -> Property mapCompose genF genA genB genC = Hog.property $ do g <- Hog.forAllFn $ Hog.fn @a genB f <- Hog.forAllFn $ Hog.fn @b genC xs <- Hog.forAll $ genF genA fmap (f . g) xs === fmap f (fmap g xs) propertyResultInterrupted :: Property propertyResultInterrupted = do mapCompose genResult (Hog.int (Hog.linear 0 100)) (Hog.int (Hog.linear 0 100)) (Hog.int (Hog.linear 0 100)) where genResult :: Gen a -> Gen (Result Text a) genResult a = Hog.choice [Pass <$> a, Fail <$> Hog.text (Hog.linear 1 100) Hog.unicode] propertyTests :: TestTree propertyTests = testGroup "Property Tests" [ testProperty "acyclic graph generation check" acyclicGraph , testProperty "fmap for Result" propertyResultInterrupted , parserTests ]