on master help sign in
Add parse/print tests for Patterns.
commit24751a3d85a140fbcbe350f771e98e3747029493 authorMax New <maxsnew@gmail.com> dateSun 29 Dec 2013, 20:18 (13 years ago) parent2da9009
2 files changed+61−7
tests/Tests/Property.hs+11−6 tests/Tests/Property/Arbitrary.hs+50−1
tests/Tests/Property.hs+11−6
@@ -5,18 +5,23 @@ import Test.Framework.Providers.QuickCheck2
55import Test.QuickCheck
66
77import SourceSyntax.Literal (Literal)
8−import SourceSyntax.PrettyPrint (pretty)
9−import Parse.Helpers (iParse)
8+import SourceSyntax.PrettyPrint (Pretty, pretty)
9+import Parse.Helpers (IParser, iParse)
1010import Parse.Literal (literal)
11+import Parse.Pattern (expr)
1112import Tests.Property.Arbitrary
1213
1314propertyTests :: Test
1415propertyTests =
1516 testGroup "Parse/Print Agreement Tests"
1617 [
17− testProperty "Literal test" prop_literal_parse_print
18+ testProperty "Literal test" $ prop_parse_print literal
19+ , testProperty "Pattern test" $ prop_parse_print expr
1820 ]
1921
20−prop_literal_parse_print :: Literal -> Bool
21−prop_literal_parse_print l =
22− either (const False) (== l) . iParse literal . show . pretty $ l
22+prop_parse_print :: (Pretty a, Arbitrary a, Eq a) => IParser a -> a -> Bool
23+prop_parse_print p x =
24+ either (const False) (== x) . parse_print p $ x
25+
26+parse_print :: (Pretty a) => IParser a -> a -> Either String a
27+parse_print p = either (Left . show) (Right) . iParse p . show . pretty
tests/Tests/Property/Arbitrary.hs+50−1
@@ -1,16 +1,21 @@
11{-# OPTIONS_GHC -fno-warn-orphans #-}
22module Tests.Property.Arbitrary where
33
4−import Control.Applicative ((<$>))
4+import Control.Applicative ((<$>), (<*>), pure)
55import Test.QuickCheck.Arbitrary
66import Test.QuickCheck.Gen
77
8+import qualified Data.Set as Set
9+import qualified Parse.Helpers (reserveds)
10+
811import SourceSyntax.Literal
12+import SourceSyntax.Pattern
913
1014instance Arbitrary Literal where
1115 arbitrary = oneof [ IntNum <$> arbitrary
1216 , FloatNum <$> arbitrary
1317 , Chr <$> arbitrary
18+ -- This is too permissive
1419 , Str <$> arbitrary
1520 -- Booleans aren't actually source syntax
1621 -- , Boolean <$> arbitrary
@@ -21,3 +26,47 @@ instance Arbitrary Literal where
2126 Chr c -> Chr <$> shrink c
2227 Str s -> Str <$> shrink s
2328 Boolean b -> Boolean <$> shrink b
29+
30+instance Arbitrary Pattern where
31+ arbitrary = sized pat
32+ where pat :: Int -> Gen Pattern
33+ pat n = oneof [ pure PAnything
34+ , PVar <$> lowVar
35+ , PRecord <$> (listOf1 lowVar)
36+ , PLiteral <$> arbitrary
37+ , PAlias <$> lowVar <*> pat (n-1)
38+ , PData <$> capVar <*> sizedPats
39+ ]
40+ where sizedPats = do
41+ len <- choose (0,n)
42+ let m = n `div` len in
43+ vectorOf len $ pat m
44+
45+ shrink pat = case pat of
46+ PAnything -> []
47+ PVar v -> PVar <$> shrinkWHead v
48+ PRecord fs -> PRecord <$> (filter (all $ not.null) . filter (not.null) $ shrink fs)
49+ PLiteral l -> PLiteral <$> shrink l
50+ PAlias s p -> p : (PAlias <$> shrinkWHead s <*> shrink p)
51+ PData s ps -> ps ++ (PData <$> shrinkWHead s <*> shrink ps)
52+ where shrinkWHead (x:xs) = (x:) <$> shrink xs
53+
54+lowVar :: Gen String
55+lowVar = notReserved $ (:) <$> lower <*> listOf varLetter
56+ where lower = elements ['a'..'z']
57+
58+capVar :: Gen String
59+capVar = notReserved $ (:) <$> upper <*> listOf varLetter
60+ where upper = elements ['A'..'Z']
61+
62+varLetter :: Gen Char
63+varLetter = elements $ ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ ['\'', '_']
64+
65+notReserved :: Gen String -> Gen String
66+notReserved = flip exceptFor Parse.Helpers.reserveds
67+
68+exceptFor :: (Ord a) => Gen a -> [a] -> Gen a
69+exceptFor g xs = suchThat g notAnX
70+ where notAnX = flip Set.notMember xset
71+ xset = Set.fromList xs
72+