Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add checks for Enum #23

Merged
merged 18 commits into from
Nov 10, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/Test/QuickCheck/Laws.purs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Test.QuickCheck.Laws

import Prelude
import Control.Monad.Eff.Console (log)
import Data.Enum (class BoundedEnum)
import Data.Enum (class Enum, class BoundedEnum)
import Data.Monoid (class Monoid)
import Test.QuickCheck (QC)
import Test.QuickCheck.Arbitrary (class Arbitrary, class Coarbitrary)
Expand All @@ -21,6 +21,7 @@ derive newtype instance arbitraryA ∷ Arbitrary A
derive newtype instance boundedA ∷ Bounded A
derive newtype instance boundedEnumA :: BoundedEnum A
derive newtype instance coarbitraryA ∷ Coarbitrary A
derive newtype instance enumA ∷ Enum A
derive newtype instance eqA ∷ Eq A
derive newtype instance ordA ∷ Ord A
derive newtype instance semigroupA ∷ Semigroup A
Expand All @@ -32,6 +33,7 @@ derive newtype instance arbitraryB ∷ Arbitrary B
derive newtype instance boundedB ∷ Bounded B
derive newtype instance boundedEnumB :: BoundedEnum B
derive newtype instance coarbitraryB ∷ Coarbitrary B
derive newtype instance enumB ∷ Enum B
derive newtype instance eqB ∷ Eq B
derive newtype instance ordB ∷ Ord B
derive newtype instance semigroupB ∷ Semigroup B
Expand All @@ -43,6 +45,7 @@ derive newtype instance arbitraryC ∷ Arbitrary C
derive newtype instance boundedC ∷ Bounded C
derive newtype instance boundedEnumC :: BoundedEnum C
derive newtype instance coarbitraryC ∷ Coarbitrary C
derive newtype instance enumC ∷ Enum C
derive newtype instance eqC ∷ Eq C
derive newtype instance ordC ∷ Ord C
derive newtype instance semigroupC ∷ Semigroup C
Expand All @@ -54,6 +57,7 @@ derive newtype instance arbitraryD ∷ Arbitrary D
derive newtype instance boundedD ∷ Bounded D
derive newtype instance boundedEnumD :: BoundedEnum D
derive newtype instance coarbitraryD ∷ Coarbitrary D
derive newtype instance enumD ∷ Enum D
derive newtype instance eqD ∷ Eq D
derive newtype instance ordD ∷ Ord D
derive newtype instance semigroupD ∷ Semigroup D
Expand All @@ -65,6 +69,7 @@ derive newtype instance arbitraryE ∷ Arbitrary E
derive newtype instance boundedE ∷ Bounded E
derive newtype instance boundedEnumE :: BoundedEnum E
derive newtype instance coarbitraryE ∷ Coarbitrary E
derive newtype instance enumE ∷ Enum E
derive newtype instance eqE ∷ Eq E
derive newtype instance ordE ∷ Ord E
derive newtype instance semigroupE ∷ Semigroup E
Expand Down
1 change: 1 addition & 0 deletions src/Test/QuickCheck/Laws/Data.purs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module Test.QuickCheck.Laws.Data (module Exports) where
import Test.QuickCheck.Laws.Data.BooleanAlgebra (checkBooleanAlgebra) as Exports
import Test.QuickCheck.Laws.Data.Bounded (checkBounded) as Exports
import Test.QuickCheck.Laws.Data.CommutativeRing (checkCommutativeRing) as Exports
import Test.QuickCheck.Laws.Data.Enum (checkEnum) as Exports
import Test.QuickCheck.Laws.Data.Eq (checkEq) as Exports
import Test.QuickCheck.Laws.Data.BoundedEnum (checkBoundedEnum) as Exports
import Test.QuickCheck.Laws.Data.EuclideanRing (checkEuclideanRing) as Exports
Expand Down
9 changes: 4 additions & 5 deletions src/Test/QuickCheck/Laws/Data/BoundedEnum.purs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ checkBoundedEnum
⇒ Ord a
⇒ Proxy a
→ QC eff Unit
checkBoundedEnum _ = do
checkBoundedEnum p = do

log "Checking 'succ' law for BoundedEnum"
quickCheck' 1 succLaw
Expand All @@ -54,7 +54,6 @@ checkBoundedEnum _ = do
log "Checking 'tofromenum' law for BoundedEnum"
quickCheck' 1000 tofromenumLaw


where
c :: Int
c = unwrap (cardinality :: Cardinality a)
Expand All @@ -74,10 +73,10 @@ checkBoundedEnum _ = do
succpredLaw a = a == top || (succ a >>= pred) == Just a

enumpredLaw :: a -> Boolean
enumpredLaw a = a == bottom || (fromEnum <$> pred a) == Just (fromEnum a - 1)

enumpredLaw a = a == bottom || (fromEnum <$> pred a) == pred (fromEnum a)
enumsuccLaw :: a -> Boolean
enumsuccLaw a = a == top || (fromEnum <$> succ a) == Just (fromEnum a + 1)
enumsuccLaw a = a == top || (fromEnum <$> succ a) == succ (fromEnum a)

