hw-excess-0.2.0.0: test/HaskellWorks/Data/Excess/MinMaxExcess1Spec.hs
{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
{-# LANGUAGE ScopedTypeVariables #-}
module HaskellWorks.Data.Excess.MinMaxExcess1Spec (spec) where
import Data.Word
import HaskellWorks.Data.Bits.Word
import HaskellWorks.Data.Excess.MinMaxExcess1
import HaskellWorks.Data.Excess.Triplet
import HaskellWorks.Data.Naive
import Test.Hspec
import Test.QuickCheck
import qualified Data.Vector.Storable as DVS
{-# 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" $
property $ \(w :: Word8) ->
let Triplet minE e maxE = minMaxExcess1 w in
minE <= e && e <= maxE
it "minE2 == minE0 `min` (minE1 + e0)" $
property $ \(w0 :: Word8, w1 :: Word8) ->
let w2 = leConcat w0 w1 in
let Triplet minE0 e0 _ = minMaxExcess1 w0 in
let Triplet minE1 _ _ = minMaxExcess1 w1 in
let Triplet minE2 _ _ = minMaxExcess1 w2 in
minE2 == minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0)" $
property $ \(w0 :: Word8, w1 :: Word8) ->
let w2 = leConcat w0 w1 in
let Triplet _ e0 maxE0 = minMaxExcess1 w0 in
let Triplet _ _ maxE1 = minMaxExcess1 w1 in
let Triplet _ _ maxE2 = minMaxExcess1 w2 in
maxE2 == maxE0 `max` (maxE1 + e0)
it "minE2 == minE0 `min` (minE1 + e0) via vector" $
property $ \(w0 :: Word8, w1 :: Word8) ->
let w2 = DVS.fromList [w0, w1] in
let Triplet minE0 e0 _ = minMaxExcess1 w0 in
let Triplet minE1 _ _ = minMaxExcess1 w1 in
let Triplet minE2 _ _ = minMaxExcess1 w2 in
minE2 == minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
property $ \(w0 :: Word8, w1 :: Word8) ->
let w2 = DVS.fromList [w0, w1] in
let Triplet _ e0 maxE0 = minMaxExcess1 w0 in
let Triplet _ _ maxE1 = minMaxExcess1 w1 in
let Triplet _ _ maxE2 = minMaxExcess1 w2 in
maxE2 == maxE0 `max` (maxE1 + e0)
describe "For Word16" $ do
it "Excess should be between min excess and max excess" $
property $ \(w :: Word16) ->
let Triplet minE e maxE = minMaxExcess1 w in
minE <= e && e <= maxE
it "minE2 == minE0 `min` (minE1 + e0)" $
property $ \(w0 :: Word16, w1 :: Word16) ->
let w2 = leConcat w0 w1 in
let Triplet minE0 e0 _ = minMaxExcess1 w0 in
let Triplet minE1 _ _ = minMaxExcess1 w1 in
let Triplet minE2 _ _ = minMaxExcess1 w2 in
minE2 == minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0)" $
property $ \(w0 :: Word16, w1 :: Word16) ->
let w2 = leConcat w0 w1 in
let Triplet _ e0 maxE0 = minMaxExcess1 w0 in
let Triplet _ _ maxE1 = minMaxExcess1 w1 in
let Triplet _ _ maxE2 = minMaxExcess1 w2 in
maxE2 == maxE0 `max` (maxE1 + e0)
it "minE2 == minE0 `min` (minE1 + e0) via vector" $
property $ \(w0 :: Word16, w1 :: Word16) ->
let w2 = DVS.fromList [w0, w1] in
let Triplet minE0 e0 _ = minMaxExcess1 w0 in
let Triplet minE1 _ _ = minMaxExcess1 w1 in
let Triplet minE2 _ _ = minMaxExcess1 w2 in
minE2 == minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
property $ \(w0 :: Word16, w1 :: Word16) ->
let w2 = DVS.fromList [w0, w1] in
let Triplet _ e0 maxE0 = minMaxExcess1 w0 in
let Triplet _ _ maxE1 = minMaxExcess1 w1 in
let Triplet _ _ maxE2 = minMaxExcess1 w2 in
maxE2 == maxE0 `max` (maxE1 + e0)
describe "For Word32" $ do
it "Excess should be between min excess and max excess" $
property $ \(w :: Word32) ->
let Triplet minE e maxE = minMaxExcess1 w in
minE <= e && e <= maxE
it "minE2 == minE0 `min` (minE1 + e0)" $
property $ \(w0 :: Word32, w1 :: Word32) ->
let w2 = leConcat w0 w1 in
let Triplet minE0 e0 _ = minMaxExcess1 w0 in
let Triplet minE1 _ _ = minMaxExcess1 w1 in
let Triplet minE2 _ _ = minMaxExcess1 w2 in
minE2 == minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0)" $
property $ \(w0 :: Word32, w1 :: Word32) ->
let w2 = leConcat w0 w1 in
let Triplet _ e0 maxE0 = minMaxExcess1 w0 in
let Triplet _ _ maxE1 = minMaxExcess1 w1 in
let Triplet _ _ maxE2 = minMaxExcess1 w2 in
maxE2 == maxE0 `max` (maxE1 + e0)
it "minE2 == minE0 `min` (minE1 + e0) via vector" $
property $ \(w0 :: Word32, w1 :: Word32) ->
let w2 = DVS.fromList [w0, w1] in
let Triplet minE0 e0 _ = minMaxExcess1 w0 in
let Triplet minE1 _ _ = minMaxExcess1 w1 in
let Triplet minE2 _ _ = minMaxExcess1 w2 in
minE2 == minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
property $ \(w0 :: Word32, w1 :: Word32) ->
let w2 = DVS.fromList [w0, w1] in
let Triplet _ e0 maxE0 = minMaxExcess1 w0 in
let Triplet _ _ maxE1 = minMaxExcess1 w1 in
let Triplet _ _ maxE2 = minMaxExcess1 w2 in
maxE2 == maxE0 `max` (maxE1 + e0)
describe "For Word64" $ do
it "Excess should be between min excess and max excess" $
property $ \(w :: Word64) ->
let Triplet minE e maxE = minMaxExcess1 w in
minE <= e && e <= maxE
it "minE2 == minE0 `min` (minE1 + e0) via vector" $
property $ \(w0 :: Word64, w1 :: Word64) ->
let w2 = DVS.fromList [w0, w1] in
let Triplet minE0 e0 _ = minMaxExcess1 w0 in
let Triplet minE1 _ _ = minMaxExcess1 w1 in
let Triplet minE2 _ _ = minMaxExcess1 w2 in
minE2 == minE0 `min` (minE1 + e0)
it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
property $ \(w0 :: Word64, w1 :: Word64) ->
let w2 = DVS.fromList [w0, w1] in
let Triplet _ e0 maxE0 = minMaxExcess1 w0 in
let Triplet _ _ maxE1 = minMaxExcess1 w1 in
let Triplet _ _ maxE2 = minMaxExcess1 w2 in
maxE2 == maxE0 `max` (maxE1 + e0)
describe "Equivalent to native implementation" $ do
it "For Word8" $ do
property $ \(w :: Word8) ->
minMaxExcess1 w == minMaxExcess1 (Naive w)
it "For Word16" $ do
property $ \(w :: Word16) ->
minMaxExcess1 w == minMaxExcess1 (Naive w)
it "For Word32" $ do
property $ \(w :: Word32) ->
minMaxExcess1 w == minMaxExcess1 (Naive w)
it "For Word64" $ do
property $ \(w :: Word64) ->
minMaxExcess1 w == minMaxExcess1 (Naive w)