@@ -12,6 +12,7 @@ import qualified Database.PostgreSQL.Simple.Transaction as ST
1212import Control.Applicative
1313import Control.Exception as E
1414import Control.Monad
15+ import Data.Char
1516import Data.List (sort )
1617import Data.IORef
1718import Data.Typeable
@@ -20,13 +21,16 @@ import GHC.Generics (Generic)
2021import Data.Aeson
2122import Data.ByteString (ByteString )
2223import qualified Data.ByteString as B
24+ import qualified Data.ByteString.Lazy.Char8 as BL
2325import Data.Map (Map )
2426import qualified Data.Map as Map
2527import Data.Text (Text )
2628import qualified Data.Text.Encoding as T
2729import qualified Data.Vector as V
30+ import System.FilePath
2831
2932import Test.Tasty
33+ import Test.Tasty.Golden
3034import Notify
3135import Serializable
3236import Time
@@ -47,6 +51,7 @@ tests env = testGroup "tests"
4751 , testCase " Unicode" . testUnicode
4852 , testCase " Values" . testValues
4953 , testCase " Copy" . testCopy
54+ , testCopyFailures
5055 , testCase " Double" . testDouble
5156 , testCase " 1-ary generic" . testGeneric1
5257 , testCase " 2-ary generic" . testGeneric2
@@ -317,6 +322,35 @@ testCopy TestEnv{..} = do
317322 CopyOutDone _ -> return rows
318323 CopyOutRow row -> loop (row: rows)
319324
325+ testCopyFailures :: TestEnv -> TestTree
326+ testCopyFailures env = testGroup " Copy failures"
327+ $ map ($ env)
328+ [ testCopyUniqueConstraintError ]
329+
330+ goldenTest :: TestName -> IO BL. ByteString -> TestTree
331+ goldenTest testName =
332+ goldenVsString testName (resultsDir </> fileName<.> " expected" )
333+ where
334+ resultsDir = " test" </> " results"
335+ fileName = map normalize testName
336+ normalize c | not (isAlpha c) = ' -'
337+ | otherwise = c
338+
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
348+ return BL. empty
349+ where
350+ copyRows = [" 1,foo\n "
351+ ," 2,bar\n "
352+ ," 1,baz\n " ]
353+
320354testDouble :: TestEnv -> Assertion
321355testDouble TestEnv {.. } = do
322356 [Only (x :: Double )] <- query_ conn " SELECT 'NaN'::float8"
0 commit comments