compareLaw :: a -> a -> Boolean
compareLaw a b = a `compare` b == fromEnum a `compare` fromEnum b
Expand Down
60 changes: 60 additions & 0 deletions src/Test/QuickCheck/Laws/Data/Enum.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

module Test.QuickCheck.Laws.Data.Enum where

import Prelude
import Control.Monad.Eff.Console (log)
import Data.Enum (pred, succ, class Enum)
import Data.Maybe (maybe)
import Test.QuickCheck (QC, quickCheck')
import Test.QuickCheck.Arbitrary (class Arbitrary)
import Type.Proxy (Proxy)

checkEnum
∷ ∀ eff a
. Arbitrary a
⇒ Enum a
⇒ Ord a
⇒ Proxy a
→ QC eff Unit
checkEnum _ = do


log "Checking 'Successor' law for Enum"
quickCheck' 1000 successor

log "Checking 'Predecessor' law for Enum"
quickCheck' 1000 predecessor

log "Checking 'Succ retracts pred' law for Enum"
quickCheck' 1000 succRetractsPred

log "Checking 'Pred retracts succ' law for Enum"
quickCheck' 1000 predRetractsSucc

log "Checking 'Non-skipping succ' law for Enum"
quickCheck' 1000 nonSkippingSucc

log "Checking 'Non-skipping pred' law for Enum"
quickCheck' 1000 nonSkippingPred


where

successor :: a -> Boolean
successor a = maybe true (a < _) (succ a)

predecessor :: a -> Boolean
predecessor a = maybe true (_ < a) (pred a)

succRetractsPred :: a -> Boolean
succRetractsPred a = (pred a >>= succ >>= pred) == pred a

predRetractsSucc :: a -> Boolean
predRetractsSucc a = (succ a >>= pred >>= succ) == succ a

nonSkippingSucc :: a -> a -> Boolean
nonSkippingSucc a b = b <= a || maybe false (_ <= b) (succ a)

nonSkippingPred :: a -> a -> Boolean
nonSkippingPred a b = a <= b || maybe false (b <= _) (pred a)

9 changes: 7 additions & 2 deletions src/Test/QuickCheck/Laws/Data/EuclideanRing.purs
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,10 @@ checkEuclideanRing _ = do

submultiplicative ∷ a → a → Boolean
submultiplicative a b
| a /= zero && b /= zero = degree a <= degree (a * b)
| otherwise = true
| a == zero || b == zero = true
| productOverflows a b = true
| otherwise = degree a <= degree (a * b)

productOverflows :: a -> a -> Boolean
productOverflows a b = p / b /= a
where p = a * b
JordanMartinez marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions test/Test/Data/Either.purs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ checkEither = checkLaws "Either" do
Data.checkEq prxEither
Data.checkOrd prxEither
Data.checkBounded prxEither
Data.checkEnum prxEither
Data.checkBoundedEnum prxEither
Data.checkFunctor prx2Either
Data.checkFoldableFunctor prx2Either
Expand Down
1 change: 1 addition & 0 deletions test/Test/Data/Maybe.purs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ checkMaybe = checkLaws "Maybe" do
Data.checkEq prxMaybe
Data.checkOrd prxMaybe
Data.checkBounded prxMaybe
Data.checkEnum prxMaybe
Data.checkBoundedEnum prxMaybe
Data.checkSemigroup prxMaybe
Data.checkMonoid prxMaybe
Expand Down
1 change: 1 addition & 0 deletions test/Test/Data/Ordering.purs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ checkOrdering = checkLaws "Ordering" do
Data.checkEq prxOrdering
Data.checkOrd prxOrdering
Data.checkBounded prxOrdering
Data.checkEnum prxOrdering
Data.checkBoundedEnum prxOrdering
Data.checkSemigroup prxOrdering
where
Expand Down
1 change: 1 addition & 0 deletions test/Test/Data/Tuple.purs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ checkTuple = checkLaws "Tuple" do
Data.checkEq prxTuple
Data.checkOrd prxTuple
Data.checkBounded prxTuple
Data.checkEnum prxTuple
Data.checkBoundedEnum prxTuple
Data.checkSemigroup prxTuple
Data.checkMonoid prxTuple
Expand Down
1 change: 1 addition & 0 deletions test/Test/Data/Unit.purs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ checkUnit = checkLaws "Unit" do
Data.checkEq prxUnit
Data.checkOrd prxUnit
Data.checkBounded prxUnit
Data.checkEnum prxUnit
Data.checkBoundedEnum prxUnit
Data.checkSemigroup prxUnit
Data.checkMonoid prxUnit
Expand Down
1 change: 1 addition & 0 deletions test/Test/Prim/Boolean.purs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ checkBoolean = checkLaws "Boolean" do
Data.checkEq prxBoolean
Data.checkOrd prxBoolean
Data.checkBounded prxBoolean
Data.checkEnum prxBoolean
Data.checkBoundedEnum prxBoolean
Data.checkHeytingAlgebra prxBoolean
Data.checkBooleanAlgebra prxBoolean
Expand Down