packages feed

ascii-th-1.0.0.6: test/test.hs

module Main where

import ASCII.QuasiQuoters
import ASCII.TemplateHaskell

import ASCII.Char (Char (..))
import ASCII.Refinement (ASCII, asciiUnsafe)
import ASCII.Superset (toCharOrFail)

import Control.Applicative (Applicative (..))
import Control.Monad (Monad (..))
import Data.Bool (Bool (..))
import Data.Eq (Eq ((==)))
import Data.Function ((.), ($))
import Data.Functor (Functor (..))
import Data.List (intercalate, map, null)
import Data.Semigroup ((<>))
import Data.String (String)
import Data.Text (Text)
import Data.Word (Word8)
import Numeric.Natural (Natural)
import Prelude (Integer)
import System.Exit (die)
import System.IO (IO, putStrLn)
import Text.Show (show)

import qualified Data.ByteString.Builder as BS.Builder

main :: IO ()
main = dieIfFailures $ do
    test 1 $ ([char|e|] :: Char) == SmallLetterE
    test 2 $ ([char|e|] :: Word8) == 101
    test 3 $ (case Tilde of [char|@|] -> 1 :: Integer; [char|~|] -> 2; _ -> 3) == 2
    test 4 $ ([string|Hello!|] :: [Char]) == [CapitalLetterH, SmallLetterE, SmallLetterL, SmallLetterL, SmallLetterO, ExclamationMark]
    test 5 $ ([string|Hello!|] :: String) == "Hello!"
    test 6 $ ([string|Hello!|] :: Text) == "Hello!"
    test 7 $ (BS.Builder.toLazyByteString [string|Hello!|] == "Hello!")
    test 8 $ (case [CapitalLetterH, SmallLetterI] of [string|Bye|] -> 1 :: Integer; [string|Hi|] -> 2; _ -> 3) == 2
    test 9 $ $(toCharOrFail 'F' >>= charExp) == CapitalLetterF
    test 10 $ $(toCharOrFail '\DEL' >>= charExp) == Delete
    test 11 $ case SmallLetterS of { $(toCharOrFail 'r' >>= charPat) -> 1 :: Integer; $(toCharOrFail 's' >>= charPat) -> 2; _ -> 3 } == 2
    test 12 $ $(charListExp [CapitalLetterH, SmallLetterI]) == [CapitalLetterH, SmallLetterI]
    test 13 $ case [CapitalLetterH, SmallLetterI] of { $(charListPat [CapitalLetterH, SmallLetterA]) -> 1 :: Integer; $(charListPat [CapitalLetterH, SmallLetterI]) -> 2; _ -> 3 } == 2
    test 14 $ ($(isCharExp CapitalLetterA) :: Char) == CapitalLetterA
    test 15 $ ($(isCharExp CapitalLetterA) :: Word8) == 65
    test 16 $ ($(isCharExp CapitalLetterA) :: ASCII Word8) == asciiUnsafe 65
    test 17 $ case (66 :: Word8) of { $(isCharPat CapitalLetterA) -> 1 :: Integer; $(isCharPat CapitalLetterB) -> 2; _ -> 3 } == 2

dieIfFailures :: Failures a -> IO a
dieIfFailures (Failures fs x) =
    if null fs
        then do putStrLn "💯"; return x
        else die $ intercalate " " (map (("🔥" <> ) . show) fs)

type TestNumber = Natural

test :: TestNumber -> Bool -> Failures ()
test n t = Failures (if t then [] else [n]) ()

data Failures a = Failures [TestNumber] a

instance Functor Failures
  where
    fmap f (Failures a x) = Failures a (f x)

instance Applicative Failures
  where
    pure x = Failures [] x
    Failures a f <*> Failures b x = Failures (a <> b) (f x)

instance Monad Failures
  where
    Failures a x >>= f = let Failures b y = f x in Failures (a <> b) y