Blame tests/Types.hs

Packit 9a2dfb
{-# LANGUAGE CPP #-}
Packit 9a2dfb
{-# LANGUAGE DeriveDataTypeable #-}
Packit 9a2dfb
{-# LANGUAGE DeriveGeneric #-}
Packit 9a2dfb
{-# LANGUAGE FlexibleInstances #-}
Packit 9a2dfb
{-# LANGUAGE GADTs #-}
Packit 9a2dfb
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Packit 9a2dfb
{-# LANGUAGE StandaloneDeriving #-}
Packit 9a2dfb
{-# LANGUAGE ScopedTypeVariables #-}
Packit 9a2dfb
Packit 9a2dfb
module Types (module Types) where
Packit 9a2dfb
Packit 9a2dfb
import Prelude ()
Packit 9a2dfb
import Prelude.Compat
Packit 9a2dfb
Packit 9a2dfb
import Math.NumberTheory.Logarithms (intLog2)
Packit 9a2dfb
import Data.Data
Packit 9a2dfb
import Data.Functor.Compose (Compose (..))
Packit 9a2dfb
import Data.Functor.Identity (Identity (..))
Packit 9a2dfb
import Data.Hashable (Hashable (..))
Packit 9a2dfb
import Data.Semigroup (Option)
Packit 9a2dfb
import Data.Text
Packit 9a2dfb
import Data.Time (Day (..), fromGregorian)
Packit 9a2dfb
import GHC.Generics
Packit 9a2dfb
import Test.QuickCheck (Arbitrary (..), Property, counterexample, scale)
Packit 9a2dfb
import qualified Data.Map as Map
Packit 9a2dfb
import Data.Aeson
Packit 9a2dfb
import Data.Aeson.Types
Packit 9a2dfb
Packit 9a2dfb
type I = Identity
Packit 9a2dfb
type Compose3  f g h = Compose (Compose f g) h
Packit 9a2dfb
type Compose3' f g h = Compose f (Compose g h)
Packit 9a2dfb
Packit 9a2dfb
data Foo = Foo {
Packit 9a2dfb
      fooInt :: Int
Packit 9a2dfb
    , fooDouble :: Double
Packit 9a2dfb
    , fooTuple :: (String, Text, Int)
Packit 9a2dfb
    -- This definition causes an infinite loop in genericTo and genericFrom!
Packit 9a2dfb
    -- , fooMap :: Map.Map String Foo
Packit 9a2dfb
    , fooMap :: Map.Map String (Text,Int)
Packit 9a2dfb
    } deriving (Show, Typeable, Data)
Packit 9a2dfb
Packit 9a2dfb
data UFoo = UFoo {
Packit 9a2dfb
      _UFooInt :: Int
Packit 9a2dfb
    , uFooInt :: Int
Packit 9a2dfb
    } deriving (Show, Eq, Data, Typeable)
Packit 9a2dfb
Packit 9a2dfb
data OneConstructor = OneConstructor
Packit 9a2dfb
                      deriving (Show, Eq, Typeable, Data)
Packit 9a2dfb
Packit 9a2dfb
data Product2 a b = Product2 a b
Packit 9a2dfb
                    deriving (Show, Eq, Typeable, Data)
Packit 9a2dfb
Packit 9a2dfb
data Product6 a b c d e f = Product6 a b c d e f
Packit 9a2dfb
                    deriving (Show, Eq, Typeable, Data)
Packit 9a2dfb
Packit 9a2dfb
data Sum4 a b c d = Alt1 a | Alt2 b | Alt3 c | Alt4 d
Packit 9a2dfb
                    deriving (Show, Eq, Typeable, Data)
Packit 9a2dfb
Packit 9a2dfb
class ApproxEq a where
Packit 9a2dfb
    (=~) :: a -> a -> Bool
Packit 9a2dfb
Packit 9a2dfb
newtype Approx a = Approx { fromApprox :: a }
Packit 9a2dfb
    deriving (Show, Data, Typeable, ApproxEq, Num)
Packit 9a2dfb
Packit 9a2dfb
instance (ApproxEq a) => Eq (Approx a) where
Packit 9a2dfb
    Approx a == Approx b = a =~ b
Packit 9a2dfb
Packit 9a2dfb
data Nullary = C1 | C2 | C3 deriving (Eq, Show)
Packit 9a2dfb
Packit 9a2dfb
data SomeType a = Nullary
Packit 9a2dfb
                | Unary Int
Packit 9a2dfb
                | Product String (Maybe Char) a
Packit 9a2dfb
                | Record { testOne   :: Double
Packit 9a2dfb
                         , testTwo   :: Maybe Bool
Packit 9a2dfb
                         , testThree :: Maybe a
Packit 9a2dfb
                         }
Packit 9a2dfb
                | List [a]
Packit 9a2dfb
  deriving (Eq, Show)
Packit 9a2dfb
Packit 9a2dfb
-- | This type requires IncoherentInstances for the instances of the type
Packit 9a2dfb
-- classes Data.Aeson.TH.LookupField and Data.Aeson.Types.FromJSON.FromRecord.
Packit 9a2dfb
--
Packit 9a2dfb
-- The minimum known requirements for this type are:
Packit 9a2dfb
-- * Record type with at least two fields
Packit 9a2dfb
-- * One field type is either a type parameter or a type/data family
Packit 9a2dfb
-- * Another field type is a @Maybe@ of the above field type
Packit 9a2dfb
data IncoherentInstancesNeeded a = IncoherentInstancesNeeded
Packit 9a2dfb
  { incoherentInstancesNeededMaybeNot :: a
Packit 9a2dfb
  , incoherentInstancesNeededMaybeYes :: Maybe a
Packit 9a2dfb
  } deriving Generic
Packit 9a2dfb
Packit 9a2dfb
-- Used for testing UntaggedValue SumEncoding
Packit 9a2dfb
data EitherTextInt
Packit 9a2dfb
    = LeftBool Bool
Packit 9a2dfb
    | RightInt Int
Packit 9a2dfb
    | BothTextInt Text Int
Packit 9a2dfb
    | NoneNullary
Packit 9a2dfb
    deriving (Eq, Show)
Packit 9a2dfb
Packit 9a2dfb
data GADT a where
Packit 9a2dfb
    GADT :: { gadt :: String } -> GADT String
Packit 9a2dfb
  deriving Typeable
Packit 9a2dfb
Packit 9a2dfb
deriving instance Data (GADT String)
Packit 9a2dfb
deriving instance Eq   (GADT a)
Packit 9a2dfb
deriving instance Show (GADT a)
Packit 9a2dfb
Packit 9a2dfb
newtype MaybeField = MaybeField { maybeField :: Maybe Int }
Packit 9a2dfb
newtype OptionField = OptionField { optionField :: Option Int }
Packit 9a2dfb
  deriving (Eq, Show)
Packit 9a2dfb
Packit 9a2dfb
deriving instance Generic Foo
Packit 9a2dfb
deriving instance Generic UFoo
Packit 9a2dfb
deriving instance Generic OneConstructor
Packit 9a2dfb
deriving instance Generic (Product2 a b)
Packit 9a2dfb
deriving instance Generic (Product6 a b c d e f)
Packit 9a2dfb
deriving instance Generic (Sum4 a b c d)
Packit 9a2dfb
deriving instance Generic (Approx a)
Packit 9a2dfb
deriving instance Generic Nullary
Packit 9a2dfb
deriving instance Generic (SomeType a)
Packit 9a2dfb
#if __GLASGOW_HASKELL__ >= 706
Packit 9a2dfb
deriving instance Generic1 SomeType
Packit 9a2dfb
#endif
Packit 9a2dfb
deriving instance Generic OptionField
Packit 9a2dfb
deriving instance Generic EitherTextInt
Packit 9a2dfb
Packit 9a2dfb
failure :: Show a => String -> String -> a -> Property
Packit 9a2dfb
failure func msg v = counterexample
Packit 9a2dfb
                     (func ++ " failed: " ++ msg ++ ", " ++ show v) False
Packit 9a2dfb
Packit 9a2dfb
newtype BCEDay = BCEDay Day
Packit 9a2dfb
  deriving (Eq, Show)
Packit 9a2dfb
Packit 9a2dfb
zeroDay :: Day
Packit 9a2dfb
zeroDay = fromGregorian 0 0 0
Packit 9a2dfb
Packit 9a2dfb
instance Arbitrary BCEDay where
Packit 9a2dfb
    arbitrary = fmap (BCEDay . ModifiedJulianDay . (+ toModifiedJulianDay zeroDay)) arbitrary
Packit 9a2dfb
Packit 9a2dfb
instance ToJSON BCEDay where
Packit 9a2dfb
    toJSON (BCEDay d)     = toJSON d
Packit 9a2dfb
    toEncoding (BCEDay d) = toEncoding d
Packit 9a2dfb
Packit 9a2dfb
instance FromJSON BCEDay where
Packit 9a2dfb
    parseJSON = fmap BCEDay . parseJSON
Packit 9a2dfb
Packit 9a2dfb
-- | Scale the size of Arbitrary with ''
Packit 9a2dfb
newtype LogScaled a = LogScaled { getLogScaled :: a }
Packit 9a2dfb
  deriving (Eq, Ord, Show)
Packit 9a2dfb
Packit 9a2dfb
instance Hashable a => Hashable (LogScaled a) where
Packit 9a2dfb
    hashWithSalt salt (LogScaled a) = hashWithSalt salt a
Packit 9a2dfb
Packit 9a2dfb
instance Arbitrary a => Arbitrary (LogScaled a) where
Packit 9a2dfb
    arbitrary = fmap LogScaled $ scale (\x -> intLog2 $ x + 1) arbitrary
Packit 9a2dfb
    shrink = fmap LogScaled . shrink . getLogScaled
Packit 9a2dfb
Packit 9a2dfb
instance ToJSON a => ToJSON (LogScaled a) where
Packit 9a2dfb
    toJSON (LogScaled d)     = toJSON d
Packit 9a2dfb
    toEncoding (LogScaled d) = toEncoding d
Packit 9a2dfb
Packit 9a2dfb
instance FromJSON a => FromJSON (LogScaled a) where
Packit 9a2dfb
    parseJSON = fmap LogScaled . parseJSON
Packit 9a2dfb
Packit 9a2dfb
instance (ToJSONKey a) => ToJSONKey (LogScaled a) where
Packit 9a2dfb
    toJSONKey = contramapToJSONKeyFunction getLogScaled toJSONKey
Packit 9a2dfb
    toJSONKeyList = contramapToJSONKeyFunction (fmap getLogScaled) toJSONKeyList
Packit 9a2dfb
Packit 9a2dfb
instance (FromJSONKey a) => FromJSONKey (LogScaled a) where
Packit 9a2dfb
    fromJSONKey = fmap LogScaled fromJSONKey
Packit 9a2dfb
    fromJSONKeyList = coerceFromJSONKeyFunction (fromJSONKeyList :: FromJSONKeyFunction [a])