{-# LANGUAGE ScopedTypeVariables #-}
module Errors (
testErrorsColumns
, testErrorsInvalidParams
) where
import Prelude hiding (catch)
import Control.Exception
import qualified Data.ByteString as B
import Data.Word
import Common
assertResultErrorCaught :: IO a -> Assertion
assertResultErrorCaught action = do
catch (action >> return False) (\(_ :: ResultError) -> return True) >>=
assertBool "assertResultError exc"
assertFormatErrorCaught :: IO a -> Assertion
assertFormatErrorCaught action = do
catch (action >> return False) (\(_ :: FormatError) -> return True) >>=
assertBool "assertFormatError exc"
testErrorsColumns :: TestEnv -> Test
testErrorsColumns TestEnv{..} = TestCase $ do
execute_ conn "CREATE TABLE cols (id INTEGER PRIMARY KEY, t TEXT)"
execute_ conn "INSERT INTO cols (t) VALUES ('test string')"
rows <- query_ conn "SELECT t FROM cols" :: IO [Only String]
assertEqual "row count" 1 (length rows)
assertEqual "string" (Only "test string") (head rows)
-- Mismatched number of output columns (selects two, dest type has 1 field)
assertResultErrorCaught (query_ conn "SELECT id,t FROM cols" :: IO [Only Int])
-- Same as above but the other way round (select 1, dst has two)
assertResultErrorCaught (query_ conn "SELECT id FROM cols" :: IO [(Int, String)])
-- Mismatching types (source int,text doesn't match dst string,int
assertResultErrorCaught (query_ conn "SELECT id, t FROM cols" :: IO [(String, Int)])
-- Trying to get a blob into a string
let d = B.pack ([0..127] :: [Word8])
execute_ conn "CREATE TABLE cols_blobs (id INTEGER, b BLOB)"
execute conn "INSERT INTO cols_blobs (id, b) VALUES (?,?)" (1 :: Int, d)
assertResultErrorCaught
(do [Only _t1] <- query conn "SELECT b FROM cols_blobs WHERE id = ?" (Only (1 :: Int)) :: IO [Only String]
return ())
testErrorsInvalidParams :: TestEnv -> Test
testErrorsInvalidParams TestEnv{..} = TestCase $ do
execute_ conn "CREATE TABLE invparams (id INTEGER PRIMARY KEY, t TEXT)"
-- Test that only unnamed params are accepted
assertFormatErrorCaught
(execute conn "INSERT INTO invparams (t) VALUES (:v)" (Only ("foo" :: String)))
assertFormatErrorCaught
(execute conn "INSERT INTO invparams (id, t) VALUES (:v,$1)" (3::Int, "foo" :: String))
-- In this case, we have two bound params but only one given to
-- execute. This should cause an error.
assertFormatErrorCaught
(execute conn "INSERT INTO invparams (id, t) VALUES (?, ?)" (Only (3::Int)))