packages feed

reanimate-0.4.2.0: test/Helpers.hs

{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS_GHC -w      #-}
-- {-# LANGUAGE TemplateHaskell      #-}
module Helpers where

import qualified Data.Vector            as V
import           Linear.V2
import           Linear.Vector
import           Numeric
import           Data.List
import           Test.QuickCheck
import           Test.Tasty
import           Test.Tasty.QuickCheck

import           Reanimate.Math.Common
import           Reanimate.Math.Polygon
import           Reanimate.Math.SSSP

-- [(0.8,1),(0.04,0.1),(0.05,1)]

newtype PolyParam = PolyParam { unParam :: (Double, Double) }
  deriving (Show)
instance Arbitrary PolyParam where
  arbitrary = fmap PolyParam $
    (,) <$> choose (0.01,0.99)
              <*> choose (0.01,1)
  shrink (PolyParam (a,b)) =
    [ PolyParam (a', b')
    | a' <- a : shrinkDouble a
    , b' <- if a==a' then b : shrinkDouble b else b : shrinkDouble b
    , a' >= 0.01, b' >= 0.01
    ]

data Parameters = Parameters [(Double, Double)]
  deriving (Show)
instance Arbitrary Parameters where
  arbitrary = do
    PolyParam e1 <- arbitrary
    PolyParam e2 <- arbitrary
    PolyParam e3 <- arbitrary
    PolyParam e4 <- arbitrary
    rest <- arbitrary
    return $ Parameters $ e1:e2:e3:e4:map unParam rest
  shrink (Parameters xs) =
    map Parameters (delete xs $ shrinkListByOne xs) ++
    map Parameters (delete xs $
    sequence $ map (map unParam . shrink . PolyParam) xs)

shrinkListByOne :: [a] -> [[a]]
shrinkListByOne x | length x <= 4 = [x]
shrinkListByOne x = x : zipWith (++) (inits x) (tails $ drop 1 x)

shrinkDouble :: Double -> [Double]
shrinkDouble x =
  let s = showFFloat Nothing x "" in
  if length s < 4
    then []
    else [read (take (length s-1) s)]

instance Arbitrary Polygon where
  arbitrary =
    frequency
      [ (1, elements premade)
      , (2, pMkWinding <$> choose (1,100))
      , (99, randomPoly)
      ]
    where
      premade = [shape1, shape2, shape3, shape4, shape5, shape6
                ,shape7, shape8, shape9, shape11 ]
      randomPoly = do
        let genParameters = do
              angMod <- choose (0.01, 0.99)
              rMod   <- choose (0.01, 0.99)
              return (angMod, rMod)
        PolyParam e1 <- arbitrary
        PolyParam e2 <- arbitrary
        PolyParam e3 <- arbitrary
        PolyParam e4 <- arbitrary
        es <- listOf genParameters
        pure $ pGenerate (e1:e2:e3:e4:es)
  -- shrink p = filter isSimple $
  --   map V.fromList (sequence (map shrinkV2 (V.toList p)))

shrinkV2 (V2 a b) = V2 <$> take 1 (shrinkRealFrac a) <*> take 1 (shrinkRealFrac b)

instance (RealFrac a, Arbitrary a) => Arbitrary (V2 a) where
  arbitrary = do
    (a,b) <- arbitrary
    pure $ V2 a b
  shrink = shrinkV2
  -- shrink (V2 a b) =
  --   [ V2 a b | (a',b') <- shrink (a,b) ]

percent :: (Testable prop) => (Rational -> prop) -> Property
percent gen = forAll (choose (0,1::Double)) $ gen . realToFrac