content: {-# LANGUAGE RankNTypes #-}
  
  module Clash.Tests.Laws.Enum (tests) where
  
  import Control.DeepSeq (NFData)
  import Data.Proxy
  import Test.Tasty
  import Test.Tasty.HUnit
  
  import Clash.Sized.Index (Index)
  import Clash.Sized.Signed (Signed)
  import Clash.Sized.Unsigned (Unsigned)
  
  import Test.Tasty.HUnit.Extra
  
  succMaxBoundLaw ::
    forall a .
    (NFData a, Show a, Enum a, Bounded a) =>
    Proxy a ->
    Assertion
  succMaxBoundLaw Proxy = expectException (succ @a maxBound)
  
  predMinBoundLaw ::
    forall a .
    (NFData a, Show a, Enum a, Bounded a) =>
    Proxy a ->
    Assertion
  predMinBoundLaw Proxy = expectException (pred @a minBound)
  
  enumLaws ::
    (NFData a, Show a, Enum a, Bounded a) =>
    Proxy a ->
    [TestTree]
  enumLaws proxy =
    [ testCase "succ maxBound ~ _|_" (succMaxBoundLaw proxy)
    , testCase "pred minBound ~ _|_" (predMinBoundLaw proxy)
    ]
  
  testEnumLaws ::
    (NFData a, Show a, Enum a, Bounded a) =>
    String ->
    Proxy a ->
    TestTree
  testEnumLaws typeName proxy = testGroup typeName (enumLaws proxy)
  
  tests :: TestTree
  tests = testGroup "Enum"
    [ testEnumLaws "Index 1" (Proxy @(Index 1))
    , testEnumLaws "Index 2" (Proxy @(Index 2))
    , testEnumLaws "Index 128" (Proxy @(Index 128))
  
    , testEnumLaws "Unsigned 0" (Proxy @(Unsigned 0))
    , testEnumLaws "Unsigned 1" (Proxy @(Unsigned 1))
    , testEnumLaws "Unsigned 32" (Proxy @(Unsigned 32))
    , testEnumLaws "Unsigned 127" (Proxy @(Unsigned 127))
    , testEnumLaws "Unsigned 128" (Proxy @(Unsigned 128))
  
    , testEnumLaws "Signed 0" (Proxy @(Signed 0))
    , testEnumLaws "Signed 1" (Proxy @(Signed 1))
    , testEnumLaws "Signed 32" (Proxy @(Signed 32))
    , testEnumLaws "Signed 127" (Proxy @(Signed 127))
    , testEnumLaws "Signed 128" (Proxy @(Signed 128))
  
    -- Note Fixed is tested elsewhere.
    ]
  