{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}


module DichotomousSpec where


import           Control.Functor.Dichotomous (Dichotomous (..), LeftOnly,
                                              LeftOrBoth, MaybeBoth,
                                              MaybeEither, MaybeLeft,
                                              MaybeLeftOrBoth, MaybeRight,
                                              MaybeRightOrBoth, None, RightOnly,
                                              RightOrBoth, These, TheseOrNot)
import           Core                        ()
import           Data.These                  (These)
import           Test.QuickCheck             (Arbitrary, Testable (property))
import           Test.Syd                    (SpecWith, describe, it, parallel)


sweetIsomorphism
  :: forall g
   . ( Eq (g Int String)
     , Show (g Int String)
     , Arbitrary (g Int String)
     , Dichotomous g
   ) => SpecWith ()
sweetIsomorphism = do
  it "ymotohcid . dichotomy = Just" . property $ \(g :: g Int String) -> ymotohcid (dichotomy g) == Just g


spec :: SpecWith ()
spec = describe "Dichotomous" $ do
  describe "(,)" $ sweetIsomorphism @(,)
  describe "LeftOnly" $ sweetIsomorphism @LeftOnly
  describe "LeftOrBoth" $ sweetIsomorphism @LeftOrBoth
  describe "RightOnly" $ sweetIsomorphism @RightOnly
  describe "RightOrBoth" $ sweetIsomorphism @RightOrBoth
  describe "Either" $ sweetIsomorphism @Either
  describe "These" $ sweetIsomorphism @These
  describe "None" $ sweetIsomorphism @None
  describe "MaybeBoth" $ sweetIsomorphism @MaybeBoth
  describe "MaybeRight" $ sweetIsomorphism @MaybeRight
  describe "MaybeRightOrBoth" $ sweetIsomorphism @MaybeRightOrBoth
  describe "MaybeLeft" $ sweetIsomorphism @MaybeLeft
  describe "MaybeLeftOrBoth" $ sweetIsomorphism @MaybeLeftOrBoth
  describe "MaybeEither" $ sweetIsomorphism @MaybeEither
  describe "TheseOrNot" $ sweetIsomorphism @TheseOrNot

