Skip to content

Commit 7ceb258

Browse files
Fix Arbitrary instance for Var (#1942)
* Fix `Arbitrary` instance for `Var` ... by disallowing backtick characters in the label Fixes #1941 * Fix generation of all labels ... using `ConstrGen`, like @sjakobi suggested * Fix order of `generic-random` cases ... as caught by @sjakobi Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent cefe5e6 commit 7ceb258

File tree

1 file changed

+59
-25
lines changed

1 file changed

+59
-25
lines changed

dhall/tests/Dhall/Test/QuickCheck.hs

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{-# LANGUAGE CPP #-}
22
{-# LANGUAGE DataKinds #-}
3+
{-# LANGUAGE FlexibleInstances #-}
34
{-# LANGUAGE NamedFieldPuns #-}
45
{-# LANGUAGE OverloadedStrings #-}
56
{-# LANGUAGE RankNTypes #-}
@@ -18,6 +19,7 @@ module Dhall.Test.QuickCheck where
1819
import Data.Either (isRight)
1920
import Data.Either.Validation (Validation (..))
2021
import Data.Monoid ((<>))
22+
import Data.Text (Text)
2123
import Data.Void (Void)
2224
import Dhall
2325
( FromDhall (..)
@@ -58,7 +60,7 @@ import Dhall.Set (Set)
5860
import Dhall.Src (Src (..))
5961
import Dhall.Test.Format (format)
6062
import Dhall.TypeCheck (TypeError, Typer)
61-
import Generic.Random ((:+) (..), W, Weights, (%))
63+
import Generic.Random ((:+) (..), W, Weights, (%), ConstrGen(..))
6264
import Test.QuickCheck
6365
( Arbitrary (..)
6466
, Gen
@@ -205,10 +207,10 @@ instance Arbitrary Header where
205207
shrink (Header "") = []
206208
shrink _ = [Header ""]
207209

208-
instance (Ord k, Arbitrary k, Arbitrary v) => Arbitrary (Map k v) where
210+
instance (Arbitrary v) => Arbitrary (Map Text v) where
209211
arbitrary = do
210212
n <- Test.QuickCheck.choose (0, 2)
211-
kvs <- Test.QuickCheck.vectorOf n ((,) <$> arbitrary <*> arbitrary)
213+
kvs <- Test.QuickCheck.vectorOf n ((,) <$> label <*> arbitrary)
212214
-- Sorting the fields here because serialization needs them in order
213215
return (Dhall.Map.fromList (Data.List.sortOn fst kvs))
214216

@@ -218,12 +220,20 @@ instance (Ord k, Arbitrary k, Arbitrary v) => Arbitrary (Map k v) where
218220
. Dhall.Map.toList
219221

220222
instance (Arbitrary s, Arbitrary a) => Arbitrary (Binding s a) where
221-
arbitrary =
222-
let adapt = fmap ((,) Nothing)
223-
f a b = Binding Nothing "_" Nothing (adapt a) Nothing b
224-
g a b c = Binding Nothing a Nothing (adapt b) Nothing c
223+
arbitrary = do
224+
let bindingSrc0 = Nothing
225+
let bindingSrc1 = Nothing
226+
let bindingSrc2 = Nothing
227+
228+
variable <- Test.QuickCheck.oneof [ pure "_", label ]
229+
230+
a <- arbitrary
231+
232+
let annotation = fmap ((,) Nothing) a
225233

226-
in Test.QuickCheck.oneof [ lift2 f, lift3 g ]
234+
value <- arbitrary
235+
236+
return Binding{..}
227237

228238
shrink = genericShrink
229239

@@ -275,17 +285,31 @@ instance (Arbitrary s, Arbitrary a) => Arbitrary (Expr s a) where
275285
standardizedExpression
276286
where
277287
customGens
278-
:: Gen Integer -- Generates all Integer fields in Expr
279-
:+ Gen Text.Text -- Generates all Text fields in Expr
288+
:: ConstrGen "Lam" 0 Text
289+
:+ ConstrGen "Pi" 0 Text
290+
:+ ConstrGen "Field" 1 Text
291+
:+ ConstrGen "Project" 1 (Either (Set Text) (Expr s a))
292+
:+ Gen Integer -- Generates all Integer fields in Expr
293+
:+ Gen Text -- Generates all Text fields in Expr
280294
:+ ()
281295
customGens =
282-
integer
296+
ConstrGen label
297+
:+ ConstrGen label
298+
:+ ConstrGen label
299+
:+ ConstrGen projection
300+
:+ integer
283301
-- 'Lam's and 'Pi's are encoded differently when the binding is
284302
-- the special string "_", so we generate some of these strings
285303
-- to improve test coverage for these code paths.
286304
:+ Test.QuickCheck.oneof [pure "_", arbitrary]
287305
:+ ()
288306

307+
projection =
308+
Test.QuickCheck.oneof
309+
[ fmap (Left . Dhall.Set.fromList) (Test.QuickCheck.listOf label)
310+
, arbitrary
311+
]
312+
289313
-- These weights determine the frequency of constructors in the generated
290314
-- Expr.
291315
-- They will fail to compile if the constructors don't appear in the order
@@ -392,6 +416,14 @@ standardizedExpression (Annot (ToMap _ Nothing) _) =
392416
standardizedExpression _ =
393417
True
394418

419+
chooseCharacter :: (Char, Char) -> Gen Char
420+
chooseCharacter =
421+
#if MIN_VERSION_QuickCheck(2,14,0)
422+
Test.QuickCheck.chooseEnum
423+
#else
424+
Test.QuickCheck.choose
425+
#endif
426+
395427
instance Arbitrary File where
396428
arbitrary = lift2 File
397429

@@ -473,15 +505,9 @@ instance Arbitrary URL where
473505

474506
let validPChar =
475507
Test.QuickCheck.frequency
476-
#if MIN_VERSION_QuickCheck(2,14,0)
477-
[ (26, Test.QuickCheck.chooseEnum ('\x41', '\x5A'))
478-
, (26, Test.QuickCheck.chooseEnum ('\x61', '\x7A'))
479-
, (10, Test.QuickCheck.chooseEnum ('\x30', '\x39'))
480-
#else
481-
[ (26, Test.QuickCheck.choose ('\x41', '\x5A'))
482-
, (26, Test.QuickCheck.choose ('\x61', '\x7A'))
483-
, (10, Test.QuickCheck.choose ('\x30', '\x39'))
484-
#endif
508+
[ (26, chooseCharacter ('\x41', '\x5A'))
509+
, (26, chooseCharacter ('\x61', '\x7A'))
510+
, (10, chooseCharacter ('\x30', '\x39'))
485511
, (17, Test.QuickCheck.elements "-._~!$&'()*+,;=:@")
486512
]
487513

@@ -516,12 +542,20 @@ instance Arbitrary Var where
516542
arbitrary =
517543
Test.QuickCheck.oneof
518544
[ fmap (V "_") (getNonNegative <$> arbitrary)
519-
, lift1 (\t -> V t 0)
520-
, lift1 V <*> (getNonNegative <$> arbitrary)
545+
, fmap (\t -> V t 0) label
546+
, V <$> label <*> (getNonNegative <$> arbitrary)
521547
]
522-
523548
shrink = genericShrink
524549

550+
label :: Gen Text
551+
label = fmap Text.pack (Test.QuickCheck.listOf labelCharacter)
552+
where
553+
labelCharacter =
554+
Test.QuickCheck.frequency
555+
[ (64, chooseCharacter ('\x20', '\x5F'))
556+
, (30, chooseCharacter ('\x61', '\x7e'))
557+
]
558+
525559
binaryRoundtrip :: Expr () Import -> Property
526560
binaryRoundtrip expression =
527561
Dhall.Binary.decodeExpression (Dhall.Binary.encodeExpression denotedExpression)
@@ -662,13 +696,13 @@ tests =
662696
, Test.QuickCheck.property noDoubleNotes
663697
, adjustQuickCheckTests 100
664698
)
665-
, embedThenExtractIsIdentity (Proxy :: Proxy (Text.Text))
699+
, embedThenExtractIsIdentity (Proxy :: Proxy (Text))
666700
, embedThenExtractIsIdentity (Proxy :: Proxy [Nat.Natural])
667701
, embedThenExtractIsIdentity (Proxy :: Proxy (Bool, Double))
668702
, embedThenExtractIsIdentity (Proxy :: Proxy (Data.Sequence.Seq ()))
669703
, embedThenExtractIsIdentity (Proxy :: Proxy (Maybe Integer))
670704
, embedThenExtractIsIdentity (Proxy :: Proxy (Data.Set.Set Nat.Natural))
671-
, embedThenExtractIsIdentity (Proxy :: Proxy (Data.HashSet.HashSet Text.Text))
705+
, embedThenExtractIsIdentity (Proxy :: Proxy (Data.HashSet.HashSet Text))
672706
, embedThenExtractIsIdentity (Proxy :: Proxy (Vector Double))
673707
, embedThenExtractIsIdentity (Proxy :: Proxy (Data.Map.Map Double Bool))
674708
, embedThenExtractIsIdentity (Proxy :: Proxy (HashMap.HashMap Double Bool))

0 commit comments

Comments
 (0)