{-|
Module      : Test.Aeson.GenericSpecs
Description : Export all necessary functions
Copyright   : (c) Plow Technologies, 2016
License     : BSD3
Maintainer  : mchaver@gmail.com
Stability   : Beta

This package provides tools for testing Aeson serialization.

- Test that 'ToJSON' and 'FromJSON' instances are isomorphic.
- Alert you when unexpected changes in Aeson serialization occur.
- Record JSON formatting of Haskell types.

-}

{-# LANGUAGE ScopedTypeVariables #-}

module Test.Aeson.GenericSpecs
  (
    -- * Arbitrary testing
    goldenSpecs
  , roundtripSpecs
  , roundtripAndGoldenSpecs

  -- * ToADTArbitrary testing
  , goldenADTSpecs
  , roundtripADTSpecs
  , roundtripAndGoldenSpecsWithSettings
  , roundtripAndGoldenADTSpecs
  , roundtripAndGoldenADTSpecsWithSettings

  -- * Make Files
  , mkGoldenFileForType
  
  -- * Util
  , shouldBeIdentity
  , GoldenDirectoryOption(..)
  , Settings(..)
  , defaultSettings

  -- * re-exports
  , Proxy(..)
  ) where

import           Data.Aeson                             (FromJSON, ToJSON)
import           Data.Proxy
import           Data.Typeable

import           Test.Aeson.Internal.ADT.GoldenSpecs    (goldenADTSpecs, mkGoldenFileForType)
import           Test.Aeson.Internal.ADT.RoundtripSpecs (roundtripADTSpecs)
import           Test.Aeson.Internal.GoldenSpecs        (goldenSpecs)
import           Test.Aeson.Internal.RoundtripSpecs     (roundtripSpecs)
import           Test.Aeson.Internal.Utils
import           Test.Hspec
import           Test.QuickCheck
import           Test.QuickCheck.Arbitrary.ADT

-- | run roundtrip and golden test for a type.
-- sampleSize is used only when creating the golden file. When it is
-- compared, the sampleSize is derived from the file.
roundtripAndGoldenSpecs :: forall a.
  (Arbitrary a, ToJSON a, FromJSON a, Typeable a)
  => Proxy a -> Spec
roundtripAndGoldenSpecs :: Proxy a -> Spec
roundtripAndGoldenSpecs proxy :: Proxy a
proxy =
  Settings -> Proxy a -> Spec
forall a.
(Arbitrary a, ToJSON a, FromJSON a, Typeable a) =>
Settings -> Proxy a -> Spec
roundtripAndGoldenSpecsWithSettings Settings
defaultSettings Proxy a
proxy

-- | 'roundtripAndGoldenSpecs' with custom settings.
roundtripAndGoldenSpecsWithSettings :: forall a.
  (Arbitrary a, ToJSON a, FromJSON a, Typeable a)
  => Settings -> Proxy a -> Spec
roundtripAndGoldenSpecsWithSettings :: Settings -> Proxy a -> Spec
roundtripAndGoldenSpecsWithSettings settings :: Settings
settings proxy :: Proxy a
proxy = do
  Proxy a -> Spec
forall a.
(Typeable a, Arbitrary a, ToJSON a, FromJSON a) =>
Proxy a -> Spec
roundtripSpecs Proxy a
proxy
  Settings -> Proxy a -> Spec
forall a.
(Typeable a, Arbitrary a, ToJSON a, FromJSON a) =>
Settings -> Proxy a -> Spec
goldenSpecs Settings
settings Proxy a
proxy

-- | run roundtrip and golden tests for all constructors of a type.
-- sampleSize is used only when creating the golden files. When they are
-- compared, the sampleSize is derived from the file.
roundtripAndGoldenADTSpecs :: forall a.
  (Arbitrary a, ToADTArbitrary a, Eq a, Show a, ToJSON a, FromJSON a)
  => Proxy a -> Spec
roundtripAndGoldenADTSpecs :: Proxy a -> Spec
roundtripAndGoldenADTSpecs proxy :: Proxy a
proxy =
  Settings -> Proxy a -> Spec
forall a.
(Arbitrary a, ToADTArbitrary a, Eq a, Show a, ToJSON a,
 FromJSON a) =>
Settings -> Proxy a -> Spec
roundtripAndGoldenADTSpecsWithSettings Settings
defaultSettings Proxy a
proxy

-- | 'roundtripAndGoldenADTSpecs' with custom settings.
roundtripAndGoldenADTSpecsWithSettings :: forall a.
  (Arbitrary a, ToADTArbitrary a, Eq a, Show a, ToJSON a, FromJSON a)
  => Settings -> Proxy a -> Spec
roundtripAndGoldenADTSpecsWithSettings :: Settings -> Proxy a -> Spec
roundtripAndGoldenADTSpecsWithSettings settings :: Settings
settings proxy :: Proxy a
proxy = do
  Proxy a -> Spec
forall a.
(Arbitrary a, ToADTArbitrary a, Eq a, Show a, ToJSON a,
 FromJSON a) =>
Proxy a -> Spec
roundtripADTSpecs Proxy a
proxy
  Settings -> Proxy a -> Spec
forall a.
(ToADTArbitrary a, Eq a, Show a, ToJSON a, FromJSON a) =>
Settings -> Proxy a -> Spec
goldenADTSpecs Settings
settings Proxy a
proxy