{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Constrained.Test where

import Constrained.API
import Constrained.Examples.Basic
import Constrained.Examples.Either
import Constrained.Examples.Fold (
  Outcome (..),
  evenSpec,
  listSumComplex,
  logishProp,
  oddSpec,
  pickProp,
  sum3,
  sum3WithLength,
  sumProp,
  sumProp2,
  testFoldSpec,
 )
import Constrained.Examples.List
import Constrained.Examples.Map
import Constrained.Examples.Set
import Constrained.Examples.Tree
import Constrained.Properties hiding (main)
import Constrained.SumList (narrowByFuelAndSize)
import Control.Monad
import Data.Int
import qualified Data.List.NonEmpty as NE
import Data.Map (Map)
import Data.Set (Set)
import Data.Word
import GHC.Natural
import Test.Hspec
import Test.Hspec.QuickCheck
import Test.QuickCheck hiding (Args, Fun, forAll)

------------------------------------------------------------------------
-- Test suite
------------------------------------------------------------------------

testAll :: IO ()
testAll :: IO ()
testAll = Spec -> IO ()
hspec (Spec -> IO ()) -> Spec -> IO ()
forall a b. (a -> b) -> a -> b
$ Bool -> Spec
tests Bool
False

tests :: Bool -> Spec
tests :: Bool -> Spec
tests Bool
nightly =
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"constrained" (Spec -> Spec) -> (Spec -> Spec) -> Spec -> Spec
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int) -> Spec -> Spec
forall a. (Int -> Int) -> SpecWith a -> SpecWith a
modifyMaxSuccess (\Int
ms -> if Bool
nightly then Int
ms Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10 else Int
ms) (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    -- TODO: double-shrinking
    String -> Specification (Int, Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"reifiesMultiple" Specification (Int, Int, Int)
reifiesMultiple
    String -> Specification Int -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"assertReal" Specification Int
assertReal
    String -> Specification (Int, [Int]) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"chooseBackwards" Specification (Int, [Int])
chooseBackwards
    String -> Specification ([(Int, [Int])], (Int, [Int])) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"chooseBackwards'" Specification ([(Int, [Int])], (Int, [Int]))
chooseBackwards'
    -- TODO: turn this on again when QuickCheck version is bumped
    -- testSpec "whenTrueExists" whenTrueExists
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"assertRealMultiple" Specification (Int, Int)
assertRealMultiple
    -- TODO: quickcheck version
    String -> Specification (Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"setSpec" Specification (Set Int)
setSpec
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"leqPair" Specification (Int, Int)
leqPair
    String -> Specification (Set (Int, Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"setPair" Specification (Set (Int, Int))
setPair
    String -> Specification [Int] -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"listEmpty" Specification [Int]
listEmpty
    -- TODO: quickcheck version
    String -> Specification (Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"compositionalSpec" Specification (Set Int)
compositionalSpec
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"simplePairSpec" Specification (Int, Int)
simplePairSpec
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"trickyCompositional" Specification (Int, Int)
trickyCompositional
    String
-> Specification ([Int], NotASet (Either Int Int, Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"emptyListSpec" Specification ([Int], NotASet (Either Int Int, Int))
emptyListSpec
    String -> Specification (Either Int Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"eitherSpec" Specification (Either Int Int)
eitherSpec
    String -> Specification (Set (Maybe Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"maybeSpec" Specification (Set (Maybe Int))
maybeSpec
    String
-> Specification
     (Set (Either Int Int), Set (Either Int Int), Set (Either Int Int))
-> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"eitherSetSpec" Specification
  (Set (Either Int Int), Set (Either Int Int), Set (Either Int Int))
eitherSetSpec
    String -> Specification Foo -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"fooSpec" Specification Foo
fooSpec
    String -> Specification (Map Int (Bool, Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"mapElemSpec" Specification (Map Int (Bool, Int))
mapElemSpec
    String -> Specification Int -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"mapElemKeySpec" Specification Int
mapElemKeySpec
    -- TODO: double shrinking
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"mapIsJust" Specification (Int, Int)
mapIsJust
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"intSpec" Specification (Int, Int)
intSpec
    String -> Specification (Map Int Int, Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"mapPairSpec" Specification (Map Int Int, Set Int)
mapPairSpec
    String -> Specification (Map Int Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"mapEmptyDomainSpec" Specification (Map Int Int)
mapEmptyDomainSpec
    -- TODO: this _can_ be shrunk, but it's incredibly expensive to do
    -- so and it's not obvious if there is a faster way without implementing
    -- more detailed shrinking of `SuspendedSpec`s
    String -> Specification (Set Int, Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"setPairSpec" Specification (Set Int, Set Int)
setPairSpec
    -- TODO: quickcheck version
    String -> Specification (Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"fixedSetSpec" Specification (Set Int)
fixedSetSpec
    String -> Specification (Set (Int, Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"setOfPairLetSpec" Specification (Set (Int, Int))
setOfPairLetSpec
    String -> Specification (Set (Either Int Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"emptyEitherSpec" Specification (Set (Either Int Int))
emptyEitherSpec
    String -> Specification (Set (Either Int Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"emptyEitherMemberSpec" Specification (Set (Either Int Int))
emptyEitherMemberSpec
    String -> Specification (Set (Int, Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"setSingletonSpec" Specification (Set (Int, Int))
setSingletonSpec
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"pairSingletonSpec" Specification (Int, Int)
pairSingletonSpec
    String -> Specification (Set (Either Int Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"eitherSimpleSetSpec" Specification (Set (Either Int Int))
eitherSimpleSetSpec
    String -> Specification (Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"emptySetSpec" Specification (Set Int)
emptySetSpec
    String -> Specification (Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"forAllAnySpec" Specification (Set Int)
forAllAnySpec
    String -> Specification (Set Int, Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"notSubsetSpec" Specification (Set Int, Set Int)
notSubsetSpec
    String -> Specification (Set (Maybe Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"maybeJustSetSpec" Specification (Set (Maybe Int))
maybeJustSetSpec
    String -> Specification ([Int], Set (Either Int Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"weirdSetPairSpec" Specification ([Int], Set (Either Int Int))
weirdSetPairSpec
    String -> Specification (Map Int Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"knownDomainMap" Specification (Map Int Int)
knownDomainMap
    -- TODO: figure out double-shrinking
    String -> Specification ((Int, Int), (Int, Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"testRewriteSpec" Specification ((Int, Int), (Int, Int))
testRewriteSpec
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"parallelLet" Specification (Int, Int)
parallelLet
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"letExists" Specification (Int, Int)
letExists
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"letExistsLet" Specification (Int, Int)
letExistsLet
    String -> Specification (Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"notSubset" Specification (Set Int)
notSubset
    String -> Specification (Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"unionSized" Specification (Set Int)
unionSized
    -- TODO: figure out double-shrinking
    String -> Specification (Int, Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"dependencyWeirdness" Specification (Int, Int, Int)
dependencyWeirdness
    String -> Specification (Either Int Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"foldTrueCases" Specification (Either Int Int)
foldTrueCases
    String -> Specification Int -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"foldSingleCase" Specification Int
foldSingleCase
    String -> Specification [(Int, Int)] -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"listSumPair" (forall a. Numbery a => Specification [(a, Int)]
listSumPair @Int)
    -- TODO: figure out double-shrinking
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"parallelLetPair" Specification (Int, Int)
parallelLetPair
    String -> Specification (Map Three Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"mapSizeConstrained" Specification (Map Three Int)
mapSizeConstrained
    String -> Specification (Tree Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"isAllZeroTree" Specification (Tree Int)
isAllZeroTree
    String -> Specification (BinTree Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"noChildrenSameTree" Specification (BinTree Int)
noChildrenSameTree
    String -> Specification (BinTree Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"isBST" Specification (BinTree Int)
isBST
    String -> Specification [(Int, Int)] -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"pairListError" Specification [(Int, Int)]
pairListError
    String -> Specification [Int] -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"listMustSizeIssue" Specification [Int]
listMustSizeIssue
    String -> Specification (Tree Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"successiveChildren" Specification (Tree Int)
successiveChildren
    String -> Specification (Tree Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"successiveChildren8" Specification (Tree Int)
successiveChildren8
    String -> Specification [Tree Int] -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"roseTreeList" Specification [Tree Int]
roseTreeList
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"orPair" Specification (Int, Int)
orPair
    String -> Specification (Tree ([Int], [Int])) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"roseTreePairs" Specification (Tree ([Int], [Int]))
roseTreePairs
    String -> Specification (Tree (Maybe (Int, Int))) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"roseTreeMaybe" Specification (Tree (Maybe (Int, Int)))
roseTreeMaybe
    String -> Specification (Tree (Either Int Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"badTreeInteraction" Specification (Tree (Either Int Int))
badTreeInteraction
    String -> Specification (Map Word64 Word64) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"sumRange" Specification (Map Word64 Word64)
sumRange
    String -> Specification [Word64] -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"sumListBad" Specification [Word64]
sumListBad
    String -> Specification [Int] -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"listExistsUnfree" Specification [Int]
listExistsUnfree
    -- TODO: turn this on when we bump quickcheck version
    -- testSpec "listSumShort" listSumShort
    String -> Specification Int -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"existsUnfree" Specification Int
existsUnfree
    String -> Specification ([Int], [Int]) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"appendSize" Specification ([Int], [Int])
appendSize
    String -> Specification Int -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"appendSingleton" Specification Int
appendSingleton
    String -> Specification Int -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"singletonSubset" Specification Int
singletonSubset
    -- TODO: double shrinking
    String -> Specification (Int, Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"reifyYucky" Specification (Int, Int, Int)
reifyYucky
    String -> Specification (Map Int Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"fixedRange" Specification (Map Int Int)
fixedRange
    String -> Specification (Map Int Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"rangeHint" Specification (Map Int Int)
rangeHint
    String -> Specification Int -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"basicSpec" Specification Int
basicSpec
    String -> Specification ((Int, Int), (Int, Int)) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"canFollowLike" Specification ((Int, Int), (Int, Int))
canFollowLike
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"ifElseBackwards" Specification (Int, Int)
ifElseBackwards
    String -> Specification Three -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"three" Specification Three
three
    String -> Specification Three -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"three'" Specification Three
three'
    String -> Specification Three -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"threeSpecific" Specification Three
threeSpecific
    String -> Specification Three -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"threeSpecific'" Specification Three
threeSpecific'
    String -> Specification Three -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"trueSpecUniform" Specification Three
trueSpecUniform
    String -> Specification (Bool, Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"ifElseMany" Specification (Bool, Int, Int)
ifElseMany
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"propBack" Specification (Int, Int)
propBack
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"propBack'" Specification (Int, Int)
propBack'
    String -> Specification (Int, Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"propBack''" Specification (Int, Int)
propBack''
    String -> Specification (Set Int, Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"complexUnion" Specification (Set Int, Set Int)
complexUnion
    String -> Specification (Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"unionBounded" Specification (Set Int)
unionBounded
    String -> Specification (Int, Int, Map Int Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"elemSpec" Specification (Int, Int, Map Int Int)
elemSpec
    String -> Specification (Int, Int, Map Int Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"lookupSpecific" Specification (Int, Int, Map Int Int)
lookupSpecific
    String -> Specification (Map (Either Int ()) Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"mapRestrictedValues" Specification (Map (Either Int ()) Int)
mapRestrictedValues
    String -> Specification (Map Three Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"mapRestrictedValuesThree" Specification (Map Three Int)
mapRestrictedValuesThree
    String -> Specification (Map Bool Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"mapRestrictedValuesBool" Specification (Map Bool Int)
mapRestrictedValuesBool
    String -> Specification (Map (Set Int) Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"mapSetSmall" Specification (Map (Set Int) Int)
mapSetSmall
    String -> Specification (Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"powersetPickOne" Specification (Set Int)
powersetPickOne
    String -> Specification ([Int], [Int]) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"appendSuffix" Specification ([Int], [Int])
appendSuffix
    String -> Specification ([Int], [Int]) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"appendForAll" Specification ([Int], [Int])
appendForAll
    String -> Specification ([Int], Maybe ((), [Int])) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"wtfSpec" Specification ([Int], Maybe ((), [Int]))
wtfSpec
    Spec
numberyTests
    Spec
sizeTests
    Spec
numNumSpecTree
    [Spec] -> Spec
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_
      [ String -> Specification Int -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec (String
"intRangeSpec " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i) (Int -> Specification Int
intRangeSpec Int
i)
      | Int
i <- [-Int
1000, -Int
100, -Int
10, Int
0, Int
10, Int
100, Int
1000]
      ]
    String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"prop_conformEmpty" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      String -> (Int -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Int" ((Int -> Property) -> Spec) -> (Int -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => a -> Property
prop_conformEmpty @Int
      String -> (Set Int -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Set Int" ((Set Int -> Property) -> Spec) -> (Set Int -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => a -> Property
prop_conformEmpty @(Set Int)
      String -> (Map Int Int -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Map Int Int" ((Map Int Int -> Property) -> Spec)
-> (Map Int Int -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => a -> Property
prop_conformEmpty @(Map Int Int)
      String -> ([Int] -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"[Int]" (([Int] -> Property) -> Spec) -> ([Int] -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => a -> Property
prop_conformEmpty @[Int]
      String -> ([(Int, Int)] -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"[(Int, Int)]" (([(Int, Int)] -> Property) -> Spec)
-> ([(Int, Int)] -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => a -> Property
prop_conformEmpty @[(Int, Int)]
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"prop_univSound @BaseFn" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
      Int -> (TestableFn -> Property) -> Property
forall prop. Testable prop => Int -> prop -> Property
withMaxSuccess (if Bool
nightly then Int
100_000 else Int
10_000) ((TestableFn -> Property) -> Property)
-> (TestableFn -> Property) -> Property
forall a b. (a -> b) -> a -> b
$
        TestableFn -> Property
prop_univSound
    String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"prop_gen_sound" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      (Int -> Int) -> Spec -> Spec
forall a. (Int -> Int) -> SpecWith a -> SpecWith a
modifyMaxSuccess (Int -> Int -> Int
forall a b. a -> b -> a
const (Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
$ if Bool
nightly then Int
10_000 else Int
1000) (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
        String -> (Specification Int -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Int" ((Specification Int -> Property) -> Spec)
-> (Specification Int -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @Int
        String -> (Specification Bool -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Bool" ((Specification Bool -> Property) -> Spec)
-> (Specification Bool -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @Bool
        String -> (Specification (Int, Int) -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"(Int, Int)" ((Specification (Int, Int) -> Property) -> Spec)
-> (Specification (Int, Int) -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @(Int, Int)
        String -> (Specification (Map Int Int) -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Map Int Int" ((Specification (Map Int Int) -> Property) -> Spec)
-> (Specification (Map Int Int) -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @(Map Int Int)
        String -> (Specification (Set Int) -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Set Int" ((Specification (Set Int) -> Property) -> Spec)
-> (Specification (Set Int) -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @(Set Int)
        String -> (Specification (Set Bool) -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Set Bool" ((Specification (Set Bool) -> Property) -> Spec)
-> (Specification (Set Bool) -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @(Set Bool)
        String -> (Specification [Int] -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"[Int]" ((Specification [Int] -> Property) -> Spec)
-> (Specification [Int] -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @[Int]
        String -> (Specification [(Int, Int)] -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"[(Int, Int)]" ((Specification [(Int, Int)] -> Property) -> Spec)
-> (Specification [(Int, Int)] -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @[(Int, Int)]
        String -> (Specification (Map Bool Int) -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Map Bool Int" ((Specification (Map Bool Int) -> Property) -> Spec)
-> (Specification (Map Bool Int) -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @(Map Bool Int)
      -- Slow tests that shouldn't run 1000 times
      String -> (Specification (Map (Set Int) Int) -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
xprop String
"Map (Set Int) Int" ((Specification (Map (Set Int) Int) -> Property) -> Spec)
-> (Specification (Map (Set Int) Int) -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @(Map (Set Int) Int)
      String -> (Specification [(Set Int, Set Bool)] -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"[(Set Int, Set Bool)]" ((Specification [(Set Int, Set Bool)] -> Property) -> Spec)
-> (Specification [(Set Int, Set Bool)] -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @[(Set Int, Set Bool)]
      String -> (Specification (Set (Set Bool)) -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Set (Set Bool)" ((Specification (Set (Set Bool)) -> Property) -> Spec)
-> (Specification (Set (Set Bool)) -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Specification a -> Property
prop_gen_sound @(Set (Set Bool))
    Spec
negativeTests
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"prop_noNarrowLoop" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> (Int
    -> Int -> Specification Int -> Specification Int -> Property)
-> Property
forall prop. Testable prop => Int -> prop -> Property
withMaxSuccess Int
1000 Int -> Int -> Specification Int -> Specification Int -> Property
prop_noNarrowLoop
    Spec
conformsToSpecESpec
    Spec
foldWithSizeTests

negativeTests :: Spec
negativeTests :: Spec
negativeTests =
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"negative tests" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"reifies 10 x id" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
      Property -> Property
forall prop. Testable prop => prop -> Property
expectFailure (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
        forall a. HasSpec a => Specification a -> Property
prop_complete @Int (Specification Int -> Property) -> Specification Int -> Property
forall a b. (a -> b) -> a -> b
$
          (Term Int -> Pred) -> Specification Int
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained ((Term Int -> Pred) -> Specification Int)
-> (Term Int -> Pred) -> Specification Int
forall a b. (a -> b) -> a -> b
$
            \Term Int
x ->
              NonEmpty String -> Pred -> Pred
explanation (String -> NonEmpty String
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"The value is decided before reifies happens") (Pred -> Pred) -> Pred -> Pred
forall a b. (a -> b) -> a -> b
$
                Term Int -> Term Int -> (Int -> Int) -> Pred
forall a b.
(HasSpec a, HasSpec b) =>
Term b -> Term a -> (a -> b) -> Pred
reifies Term Int
10 Term Int
x Int -> Int
forall a. a -> a
id
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"reify overconstrained" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
      Property -> Property
forall prop. Testable prop => prop -> Property
expectFailure (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
        forall a. HasSpec a => Specification a -> Property
prop_complete @Int (Specification Int -> Property) -> Specification Int -> Property
forall a b. (a -> b) -> a -> b
$
          (Term Int -> Pred) -> Specification Int
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained ((Term Int -> Pred) -> Specification Int)
-> (Term Int -> Pred) -> Specification Int
forall a b. (a -> b) -> a -> b
$ \Term Int
x ->
            NonEmpty String -> Pred -> Pred
explanation
              (String -> NonEmpty String
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"You can't constrain the variable introduced by reify as its already decided")
              (Pred -> Pred) -> Pred -> Pred
forall a b. (a -> b) -> a -> b
$ Term Int -> (Int -> Int) -> (Term Int -> Term Bool) -> Pred
forall a b p.
(HasSpec a, HasSpec b, IsPred p) =>
Term a -> (a -> b) -> (Term b -> p) -> Pred
reify Term Int
x Int -> Int
forall a. a -> a
id
              ((Term Int -> Term Bool) -> Pred)
-> (Term Int -> Term Bool) -> Pred
forall a b. (a -> b) -> a -> b
$ \Term Int
y -> Term Int
y Term Int -> Term Int -> Term Bool
forall a. HasSpec a => Term a -> Term a -> Term Bool
==. Term Int
10
    String -> Specification Int -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecFail String
"singletonErrorTooMany" Specification Int
singletonErrorTooMany
    String -> Specification Int -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecFail String
"singletonErrorTooLong" Specification Int
singletonErrorTooLong
    String -> Specification [Int] -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecFail String
"appendTooLong" Specification [Int]
appendTooLong
    String -> Specification ([Int], [Int]) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecFail String
"overconstrainedAppend" Specification ([Int], [Int])
overconstrainedAppend
    String -> Specification ([Int], [Int], [Int]) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecFail String
"overconstrainedPrefixes" Specification ([Int], [Int], [Int])
overconstrainedPrefixes
    String -> Specification ([Int], [Int], [Int]) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecFail String
"overconstrainedSuffixes" Specification ([Int], [Int], [Int])
overconstrainedSuffixes
    String -> Specification ([Int], [Int]) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecFail String
"appendForAllBad" Specification ([Int], [Int])
appendForAllBad

testSpecFail :: HasSpec a => String -> Specification a -> Spec
testSpecFail :: forall a. HasSpec a => String -> Specification a -> Spec
testSpecFail String
s Specification a
spec =
  String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop (String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" fails") (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
    Property -> Property
forall prop. Testable prop => prop -> Property
expectFailure (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
      Int -> Property -> Property
forall prop. Testable prop => Int -> prop -> Property
withMaxSuccess Int
1 (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
        Specification a -> Property
forall a. HasSpec a => Specification a -> Property
prop_complete Specification a
spec

numberyTests :: Spec
numberyTests :: Spec
numberyTests =
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"numbery tests" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpec String
"listSum" Specification [a]
forall a. Numbery a => Specification [a]
listSum
    String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpecNoShrink String
"listSumForall" Specification [a]
forall a. Numbery a => Specification [a]
listSumForall
    String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpec String
"listSumRange" Specification [a]
forall a. Numbery a => Specification [a]
listSumRange
    String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpec String
"listSumRangeUpper" Specification [a]
forall a. Numbery a => Specification [a]
listSumRangeUpper
    String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpec String
"listSumRangeRange" Specification [a]
forall a. Numbery a => Specification [a]
listSumRangeRange
    String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpec String
"listSumElemRange" Specification [a]
forall a. Numbery a => Specification [a]
listSumElemRange

sizeTests :: Spec
sizeTests :: Spec
sizeTests =
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"SizeTests" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> Specification Integer -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"sizeAddOrSub1" Specification Integer
sizeAddOrSub1
    String -> Specification Integer -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"sizeAddOrSub2" Specification Integer
sizeAddOrSub2
    String -> Specification Integer -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"sizeAddOrSub3" Specification Integer
sizeAddOrSub3
    String -> Specification Integer -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"sizeAddOrSub4 returns Negative Size" Specification Integer
sizeAddOrSub4
    String -> Specification Integer -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"sizeAddOrSub5" Specification Integer
sizeAddOrSub5
    String -> Specification Integer -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink String
"sizeAddOrSub5" Specification Integer
sizeAddOrSub5
    String -> Specification [Int] -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"listSubSize" Specification [Int]
listSubSize
    String -> Specification (Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"listSubSize" Specification (Set Int)
setSubSize
    String -> Specification (Map Int Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"listSubSize" Specification (Map Int Int)
mapSubSize
    String -> Specification [Int] -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"hasSizeList" Specification [Int]
hasSizeList
    String -> Specification (Set Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"hasSizeSet" Specification (Set Int)
hasSizeSet
    String -> Specification (Map Int Int) -> Spec
forall a. HasSpec a => String -> Specification a -> Spec
testSpec String
"hasSizeMap" Specification (Map Int Int)
hasSizeMap

testNumberyListSpec :: String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpec :: String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpec = Bool
-> String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpec' Bool
True

testNumberyListSpecNoShrink :: String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpecNoShrink :: String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpecNoShrink = Bool
-> String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpec' Bool
False

testNumberyListSpec' :: Bool -> String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpec' :: Bool
-> String -> (forall a. Numbery a => Specification [a]) -> Spec
testNumberyListSpec' Bool
withShrink String
n forall a. Numbery a => Specification [a]
p =
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
n (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    Bool -> String -> Specification [Integer] -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
withShrink String
"Integer" (forall a. Numbery a => Specification [a]
p @Integer)
    Bool -> String -> Specification [Natural] -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
withShrink String
"Natural" (forall a. Numbery a => Specification [a]
p @Natural)
    Bool -> String -> Specification [Word64] -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
withShrink String
"Word64" (forall a. Numbery a => Specification [a]
p @Word64)
    Bool -> String -> Specification [Word32] -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
withShrink String
"Word32" (forall a. Numbery a => Specification [a]
p @Word32)
    Bool -> String -> Specification [Word16] -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
withShrink String
"Word16" (forall a. Numbery a => Specification [a]
p @Word16)
    Bool -> String -> Specification [Word8] -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
withShrink String
"Word8" (forall a. Numbery a => Specification [a]
p @Word8)
    Bool -> String -> Specification [Int64] -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
withShrink String
"Int64" (forall a. Numbery a => Specification [a]
p @Int64)
    Bool -> String -> Specification [Int32] -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
withShrink String
"Int32" (forall a. Numbery a => Specification [a]
p @Int32)
    Bool -> String -> Specification [Int16] -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
withShrink String
"Int16" (forall a. Numbery a => Specification [a]
p @Int16)
    Bool -> String -> Specification [Int8] -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
withShrink String
"Int8" (forall a. Numbery a => Specification [a]
p @Int8)

testSpec :: HasSpec a => String -> Specification a -> Spec
testSpec :: forall a. HasSpec a => String -> Specification a -> Spec
testSpec = Bool -> String -> Specification a -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
True

testSpecNoShrink :: HasSpec a => String -> Specification a -> Spec
testSpecNoShrink :: forall a. HasSpec a => String -> Specification a -> Spec
testSpecNoShrink = Bool -> String -> Specification a -> Spec
forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
False

testSpec' :: HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' :: forall a. HasSpec a => Bool -> String -> Specification a -> Spec
testSpec' Bool
withShrink String
n Specification a
s = do
  let checkCoverage' :: Property -> Property
checkCoverage' = Confidence -> Property -> Property
forall prop. Testable prop => Confidence -> prop -> Property
checkCoverageWith Confidence
stdConfidence {certainty = 1_000_000}
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
n (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"prop_sound" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
      Int -> Property -> Property
forall prop. Testable prop => Int -> prop -> Property
within Int
10_000_000 (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
        Property -> Property
checkCoverage' (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
          Specification a -> Property
forall a. HasSpec a => Specification a -> Property
prop_sound Specification a
s
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"prop_constrained_satisfies_sound" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
      Int -> Property -> Property
forall prop. Testable prop => Int -> prop -> Property
within Int
10_000_000 (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
        Property -> Property
checkCoverage' (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
          Specification a -> Property
forall a. HasSpec a => Specification a -> Property
prop_constrained_satisfies_sound Specification a
s

    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"prop_constrained_explained" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
      Int -> Property -> Property
forall prop. Testable prop => Int -> prop -> Property
within Int
10_000_0000 (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
        Property -> Property
checkCoverage' (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
          Specification a -> Property
forall a. HasSpec a => Specification a -> Property
prop_constrained_explained Specification a
s

    Bool -> Spec -> Spec
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
withShrink (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$
      String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"prop_shrink_sound" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
        Int -> Property -> Property
forall prop. Testable prop => Int -> prop -> Property
discardAfter Int
100_000 (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
          Property -> Property
checkCoverage' (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
            Specification a -> Property
forall a. HasSpec a => Specification a -> Property
prop_shrink_sound Specification a
s

------------------------------------------------------------------------
-- Test properties of the instance Num (NumSpec Integer)
------------------------------------------------------------------------

-- | When we multiply intervals, we get a bounding box, around the possible values.
--   When the intervals have infinities, the bounding box can be very loose. In fact the
--   order in which we multiply intervals with infinities can affect how loose the bounding box is.
--   So ((NegInf, n) * (a, b)) * (c,d)  AND  (NegInf, n) * ((a, b) * (c,d)) may have different bounding boxes
--   To test the associative laws we must have no infinities, and then the associative law will hold.
noInfinity :: Gen (NumSpec Integer)
noInfinity :: Gen (NumSpec Integer)
noInfinity = do
  Integer
lo <- Gen Integer
forall a. Arbitrary a => Gen a
arbitrary
  Integer
hi <- Gen Integer -> (Integer -> Bool) -> Gen Integer
forall a. Gen a -> (a -> Bool) -> Gen a
suchThat Gen Integer
forall a. Arbitrary a => Gen a
arbitrary (Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
lo)
  NumSpec Integer -> Gen (NumSpec Integer)
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NumSpec Integer -> Gen (NumSpec Integer))
-> NumSpec Integer -> Gen (NumSpec Integer)
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> Maybe Integer -> NumSpec Integer
forall n. Maybe n -> Maybe n -> NumSpec n
NumSpecInterval (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
lo) (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
hi)

plusNegate :: NumSpec Integer -> NumSpec Integer -> Property
plusNegate :: NumSpec Integer -> NumSpec Integer -> Property
plusNegate NumSpec Integer
x NumSpec Integer
y = NumSpec Integer
x NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
- NumSpec Integer
y NumSpec Integer -> NumSpec Integer -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== NumSpec Integer
x NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
+ NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a
negate NumSpec Integer
y

commutesNumSpec :: NumSpec Integer -> NumSpec Integer -> Property
commutesNumSpec :: NumSpec Integer -> NumSpec Integer -> Property
commutesNumSpec NumSpec Integer
x NumSpec Integer
y = NumSpec Integer
x NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
+ NumSpec Integer
y NumSpec Integer -> NumSpec Integer -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== NumSpec Integer
y NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
+ NumSpec Integer
x

assocNumSpec :: NumSpec Integer -> NumSpec Integer -> NumSpec Integer -> Property
assocNumSpec :: NumSpec Integer -> NumSpec Integer -> NumSpec Integer -> Property
assocNumSpec NumSpec Integer
x NumSpec Integer
y NumSpec Integer
z = NumSpec Integer
x NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
+ (NumSpec Integer
y NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
+ NumSpec Integer
z) NumSpec Integer -> NumSpec Integer -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== (NumSpec Integer
x NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
+ NumSpec Integer
y) NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
+ NumSpec Integer
z

commuteTimes :: NumSpec Integer -> NumSpec Integer -> Property
commuteTimes :: NumSpec Integer -> NumSpec Integer -> Property
commuteTimes NumSpec Integer
x NumSpec Integer
y = NumSpec Integer
x NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
* NumSpec Integer
y NumSpec Integer -> NumSpec Integer -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== NumSpec Integer
y NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
* NumSpec Integer
x

assocNumSpecTimes :: Gen Property
assocNumSpecTimes :: Gen Property
assocNumSpecTimes = do
  NumSpec Integer
x <- Gen (NumSpec Integer)
noInfinity
  NumSpec Integer
y <- Gen (NumSpec Integer)
noInfinity
  NumSpec Integer
z <- Gen (NumSpec Integer)
noInfinity
  Property -> Gen Property
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NumSpec Integer
x NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
* (NumSpec Integer
y NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
* NumSpec Integer
z) NumSpec Integer -> NumSpec Integer -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== (NumSpec Integer
x NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
* NumSpec Integer
y) NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
* NumSpec Integer
z)

negNegate :: NumSpec Integer -> Property
negNegate :: NumSpec Integer -> Property
negNegate NumSpec Integer
x = NumSpec Integer
x NumSpec Integer -> NumSpec Integer -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a
negate (NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a
negate NumSpec Integer
x)

scaleNumSpec :: NumSpec Integer -> Property
scaleNumSpec :: NumSpec Integer -> Property
scaleNumSpec NumSpec Integer
y = NumSpec Integer
y NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
+ NumSpec Integer
y NumSpec Integer -> NumSpec Integer -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== NumSpec Integer
2 NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
* NumSpec Integer
y

scaleOne :: NumSpec Integer -> Property
scaleOne :: NumSpec Integer -> Property
scaleOne NumSpec Integer
y = NumSpec Integer
y NumSpec Integer -> NumSpec Integer -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== NumSpec Integer
1 NumSpec Integer -> NumSpec Integer -> NumSpec Integer
forall a. Num a => a -> a -> a
* NumSpec Integer
y

numNumSpecTree :: Spec
numNumSpecTree :: Spec
numNumSpecTree =
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"Num (NumSpec Integer) properties" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$
    (Int -> Int) -> Spec -> Spec
forall a. (Int -> Int) -> SpecWith a -> SpecWith a
modifyMaxSuccess (Int -> Int -> Int
forall a b. a -> b -> a
const Int
10000) (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      String -> (NumSpec Integer -> NumSpec Integer -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"plusNegate(x - y == x + negate y)" NumSpec Integer -> NumSpec Integer -> Property
plusNegate
      String -> (NumSpec Integer -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"scaleNumSpec(y + y = 2 * y)" NumSpec Integer -> Property
scaleNumSpec
      String -> (NumSpec Integer -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"scaleOne(y = 1 * y)" NumSpec Integer -> Property
scaleOne
      String -> (NumSpec Integer -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"negNagate(x = x == negate (negate x))" NumSpec Integer -> Property
negNegate
      String -> (NumSpec Integer -> NumSpec Integer -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"commutesNumSpec(x+y = y+x)" NumSpec Integer -> NumSpec Integer -> Property
commutesNumSpec
      String
-> (NumSpec Integer
    -> NumSpec Integer -> NumSpec Integer -> Property)
-> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"assocNumSpec(x+(y+z) == (x+y)+z)" NumSpec Integer -> NumSpec Integer -> NumSpec Integer -> Property
assocNumSpec
      String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"assocNumSpecTimes(x*(y*z) == (x*y)*z)" Gen Property
assocNumSpecTimes
      String -> (NumSpec Integer -> NumSpec Integer -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"commuteTimes" NumSpec Integer -> NumSpec Integer -> Property
commuteTimes

------------------------------------------------------------------------
-- Tests for `hasSize`
------------------------------------------------------------------------

hasSizeList :: Specification [Int]
hasSizeList :: Specification [Int]
hasSizeList = NumSpec Integer -> Specification [Int]
forall t.
(HasSpec t, Sized t) =>
NumSpec Integer -> Specification t
hasSize (Integer -> Integer -> NumSpec Integer
rangeSize Integer
0 Integer
4)

hasSizeSet :: Specification (Set Int)
hasSizeSet :: Specification (Set Int)
hasSizeSet = NumSpec Integer -> Specification (Set Int)
forall t.
(HasSpec t, Sized t) =>
NumSpec Integer -> Specification t
hasSize (Integer -> Integer -> NumSpec Integer
rangeSize Integer
1 Integer
3)

hasSizeMap :: Specification (Map Int Int)
hasSizeMap :: Specification (Map Int Int)
hasSizeMap = NumSpec Integer -> Specification (Map Int Int)
forall t.
(HasSpec t, Sized t) =>
NumSpec Integer -> Specification t
hasSize (Integer -> Integer -> NumSpec Integer
rangeSize Integer
1 Integer
3)

------------------------------------------------------------------------
-- Tests for narrowing
------------------------------------------------------------------------

prop_noNarrowLoop :: Int -> Int -> Specification Int -> Specification Int -> Property
prop_noNarrowLoop :: Int -> Int -> Specification Int -> Specification Int -> Property
prop_noNarrowLoop Int
f Int
s Specification Int
eSpec Specification Int
fSpec =
  -- Make sure the fuel is non-negative
  Int
f Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Property -> Property
forall prop. Testable prop => Bool -> prop -> Property
==>
    Int -> Property -> Property
forall prop. Testable prop => Int -> prop -> Property
discardAfter Int
100_000 (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
      Int
-> Int
-> (Specification Int, Specification Int)
-> (Specification Int, Specification Int)
forall a.
(TypeSpec a ~ NumSpec a, Arbitrary a, Integral a, Random a,
 MaybeBounded a, Complete a) =>
a
-> Int
-> (Specification a, Specification a)
-> (Specification a, Specification a)
narrowByFuelAndSize Int
f Int
s (Specification Int
eSpec, Specification Int
fSpec) (Specification Int, Specification Int) -> Property -> Property
forall a b. a -> b -> b
`seq`
        Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True

-- | The test succeeds if conformsToSpec and conformsToSpecE both conform, or both fail to conform.
--   We collect answers by specType (ErrorSpec, MemberSpec, SuspendedSpec, ...) and whether
--   they both conform, or they both fail to conform.
conformsToSpecETest :: forall a. HasSpec a => a -> Specification a -> Property
conformsToSpecETest :: forall a. HasSpec a => a -> Specification a -> Property
conformsToSpecETest a
a Specification a
speca =
  let resultE :: Maybe (NonEmpty String)
resultE = a -> Specification a -> NonEmpty String -> Maybe (NonEmpty String)
forall a.
HasSpec a =>
a -> Specification a -> NonEmpty String -> Maybe (NonEmpty String)
conformsToSpecE a
a Specification a
speca (String -> NonEmpty String
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String
"ConformsToSpecETest " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Specification a -> String
forall a. Show a => a -> String
show Specification a
speca))
   in if a -> Specification a -> Bool
forall a. HasSpec a => a -> Specification a -> Bool
conformsToSpec a
a Specification a
speca
        then case Maybe (NonEmpty String)
resultE of
          Maybe (NonEmpty String)
Nothing -> Property -> Property
forall prop. Testable prop => prop -> Property
property (String -> Bool -> Property
forall a prop. (Show a, Testable prop) => a -> prop -> Property
collect (Specification a -> String
forall a. Specification a -> String
specType Specification a
speca String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" both conform") Bool
True)
          Just NonEmpty String
xs -> String -> Bool -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample ([String] -> String
unlines (NonEmpty String -> [String]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty String
xs)) Bool
False
        else case Maybe (NonEmpty String)
resultE of
          Maybe (NonEmpty String)
Nothing ->
            String -> Bool -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample (String
"conformstoSpec returns False, but conformsToSpecE returns no explanations") Bool
False
          Just NonEmpty String
_ -> Property -> Property
forall prop. Testable prop => prop -> Property
property (String -> Bool -> Property
forall a prop. (Show a, Testable prop) => a -> prop -> Property
collect (Specification a -> String
forall a. Specification a -> String
specType Specification a
speca String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" both fail to conform") Bool
True)

conformsToSpecESpec :: Spec
conformsToSpecESpec :: Spec
conformsToSpecESpec =
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"Testing alignment of conformsToSpec and conformsToSpecE" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$
    (Int -> Int) -> Spec -> Spec
forall a. (Int -> Int) -> SpecWith a -> SpecWith a
modifyMaxSuccess (Int -> Int -> Int
forall a b. a -> b -> a
const Int
1000) (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      String -> (Int -> Specification Int -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Int" (forall a. HasSpec a => a -> Specification a -> Property
conformsToSpecETest @Int)
      String -> (Word64 -> Specification Word64 -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Word64" (forall a. HasSpec a => a -> Specification a -> Property
conformsToSpecETest @Word64)
      String -> (Bool -> Specification Bool -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Bool" (forall a. HasSpec a => a -> Specification a -> Property
conformsToSpecETest @Bool)
      String -> ([Int] -> Specification [Int] -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"[Int]" (forall a. HasSpec a => a -> Specification a -> Property
conformsToSpecETest @[Int])
      String
-> ((Int, Bool) -> Specification (Int, Bool) -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"(Int,Bool)" (forall a. HasSpec a => a -> Specification a -> Property
conformsToSpecETest @(Int, Bool))
      String
-> (Set Integer -> Specification (Set Integer) -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Set Integer" (forall a. HasSpec a => a -> Specification a -> Property
conformsToSpecETest @(Set Integer))
      String
-> (Set [Int] -> Specification (Set [Int]) -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Set[Int]" (forall a. HasSpec a => a -> Specification a -> Property
conformsToSpecETest @(Set [Int]))
      String
-> (Map Int Int -> Specification (Map Int Int) -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Map Int Int" (forall a. HasSpec a => a -> Specification a -> Property
conformsToSpecETest @(Map Int Int))

-- ======================================================================
-- Test for use of Fold with size annotations

foldWithSizeTests :: Spec
foldWithSizeTests :: Spec
foldWithSizeTests = do
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"Summation tests with size. " (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"logish is sound" Gen Property
logishProp
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"small odd/even tests" Gen Property
pickProp
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"negative small" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp (-Int
1000) Int
100 Specification Int
forall deps a. SpecificationD deps a
TrueSpec (-Int
400 :: Int) Int
4 Outcome
Succeed
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"negative sum too small" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp (-Int
1000) Int
0 Specification Int
forall deps a. SpecificationD deps a
TrueSpec (-Int
8002 :: Int) Int
4 Outcome
Fail
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"negative large" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp (-Int
60000 :: Int) Int
0 Specification Int
forall deps a. SpecificationD deps a
TrueSpec (-Int
1000) Int
4 Outcome
Succeed
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"(between 50 60) small enough" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp Int
1 Int
10 (Int -> Int -> Specification Int
forall a.
(HasSpec a, TypeSpec a ~ NumSpec a) =>
a -> a -> Specification a
between Int
50 Int
60) (Int
200 :: Int) Int
4 Outcome
Succeed
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"(between 50 60) too large" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp Int
1 Int
10 (Int -> Int -> Specification Int
forall a.
(HasSpec a, TypeSpec a ~ NumSpec a) =>
a -> a -> Specification a
between Int
50 Int
60) (Int
400 :: Int) Int
4 Outcome
Fail
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"(count 2) large is fast" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp Int
1 Int
5000000 Specification Int
forall deps a. SpecificationD deps a
TrueSpec (Int
5000000 :: Int) Int
2 Outcome
Succeed
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"(count 5) large is fast" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp Int
1 Int
5000000 Specification Int
forall deps a. SpecificationD deps a
TrueSpec (Int
5000000 :: Int) Int
5 Outcome
Succeed
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"even succeeds on even" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> (String, Int -> Bool)
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Show t, Integral t, Random t) =>
t
-> t -> (String, t -> Bool) -> t -> Int -> Outcome -> Gen Property
sumProp2 Int
1 Int
50000 (String
"even", Int -> Bool
forall a. Integral a => a -> Bool
even) (Int
45876 :: Int) Int
5 Outcome
Succeed
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"even succeeds on even spec" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp Int
1 Int
50000 Specification Int
forall n.
(TypeSpec n ~ NumSpec n, Integral n, HasSpec n, MaybeBounded n) =>
Specification n
evenSpec (Int
45876 :: Int) Int
5 Outcome
Succeed
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"even fails on odd total, odd count" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp Int
1 Int
50000 Specification Int
forall n.
(TypeSpec n ~ NumSpec n, Integral n, HasSpec n, MaybeBounded n) =>
Specification n
evenSpec (Int
45875 :: Int) Int
3 Outcome
Fail
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"odd fails on odd total, even count" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp Int
1 Int
50000 Specification Int
oddSpec (Int
45878 :: Int) Int
3 Outcome
Fail
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"odd succeeds on odd total, odd count" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp Int
1 Int
50000 Specification Int
oddSpec (Int
45871 :: Int) Int
3 Outcome
Succeed
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
xprop String
"succeeds with large count" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
      Int -> Gen Property -> Property
forall prop. Testable prop => Int -> prop -> Property
withMaxSuccess Int
100 (Int
-> Int
-> Specification Int
-> Int
-> Int
-> Outcome
-> Gen Property
forall t.
(Integral t, Random t, HasSpec t) =>
t -> t -> Specification t -> t -> Int -> Outcome -> Gen Property
sumProp Int
1 Int
1500567 Specification Int
forall deps a. SpecificationD deps a
TrueSpec (Int
1500567 :: Int) Int
20 Outcome
Succeed)
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"sum3 is sound" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Specification [Int] -> Property
forall a. HasSpec a => Specification a -> Property
prop_constrained_satisfies_sound Specification [Int]
sum3
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"(sum3WithLength 3) is sound" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Specification ([Int], Int, Int, Int) -> Property
forall a. HasSpec a => Specification a -> Property
prop_constrained_satisfies_sound (Integer -> Specification ([Int], Int, Int, Int)
sum3WithLength Integer
3)
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"(sum3WithLength 4) is sound" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Specification ([Int], Int, Int, Int) -> Property
forall a. HasSpec a => Specification a -> Property
prop_constrained_satisfies_sound (Integer -> Specification ([Int], Int, Int, Int)
sum3WithLength Integer
4)
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"(sum3WithLength 7) is sound" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Specification ([Int], Int, Int, Int) -> Property
forall a. HasSpec a => Specification a -> Property
prop_constrained_satisfies_sound (Integer -> Specification ([Int], Int, Int, Int)
sum3WithLength Integer
7)
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"listSum is sound" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Specification [Int] -> Property
forall a. HasSpec a => Specification a -> Property
prop_constrained_satisfies_sound (forall a. Numbery a => Specification [a]
listSum @Int)
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"listSumPair is sound" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Specification [(Word64, Int)] -> Property
forall a. HasSpec a => Specification a -> Property
prop_constrained_satisfies_sound (forall a. Numbery a => Specification [(a, Int)]
listSumPair @Word64)
    -- This, by design, will fail for inputs greater than 7
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"listSumComplex is sound" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Specification [Integer] -> Property
forall a. HasSpec a => Specification a -> Property
prop_constrained_satisfies_sound (forall a. Numbery a => a -> Specification [a]
listSumComplex @Integer Integer
7)
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"All sizes are negative" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$
      forall a.
(Foldy a, Random a, Integral a, TypeSpec a ~ NumSpec a,
 Arbitrary a, MaybeBounded a) =>
Specification Integer
-> Specification a -> Specification a -> Outcome -> Gen Property
testFoldSpec @Int (Integer -> Integer -> Specification Integer
forall a.
(HasSpec a, TypeSpec a ~ NumSpec a) =>
a -> a -> Specification a
between (-Integer
5) (-Integer
2)) Specification Int
forall n.
(TypeSpec n ~ NumSpec n, Integral n, HasSpec n, MaybeBounded n) =>
Specification n
evenSpec (NonEmpty Int -> Specification Int
forall a deps. NonEmpty a -> SpecificationD deps a
MemberSpec (Int -> NonEmpty Int
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
100)) Outcome
Fail
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Only some sizes are negative" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$
      forall a.
(Foldy a, Random a, Integral a, TypeSpec a ~ NumSpec a,
 Arbitrary a, MaybeBounded a) =>
Specification Integer
-> Specification a -> Specification a -> Outcome -> Gen Property
testFoldSpec @Int (Integer -> Integer -> Specification Integer
forall a.
(HasSpec a, TypeSpec a ~ NumSpec a) =>
a -> a -> Specification a
between (-Integer
5) Integer
0) Specification Int
forall n.
(TypeSpec n ~ NumSpec n, Integral n, HasSpec n, MaybeBounded n) =>
Specification n
evenSpec (NonEmpty Int -> Specification Int
forall a deps. NonEmpty a -> SpecificationD deps a
MemberSpec (Int -> NonEmpty Int
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
100)) Outcome
Fail
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"total and count can only be 0 in Word type" (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$
      forall a.
(Foldy a, Random a, Integral a, TypeSpec a ~ NumSpec a,
 Arbitrary a, MaybeBounded a) =>
Specification Integer
-> Specification a -> Specification a -> Outcome -> Gen Property
testFoldSpec @Word64 (Integer -> Integer -> Specification Integer
forall a.
(HasSpec a, TypeSpec a ~ NumSpec a) =>
a -> a -> Specification a
between Integer
0 Integer
0) Specification Word64
forall n.
(TypeSpec n ~ NumSpec n, Integral n, HasSpec n, MaybeBounded n) =>
Specification n
evenSpec (NonEmpty Word64 -> Specification Word64
forall a deps. NonEmpty a -> SpecificationD deps a
MemberSpec (Word64 -> NonEmpty Word64
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word64
0)) Outcome
Succeed
    String -> Gen Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"something of size 2, can add to 0 in type with negative values." (Gen Property -> Spec) -> Gen Property -> Spec
forall a b. (a -> b) -> a -> b
$
      forall a.
(Foldy a, Random a, Integral a, TypeSpec a ~ NumSpec a,
 Arbitrary a, MaybeBounded a) =>
Specification Integer
-> Specification a -> Specification a -> Outcome -> Gen Property
testFoldSpec @Int (Integer -> Integer -> Specification Integer
forall a.
(HasSpec a, TypeSpec a ~ NumSpec a) =>
a -> a -> Specification a
between Integer
2 Integer
2) (Int -> Int -> Specification Int
forall a.
(HasSpec a, TypeSpec a ~ NumSpec a) =>
a -> a -> Specification a
between (-Int
10) Int
10) (NonEmpty Int -> Specification Int
forall a deps. NonEmpty a -> SpecificationD deps a
MemberSpec (Int -> NonEmpty Int
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
0)) Outcome
Succeed
    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"TEST listSum" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Specification [Int] -> Property
forall a. HasSpec a => Specification a -> Property
prop_constrained_satisfies_sound (forall a. Numbery a => Specification [a]
listSum @Int)

-- TODO Needs to sample like this: OR [pick t c | t <- total, c <- count]
-- prop "count =0, total is 0,1,2" $ testFoldSpec @Int (between 0 1) evenSpec (between 0 2) Succeed