packages feed

HCodecs-0.5: src/Codec/Internal/TestSuite.hs

module Main (main) where

import qualified Codec.Wav as Wav
import qualified Codec.SoundFont as SF
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L

import Test.QuickCheck (quickCheck, (==>))

import Data.Audio
import Codec.Midi
import Codec.ByteString.Parser
import Codec.ByteString.Builder

import Data.Int
import Data.Word
import Data.Bits
import Data.Monoid
import Debug.Trace

roundTrip :: (Eq a, Show a) => (a -> Builder) -> Parser a -> a -> Bool
roundTrip b p a = if Right a == ea'
  then True
  else trace (unlines $ [show ea']) $ False
  where ea' = runParser p bs
        bs = toLazyByteString $ b a

testAudio :: IO ()
testAudio = do
  putStrLn "TESTING Inctances of Audible"
  quickCheck (prop_audible :: Word8 -> Bool)
  quickCheck (prop_audible :: Word16 -> Bool)
  quickCheck (prop_audible :: Word32 -> Bool)
  -- quickCheck (prop_audible :: Word64 -> Bool)
  quickCheck (prop_audible :: Int8 -> Bool)
  quickCheck (prop_audible :: Int16 -> Bool)
  quickCheck (prop_audible :: Int32 -> Bool)
  -- quickCheck (prop_audible :: Int64 -> Bool)

  -- These two tests are commented, because they fail
  -- Reason for that is the fact that Double is not abble to accomodate
  -- 64 bit numbers in full precision
  where
  prop_audible :: (Eq a, Audible a) => a -> Bool
  prop_audible a = (a ==  fromSample s) && (s >= -1.0) && (s <= 1.0)
    where s = toSample a

testMidi :: IO ()
testMidi =  do
  putStrLn "TESTING PARSING AND BUILDING of Midi"

  quickCheck $ roundTrip buildMessage (parseMessage Nothing)
  quickCheck $ roundTrip buildMidi parseMidi
  quickCheck $ \trk -> trk == fromAbsTime (toAbsTime trk :: Track Ticks)
  quickCheck $ \trk td -> trk == fromRealTime td (toRealTime td trk)

  quickCheck $ \m -> (not $ null $ tracks m) ==>
                       let (Midi SingleTrack _ trks) = toSingleTrack m
                       in  length (concat $ tracks m) - length (concat trks) == length (tracks m) - 1

testWav :: IO ()
testWav =  do
  putStrLn "TESTING PARSING AND BUILDING of Wav"
  quickCheck $ roundTrip (Wav.buildWav :: Audio Word8 -> Builder) Wav.parseWav
  quickCheck $ roundTrip (Wav.buildWav :: Audio Int16 -> Builder) Wav.parseWav
  quickCheck $ roundTrip (Wav.buildWav :: Audio Int32 -> Builder) Wav.parseWav

testSoundFont :: IO ()
testSoundFont =  do
  putStrLn "TESTING PARSING AND BUILDING of SoundFont"
  quickCheck $ roundTrip SF.buildSoundFont SF.parseSoundFont

testParserBuilder :: IO ()
testParserBuilder = do
  putStrLn "TESTING PARSING AND BUILDING OF NUMERICAL TYPES"

  quickCheck $ roundTrip putWord8 getWord8
  quickCheck $ roundTrip putWord16be getWord16be
  quickCheck $ roundTrip putWord16le getWord16le
  quickCheck $ \w -> roundTrip putWord24be getWord24be (w .&. 0xFFFFFF)
  quickCheck $ \w -> roundTrip putWord24le getWord24le (w .&. 0xFFFFFF)
  quickCheck $ roundTrip putWord32be getWord32be
  quickCheck $ roundTrip putWord32le getWord32le
  quickCheck $ roundTrip putWord64be getWord64be
  quickCheck $ roundTrip putWord64le getWord64le

  quickCheck $ roundTrip putInt8 getInt8
  quickCheck $ roundTrip putInt16be getInt16be
  quickCheck $ roundTrip putInt16le getInt16le
  quickCheck $ roundTrip putInt32be getInt32be
  quickCheck $ roundTrip putInt32le getInt32le
  quickCheck $ roundTrip putInt64be getInt64be
  quickCheck $ roundTrip putInt64le getInt64le

  quickCheck $ roundTrip putWordHost getWordHost
  quickCheck $ roundTrip putWord16host getWord16host
  quickCheck $ roundTrip putWord32host getWord32host
  quickCheck $ roundTrip putWord64host getWord64host

  quickCheck $ roundTrip putVarLenBe getVarLenBe
  quickCheck $ roundTrip putVarLenLe getVarLenLe

  putStrLn "TESTING PARSING AND BUILDING OF String and ByteString"

  quickCheck $ \s1 s2 -> roundTrip (\s -> putString s `mappend` putString s2) (getString $ length s1) s1
  quickCheck $ \s1 s2 -> roundTrip (\s -> fromByteString s `mappend` fromByteString s2) (getByteString $ B.length s1) s1
  quickCheck $ \s1 s2 -> roundTrip (\s -> fromLazyByteString s `mappend` fromLazyByteString s2) (getLazyByteString $  L.length s1) s1
  quickCheck $ \bs -> roundTrip fromLazyByteString getRemainingLazyByteString bs


main :: IO ()
main = do
  testAudio
  testParserBuilder
  testMidi
  testWav
  testSoundFont