linear 1.21.10 → 1.23.3
raw patch · 22 files changed
Files
- CHANGELOG.markdown +38/−0
- linear.cabal +26/−20
- src/Linear/Affine.hs +2/−6
- src/Linear/Plucker.hs +15/−8
- src/Linear/Quaternion.hs +9/−13
- src/Linear/V.hs +10/−16
- src/Linear/V0.hs +7/−17
- src/Linear/V1.hs +7/−17
- src/Linear/V2.hs +7/−17
- src/Linear/V3.hs +12/−13
- src/Linear/V4.hs +13/−12
- src/Linear/Vector.hs +6/−1
- tests/Binary.hs +0/−19
- tests/Plucker.hs +0/−35
- tests/Prop/Quaternion.hs +28/−0
- tests/Prop/V3.hs +8/−0
- tests/Test.hs +24/−0
- tests/Unit/Binary.hs +20/−0
- tests/Unit/Plucker.hs +36/−0
- tests/Unit/V.hs +14/−0
- tests/UnitTests.hs +0/−16
- tests/V.hs +0/−13
CHANGELOG.markdown view
@@ -1,3 +1,41 @@+1.23.3 [2026.01.10]+-------------------+* Remove unused `ghc-prim`, `tagged, `transformers-compat`, and `void`+ dependencies.++1.23.2 [2025.06.17]+-------------------+* Replace `test-framework` with `tasty` in the test suite.++1.23.1 [2025.03.03]+-------------------+* Add `Uniform` and `UniformRange` instances for `Plucker`, `Quaternion`, `V`,+ and `V{0,1,2,3,4}`.++1.23 [2024.04.15]+-----------------+* The direction of interpolation of `lerp` has been reversed;+ now `lerp 0 a b == a` and `lerp 1 a b == b`.+ This brings `lerp` in line not only with its implementation+ in other languages and frameworks, but also with `slerp` in this package.++1.22 [2022.11.30]+-----------------+* The types of `_Point` and `lensP` have been generalized:++ ```diff+ -_Point :: Iso' (Point f a) (f a)+ +_Point :: Iso (Point f a) (Point g b) (f a) (g b)++ -lensP :: Lens' (Point g a) (g a)+ +lensP :: Lens (Point f a) (Point g b) (f a) (g b)+ ```++ There is a chance that existing uses of `_Point` or `lensP` will fail to+ typecheck due to their more general types. You can use `_Point.simple` or+ `lensP.simple` to restore their old, more restricted types (where `simple`+ comes from `Control.Lens` in the `lens` library).+ 1.21.10 [2022.06.21] -------------------- * Allow building with `vector-0.13.*`.
linear.cabal view
@@ -1,6 +1,6 @@ name: linear category: Math, Algebra-version: 1.21.10+version: 1.23.3 license: BSD3 cabal-version: >= 1.10 license-file: LICENSE@@ -20,7 +20,13 @@ , GHC == 8.8.4 , GHC == 8.10.7 , GHC == 9.0.2- , GHC == 9.2.2+ , GHC == 9.2.8+ , GHC == 9.4.8+ , GHC == 9.6.7+ , GHC == 9.8.4+ , GHC == 9.10.3+ , GHC == 9.12.2+ , GHC == 9.14.1 extra-source-files: .gitignore .hlint.yaml@@ -53,23 +59,18 @@ binary >= 0.5 && < 0.9, bytes >= 0.15 && < 1, cereal >= 0.4.1.1 && < 0.6,- containers >= 0.4 && < 0.7,- deepseq >= 1.1 && < 1.5,+ containers >= 0.4 && < 0.9,+ deepseq >= 1.1 && < 1.6, distributive >= 0.5.1 && < 1,- ghc-prim,- hashable >= 1.2.7.0 && < 1.5,+ hashable >= 1.2.7.0 && < 1.6, indexed-traversable >= 0.1.1 && < 0.2, lens >= 4.15.2 && < 6,- random >= 1.0 && < 1.3,+ random >= 1.2 && < 1.4, reflection >= 2 && < 3,- semigroups >= 0.9 && < 1,- semigroupoids >= 5.2.1 && < 6,- tagged >= 0.8.6 && < 1,+ semigroupoids >= 5.2.1 && < 7, transformers >= 0.5 && < 0.7,- transformers-compat >= 0.5.0.4 && < 1, unordered-containers >= 0.2.3 && < 0.3,- vector >= 0.12.1.2 && < 0.14,- void >= 0.6 && < 1+ vector >= 0.12.1.2 && < 0.14 if flag(template-haskell) && impl(ghc) build-depends: template-haskell >= 2.11.1.0 && < 3.0@@ -120,12 +121,16 @@ hs-source-dirs: tests default-language: Haskell2010 - build-depends: base, simple-reflect >= 0.3.1+ build-depends: base < 5, simple-reflect >= 0.3.1 -test-suite UnitTests+test-suite test type: exitcode-stdio-1.0- main-is: UnitTests.hs- other-modules: Plucker, Binary, V+ main-is: Test.hs+ other-modules: Prop.Quaternion+ Prop.V3+ Unit.Binary+ Unit.Plucker+ Unit.V ghc-options: -Wall -threaded hs-source-dirs: tests build-depends:@@ -133,10 +138,11 @@ binary, bytestring, deepseq,- test-framework >= 0.8,- test-framework-hunit >= 0.3,- HUnit >= 1.2.5,+ tasty >= 1.4 && < 1.6,+ tasty-hunit >= 0.10 && < 0.11,+ tasty-quickcheck >= 0.10 && < 0.12, linear,+ QuickCheck >= 2.5, reflection, vector default-language: Haskell2010
src/Linear/Affine.hs view
@@ -14,10 +14,6 @@ {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE ScopedTypeVariables #-} -#ifndef MIN_VERSION_hashable-#define MIN_VERSION_hashable(x,y,z) 1-#endif- ----------------------------------------------------------------------------- -- | -- License : BSD-style (see the file LICENSE)@@ -177,11 +173,11 @@ liftHashWithSalt h s (P f) = liftHashWithSalt h s f {-# INLINE liftHashWithSalt #-} -lensP :: Lens' (Point g a) (g a)+lensP :: Lens (Point f a) (Point g b) (f a) (g b) lensP afb (P a) = P <$> afb a {-# INLINE lensP #-} -_Point :: Iso' (Point f a) (f a)+_Point :: Iso (Point f a) (Point g b) (f a) (g b) _Point = iso (\(P a) -> a) P {-# INLINE _Point #-}
src/Linear/Plucker.hs view
@@ -9,13 +9,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveLift #-} -#ifndef MIN_VERSION_vector-#define MIN_VERSION_vector(x,y,z) 1-#endif--#ifndef MIN_VERSION_transformers-#define MIN_VERSION_transformers(x,y,z) 1-#endif ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2012-2015 Edward Kmett@@ -53,7 +46,9 @@ , e01, e02, e03, e12, e31, e23 ) where +#if !MIN_VERSION_base(4,18,0) import Control.Applicative+#endif import Control.DeepSeq (NFData(rnf)) import Control.Monad (liftM) import Control.Monad.Fix@@ -91,7 +86,8 @@ import Linear.V3 import Linear.V4 import Linear.Vector-import System.Random (Random(..))+import System.Random (Random(..), Uniform)+import System.Random.Stateful (UniformRange(..)) -- | Plücker coordinates for lines in a 3-dimensional space. data Plucker a = Plucker !a !a !a !a !a !a deriving (Eq,Ord,Show,Read@@ -121,6 +117,17 @@ (d'', g4) -> case randomR (e,e') g4 of (e'', g5) -> case randomR (f,f') g5 of (f'', g6) -> (Plucker a'' b'' c'' d'' e'' f'', g6)++instance Uniform a => Uniform (Plucker a) where++instance UniformRange a => UniformRange (Plucker a) where+ uniformRM (Plucker a b c d e f, Plucker a' b' c' d' e' f') g = Plucker+ <$> uniformRM (a, a') g+ <*> uniformRM (b, b') g+ <*> uniformRM (c, c') g+ <*> uniformRM (d, d') g+ <*> uniformRM (e, e') g+ <*> uniformRM (f, f') g instance Functor Plucker where fmap g (Plucker a b c d e f) = Plucker (g a) (g b) (g c) (g d) (g e) (g f)
src/Linear/Quaternion.hs view
@@ -10,18 +10,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveLift #-} -#ifndef MIN_VERSION_hashable-#define MIN_VERSION_hashable(x,y,z) 1-#endif--#ifndef MIN_VERSION_vector-#define MIN_VERSION_vector(x,y,z) 1-#endif--#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif- ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2012-2015 Edward Kmett@@ -96,7 +84,8 @@ import Linear.V4 import Linear.Vector import Prelude hiding (any)-import System.Random (Random(..))+import System.Random (Random(..), Uniform)+import System.Random.Stateful (UniformRange(..)) -- | Quaternions data Quaternion a = Quaternion !a {-# UNPACK #-}!(V3 a)@@ -119,6 +108,13 @@ randomR (Quaternion a b, Quaternion c d) g = case randomR (a,c) g of (e, g') -> case randomR (b,d) g' of (f, g'') -> (Quaternion e f, g'')++instance Uniform a => Uniform (Quaternion a) where++instance UniformRange a => UniformRange (Quaternion a) where+ uniformRM (Quaternion a b, Quaternion c d) g = Quaternion+ <$> uniformRM (a, c) g+ <*> uniformRM (b, d) g instance Functor Quaternion where fmap f (Quaternion e v) = Quaternion (f e) (fmap f v)
src/Linear/V.hs view
@@ -15,22 +15,6 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE DeriveGeneric #-} -#ifndef MIN_VERSION_hashable-#define MIN_VERSION_hashable(x,y,z) 1-#endif--#ifndef MIN_VERSION_reflection-#define MIN_VERSION_reflection(x,y,z) 1-#endif--#ifndef MIN_VERSION_transformers-#define MIN_VERSION_transformers(x,y,z) 1-#endif--#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif- ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2012-2015 Edward Kmett@@ -104,6 +88,7 @@ import Data.Semigroup #endif import System.Random (Random(..))+import System.Random.Stateful (Uniform(..), UniformRange(..)) class Dim n where reflectDim :: p n -> Int@@ -148,6 +133,15 @@ instance (Dim n, Random a) => Random (V n a) where random = runState (V <$> V.replicateM (reflectDim (Proxy :: Proxy n)) (state random)) randomR (V ls,V hs) = runState (V <$> V.zipWithM (\l h -> state $ randomR (l,h)) ls hs)++instance (Dim n, Uniform a) => Uniform (V n a) where+ uniformM g = V <$> V.replicateM (reflectDim (Proxy :: Proxy n)) (uniformM g)++instance (Dim n, UniformRange a) => UniformRange (V n a) where+ uniformRM (V ls, V hs) g = V <$> V.zipWithM (\l h -> uniformRM (l, h) g) ls hs+#if (MIN_VERSION_random(1,3,0))+ isInRange (V ls, V hs) (V xs) = V.and $ V.zipWith3 (\l h x -> isInRange (l, h) x) ls hs xs+#endif data ReifiedDim (s :: Type)
src/Linear/V0.hs view
@@ -9,22 +9,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveLift #-} -#ifndef MIN_VERSION_hashable-#define MIN_VERSION_hashable(x,y,z) 1-#endif--#ifndef MIN_VERSION_vector-#define MIN_VERSION_vector(x,y,z) 1-#endif--#ifndef MIN_VERSION_transformers-#define MIN_VERSION_transformers(x,y,z) 1-#endif--#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif- ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2012-2015 Edward Kmett@@ -76,7 +60,8 @@ import Linear.Epsilon import Linear.Vector import Linear.V-import System.Random (Random(..))+import System.Random (Random(..), Uniform)+import System.Random.Stateful (UniformRange(..)) import Prelude hiding (sum) -- $setup@@ -110,6 +95,11 @@ randomR _ g = (V0, g) randomRs _ _ = repeat V0 randoms _ = repeat V0++instance Uniform (V0 a) where++instance UniformRange (V0 a) where+ uniformRM (_, _) _ = pure V0 instance Serial1 V0 where serializeWith _ = serialize
src/Linear/V1.hs view
@@ -13,22 +13,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveLift #-} -#ifndef MIN_VERSION_hashable-#define MIN_VERSION_hashable(x,y,z) 1-#endif--#ifndef MIN_VERSION_vector-#define MIN_VERSION_vector(x,y,z) 1-#endif--#ifndef MIN_VERSION_transformers-#define MIN_VERSION_transformers(x,y,z) 1-#endif--#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif- ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2012-2015 Edward Kmett@@ -79,7 +63,8 @@ import Linear.Epsilon import Linear.Vector import Prelude hiding (sum)-import System.Random (Random(..))+import System.Random (Random(..), Uniform)+import System.Random.Stateful (UniformRange(..)) #if !(MIN_VERSION_base(4,11,0)) import Data.Semigroup #endif@@ -386,6 +371,11 @@ randoms g = V1 <$> randoms g randomR (V1 a, V1 b) g = case randomR (a, b) g of (a', g') -> (V1 a', g') randomRs (V1 a, V1 b) g = V1 <$> randomRs (a, b) g++instance Uniform a => Uniform (V1 a) where++instance UniformRange a => UniformRange (V1 a) where+ uniformRM (V1 a, V1 b) g = V1 <$> uniformRM (a, b) g instance Eq1 V1 where liftEq f (V1 a) (V1 b) = f a b
src/Linear/V2.hs view
@@ -10,22 +10,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveLift #-} -#ifndef MIN_VERSION_hashable-#define MIN_VERSION_hashable(x,y,z) 1-#endif--#ifndef MIN_VERSION_vector-#define MIN_VERSION_vector(x,y,z) 1-#endif--#ifndef MIN_VERSION_transformers-#define MIN_VERSION_transformers(x,y,z) 1-#endif--#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif- ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2012-2015 Edward Kmett@@ -88,7 +72,8 @@ import Linear.Vector import Linear.V1 (R1(..),ex) import Prelude hiding (sum)-import System.Random (Random(..))+import System.Random (Random(..), Uniform)+import System.Random.Stateful (UniformRange(..)) -- $setup -- >>> import Control.Applicative@@ -132,6 +117,11 @@ (x, g') -> case randomR (b, d) g' of (y, g'') -> (V2 x y, g'') {-# inline randomR #-}++instance Uniform a => Uniform (V2 a) where++instance UniformRange a => UniformRange (V2 a) where+ uniformRM (V2 a b, V2 c d) g = V2 <$> uniformRM (a, c) g <*> uniformRM (b, d) g instance Functor V2 where fmap f (V2 a b) = V2 (f a) (f b)
src/Linear/V3.hs view
@@ -10,18 +10,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveLift #-} -#ifndef MIN_VERSION_hashable-#define MIN_VERSION_hashable(x,y,z) 1-#endif--#ifndef MIN_VERSION_vector-#define MIN_VERSION_vector(x,y,z) 1-#endif--#ifndef MIN_VERSION_transformers-#define MIN_VERSION_transformers(x,y,z) 1-#endif- ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2012-2015 Edward Kmett@@ -45,7 +33,9 @@ , ex, ey, ez ) where +#if !MIN_VERSION_base(4,18,0) import Control.Applicative+#endif import Control.DeepSeq (NFData(rnf)) import Control.Monad (liftM) import Control.Monad.Fix@@ -85,7 +75,8 @@ import Linear.V import Linear.V2 import Linear.Vector-import System.Random (Random(..))+import System.Random (Random(..), Uniform)+import System.Random.Stateful (UniformRange(..)) -- $setup -- >>> import Control.Lens hiding (index)@@ -128,6 +119,14 @@ (a'', g') -> case randomR (b,b') g' of (b'', g'') -> case randomR (c,c') g'' of (c'', g''') -> (V3 a'' b'' c'', g''')++instance Uniform a => Uniform (V3 a) where++instance UniformRange a => UniformRange (V3 a) where+ uniformRM (V3 a b c, V3 a' b' c') g = V3+ <$> uniformRM (a, a') g+ <*> uniformRM (b, b') g+ <*> uniformRM (c, c') g instance Traversable V3 where traverse f (V3 a b c) = V3 <$> f a <*> f b <*> f c
src/Linear/V4.hs view
@@ -10,17 +10,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveLift #-} -#ifndef MIN_VERSION_hashable-#define MIN_VERSION_hashable(x,y,z) 1-#endif--#ifndef MIN_VERSION_vector-#define MIN_VERSION_vector(x,y,z) 1-#endif--#ifndef MIN_VERSION_transformers-#define MIN_VERSION_transformers(x,y,z) 1-#endif ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2012-2015 Edward Kmett@@ -51,7 +40,9 @@ , ex, ey, ez, ew ) where +#if !MIN_VERSION_base(4,18,0) import Control.Applicative+#endif import Control.DeepSeq (NFData(rnf)) import Control.Monad (liftM) import Control.Monad.Fix@@ -92,7 +83,8 @@ import Linear.V2 import Linear.V3 import Linear.Vector-import System.Random (Random(..))+import System.Random (Random(..), Uniform)+import System.Random.Stateful (UniformRange(..)) -- $setup -- >>> import Control.Lens hiding (index)@@ -137,6 +129,15 @@ (b'', g'') -> case randomR (c,c') g'' of (c'', g''') -> case randomR (d,d') g''' of (d'', g'''') -> (V4 a'' b'' c'' d'', g'''')++instance Uniform a => Uniform (V4 a) where++instance UniformRange a => UniformRange (V4 a) where+ uniformRM (V4 a b c d, V4 a' b' c' d') g = V4+ <$> uniformRM (a, a') g+ <*> uniformRM (b, b') g+ <*> uniformRM (c, c') g+ <*> uniformRM (d, d') g instance Traversable V4 where traverse f (V4 a b c d) = V4 <$> f a <*> f b <*> f c <*> f d
src/Linear/Vector.hs view
@@ -133,8 +133,13 @@ x ^-^ y = x ^+^ negated y -- | Linearly interpolate between two vectors.+ --+ -- /Since linear version 1.23, interpolation direction has been reversed; now/+ --+ -- > lerp 0 a b == a+ -- > lerp 1 a b == b lerp :: Num a => a -> f a -> f a -> f a- lerp alpha u v = alpha *^ u ^+^ (1 - alpha) *^ v+ lerp alpha u v = (1 - alpha) *^ u ^+^ alpha *^ v {-# INLINE lerp #-} -- | Apply a function to merge the 'non-zero' components of two vectors, unioning the rest of the values.
− tests/Binary.hs
@@ -1,19 +0,0 @@-module Binary (tests) where--import Data.Binary.Put-import Data.Binary.Get-import Linear-import qualified Data.ByteString.Lazy as BS-import Test.HUnit--originalVecs :: (V3 Float, V2 Char)-originalVecs = (V3 1 2 3, V2 'a' 'b')--bytes :: BS.ByteString-bytes = runPut $ do putLinear $ fst originalVecs- putLinear $ snd originalVecs--tests :: Test-tests = test [ "Serialized length" ~: BS.length bytes ~?= 3*13+2- , "Deserialization" ~: deserialized ~?= originalVecs ]- where deserialized = runGet ((,) <$> getLinear <*> getLinear) bytes
− tests/Plucker.hs
@@ -1,35 +0,0 @@-module Plucker (tests) where-import Linear-import Linear.Plucker-import Linear.Plucker.Coincides-import Test.HUnit--ln2,ln3,ln4,ln5,ln6,ln7,ln8,ln9 :: Plucker Float-ln2 = plucker3D (V3 1 3 0) (V3 1 3 (-2)) -- starting line-ln3 = plucker3D (V3 2 3 0) (V3 2 3 (-2)) -- parallel-ln4 = plucker3D (V3 2 4 0) (V3 1 4 (-2)) -- ccw-ln5 = plucker3D (V3 (-2) 4 0) (V3 2 4 (-2)) -- cw-ln6 = plucker3D (V3 2 3 0) (V3 1 3 (-2)) -- intersect-ln7 = plucker3D (V3 1 3 0) (V3 1 3 2) -- reversed-ln8 = plucker3D (V3 0 4 4) (V3 0 (-4) (-4)) -- through origin-ln9 = Plucker 1 2 3 4 5 6 -- not a 3D line--tests :: Test-tests = test [ "parallel" ~: parallel ln2 ln3 ~?= True- , "CCW" ~: passes ln2 ln4 ~?= Counterclockwise - , "CW" ~: passes ln2 ln5 ~?= Clockwise- , "intersect1" ~: intersects ln2 ln6 ~?= True - , "intersect2" ~: intersects ln2 ln3 ~?= False- , "line equality 1" ~: Line ln2 == Line ln2 ~?= True - , "line equality 2" ~: Line ln2 == Line ln7 ~?= True - , "line equality 3" ~: Line ln2 == Ray ln7 ~?= True- , "line equality 4" ~: Ray ln2 == Line ln7 ~?= True- , "ray equality 1" ~: Ray ln2 == Ray ln7 ~?= False- , "ray equality 2" ~: Ray ln2 == Ray (3 *^ ln2) ~?= True- , "ray equality 3" ~: Ray ln2 == Ray (negate ln7) ~?= True- , "quadrance" ~: nearZero (quadranceToOrigin ln2 - 10) ~?= True- , "closest 1" ~: - nearZero (qd (V3 1 3 0) $ closestToOrigin ln2) ~?= True- , "closest 2" ~: nearZero (qd 0 $ closestToOrigin ln8) ~?= True- , "isLine 1" ~: isLine ln2 ~?= True- , "isLine 2" ~: isLine ln9 ~?= False ]
+ tests/Prop/Quaternion.hs view
@@ -0,0 +1,28 @@+{-# OPTIONS_GHC -Wno-orphans #-}+module Prop.Quaternion (tests) where++import Linear.Quaternion (Quaternion(..))+import Linear.Epsilon (nearZero)+import Linear.Vector (lerp)+import Test.QuickCheck (Arbitrary(..))+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.QuickCheck (testProperty)++import Prop.V3 ()++instance Arbitrary a => Arbitrary (Quaternion a) where+ arbitrary = Quaternion <$> arbitrary <*> arbitrary++prop_lerp0 :: Quaternion Double -> Quaternion Double -> Bool+prop_lerp0 a b = nearZero (lerp 0 a b - a)++prop_lerp1 :: Quaternion Double -> Quaternion Double -> Bool+prop_lerp1 a b = nearZero (lerp 1 a b - b)++tests :: [TestTree]+tests =+ [ testGroup "lerp"+ [ testProperty "lerp 0 a b == a" prop_lerp0+ , testProperty "lerp 1 a b == b" prop_lerp1+ ]+ ]
+ tests/Prop/V3.hs view
@@ -0,0 +1,8 @@+{-# OPTIONS_GHC -Wno-orphans #-}+module Prop.V3 () where++import Linear.V3 (V3(..))+import Test.QuickCheck (Arbitrary(..))++instance Arbitrary a => Arbitrary (V3 a) where+ arbitrary = V3 <$> arbitrary <*> arbitrary <*> arbitrary
+ tests/Test.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE CPP #-}+module Main (main) where++import Test.Tasty (defaultMain, testGroup, TestTree)++import qualified Prop.Quaternion+import qualified Unit.Binary+import qualified Unit.Plucker+import qualified Unit.V++tests :: [TestTree]+tests =+ [ testGroup "Property tests"+ [ testGroup "Quaternion" Prop.Quaternion.tests+ ]+ , testGroup "Unit tests"+ [ testGroup "Binary" Unit.Binary.tests+ , testGroup "Plucker" Unit.Plucker.tests+ , testGroup "V" Unit.V.tests+ ]+ ]++main :: IO ()+main = defaultMain $ testGroup "linear" tests
+ tests/Unit/Binary.hs view
@@ -0,0 +1,20 @@+module Unit.Binary (tests) where++import Data.Binary.Put+import Data.Binary.Get+import Linear+import qualified Data.ByteString.Lazy as BS+import Test.Tasty (TestTree)+import Test.Tasty.HUnit ((@?=), testCase)++originalVecs :: (V3 Float, V2 Char)+originalVecs = (V3 1 2 3, V2 'a' 'b')++bytes :: BS.ByteString+bytes = runPut $ do putLinear $ fst originalVecs+ putLinear $ snd originalVecs++tests :: [TestTree]+tests = [ testCase "Serialized length" $ BS.length bytes @?= 3*13+2+ , testCase "Deserialization" $ deserialized @?= originalVecs ]+ where deserialized = runGet ((,) <$> getLinear <*> getLinear) bytes
+ tests/Unit/Plucker.hs view
@@ -0,0 +1,36 @@+module Unit.Plucker (tests) where+import Linear+import Linear.Plucker+import Linear.Plucker.Coincides+import Test.Tasty (TestTree)+import Test.Tasty.HUnit ((@?=), testCase)++ln2,ln3,ln4,ln5,ln6,ln7,ln8,ln9 :: Plucker Float+ln2 = plucker3D (V3 1 3 0) (V3 1 3 (-2)) -- starting line+ln3 = plucker3D (V3 2 3 0) (V3 2 3 (-2)) -- parallel+ln4 = plucker3D (V3 2 4 0) (V3 1 4 (-2)) -- ccw+ln5 = plucker3D (V3 (-2) 4 0) (V3 2 4 (-2)) -- cw+ln6 = plucker3D (V3 2 3 0) (V3 1 3 (-2)) -- intersect+ln7 = plucker3D (V3 1 3 0) (V3 1 3 2) -- reversed+ln8 = plucker3D (V3 0 4 4) (V3 0 (-4) (-4)) -- through origin+ln9 = Plucker 1 2 3 4 5 6 -- not a 3D line++tests :: [TestTree]+tests = [ testCase "parallel" $ parallel ln2 ln3 @?= True+ , testCase "CCW" $ passes ln2 ln4 @?= Counterclockwise+ , testCase "CW" $ passes ln2 ln5 @?= Clockwise+ , testCase "intersect1" $ intersects ln2 ln6 @?= True+ , testCase "intersect2" $ intersects ln2 ln3 @?= False+ , testCase "line equality 1" $ Line ln2 == Line ln2 @?= True+ , testCase "line equality 2" $ Line ln2 == Line ln7 @?= True+ , testCase "line equality 3" $ Line ln2 == Ray ln7 @?= True+ , testCase "line equality 4" $ Ray ln2 == Line ln7 @?= True+ , testCase "ray equality 1" $ Ray ln2 == Ray ln7 @?= False+ , testCase "ray equality 2" $ Ray ln2 == Ray (3 *^ ln2) @?= True+ , testCase "ray equality 3" $ Ray ln2 == Ray (negate ln7) @?= True+ , testCase "quadrance" $ nearZero (quadranceToOrigin ln2 - 10) @?= True+ , testCase "closest 1" $+ nearZero (qd (V3 1 3 0) $ closestToOrigin ln2) @?= True+ , testCase "closest 2" $ nearZero (qd 0 $ closestToOrigin ln8) @?= True+ , testCase "isLine 1" $ isLine ln2 @?= True+ , testCase "isLine 2" $ isLine ln9 @?= False ]
+ tests/Unit/V.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE DataKinds #-}+module Unit.V (tests) where++import Control.DeepSeq (rnf)+import qualified Data.Vector.Unboxed as U (fromList)+import Linear.V (V)+import Test.Tasty (TestTree)+import Test.Tasty.HUnit ((@?=), testCase)++v10 :: V 10 Int+v10 = return 5++tests :: [TestTree]+tests = [ testCase "GH124" $ rnf (U.fromList [v10]) @?= () ]
− tests/UnitTests.hs
@@ -1,16 +0,0 @@-{-# LANGUAGE CPP #-}-module Main (main) where-import Test.Framework (defaultMain, testGroup, Test)-import Test.Framework.Providers.HUnit-import qualified Plucker-import qualified Binary-import qualified V--tests :: [Test]-tests = [ testGroup "Plucker" $ hUnitTestToTests Plucker.tests- , testGroup "Binary" $ hUnitTestToTests Binary.tests- , testGroup "V" $ hUnitTestToTests V.tests- ]--main :: IO ()-main = defaultMain tests
− tests/V.hs
@@ -1,13 +0,0 @@-{-# LANGUAGE DataKinds #-}-module V (tests) where--import Control.DeepSeq (rnf)-import qualified Data.Vector.Unboxed as U (fromList)-import Linear.V (V)-import Test.HUnit--v10 :: V 10 Int-v10 = return 5--tests :: Test-tests = test [ "GH124" ~: rnf (U.fromList [v10]) ~?= () ]