1{-# OPTIONS_GHC -W -fno-warn-orphans #-}
2module Test.Property.Arbitrary where
4import Control.Applicative ((<$>), (<*>), pure)
5import Test.QuickCheck.Arbitrary
6import Test.QuickCheck.Gen
8import qualified Data.Set as Set
9import qualified Parse.Helpers (reserveds)
11import qualified AST.Literal as L
12import qualified AST.Pattern as P
13import qualified AST.Type as T
14import qualified AST.Variable as V
17instance Arbitrary V.Raw where
25instance Arbitrary L.Literal where
28 [ L.IntNum <$> arbitrary
29 , L.FloatNum <$> (arbitrary `suchThat` noE)
31 -- This is too permissive
33 -- Booleans aren't actually source syntax
34 -- , Boolean <$> arbitrary
40 L.IntNum <$> shrink int
43 L.FloatNum <$> filter noE (shrink float)
49 L.Str <$> shrink string
52 L.Boolean <$> shrink bool
60genVector :: Int -> (Int -> Gen a) -> Gen [a]
61genVector n generator =
62 do len <- choose (0,n)
63 let m = n `div` (len + 1)
64 vectorOf len $ generator m
66instance Arbitrary v => Arbitrary (P.Pattern v) where
70 pattern :: (Arbitrary v) => Int -> Gen (P.Pattern v)
75 , P.Record <$> (listOf1 lowVar)
76 , P.Literal <$> arbitrary
77 , P.Alias <$> lowVar <*> pattern (n-1)
78 , P.Data <$> arbitrary <*> genVector n pattern
87 P.Var <$> consAndShrink var
90 P.Literal <$> shrink literal
92 P.Alias alias pattern ->
93 pattern : (P.Alias <$> consAndShrink alias <*> shrink pattern)
95 P.Data name patterns ->
96 patterns ++ (P.Data <$> shrink name <*> shrink patterns)
99 P.Record <$> filter (all notNull) (filter notNull (shrink fields))
104consAndShrink :: Arbitrary a => [a] -> [[a]]
105consAndShrink values =
107 [] -> error "Should be nonempty"
108 x:xs -> (x:) <$> shrink xs
111instance Arbitrary v => Arbitrary (T.Type v) where
115 tipe :: Arbitrary v => Int -> Gen (T.Type v)
117 let depthTipe = tipe =<< choose (0,n)
118 field = (,) <$> lowVar <*> depthTipe
119 fields = genVector n (\m -> (,) <$> lowVar <*> tipe m)
120 fields1 = (:) <$> field <*> fields
121 depthTipes = (:) <$> depthTipe <*> genVector n tipe
124 [ T.Lambda <$> depthTipe <*> depthTipe
126 , T.Type <$> arbitrary
127 , T.App <$> (T.Type <$> arbitrary) <*> depthTipes
128 , T.Record <$> fields <*> pure Nothing
129 , T.Record <$> fields1 <*> (Just . T.Var <$> lowVar)
134 T.Lambda arg result ->
135 arg : result : (T.Lambda <$> shrink arg <*> shrink result)
140 T.Aliased name tvars rootType ->
141 rootType : (T.Aliased name <$> shrinkList shrinkPair tvars <*> shrink rootType)
144 T.Type <$> shrink name
147 func : args ++ (T.App <$> shrink func <*> shrink args)
149 T.Record fields extension ->
150 map snd fields ++ record
155 T.Record <$> shrinkList shrinkPair fields <*> pure Nothing
158 do fields' <- filter (not . null) $ shrinkList shrinkPair fields
159 return $ T.Record fields' extension
161 shrinkPair (name, tipe) =
162 (,) <$> consAndShrink name <*> shrink tipe
168 (:) <$> elements ['a'..'z'] <*> listOf varLetter
174 (:) <$> elements ['A'..'Z'] <*> listOf varLetter
179 elements $ ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ ['\'', '_']
182notReserved :: Gen String -> Gen String
184 string `exceptFor` Parse.Helpers.reserveds
187exceptFor :: (Ord a) => Gen a -> [a] -> Gen a
188exceptFor generator list =
189 generator `suchThat` notInList
191 set = Set.fromList list
192 notInList x = Set.notMember x set
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list