packages feed

type-spec-0.2.0.0: examples/Main.hs

-- | Some examples for 'Test.TypeSpec'
module Main where

import GHC.TypeLits
import Test.TypeSpecCrazy

main :: IO ()
main = do
  print specHelloWorld
  print specGrouped
  print specAliases
  print specTuple
  print specFamilyInstancesSuperCrazy
  print spec1
  print specCrazy
  print specInvalidCrazy
  print specCrazyMoreNested

-- * TypeSpec Examples

-- | Let's start off simple:
specHelloWorld :: Expect (Int `Isn't` Bool)
specHelloWorld = Valid

-- | We can also expect a bit more using lists and tuples:
specGrouped
  :: Expect '[ Int  `Isn't` Bool
             , Int  `Is`    Int
             , Bool `Is`    Bool  `ButNot`  String
             ]
specGrouped = Valid

specTuple ::
  Explain "Type level tuples can also be used to group tests."
    (They "accept only two elments"
      '( (5 - 4) `Is` 1, (3 + 3) `Is` 6 `ButNot` (3 - 3) ) )
specTuple = Valid

-- * Some nice aliases

type ALot = 1000

specAliases ::
  (Explain "There are a variety aliases for the basic combinators."
    (Context "Basic Combinators"
      (Describe "Context"
        (It "labels expectations using 'It'"
          (Describe "Describe"
            (It's "an alias for It, just like They"
              (It's "time for the first assertion"
                (1000 `Is` ALot))))))))
specAliases = Valid


-- * More complex example

type family Swap a
type instance Swap (a,b) = (b,a)

type family SwapT (a :: (k1, k2)) :: (k2, k1)
type instance SwapT '(a,b) = '(b,a)

type family Fst a where
  Fst (a,b) = a

type family Count a :: Nat where
  Count (a,b) = 2
  Count (a,b,c) = 3
  Count (a,b,c,d) = 4

-- A failing test case example:
-- specFailing ::
--     TypeSpec
--       (It "counts the number of elements in a tuple"
--           (Count ((),(),()) `ShouldBe` 4))
-- specFailing = Valid

specFamilyInstancesSuperCrazy ::

    "Only one title like this"
    ###########################

    "Describe the following expectations"

     --* Swap (Int, Bool) `Isn't` (Int, Int)
      -* Swap (Int, Bool) `Is`    (Bool, Int)
      -* Swap (Int, Bool) `Isn't` Swap (Swap (Int, Bool))
      -* (Int, Bool)      `Is`    Swap (Swap (Int, Bool))
      -*
         ("... now there is maybe a nested block"

           --* Count    (Int,Int,Int,Int) `ShouldBe`      4
            -* SwapT               '(0,1) `ShouldBe` '(1,0)
            -* And   (Count (Int,Int,Int)     <=?         4))

    -/-

    "Here there is another top-level block"
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     [ Count (Int,Int,Int,Int)    `Is`  4
     , SwapT '(0,1)               `Is`  '(1,0)
     , And   (Count (Int,Int,Int)  <=?   4)
     ]


specFamilyInstancesSuperCrazy = Valid

-- * More examples

spec1 ::
  Explain "TypeSpec"
    (It "Allows explanations of types"  (ShouldBe Int Int))
spec1 = Valid

specCrazy ::

    "Higher kinded assertions"
   ###########################

   "ShouldBe accepts types of kind * -> *"
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

       ShouldBe  Maybe Maybe
    -* ShouldBe  []    []
    -* ShouldBe  (->)  (->)

specCrazy = Valid

-- --------------------------------------------------------

type SpecInvalidCrazy =

  "One of the following specs is not OK"
 #######################################

 "This should be ok"
 ~~~~~~~~~~~~~~~~~~~~~

 TheseAreEqual    Bool Bool

 -/-

 "This should also be ok"
 ~~~~~~~~~~~~~~~~~~~~~~~~

 TheseAreNotEqual (Maybe Int) (Maybe Int)

 -/-

 "But this looks bad:"
 ~~~~~~~~~~~~~~~~~~~~~

 TheseAreEqual    Maybe (Either Int)

specInvalidCrazy :: SpecInvalidCrazy
specInvalidCrazy = Invalid


specCrazyMoreNested ::

  "Title"
  ######

    "Top-level "
    ~~~~~~~~~~~~

         "Nested:"
         ~~~~~~~~~
         Int `Is` Int
                            -*-
         Int `Is` Int
                            -*-
         Int `Is` Int

                            -/-

    "Top-level "
    ~~~~~~~~~~~~

         "Nested:"
         ~~~~~~~~~
         Int `Is` Int
                            -*-
             "Nested:"
             ~~~~~~~~~
             Int `Is` Int
                                -*-
             Int `Is` Int

specCrazyMoreNested = Valid