packages feed

ascii-predicates-1.0.0.6: test/test.hs

module Main where

import ASCII.ListsAndPredicates

import qualified ASCII.Char

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 (filter, intercalate, map, null)
import Data.Semigroup ((<>))
import Numeric.Natural (Natural)
import System.Exit (die)
import System.IO (IO, putStrLn)
import Text.Show (show)

import qualified Data.Char as Char
import qualified Data.List as List

main :: IO ()
main = dieIfFailures $ do

    do
        let lists = [ all, printableCharacters, controlCodes, letters,
                      capitalLetters, smallLetters, digits, octDigits,
                      hexDigits, numbers]

        test 1 $ List.all (\xs -> List.sort xs == xs) lists

    do
        let convert = Char.chr . ASCII.Char.toInt
            eq f g = List.all (\x -> f x == g (convert x))
                              ASCII.Char.allCharacters

        test 2 $ eq isControl Char.isControl
        test 3 $ eq isSpace Char.isSpace
        test 4 $ eq isLower Char.isLower
        test 5 $ eq isUpper Char.isUpper
        test 6 $ eq isAlpha Char.isAlpha
        test 7 $ eq isAlphaNum Char.isAlphaNum
        test 8 $ eq isPrint Char.isPrint
        test 9 $ eq isDigit Char.isDigit
        test 10 $ eq isOctDigit Char.isOctDigit
        test 11 $ eq isHexDigit Char.isHexDigit
        test 12 $ eq isLetter Char.isLetter
        test 13 $ eq isMark Char.isMark
        test 14 $ eq isNumber Char.isNumber
        test 15 $ eq isPunctuation Char.isPunctuation
        test 16 $ eq isSymbol Char.isSymbol
        test 17 $ eq isSeparator Char.isSeparator

    test 18 $ controlCodes == filter isControl all
    test 19 $ printableCharacters == filter isPrint all
    test 20 $ letters == filter isLetter all
    test 21 $ capitalLetters == filter isUpper all
    test 22 $ smallLetters == filter isLower all
    test 23 $ digits == filter isDigit all
    test 24 $ numbers == filter isNumber all
    test 25 $ octDigits == filter isOctDigit all
    test 26 $ hexDigits == filter isHexDigit all

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