module Main (main) where

import Test.Framework
import Test.HUnit
import Test.Framework.Providers.HUnit
import Test.Framework.Providers.QuickCheck2
import HuffmanTree
import Bit

main :: IO ()
main = defaultMain tests

tests = [
    --Test Bit .&.
    testCase "Bit .&. test, One && One = One"
        $ testBitAnd One One One,
    testCase "Bit .&. test, Zero && Zero = Zero"
        $ testBitAnd Zero Zero Zero,
    testCase "Bit .&. test, One && Zero  = Zero"
        $ testBitAnd One Zero Zero,
    testCase "Bit .&. test, Zero && One = Zero"
        $ testBitAnd Zero One Zero,
    
    --Test Bit .|.
    testCase "Bit .|. test, One && One = One"
        $ testBitOr One One One,
    testCase "Bit .|. test, Zero && Zero = Zero"
        $ testBitOr Zero Zero Zero,
    testCase "Bit .|. test, One && Zero  = Zero"
        $ testBitOr One Zero One,
    testCase "Bit .|. test, Zero && One = Zero"
        $ testBitOr Zero One One,
    
    --Test Bit xor
    testCase "Bit xor test, One && One = One"
        $ testBitXOR One One Zero,
    testCase "Bit xor test, Zero && Zero = Zero"
        $ testBitXOR Zero Zero Zero,
    testCase "Bit xor test, One && Zero  = Zero"
        $ testBitXOR One Zero One,
    testCase "Bit xor test, Zero && One = Zero"
        $ testBitXOR Zero One One,
    
    --Test Bit complement
    testCase "Bit complement test, complement One = One"
        $ testBitComplement One One,
    testCase "Bit complement test, complement One = One"
        $ testBitComplement Zero One,
    
    --Test Bit shift
    testCase "Bit shift test, shift One 1 = Zero"
        $ testBitShift One 1 Zero,
    testCase "Bit shift test, shift Zero 1 = Zero"
        $ testBitShift Zero 1 Zero,
    testCase "Bit shift test, shift One -1 = Zero"
        $ testBitShift One 1 Zero,
    testCase "Bit shift test, shift Zero -1 = Zero"
        $ testBitShift Zero 1 Zero,
    testCase "Bit shift test, shift One 0 = One"
        $ testBitShift One 0 One,
    testCase "Bit shift test, shift Zero 0 = Zero"
        $ testBitShift Zero 0 Zero,

    --Test Bit Rotate
    testCase "Bit rotate test, rotate One 1 = One"
        $ testBitRotate One 1 One,
    testCase "Bit rotate test, rotate One -1 = One"
        $ testBitRotate One (-1) One,
    testCase "Bit rotate test, rotate Zero 1 = Zero"
        $ testBitRotate Zero 1 Zero,
    testCase "Bit rotate test, rotate Zero -1 = Zero"
        $ testBitRotate Zero (-1) Zero,
    testCase "Bit rotate test, rotate One 0 = One"
        $ testBitRotate One 0 One,
    testCase "Bit rotate test, rotate Zero 0 = Zero"
        $ testBitRotate Zero 0 Zero,
    testCase "Bit rotate test, rotate Zero 50 = Zero"
        $ testBitRotate Zero 50 Zero,
    testCase "Bit rotate test, rotate One 50 = One"
        $ testBitRotate One 50 One,

    --Test bitSize
    testCase "Bit bitSize test, bitSize One = 1"
        $ testBitSize One,
    testCase "Bit bitSize test, bitSize Zero = 1"
        $ testBitSize Zero,

    --Test isSigned
    testCase "Bit isSigned test, One = False"
        $ testBitIsSigned One,
    testCase "Bit isSigned test, Zero = False"
        $ testBitIsSigned Zero,
    
    --Test testBit
    testCase "Bit testBit test, One 0 = True"
        $ testBitTestBit One 0 True,
    testCase "Bit testBit test, Zero 0 = False"
        $ testBitTestBit Zero 0 False,
    testCase "Bit testBit test, One 1 = False"
        $ testBitTestBit One 1 False,
    testCase "Bit testBit test, Zero 1 = False"
        $ testBitTestBit Zero 1 False,
    testCase "Bit testBit test, Zero 100 = False"
        $ testBitTestBit Zero 100 False,
    
    --Test Bit
    testCase "Bit test, bit 1 = One"
        $ testBitBit 1 One,
    testCase "Bit test, bit 0 = Zero"
        $ testBitBit 0 Zero,

    --Test Bit popCount
    testCase "Bit popCount test, popCount Zero = 0"
        $ testBitPopCount Zero 0,
    testCase "Bit popCount test, popCount One = 1"
        $ testBitPopCount One 1
    ]

testBitAnd :: Bit -> Bit -> Bit -> Assertion
testBitAnd a b c = c @=? (a .&. b)  

testBitOr :: Bit -> Bit -> Bit -> Assertion
testBitOr a b c  = c @=? (a .|. b)  

testBitXOR :: Bit -> Bit -> Bit -> Assertion
testBitXOR a b c = c @=? (a `xor` b) 

testBitComplement :: Bit -> Bit -> Assertion
testBitComplement a b = b @=? (complement a)

testBitShift :: Bit -> Int -> Bit -> Assertion
testBitShift a b c = c @=? (shift a b)

testBitRotate :: Bit -> Int -> Bit -> Assertion
testBitRotate a b c = c @=? (rotate a b)

testBitSize :: Bit -> Assertion
testBitSize a = 1 @=? (bitSize a) 

testBitIsSigned :: Bit -> Assertion
testBitIsSigned a = False @=? (isSigned a)

testBitTestBit :: Bit -> Int -> Bool -> Assertion
testBitTestBit a b c = c @=? (testBit a b)

testBitBit :: Int -> Bit -> Assertion
testBitBit a b = b @=? (bit a)

testBitPopCount :: Bit -> Int -> Assertion
testBitPopCount a b = b @=? (popCount a)
