Skip to content

Commit 7d8207a

Browse files
committed
WIP more unit tests for list hooks
1 parent 78cbe0d commit 7d8207a

File tree

1 file changed

+108
-20
lines changed

1 file changed

+108
-20
lines changed

booster/unit-tests/Test/Booster/Builtin.hs

Lines changed: 108 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,25 +87,15 @@ testListHooks =
8787
"LIST hooks"
8888
[ testListArityChecks
8989
, testListConcatHook
90-
, testListSizeHook
90+
, testListElementHook
9191
, testListGetHook
92+
, testListInHook
93+
, testListMakeHook
94+
, testListRangeHook
95+
, testListSizeHook
9296
, testListUpdateHook
9397
]
9498

95-
-- helpers
96-
listOfThings :: Int -> Term
97-
listOfThings n =
98-
let things = map numDV [1 .. n]
99-
in KList Fixture.testKListDef things Nothing
100-
101-
-- wrap an Int into an injection to KItem here
102-
numDV :: Int -> Term
103-
numDV n =
104-
Fixture.inj Fixture.someSort Fixture.kItemSort $ dv Fixture.someSort $ BS.pack $ show n
105-
106-
evalHook :: MonadFail m => BS.ByteString -> [Term] -> m (Maybe Term)
107-
evalHook name args = either (fail . show) pure $ runExcept $ runHook name args
108-
10999
testListArityChecks :: TestTree
110100
testListArityChecks =
111101
testGroup
@@ -114,6 +104,7 @@ testListArityChecks =
114104
assertException "LIST.concat" []
115105
assertException "LIST.concat" [[trm| X:SortList |]]
116106
assertException "LIST.concat" $ replicate 3 [trm| X:SortList |]
107+
-- , error "missing arity checks!"
117108
, testCase "LIST.size: list arg." $ do
118109
assertException "LIST.size" []
119110
assertException "LIST.size" $ replicate 2 [trm| X:SortList |]
@@ -131,6 +122,21 @@ testListArityChecks =
131122
assertException name =
132123
assertBool "Unexpected success" . isLeft . runExcept . runHook name
133124

125+
-- list and element helpers
126+
listOfThings :: Int -> Term
127+
listOfThings n =
128+
let things = map numDV [1 .. n]
129+
in KList Fixture.testKListDef things Nothing
130+
131+
-- wrap an Int into an injection to KItem here
132+
numDV :: Int -> Term
133+
numDV n =
134+
Fixture.inj Fixture.someSort Fixture.kItemSort $ dv Fixture.someSort $ BS.pack $ show n
135+
136+
-- this assumes all terms are sort KItem or that sorts are irrelevant
137+
kitemList :: [Term] -> Term
138+
kitemList items = KList Builtin.kItemListDef items Nothing
139+
134140
testListConcatHook :: TestTree
135141
testListConcatHook =
136142
testGroup
@@ -184,6 +190,88 @@ testListConcatHook =
184190
Nothing === result
185191
]
186192

