1
1
{-# LANGUAGE CPP #-}
2
2
{-# LANGUAGE DataKinds #-}
3
+ {-# LANGUAGE FlexibleInstances #-}
3
4
{-# LANGUAGE NamedFieldPuns #-}
4
5
{-# LANGUAGE OverloadedStrings #-}
5
6
{-# LANGUAGE RankNTypes #-}
@@ -18,6 +19,7 @@ module Dhall.Test.QuickCheck where
18
19
import Data.Either (isRight )
19
20
import Data.Either.Validation (Validation (.. ))
20
21
import Data.Monoid ((<>) )
22
+ import Data.Text (Text )
21
23
import Data.Void (Void )
22
24
import Dhall
23
25
( FromDhall (.. )
@@ -58,7 +60,7 @@ import Dhall.Set (Set)
58
60
import Dhall.Src (Src (.. ))
59
61
import Dhall.Test.Format (format )
60
62
import Dhall.TypeCheck (TypeError , Typer )
61
- import Generic.Random ((:+) (.. ), W , Weights , (%) )
63
+ import Generic.Random ((:+) (.. ), W , Weights , (%) , ConstrGen ( .. ) )
62
64
import Test.QuickCheck
63
65
( Arbitrary (.. )
64
66
, Gen
@@ -205,10 +207,10 @@ instance Arbitrary Header where
205
207
shrink (Header " " ) = []
206
208
shrink _ = [Header " " ]
207
209
208
- instance (Ord k , Arbitrary k , Arbitrary v ) => Arbitrary (Map k v ) where
210
+ instance (Arbitrary v ) => Arbitrary (Map Text v ) where
209
211
arbitrary = do
210
212
n <- Test.QuickCheck. choose (0 , 2 )
211
- kvs <- Test.QuickCheck. vectorOf n ((,) <$> arbitrary <*> arbitrary)
213
+ kvs <- Test.QuickCheck. vectorOf n ((,) <$> label <*> arbitrary)
212
214
-- Sorting the fields here because serialization needs them in order
213
215
return (Dhall.Map. fromList (Data.List. sortOn fst kvs))
214
216
@@ -218,12 +220,20 @@ instance (Ord k, Arbitrary k, Arbitrary v) => Arbitrary (Map k v) where
218
220
. Dhall.Map. toList
219
221
220
222
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
225
233
226
- in Test.QuickCheck. oneof [ lift2 f, lift3 g ]
234
+ value <- arbitrary
235
+
236
+ return Binding {.. }
227
237
228
238
shrink = genericShrink
229
239
@@ -275,17 +285,31 @@ instance (Arbitrary s, Arbitrary a) => Arbitrary (Expr s a) where
275
285
standardizedExpression
276
286
where
277
287
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
280
294
:+ ()
281
295
customGens =
282
- integer
296
+ ConstrGen label
297
+ :+ ConstrGen label
298
+ :+ ConstrGen label
299
+ :+ ConstrGen projection
300
+ :+ integer
283
301
-- 'Lam's and 'Pi's are encoded differently when the binding is
284
302
-- the special string "_", so we generate some of these strings
285
303
-- to improve test coverage for these code paths.
286
304
:+ Test.QuickCheck. oneof [pure " _" , arbitrary]
287
305
:+ ()
288
306
307
+ projection =
308
+ Test.QuickCheck. oneof
309
+ [ fmap (Left . Dhall.Set. fromList) (Test.QuickCheck. listOf label)
310
+ , arbitrary
311
+ ]
312
+
289
313
-- These weights determine the frequency of constructors in the generated
290
314
-- Expr.
291
315
-- They will fail to compile if the constructors don't appear in the order
@@ -392,6 +416,14 @@ standardizedExpression (Annot (ToMap _ Nothing) _) =
392
416
standardizedExpression _ =
393
417
True
394
418
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
+
395
427
instance Arbitrary File where
396
428
arbitrary = lift2 File
397
429
@@ -473,15 +505,9 @@ instance Arbitrary URL where
473
505
474
506
let validPChar =
475
507
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 ' ))
485
511
, (17 , Test.QuickCheck. elements " -._~!$&'()*+,;=:@" )
486
512
]
487
513
@@ -516,12 +542,20 @@ instance Arbitrary Var where
516
542
arbitrary =
517
543
Test.QuickCheck. oneof
518
544
[ 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)
521
547
]
522
-
523
548
shrink = genericShrink
524
549
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
+
525
559
binaryRoundtrip :: Expr () Import -> Property
526
560
binaryRoundtrip expression =
527
561
Dhall.Binary. decodeExpression (Dhall.Binary. encodeExpression denotedExpression)
@@ -662,13 +696,13 @@ tests =
662
696
, Test.QuickCheck. property noDoubleNotes
663
697
, adjustQuickCheckTests 100
664
698
)
665
- , embedThenExtractIsIdentity (Proxy :: Proxy (Text. Text ))
699
+ , embedThenExtractIsIdentity (Proxy :: Proxy (Text ))
666
700
, embedThenExtractIsIdentity (Proxy :: Proxy [Nat. Natural ])
667
701
, embedThenExtractIsIdentity (Proxy :: Proxy (Bool , Double ))
668
702
, embedThenExtractIsIdentity (Proxy :: Proxy (Data.Sequence. Seq () ))
669
703
, embedThenExtractIsIdentity (Proxy :: Proxy (Maybe Integer ))
670
704
, 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 ))
672
706
, embedThenExtractIsIdentity (Proxy :: Proxy (Vector Double ))
673
707
, embedThenExtractIsIdentity (Proxy :: Proxy (Data.Map. Map Double Bool ))
674
708
, embedThenExtractIsIdentity (Proxy :: Proxy (HashMap. HashMap Double Bool ))
0 commit comments