@@ -12,6 +12,7 @@ import qualified Database.PostgreSQL.Simple.Transaction as ST
12import Control.Applicative
12import Control.Applicative
13import Control.Exception as E
13import Control.Exception as E
14import Control.Monad
14import Control.Monad
15import Data.List (sort)
16import Data.List (sort)
16import Data.IORef
17import Data.IORef
17import Data.Typeable
18import Data.Typeable
@@ -20,13 +21,16 @@ import GHC.Generics (Generic)
20import Data.Aeson
21import Data.Aeson
21import Data.ByteString (ByteString)
22import Data.ByteString (ByteString)
22import qualified Data.ByteString as B
23import qualified Data.ByteString as B
24+import qualified Data.ByteString.Lazy.Char8 as BL
23import Data.Map (Map)
25import Data.Map (Map)
24import qualified Data.Map as Map
26import qualified Data.Map as Map
25import Data.Text(Text)
27import Data.Text(Text)
26import qualified Data.Text.Encoding as T
28import qualified Data.Text.Encoding as T
27import qualified Data.Vector as V
29import qualified Data.Vector as V
30+import System.FilePath
29import Test.Tasty
32import Test.Tasty
33+import Test.Tasty.Golden
30import Notify
34import Notify
31import Serializable
35import Serializable
32import Time
36import Time
@@ -47,6 +51,7 @@ tests env = testGroup "tests"
47 , testCase "Unicode" . testUnicode
51 , testCase "Unicode" . testUnicode
48 , testCase "Values" . testValues
52 , testCase "Values" . testValues
49 , testCase "Copy" . testCopy
53 , testCase "Copy" . testCopy
50 , testCase "Double" . testDouble
55 , testCase "Double" . testDouble
51 , testCase "1-ary generic" . testGeneric1
56 , testCase "1-ary generic" . testGeneric1
52 , testCase "2-ary generic" . testGeneric2
57 , testCase "2-ary generic" . testGeneric2
@@ -317,6 +322,35 @@ testCopy TestEnv{..} = do
317 CopyOutDone _ -> return rows
322 CopyOutDone _ -> return rows
318 CopyOutRow row -> loop (row:rows)
323 CopyOutRow row -> loop (row:rows)
325+testCopyFailures :: TestEnv -> TestTree
326+testCopyFailures env = testGroup "Copy failures"
328+ [ testCopyUniqueConstraintError ]
330+goldenTest :: TestName -> IO BL.ByteString -> TestTree
331+goldenTest testName =
332+ goldenVsString testName (resultsDir </> fileName<.>"expected")
334+ resultsDir = "test" </> "results"
335+ fileName = map normalize testName
336+ normalize c | not (isAlpha c) = '-'
339+-- | Test that we provide a sensible error message on failure
340+testCopyUniqueConstraintError :: TestEnv -> TestTree
341+testCopyUniqueConstraintError TestEnv{..} =
342+ goldenTest "unique constraint violation"
343+ $ handle (\(SomeException exc) -> return $ BL.pack $ show exc) $ do
344+ execute_ conn "CREATE TEMPORARY TABLE copy_unique_constraint_error_test (x int PRIMARY KEY, y text)"
345+ copy_ conn "COPY copy_unique_constraint_error_test FROM STDIN (FORMAT CSV)"
346+ mapM_ (putCopyData conn) copyRows
347+ _n <- putCopyEnd conn
350+ copyRows = ["1,foo\n"
320testDouble :: TestEnv -> Assertion
354testDouble :: TestEnv -> Assertion
321testDouble TestEnv{..} = do
355testDouble TestEnv{..} = do
322 [Only (x :: Double)] <- query_ conn "SELECT 'NaN'::float8"
356 [Only (x :: Double)] <- query_ conn "SELECT 'NaN'::float8"