hw-excess-0.2.0.3: test/HaskellWorks/Data/Excess/MinMaxExcess1Spec.hs
{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
{-# LANGUAGE ScopedTypeVariables #-}
module HaskellWorks.Data.Excess.MinMaxExcess1Spec (spec) where
import HaskellWorks.Data.Bits.Word
import HaskellWorks.Data.Excess.MinMaxExcess1
import HaskellWorks.Data.Excess.Triplet
import HaskellWorks.Data.Naive
import HaskellWorks.Hspec.Hedgehog
import Hedgehog
import Test.Hspec
import qualified Data.Vector.Storable as DVS
import qualified Hedgehog.Gen as G
import qualified Hedgehog.Range as R
{-# ANN module ("HLint: Ignore Redundant do" :: String) #-}
{-# ANN module ("HLint: Ignore Reduce duplication" :: String) #-}
spec :: Spec
spec = describe "HaskellWorks.Data.Excess.MinMaxExcess1Spec" $ do
describe "For Word8" $ do
it "Excess should be between min excess and max excess" $ requireProperty $ do
w <- forAll $ G.word8 R.constantBounded
let Triplet minE e maxE = minMaxExcess1 w
assert $ minE <= e && e <= maxE
it "minE2 == minE0 `min` (minE1 + e0)" $ requireProperty $ do
w0 <- forAll $ G.word8 R.constantBounded
w1 <- forAll $ G.word8 R.constantBounded
let w2 = leConcat w0 w1
let Triplet minE0 e0 _ = minMaxExcess1 w0
let Triplet minE1 _ _ = minMaxExcess1 w1
let Triplet minE2 _ _ = minMaxExcess1 w2
minE2 === minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0)" $ requireProperty $ do
w0 <- forAll $ G.word8 R.constantBounded
w1 <- forAll $ G.word8 R.constantBounded
let w2 = leConcat w0 w1
let Triplet _ e0 maxE0 = minMaxExcess1 w0
let Triplet _ _ maxE1 = minMaxExcess1 w1
let Triplet _ _ maxE2 = minMaxExcess1 w2
maxE2 === maxE0 `max` (maxE1 + e0)
it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do
w0 <- forAll $ G.word8 R.constantBounded
w1 <- forAll $ G.word8 R.constantBounded
let w2 = DVS.fromList [w0, w1]
let Triplet minE0 e0 _ = minMaxExcess1 w0
let Triplet minE1 _ _ = minMaxExcess1 w1
let Triplet minE2 _ _ = minMaxExcess1 w2
minE2 === minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do
w0 <- forAll $ G.word8 R.constantBounded
w1 <- forAll $ G.word8 R.constantBounded
let w2 = DVS.fromList [w0, w1]
let Triplet _ e0 maxE0 = minMaxExcess1 w0
let Triplet _ _ maxE1 = minMaxExcess1 w1
let Triplet _ _ maxE2 = minMaxExcess1 w2
maxE2 === maxE0 `max` (maxE1 + e0)
describe "For Word16" $ do
it "Excess should be between min excess and max excess" $ requireProperty $ do
w <- forAll $ G.word16 R.constantBounded
let Triplet minE e maxE = minMaxExcess1 w
assert $ minE <= e && e <= maxE
it "minE2 == minE0 `min` (minE1 + e0)" $ requireProperty $ do
w0 <- forAll $ G.word16 R.constantBounded
w1 <- forAll $ G.word16 R.constantBounded
let w2 = leConcat w0 w1
let Triplet minE0 e0 _ = minMaxExcess1 w0
let Triplet minE1 _ _ = minMaxExcess1 w1
let Triplet minE2 _ _ = minMaxExcess1 w2
minE2 === minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0)" $ requireProperty $ do
w0 <- forAll $ G.word16 R.constantBounded
w1 <- forAll $ G.word16 R.constantBounded
let w2 = leConcat w0 w1
let Triplet _ e0 maxE0 = minMaxExcess1 w0
let Triplet _ _ maxE1 = minMaxExcess1 w1
let Triplet _ _ maxE2 = minMaxExcess1 w2
maxE2 === maxE0 `max` (maxE1 + e0)
it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do
w0 <- forAll $ G.word16 R.constantBounded
w1 <- forAll $ G.word16 R.constantBounded
let w2 = DVS.fromList [w0, w1]
let Triplet minE0 e0 _ = minMaxExcess1 w0
let Triplet minE1 _ _ = minMaxExcess1 w1
let Triplet minE2 _ _ = minMaxExcess1 w2
minE2 === minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do
w0 <- forAll $ G.word16 R.constantBounded
w1 <- forAll $ G.word16 R.constantBounded
let w2 = DVS.fromList [w0, w1]
let Triplet _ e0 maxE0 = minMaxExcess1 w0
let Triplet _ _ maxE1 = minMaxExcess1 w1
let Triplet _ _ maxE2 = minMaxExcess1 w2
maxE2 === maxE0 `max` (maxE1 + e0)
describe "For Word32" $ do
it "Excess should be between min excess and max excess" $ requireProperty $ do
w <- forAll $ G.word32 R.constantBounded
let Triplet minE e maxE = minMaxExcess1 w
assert $ minE <= e && e <= maxE
it "minE2 == minE0 `min` (minE1 + e0)" $ requireProperty $ do
w0 <- forAll $ G.word32 R.constantBounded
w1 <- forAll $ G.word32 R.constantBounded
let w2 = leConcat w0 w1
let Triplet minE0 e0 _ = minMaxExcess1 w0
let Triplet minE1 _ _ = minMaxExcess1 w1
let Triplet minE2 _ _ = minMaxExcess1 w2
minE2 === minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0)" $ requireProperty $ do
w0 <- forAll $ G.word32 R.constantBounded
w1 <- forAll $ G.word32 R.constantBounded
let w2 = leConcat w0 w1
let Triplet _ e0 maxE0 = minMaxExcess1 w0
let Triplet _ _ maxE1 = minMaxExcess1 w1
let Triplet _ _ maxE2 = minMaxExcess1 w2
maxE2 === maxE0 `max` (maxE1 + e0)
it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do
w0 <- forAll $ G.word32 R.constantBounded
w1 <- forAll $ G.word32 R.constantBounded
let w2 = DVS.fromList [w0, w1]
let Triplet minE0 e0 _ = minMaxExcess1 w0
let Triplet minE1 _ _ = minMaxExcess1 w1
let Triplet minE2 _ _ = minMaxExcess1 w2
minE2 === minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do
w0 <- forAll $ G.word32 R.constantBounded
w1 <- forAll $ G.word32 R.constantBounded
let w2 = DVS.fromList [w0, w1]
let Triplet _ e0 maxE0 = minMaxExcess1 w0
let Triplet _ _ maxE1 = minMaxExcess1 w1
let Triplet _ _ maxE2 = minMaxExcess1 w2
maxE2 === maxE0 `max` (maxE1 + e0)
describe "For Word64" $ do
it "Excess should be between min excess and max excess" $ requireProperty $ do
w <- forAll $ G.word64 R.constantBounded
let Triplet minE e maxE = minMaxExcess1 w
assert $ minE <= e && e <= maxE
it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do
w0 <- forAll $ G.word64 R.constantBounded
w1 <- forAll $ G.word64 R.constantBounded
let w2 = DVS.fromList [w0, w1]
let Triplet minE0 e0 _ = minMaxExcess1 w0
let Triplet minE1 _ _ = minMaxExcess1 w1
let Triplet minE2 _ _ = minMaxExcess1 w2
minE2 === minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do
w0 <- forAll $ G.word64 R.constantBounded
w1 <- forAll $ G.word64 R.constantBounded
let w2 = DVS.fromList [w0, w1]
let Triplet _ e0 maxE0 = minMaxExcess1 w0
let Triplet _ _ maxE1 = minMaxExcess1 w1
let Triplet _ _ maxE2 = minMaxExcess1 w2
maxE2 === maxE0 `max` (maxE1 + e0)
describe "Equivalent to native implementation" $ do
it "For Word8" $ requireProperty $ do
w <- forAll $ G.word8 R.constantBounded
minMaxExcess1 w === minMaxExcess1 (Naive w)
it "For Word16" $ requireProperty $ do
w <- forAll $ G.word16 R.constantBounded
minMaxExcess1 w === minMaxExcess1 (Naive w)
it "For Word32" $ requireProperty $ do
w <- forAll $ G.word32 R.constantBounded
minMaxExcess1 w === minMaxExcess1 (Naive w)
it "For Word64" $ requireProperty $ do
w <- forAll $ G.word64 R.constantBounded
minMaxExcess1 w === minMaxExcess1 (Naive w)