module Main (main) where import ASCII.ListsAndPredicates import qualified ASCII.Char import Control.Monad (Monad (..), when) import Data.Bool (not) import Data.Eq (Eq ((==))) import Data.Function (($), (.)) import Data.List (filter) import System.Exit (exitFailure) import System.IO (IO) import qualified Data.Char as Char import qualified Data.List as List import Hedgehog (MonadTest, Property, assert, checkParallel, discover, property, withTests, (===)) main :: IO () main = checkParallel $$(discover) >>= \ok -> when (not ok) exitFailure --- -- This test ensures that all of the lists give characters in ascending order. lists :: [[ASCII.Char.Char]] lists = [ all, printableCharacters, controlCodes, letters, capitalLetters, smallLetters, digits, octDigits, hexDigits, numbers, visibleCharacters ] prop_lists_are_sorted :: Property prop_lists_are_sorted = withTests 1 $ property $ assert $ List.all (\xs -> List.sort xs == xs) lists --- -- These tests check that the predicates in our package that have corresponding functions in `base` behave the same as their counterparts. eq :: (MonadTest m, Eq a) => (ASCII.Char.Char -> a) -> (Char.Char -> a) -> m () eq f g = assert $ List.all (\x -> f x == g (convert x)) ASCII.Char.allCharacters where convert = Char.chr . ASCII.Char.toInt prop_eq_control :: Property prop_eq_control = withTests 1 $ property $ eq isControl Char.isControl prop_eq_space :: Property prop_eq_space = withTests 1 $ property $ eq isSpace Char.isSpace prop_eq_lower :: Property prop_eq_lower = withTests 1 $ property $ eq isLower Char.isLower prop_eq_upper :: Property prop_eq_upper = withTests 1 $ property $ eq isUpper Char.isUpper prop_eq_alpha :: Property prop_eq_alpha = withTests 1 $ property $ eq isAlpha Char.isAlpha prop_eq_alphaNum :: Property prop_eq_alphaNum = withTests 1 $ property $ eq isAlphaNum Char.isAlphaNum prop_eq_print :: Property prop_eq_print = withTests 1 $ property $ eq isPrint Char.isPrint prop_eq_digit :: Property prop_eq_digit = withTests 1 $ property $ eq isDigit Char.isDigit prop_eq_octDigit :: Property prop_eq_octDigit = withTests 1 $ property $ eq isOctDigit Char.isOctDigit prop_eq_hexDigit :: Property prop_eq_hexDigit = withTests 1 $ property $ eq isHexDigit Char.isHexDigit prop_eq_letter :: Property prop_eq_letter = withTests 1 $ property $ eq isLetter Char.isLetter prop_eq_mark :: Property prop_eq_mark = withTests 1 $ property $ eq isMark Char.isMark prop_eq_number :: Property prop_eq_number = withTests 1 $ property $ eq isNumber Char.isNumber prop_eq_punctuation :: Property prop_eq_punctuation = withTests 1 $ property $ eq isPunctuation Char.isPunctuation prop_eq_symbol :: Property prop_eq_symbol = withTests 1 $ property $ eq isSymbol Char.isSymbol prop_eq_separator :: Property prop_eq_separator = withTests 1 $ property $ eq isSeparator Char.isSeparator --- -- These tests ensure that the predicates are coherent with the lists. prop_list_control :: Property prop_list_control = withTests 1 $ property $ controlCodes === filter isControl all prop_list_printable :: Property prop_list_printable = withTests 1 $ property $ printableCharacters === filter isPrint all prop_list_letter :: Property prop_list_letter = withTests 1 $ property $ letters === filter isLetter all prop_list_capital :: Property prop_list_capital = withTests 1 $ property $ capitalLetters === filter isUpper all prop_list_small :: Property prop_list_small = withTests 1 $ property $ smallLetters === filter isLower all prop_list_digit :: Property prop_list_digit = withTests 1 $ property $ digits === filter isDigit all prop_list_number :: Property prop_list_number = withTests 1 $ property $ numbers === filter isNumber all prop_list_oct :: Property prop_list_oct = withTests 1 $ property $ octDigits === filter isOctDigit all prop_list_hex :: Property prop_list_hex = withTests 1 $ property $ hexDigits === filter isHexDigit all prop_list_visible :: Property prop_list_visible = withTests 1 $ property $ visibleCharacters === filter isVisible all