-- | Various functions to help test this library and analyses based on
-- it.
module Data.LLVM.Testing (
  readInputAndExpected,
  testAgainstExpected,
  module Data.LLVM.Testing.BuildModule
  ) where

import System.FilePath
import System.FilePath.Glob

import Data.LLVM.Types
import Data.LLVM.Testing.BuildModule

readInputAndExpected :: (Read a) => (FilePath -> FilePath) -> Bool -> FilePath -> IO (Module, a)
readInputAndExpected expectedFunc optimize inputFile = do
  let exFile = expectedFunc inputFile
  exContent <- readFile exFile
  -- use seq here to force the full evaluation of the read file.
  let expected = length exContent `seq` read exContent
  m <- buildModule inputFile optimize
  return (m, expected)

testAgainstExpected :: (Read a) => FilePath -> String -> (FilePath -> FilePath) -> Bool ->
                       (Module -> a) -> (a -> a -> IO ()) -> IO ()
testAgainstExpected testDir testExt expectedMap optimize buildResult compareResults = do
  -- Glob up all of the files in the test directory with the target extension
  let inputPattern = testDir </> ("*" <.> testExt)
  testInputFiles <- namesMatching inputPattern
  inputsAndExpecteds <- mapM (readInputAndExpected expectedMap optimize) testInputFiles
  mapM_ runAndCompare inputsAndExpecteds
  where
    runAndCompare (m, expected) = do
      let actual = buildResult m
      compareResults actual expected
-- | Various functions to help test this library and analyses based on
-- it.
module Data.LLVM.Testing (
  readInputAndExpected,
  testAgainstExpected,
  module Data.LLVM.Testing.BuildModule
  ) where

import System.FilePath.Glob

import Data.LLVM.Types
import Data.LLVM.Testing.BuildModule

readInputAndExpected :: (Read a) => (FilePath -> FilePath) -> Bool -> FilePath ->
                        IO (FilePath, Module, a)
readInputAndExpected expectedFunc optimize inputFile = do
  let exFile = expectedFunc inputFile
  exContent <- readFile exFile
  -- use seq here to force the full evaluation of the read file.
  let expected = length exContent `seq` read exContent
  m <- buildModule inputFile optimize
  return (inputFile, m, expected)

testAgainstExpected :: (Read a) => String -> (FilePath -> FilePath) -> Bool ->
                       (Module -> a) -> (String -> a -> a -> IO ()) -> IO ()
testAgainstExpected testPattern expectedMap optimize buildResult compareResults = do
  -- Glob up all of the files in the test directory with the target extension
  testInputFiles <- namesMatching testPattern
  inputsAndExpecteds <- mapM (readInputAndExpected expectedMap optimize) testInputFiles
  mapM_ runAndCompare inputsAndExpecteds
  where
    runAndCompare (file, m, expected) = do
      let actual = buildResult m
      compareResults file actual expected
Clean up the testing interface.
Clean up the testing interface.

Just take a pattern to glob instead of a directory and extension.
Tweak the comparison function to take a descriptive string (the
filename) as the first parameter.  This is useful for diagnosis and it
happens to match the signature of assertEqual in HUnit.
