SCargotQC.hs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module Data.SCargot.ReprQC (reprQC) where
  3. import Data.SCargot ( SExprParser
  4. , SExprPrinter
  5. , mkParser
  6. , flatPrint
  7. , encodeOne
  8. , decodeOne
  9. , asRich
  10. , asWellFormed
  11. )
  12. import Data.SCargot.Repr ( SExpr(..)
  13. , RichSExpr
  14. , fromRich
  15. , toRich
  16. , WellFormedSExpr(..)
  17. , fromWellFormed
  18. , toWellFormed
  19. )
  20. import Test.QuickCheck
  21. import Test.QuickCheck.Arbitrary
  22. import Text.Parsec (char)
  23. import Text.Parsec.Text (Parser)
  24. instance Arbitrary a => Arbitrary (SExpr a) where
  25. arbitrary = sized $ \n ->
  26. if n <= 0
  27. then pure SNil
  28. else oneof [ SAtom <$> arbitrary
  29. , do
  30. k <- choose (0, n)
  31. elems <- sequence [ resize (n-k) arbitrary
  32. | _ <- [0..k]
  33. ]
  34. tail <- oneof [ SAtom <$> arbitrary
  35. , pure SNil
  36. ]
  37. pure (foldr SCons tail elems)
  38. ]
  39. instance Arbitrary a => Arbitrary (RichSExpr a) where
  40. arbitrary = toRich `fmap` arbitrary
  41. instance Arbitrary a => Arbitrary (WellFormedSExpr a) where
  42. arbitrary = sized $ \n ->
  43. oneof [ WFSAtom <$> arbitrary
  44. , do
  45. k <- choose (0, n)
  46. WFSList <$> sequence
  47. [ resize (n-k) arbitrary
  48. | _ <- [0..k]
  49. ]
  50. ]
  51. parser :: SExprParser () (SExpr ())
  52. parser = mkParser (() <$ char 'X')
  53. printer :: SExprPrinter () (SExpr ())
  54. printer = flatPrint (const "X")
  55. richIso :: SExpr () -> Bool
  56. richIso s = fromRich (toRich s) == s
  57. richIsoBk :: RichSExpr () -> Bool
  58. richIsoBk s = toRich (fromRich s) == s
  59. wfIso :: SExpr () -> Bool
  60. wfIso s = case toWellFormed s of
  61. Left _ -> True
  62. Right y -> s == fromWellFormed y
  63. wfIsoBk :: WellFormedSExpr () -> Bool
  64. wfIsoBk s = toWellFormed (fromWellFormed s) == Right s
  65. encDec :: SExpr () -> Bool
  66. encDec s = decodeOne parser (encodeOne printer s) == Right s
  67. encDecRich :: RichSExpr () -> Bool
  68. encDecRich s = decodeOne (asRich parser) (encodeOne printer (fromRich s))
  69. == Right s
  70. encDecWF :: WellFormedSExpr () -> Bool
  71. encDecWF s = decodeOne (asWellFormed parser) (encodeOne printer (fromWellFormed s))
  72. == Right s
  73. reprQC :: IO ()
  74. reprQC = do
  75. putStrLn "The SExpr <--> Rich translation should be isomorphic"
  76. quickCheck richIso
  77. quickCheck richIsoBk
  78. putStrLn "The SExpr <--> WF translation should be near-isomorphic"
  79. quickCheck wfIso
  80. quickCheck wfIsoBk
  81. putStrLn "This should be true when parsing, as well"
  82. quickCheck encDec
  83. quickCheck encDecRich
  84. quickCheck encDecWF