193+
testListElementHook :: TestTree
194+
testListElementHook =
195+
testGroup
196+
"LIST.element"
197+
[ testCase "making a singleton list" $ do
198+
let thing = [trm| THING:SortKItem |]
199+
result <- evalHook "LIST.element" [thing]
200+
-- this will return the fixed built-in list metadata
201+
Just (kitemList [thing]) @=? result
202+
]
203+
204+
testListInHook :: TestTree
205+
testListInHook =
206+
testGroup
207+
"LIST.in"
208+
[ testCase "LIST.in is false when the list is empty" $ do
209+
let thing = numDV 0
210+
empty = listOfThings 0
211+
result <- evalHook "LIST.in" [thing, empty]
212+
result `_shouldBe_` False
213+
, testProperty "LIST.in is true when an item is present in the head" . property $ do
214+
l <- forAll $ between1And 42
215+
k <- forAll $ between1And l
216+
let list = listOfThings l -- [1 .. l]
217+
target = numDV k
218+
result <- evalHook "LIST.in" [target, list]
219+
result `shouldBe` True
220+
, testProperty "LIST.in is true when an item is present in the tail" . property $ do
221+
l <- forAll $ between1And 42
222+
k <- forAll $ between1And l
223+
let elems = map numDV [1 .. l]
224+
list = KList Fixture.testKListDef [] $ Just ([trm| INIT:SortList |], elems)
225+
target = numDV k
226+
result <- evalHook "LIST.in" [target, list]
227+
result `shouldBe` True
228+
, testProperty "LIST.in is false when an item is not present (concrete list)" . property $ do
229+
l <- forAll smallNat
230+
let list = listOfThings l -- [1 .. l]
231+
target = numDV 0
232+
result <- evalHook "LIST.in" [target, list]
233+
result `shouldBe` False
234+
, testProperty "LIST.in is indeterminate when an item is not present (list with opaque middle)" . property $ do
235+
l <- forAll smallNat
236+
let elems = map numDV [1 .. l]
237+
list = KList Fixture.testKListDef elems $ Just ([trm| INIT:SortList |], [])
238+
target = numDV 0
239+
result <- evalHook "LIST.in" [target, list]
240+
Nothing === result
241+
]
242+
where
243+
x `_shouldBe_` b = Just (Builtin.boolTerm b) @=? x
244+
x `shouldBe` b = Just (Builtin.boolTerm b) === x
245+
246+
247+
testListMakeHook :: TestTree
248+
testListMakeHook =
249+
testGroup
250+
"LIST.make"
251+
[ testCase "LIST.in makes empty lists when size 0 is given" $ do
252+
let thing = numDV 0
253+
size = Builtin.intTerm 0
254+
result <- evalHook "LIST.make" [size, thing]
255+
Just (KList Builtin.kItemListDef [] Nothing) @=? result
256+
, testProperty "LIST.in makes a list of given length" . property $ do
257+
let thing = numDV 0
258+
size <- forAll smallNat
259+
let sizeTerm = Builtin.intTerm $ fromIntegral size
260+
result <- evalHook "LIST.make" [sizeTerm, thing]
261+
case result of
262+
Nothing -> failure
263+
Just (KList _ concrete Nothing) ->
264+
concrete === replicate size thing
265+
Just other -> failure
266+
]
267+
268+
testListRangeHook :: TestTree
269+
testListRangeHook =
270+
testGroup
271+
"LIST.range"
272+
[ -- TODO
273+
]
274+
187275
testListSizeHook :: TestTree
188276
testListSizeHook =
189277
testGroup
@@ -336,9 +424,6 @@ genAssocs range = noDupKeys <$> Gen.list range genAssoc
336424
mapWith :: [(Term, Term)] -> Maybe Term -> Term
337425
mapWith = KMap Fixture.testKMapDefinition
338426

339-
concreteList :: [Term] -> Term
340-
concreteList items = KList Builtin.kItemListDef items Nothing
341-
342427
testMapUpdateHook :: TestTree
343428
testMapUpdateHook =
344429
testGroup
@@ -690,7 +775,7 @@ testMapKeysListHook =
690775
result <- runKeysList [mapWith assocs Nothing]
691776
let expected =
692777
-- map assocs are sorted and deduplicated
693-
concreteList . map fst . Set.toAscList . Set.fromList $ assocs
778+
kitemList . map fst . Set.toAscList . Set.fromList $ assocs
694779
Just expected === result
695780
]
696781
where
@@ -716,7 +801,7 @@ testMapValuesHook =
716801
result <- runValues [mapWith assocs Nothing]
717802
let expected =
718803
-- map assocs are sorted and deduplicated
719-
concreteList . map snd . Set.toAscList . Set.fromList $ assocs
804+
kitemList . map snd . Set.toAscList . Set.fromList $ assocs
720805
Just expected === result
721806
]
722807
where
@@ -826,6 +911,9 @@ runHook name =
826911
fromMaybe (error $ show name <> " hook not found") $
827912
Map.lookup name Builtin.hooks
828913

914+
evalHook :: MonadFail m => BS.ByteString -> [Term] -> m (Maybe Term)
915+
evalHook name args = either (fail . show) pure $ runExcept $ runHook name args
916+
829917
smallNat :: Gen Int
830918
smallNat = Gen.int (Range.linear 0 42)
831919

0 commit comments

Comments
 (0)