digit-0.5.2: test/Main.hs
{-# LANGUAGE RankNTypes #-}
module Main(
main
) where
import Data.Digit
import Numeric.Natural (Natural)
import Prelude (maxBound)
import Papa hiding (re)
import Hedgehog(Property, Gen, forAll, property, assert, (===))
import Test.Tasty(TestTree, defaultMain, testGroup)
import Test.Tasty.Hedgehog(testProperty)
import Test.Tasty.HUnit(testCase, (@?=))
import qualified Hedgehog.Gen as Gen(choice, integral, unicode, hexit, filter)
import qualified Hedgehog.Range as Range(linear)
import Text.Parsec(parse, ParseError, Parsec, eof)
testPrism ::
(Show x, Eq x) =>
Gen x
-> String
-> Prism' x Digit
-> [(x, Digit)]
-> [TestTree]
testPrism g n p x =
testProperty
(n ++ " prism invalid values")
(
property $
do c <- forAll . Gen.filter (`notElem` (map fst x)) $ g
(c ^? p :: Maybe Digit) === Nothing
) :
(
x >>= \(c, d) ->
[
testCase
(n ++ " prism ->")
((c ^? p :: Maybe Digit) @?= Just d)
, testCase
(n ++ " prism <-")
(p # d @?= c)
]
)
testParser ::
String
-> Parsec String () Digit
-> [(Char, Digit)]
-> [TestTree]
testParser n p x =
(
let n' = n ++ " parser invalid values"
in testProperty
n'
(
property $
do c <- forAll . Gen.filter (`notElem` (map fst x)) . Gen.choice $ [Gen.hexit, Gen.unicode]
assert (isLeft (parse p (n' ++ " test") [c] :: Either ParseError Digit))
)
) :
(
x >>= \(c, d) ->
[
let n' = n ++ " parses exactly one character"
in testCase
n'
((parse (p <* eof) (n' ++ " test") [c] :: Either ParseError Digit) @?= Right d)
, let n' = n ++ " parses the correct digit"
in testCase
n'
((parse p (n' ++ "test") (c:"xyz") :: Either ParseError Digit) @?= Right d)
]
)
integralPrism ::
(Show n, Integral n) =>
String
-> Prism' n Digit
-> [(n, Digit)]
-> [TestTree]
integralPrism =
testPrism (Gen.choice [Gen.integral (Range.linear 0 9), Gen.integral (Range.linear 10 99999), Gen.integral (Range.linear (-1) (-99999))])
charPrism ::
String
-> Prism' Char Digit
-> [(Char, Digit)]
-> [TestTree]
charPrism =
testPrism (Gen.choice [Gen.hexit, Gen.unicode])
genNatural :: Gen Natural
genNatural = fromIntegral <$> Gen.integral (Range.linear 0 (maxBound :: Int))
prop_natural_digits_roundtrip :: Property
prop_natural_digits_roundtrip = property $ do
n <- forAll genNatural
digitsToNatural (naturalToDigits n) === Just n
digitNaturalTests :: TestTree
digitNaturalTests = testGroup "digit Natural tests"
[ testProperty "Natural <-> NonEmpty Digit" prop_natural_digits_roundtrip
]
main ::
IO ()
main = defaultMain $
testGroup "All Digit Tests"
[ digitBaseTests
, digitNaturalTests
]
digitBaseTests :: TestTree
digitBaseTests =
testGroup "digit parser/prism tests" $
let q0 = ('0', Digit0)
q1 = ('1', Digit1)
q2 = ('2', Digit2)
q3 = ('3', Digit3)
q4 = ('4', Digit4)
q5 = ('5', Digit5)
q6 = ('6', Digit6)
q7 = ('7', Digit7)
q8 = ('8', Digit8)
q9 = ('9', Digit9)
qa = ('a', Digita)
qb = ('b', Digitb)
qc = ('c', Digitc)
qd = ('d', Digitd)
qe = ('e', Digite)
qf = ('f', Digitf)
qA = ('A', DigitA)
qB = ('B', DigitB)
qC = ('C', DigitC)
qD = ('D', DigitD)
qE = ('E', DigitE)
qF = ('F', DigitF)
r0 :: (Integer, Digit)
r0 = (0 , Digit0)
r1 :: (Integer, Digit)
r1 = (1 , Digit1)
r2 :: (Integer, Digit)
r2 = (2 , Digit2)
r3 :: (Integer, Digit)
r3 = (3 , Digit3)
r4 :: (Integer, Digit)
r4 = (4 , Digit4)
r5 :: (Integer, Digit)
r5 = (5 , Digit5)
r6 :: (Integer, Digit)
r6 = (6 , Digit6)
r7 :: (Integer, Digit)
r7 = (7 , Digit7)
r8 :: (Integer, Digit)
r8 = (8 , Digit8)
r9 :: (Integer, Digit)
r9 = (9 , Digit9)
ra :: (Integer, Digit)
ra = (10 , Digita)
rb :: (Integer, Digit)
rb = (11 , Digitb)
rc :: (Integer, Digit)
rc = (12 , Digitc)
rd :: (Integer, Digit)
rd = (13 , Digitd)
re :: (Integer, Digit)
re = (14 , Digite)
rf :: (Integer, Digit)
rf = (15 , Digitf)
rA :: (Integer, Digit)
rA = (10 , DigitA)
rB :: (Integer, Digit)
rB = (11 , DigitB)
rC :: (Integer, Digit)
rC = (12 , DigitC)
rD :: (Integer, Digit)
rD = (13 , DigitD)
rE :: (Integer, Digit)
rE = (14 , DigitE)
rF :: (Integer, Digit)
rF = (15 , DigitF)
in concat [
charPrism "charBinaryNoZero" charBinaryNoZero [q1]
, charPrism "charBinary" charBinary [q0, q1]
, charPrism "charOctalNoZero" charOctalNoZero [q1, q2, q3, q4, q5, q6, q7]
, charPrism "charOctal" charOctal [q0, q1, q2, q3, q4, q5, q6, q7]
, charPrism "charDecimalNoZero" charDecimalNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9]
, charPrism "charDecimal" charDecimal [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9]
, charPrism "charHexadecimalNoZero" charHexadecimalNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf]
, charPrism "charHexadecimal" charHexadecimal [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf]
, charPrism "charHEXADECIMALNoZero" charHEXADECIMALNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qA, qB, qC, qD, qE, qF]
, charPrism "charHEXADECIMAL" charHEXADECIMAL [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qA, qB, qC, qD, qE, qF]
, charPrism "charHeXaDeCiMaLNoZero" charHeXaDeCiMaLNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf, qA, qB, qC, qD, qE, qF]
, charPrism "charHeXaDeCiMaL" charHeXaDeCiMaL [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf, qA, qB, qC, qD, qE, qF]
, integralPrism "integralBinaryNoZero" integralBinaryNoZero [r1]
, integralPrism "integralBinary" integralBinary [r0, r1]
, integralPrism "integralOctalNoZero" integralOctalNoZero [r1, r2, r3, r4, r5, r6, r7]
, integralPrism "integralOctal" integralOctal [r0, r1, r2, r3, r4, r5, r6, r7]
, integralPrism "integralDecimalNoZero" integralDecimalNoZero [r1, r2, r3, r4, r5, r6, r7, r8, r9]
, integralPrism "integralDecimal" integralDecimal [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9]
, integralPrism "integralHexadecimalNoZero" integralHexadecimalNoZero [r1, r2, r3, r4, r5, r6, r7, r8, r9, ra, rb, rc, rd, re, rf]
, integralPrism "integralHexadecimal" integralHexadecimal [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, ra, rb, rc, rd, re, rf]
, integralPrism "integralHEXADECIMALNoZero" integralHEXADECIMALNoZero [r1, r2, r3, r4, r5, r6, r7, r8, r9, rA, rB, rC, rD, rE, rF]
, integralPrism "integralHEXADECIMAL" integralHEXADECIMAL [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, rA, rB, rC, rD, rE, rF] , testParser "parseBinaryNoZero" parseBinaryNoZero [q1]
, testParser "parseBinary" parseBinary [q0, q1]
, testParser "parseOctalNoZero" parseOctalNoZero [q1, q2, q3, q4, q5, q6, q7]
, testParser "parseOctal" parseOctal [q0, q1, q2, q3, q4, q5, q6, q7]
, testParser "parseDecimalNoZero" parseDecimalNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9]
, testParser "parseDecimal" parseDecimal [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9]
, testParser "parseHexadecimalNoZero" parseHexadecimalNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf]
, testParser "parseHexadecimal" parseHexadecimal [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf]
, testParser "parseHEXADECIMALNoZero" parseHEXADECIMALNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qA, qB, qC, qD, qE, qF]
, testParser "parseHEXADECIMALDecimal" parseHEXADECIMAL [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qA, qB, qC, qD, qE, qF]
, testParser "parseHeXaDeCiMaLNoZero" parseHeXaDeCiMaLNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf, qA, qB, qC, qD, qE, qF]
, testParser "parseHeXaDeCiMaLDecimal" parseHeXaDeCiMaL [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf, qA, qB, qC, qD, qE, qF]
, testParser "parse0" parse0 [q0]
, testParser "parse1" parse1 [q1]
, testParser "parse2" parse2 [q2]
, testParser "parse3" parse3 [q3]
, testParser "parse4" parse4 [q4]
, testParser "parse5" parse5 [q5]
, testParser "parse6" parse6 [q6]
, testParser "parse7" parse7 [q7]
, testParser "parse8" parse8 [q8]
, testParser "parse9" parse9 [q9]
, testParser "parsea" parsea [qa]
, testParser "parseb" parseb [qb]
, testParser "parsec" parsec [qc]
, testParser "parsed" parsed [qd]
, testParser "parsee" parsee [qe]
, testParser "parsef" parsef [qf]
, testParser "parseA" parseA [qA]
, testParser "parseB" parseB [qB]
, testParser "parseC" parseC [qC]
, testParser "parseD" parseD [qD]
, testParser "parseE" parseE [qE]
, testParser "parseF" parseF [qF]
, testParser "parseAa" parseAa [qA, qa]
, testParser "parseBb" parseBb [qB, qb]
, testParser "parseCc" parseCc [qC, qc]
, testParser "parseDd" parseDd [qD, qd]
, testParser "parseEe" parseEe [qE, qe]
, testParser "parseFf" parseFf [qF, qf]
]