Skip to content

Commit

Permalink
Add tests for the new Parsec parsers
Browse files Browse the repository at this point in the history
  • Loading branch information
smelc committed Aug 27, 2024
1 parent 6361703 commit a2521c1
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cardano-cli/cardano-cli.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ test-suite cardano-cli-test
filepath,
hedgehog,
hedgehog-extras ^>=0.6.1.0,
parsec,
regex-tdfa,
tasty,
tasty-hedgehog,
Expand All @@ -340,6 +341,7 @@ test-suite cardano-cli-test
Test.Cli.ITN
Test.Cli.Json
Test.Cli.MonadWarning
Test.Cli.Parser
Test.Cli.Pioneers.Exercise1
Test.Cli.Pioneers.Exercise2
Test.Cli.Pioneers.Exercise3
Expand Down
99 changes: 99 additions & 0 deletions cardano-cli/test/cardano-cli-test/Test/Cli/Parser.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Test.Cli.Parser
( hprop_integral_reader
, hprop_integral_pair_reader_positive
, hprop_integral_pair_reader_negative
)
where

import Cardano.CLI.EraBased.Options.Common (integralParsecParser,
pairIntegralParsecParser)

import Data.Bits (Bits)
import Data.Data (Proxy (..), Typeable)
import Data.Either (isLeft, isRight)
import Data.Word (Word16)
import qualified Text.Parsec as Parsec

import Hedgehog (Gen, Property, assert, property)
import Hedgehog.Extras (propertyOnce)
import qualified Hedgehog.Gen as Gen
import Hedgehog.Internal.Property (forAll)
import qualified Hedgehog.Range as Gen
import qualified Hedgehog.Range as Range

-- | Execute me with:
-- @cabal test cardano-cli-test --test-options '-p "/integral reader/"'@
hprop_integral_reader :: Property
hprop_integral_reader = property $ do
assert $ isRight $ parse @Word "0"
assert $ isRight $ parse @Word "42"
assert $ isLeft $ parse @Word "-1"
assert $ isLeft $ parse @Word "18446744073709551616"
assert $ isLeft $ parse @Word "-1987090"

w <- forAll $ Gen.word $ Gen.linear minBound maxBound
assert $ isRight $ parse @Word (show w)

assert $ isRight $ parse @Word16 "0"
assert $ isRight $ parse @Word16 "42"
assert $ isLeft $ parse @Word16 "-1"
assert $ isLeft $ parse @Word16 "65536"
assert $ isLeft $ parse @Word16 "298709870987"
assert $ isLeft $ parse @Word16 "-1987090"
where
parse :: (Typeable a, Integral a, Bits a) => String -> Either String a
parse s =
case Parsec.runParser integralParsecParser () "" s of
Left parsecError -> Left $ show parsecError
Right x -> Right x

-- | Execute me with:
-- @cabal test cardano-cli-test --test-options '-p "/integral pair reader positive/"'@
hprop_integral_pair_reader_positive :: Property
hprop_integral_pair_reader_positive = property $ do
validArbitraryTuple <- forAll $ genNumberTuple (Proxy :: Proxy Word)
assert $ isRight $ parse @Word validArbitraryTuple
where
parse :: (Typeable a, Integral a, Bits a) => String -> Either String (a, a)
parse s =
case Parsec.runParser pairIntegralParsecParser () "" s of
Left parsecError -> Left $ show parsecError
Right x -> Right x

genNumberTuple :: forall a. Integral a => Show a => Proxy a -> Gen String
genNumberTuple _ = do
x :: a <- Gen.integral (Range.linear 0 100)
y :: a <- Gen.integral (Range.linear 0 100)
space0 <- genArbitrarySpace
space1 <- genArbitrarySpace
space2 <- genArbitrarySpace
space3 <- genArbitrarySpace
return $
space0 ++ "(" ++ space2 ++ show x ++ space1 ++ "," ++ space2 ++ show y ++ space1 ++ ")" ++ space3

genArbitrarySpace :: Gen String
genArbitrarySpace = Gen.string (Range.linear 0 5) (return ' ')

-- | Execute me with:
-- @cabal test cardano-cli-test --test-options '-p "/integral pair reader negative/"'@
hprop_integral_pair_reader_negative :: Property
hprop_integral_pair_reader_negative = propertyOnce $ do
assert $ isLeft $ parse @Word "(0, 0, 0)"
assert $ isLeft $ parse @Word "(-1, 0)"
assert $ isLeft $ parse @Word "(18446744073709551616, 0)"
assert $ isLeft $ parse @Word "(0, 18446744073709551616)"
assert $ isLeft $ parse @Word "(0, -1)"
assert $ isLeft $ parse @Word "0, 0)"
assert $ isLeft $ parse @Word "(0, 0"
assert $ isLeft $ parse @Word "(0 0)"
assert $ isLeft $ parse @Word "( 0, 0"
where
parse :: (Typeable a, Integral a, Bits a) => String -> Either String (a, a)
parse s =
case Parsec.runParser pairIntegralParsecParser () "" s of
Left parsecError -> Left $ show parsecError
Right x -> Right x

0 comments on commit a2521c1

Please sign in to comment.