bf-optimize/test/Spec.hs

40 lines
1.7 KiB
Haskell

{-# LANGUAGE TemplateHaskell #-}
import Data.Vector (Vector)
import Test.QuickCheck.All (quickCheckAll)
import System.Exit (exitFailure, exitSuccess)
import Language.Brainfuck.Instruction (Instruction)
import qualified Data.Either as Either
import qualified Language.Brainfuck as Brainfuck
import qualified Arbitrary.ValidBrainfuckText as ValidBrainfuckText
import qualified Arbitrary.InvalidBrainfuckText as InValidBrainfuckText
import qualified Language.Brainfuck.Instruction.Compressed as CompressedInstruction
-- | ValidBrainfuckText will produce a text with comments, it must be parsed correctly
prop_acceptValidTexts :: ValidBrainfuckText.ValidBrainfuckText -> Bool
prop_acceptValidTexts = Either.isRight . Brainfuck.parse . ValidBrainfuckText.get
-- | InvalidBrainfuckText will insert unbalanced brackets, they must be rejected
prop_rejectInvalidTexts :: InValidBrainfuckText.InvalidBrainfuckText -> Bool
prop_rejectInvalidTexts = Either.isLeft . Brainfuck.parse . InValidBrainfuckText.get
-- | Does rendering and parsing a vector of instructions yield the exact same result?
prop_renderParseInverse :: Vector Instruction -> Bool
prop_renderParseInverse source = Right source == (Brainfuck.parse . Brainfuck.render $ source)
-- | Compressing and Uncompressing should be inverse. The opposite must not be true, since `compress $ replicate 300 Increment` is `Add 44`
prop_CompressUncompressInverse :: Vector Instruction -> Bool
prop_CompressUncompressInverse source = source == (CompressedInstruction.uncompress . CompressedInstruction.compress) source
return [] -- template haskell guard
runQuickCheck :: IO Bool
runQuickCheck = $quickCheckAll
main :: IO ()
main = do
quickCheckGood <- runQuickCheck
if quickCheckGood then exitSuccess else exitFailure