{-# LANGUAGE ScopedTypeVariables #-}
import Test.Tasty
import Test.Tasty.QuickCheck
import Data.Vec3
infix 4 <~=>
(<~=>) :: CVec3 -> CVec3 -> Bool
(<~=>) a b = ax ~= bx &&
ay ~= by &&
az ~= bz
where
(ax, ay, az) = toXYZ (a :: CVec3)
(bx, by, bz) = toXYZ (b :: CVec3)
infix 4 ~=
(~=) :: Double -> Double -> Bool
(~=) a b | a == b = True
| a == 0 || b == 0 || isDenormalized absDiff = absDiff < maxError
| otherwise = absDiff / (abs a + abs b) < maxError
where
absDiff = abs $ a - b
maxError = 1e-13
tests :: [TestTree]
tests =
[ testProperty
"Commutativity of addition: a + b = b + a"
(\(a :: CVec3) b -> a <+> b <~=> b <+> a)
, testProperty
"Associativity of addition: (a + b) + c = a + (b + c)"
(\(a :: CVec3) b c -> (a <+> b) <+> c <~=> a <+> (b <+> c))
, testProperty
"Identity element of addition (zero): v + 0 = v"
(\(v :: CVec3) -> (v <+> origin <~=> v))
, testProperty
"Inverse elements of addition: v + (-v) = 0"
(\(v :: CVec3) -> (v <+> invert v <~=> origin))
, testProperty
"Compatibility of scalar and field multiplication"
(\(v :: CVec3) p q -> (v .^ p .^ q <~=> v .^ (p * q)))
, testProperty
"Identity of scalar multiplication"
(\(v :: CVec3) -> (v .^ 1 <~=> v))
, testProperty
"Distributivity wrt vector addition"
(\(a :: CVec3) b p -> ((a <+> b) .^ p) <~=> (a .^ p) <+> (b .^ p))
, testProperty
"Distributivity wrt scalar addition"
(\(a :: CVec3) p q -> (a .^ (p + q) <~=> (a .^ p) <+> (a .^ q)))
, testProperty
"Subtraction definition"
(\(a :: CVec3) b -> (a <+> invert b <~=> a <-> b))
, testProperty
"Normalization"
(\(v :: CVec3) -> (v <~=> origin || norm (normalize v) ~= 1))
, testProperty
"Triangle inequality"
(\(a :: CVec3) b c -> (distance a b + distance b c >= distance a c))
]
main :: IO ()
main = defaultMain $ testGroup "Tests" tests