Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing space in shown exceptions; test both legacy and new Exception(s) module API #154

Merged
merged 2 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion inline-c-cpp/src/Language/C/Inline/Cpp/Exception.hs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ data CppException
| CppNonStdException CppExceptionPtr (Maybe ByteString)

instance Show CppException where
showsPrec p (CppStdException _ msg typ) = showParen (p >= 11) (showString "CppStdException e " . showsPrec 11 msg . showsPrec 11 typ)
showsPrec p (CppStdException _ msg typ) = showParen (p >= 11) (showString "CppStdException e " . showsPrec 11 msg . showChar ' ' . showsPrec 11 typ)
showsPrec p (CppHaskellException e) = showParen (p >= 11) (showString "CppHaskellException " . showsPrec 11 e)
showsPrec p (CppNonStdException _ typ) = showParen (p >= 11) (showString "CppOtherException e " . showsPrec 11 typ)

Expand Down
60 changes: 44 additions & 16 deletions inline-c-cpp/test/tests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeInType #-}

Check warning on line 16 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-nightly

-XTypeInType is deprecated: use -XDataKinds and -XPolyKinds instead

Check warning on line 16 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-nightly

-XTypeInType is deprecated: use -XDataKinds and -XPolyKinds instead
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeApplications #-}
Expand Down Expand Up @@ -121,21 +121,26 @@
throw std::runtime_error("C++ error message");
|]

result `shouldBeCppStdException` "Exception: C++ error message; type: std::runtime_error"
result `shouldBeCppStdException` ("C++ error message", Just "std::runtime_error")
result `shouldBeLegacyCppStdException` "Exception: C++ error message; type: std::runtime_error"
-- Test that we don't accidentally mess up formatting:
result `shouldBeShownException` "CppStdException e \"C++ error message\" (Just \"std::runtime_error\")"

Hspec.it "non-exceptions are caught (unsigned int)" $ do
result <- try [C.catchBlock|
throw 0xDEADBEEF;
|]

result `shouldBeCppOtherException` (Just "unsigned int")
result `shouldBeCppNonStdException` (Just "unsigned int")
result `shouldBeLegacyCppOtherException` (Just "unsigned int")

Hspec.it "non-exceptions are caught (void *)" $ do
result <- try [C.catchBlock|
throw (void *)0xDEADBEEF;
|]

result `shouldBeCppOtherException` (Just "void*")
result `shouldBeCppNonStdException` (Just "void*")
result `shouldBeLegacyCppOtherException` (Just "void*")

Hspec.it "non-exceptions are caught (std::string)" $ do
result <- try [C.catchBlock|
Expand Down Expand Up @@ -169,7 +174,8 @@
}
|]

result `shouldBeCppStdException` "Exception: C++ error message; type: std::runtime_error"
result `shouldBeCppStdException` ("C++ error message", Just "std::runtime_error")
result `shouldBeLegacyCppStdException` "Exception: C++ error message; type: std::runtime_error"

Hspec.it "try and return without throwing (pure)" $ do
result <- [C.tryBlock| int {
Expand All @@ -195,15 +201,17 @@
}
|]

result `shouldBeCppStdException` "Exception: C++ error message; type: std::runtime_error"
result `shouldBeCppStdException` ("C++ error message", Just "std::runtime_error")
result `shouldBeLegacyCppStdException` "Exception: C++ error message; type: std::runtime_error"

Hspec.it "catch without return (pure)" $ do
result <- [C.tryBlock| void {
throw std::runtime_error("C++ error message");
}
|]

result `shouldBeCppStdException` "Exception: C++ error message; type: std::runtime_error"
result `shouldBeCppStdException` ("C++ error message", Just "std::runtime_error")
result `shouldBeLegacyCppStdException` "Exception: C++ error message; type: std::runtime_error"

Hspec.it "try and return without throwing (throw)" $ do
result :: Either C.CppException C.CInt <- try [C.throwBlock| int {
Expand All @@ -229,7 +237,8 @@
}
|]

result `shouldBeCppStdException` "Exception: C++ error message; type: std::runtime_error"
result `shouldBeCppStdException` ("C++ error message", Just "std::runtime_error")
result `shouldBeLegacyCppStdException` "Exception: C++ error message; type: std::runtime_error"

Hspec.it "return throwing Haskell" $ do
let exc = toException $ userError "This is from Haskell"
Expand Down Expand Up @@ -275,7 +284,8 @@
}
|]

result `shouldBeCppStdException` "Exception: C++ error message; type: std::runtime_error"
result `shouldBeCppStdException` ("C++ error message", Just "std::runtime_error")
result `shouldBeLegacyCppStdException` "Exception: C++ error message; type: std::runtime_error"

Hspec.it "code without exceptions works normally" $ do
result :: Either C.CppException C.CInt <- try $ C.withPtr_ $ \resPtr -> [C.catchBlock|
Expand All @@ -298,19 +308,19 @@
{- Manual test cases for testing lineDirective and splitTypedC -- For CI, uncomment this line.

Hspec.it "error reporting test case" $ do
result <- try $ [C.throwBlock| int { 0 = 0; return 0xDEADBEEF; /* Test this line. */}|]

Check failure on line 311 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-lts-20

error: lvalue required as left operand of assignment

Check failure on line 311 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-nightly

error: lvalue required as left operand of assignment

Check failure on line 311 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-lts-21

error: lvalue required as left operand of assignment

Check failure on line 311 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-lts-20

|

Check failure on line 311 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-lts-21

|

Check failure on line 311 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-nightly

|
result `shouldBeRight` 0xDEADBEEF

Hspec.it "error reporting test case" $ do
result <- try $ [C.throwBlock| int
{ 1 = 1; return 0xDEADBEEF; /* Test this line. */}

Check failure on line 316 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-lts-20

error: lvalue required as left operand of assignment

Check failure on line 316 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-nightly

error: lvalue required as left operand of assignment

Check failure on line 316 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-lts-21

error: lvalue required as left operand of assignment

Check failure on line 316 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-lts-20

error: expression is not assignable

Check failure on line 316 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-lts-21

error: expression is not assignable

Check failure on line 316 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-nightly

error: expression is not assignable
|]
result `shouldBeRight` 0xDEADBEEF

Hspec.it "error reporting test case" $ do
result <- try $ [C.throwBlock| int
{
2 = 2; /* Test this line. */

Check failure on line 323 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-lts-20

error: lvalue required as left operand of assignment

Check failure on line 323 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-nightly

error: lvalue required as left operand of assignment

Check failure on line 323 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-lts-21

error: lvalue required as left operand of assignment

Check failure on line 323 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-lts-20

error: expression is not assignable

Check failure on line 323 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-lts-21

error: expression is not assignable

Check failure on line 323 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-nightly

error: expression is not assignable
return 0xDEADBEEF;
}
|]
Expand All @@ -320,7 +330,7 @@
result <- try $ [C.throwBlock|
int
{
3 = 3; /* Test this line. */

Check failure on line 333 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-lts-20

error: lvalue required as left operand of assignment

Check failure on line 333 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-nightly

error: lvalue required as left operand of assignment

Check failure on line 333 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-lts-21

error: lvalue required as left operand of assignment

Check failure on line 333 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-lts-20

error: expression is not assignable

Check failure on line 333 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-lts-21

error: expression is not assignable

Check failure on line 333 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-nightly

error: expression is not assignable
return 0xDEADBEEF;
}
|]
Expand All @@ -331,7 +341,7 @@

int
{
4 = 4; /* Test this line. */

Check failure on line 344 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-lts-20

error: lvalue required as left operand of assignment

Check failure on line 344 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-nightly

error: lvalue required as left operand of assignment

Check failure on line 344 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-stack-lts-21

error: lvalue required as left operand of assignment

Check failure on line 344 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-lts-20

error: expression is not assignable

Check failure on line 344 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-lts-21

error: expression is not assignable

Check failure on line 344 in inline-c-cpp/test/tests.hs

View workflow job for this annotation

GitHub Actions / macos-latest-stack-nightly

error: expression is not assignable
return 0xDEADBEEF;
}
|]
Expand Down Expand Up @@ -368,19 +378,37 @@
tag :: C.CppException -> String
tag (C.CppStdException {}) = "CppStdException"
tag (C.CppHaskellException {}) = "CppHaskellException"
tag (Legacy.CppOtherException {}) = "CppStdException"
tag (C.CppNonStdException {}) = "CppNonStdException"

shouldBeCppStdException :: Either C.CppException a -> String -> IO ()
shouldBeCppStdException (Left (Legacy.CppStdException actualMsg)) expectedMsg = do
actualMsg `Hspec.shouldBe` expectedMsg
shouldBeShownException :: Either C.CppException a -> String -> IO ()
shouldBeShownException (Left e) expectedStr = show e `shouldBe` expectedStr
shouldBeShownException (Right _) _expectedStr = "Right _" `Hspec.shouldBe` "Left _"

shouldBeCppStdException :: Either C.CppException a -> (ByteString, Maybe ByteString) -> IO ()
shouldBeCppStdException (Left (C.CppStdException _ actualMsg actualType)) (expectedMsg, expectedType) = do
(actualMsg, actualType) `shouldBe` (expectedMsg, expectedType)
shouldBeCppStdException (Left x) expectedMsg = tag x `Hspec.shouldBe` ("CppStdException " <> show expectedMsg)
shouldBeCppStdException (Right _) expectedMsg = "Right _" `Hspec.shouldBe` ("Left (CppStdException " <> show expectedMsg <> ")")

shouldBeCppOtherException :: Either C.CppException a -> Maybe String -> IO ()
shouldBeCppOtherException (Left (Legacy.CppOtherException actualType)) expectedType = do
-- | Tests that the old, deprecated exception's module and error messages still work.
shouldBeLegacyCppStdException :: Either Legacy.CppException a -> String -> IO ()
shouldBeLegacyCppStdException (Left (Legacy.CppStdException actualMsg)) expectedMsg = do
actualMsg `Hspec.shouldBe` expectedMsg
shouldBeLegacyCppStdException (Left x) expectedMsg = tag x `Hspec.shouldBe` ("CppStdException " <> show expectedMsg)
shouldBeLegacyCppStdException (Right _) expectedMsg = "Right _" `Hspec.shouldBe` ("Left (CppStdException " <> show expectedMsg <> ")")

shouldBeCppNonStdException :: Either C.CppException a -> Maybe ByteString -> IO ()
shouldBeCppNonStdException (Left (C.CppNonStdException _ actualType)) expectedType = do
actualType `Hspec.shouldBe` expectedType
shouldBeCppNonStdException (Left x) expectedType = tag x `Hspec.shouldBe` ("CppOtherException " <> show expectedType)
shouldBeCppNonStdException (Right _) expectedType = "Right _" `Hspec.shouldBe` ("Left (CppOtherException " <> show expectedType <> ")")

-- | Tests that the old, deprecated exception's module and error messages still work.
shouldBeLegacyCppOtherException :: Either Legacy.CppException a -> Maybe String -> IO ()
shouldBeLegacyCppOtherException (Left (Legacy.CppOtherException actualType)) expectedType = do
actualType `Hspec.shouldBe` expectedType
shouldBeCppOtherException (Left x) expectedType = tag x `Hspec.shouldBe` ("CppOtherException " <> show expectedType)
shouldBeCppOtherException (Right _) expectedType = "Right _" `Hspec.shouldBe` ("Left (CppOtherException " <> show expectedType <> ")")
shouldBeLegacyCppOtherException (Left x) expectedType = tag x `Hspec.shouldBe` ("CppOtherException " <> show expectedType)
shouldBeLegacyCppOtherException (Right _) expectedType = "Right _" `Hspec.shouldBe` ("Left (CppOtherException " <> show expectedType <> ")")

shouldBeRight :: (Eq a, Show a) => Either C.CppException a -> a -> IO ()
shouldBeRight (Right actual) expected = actual `Hspec.shouldBe` expected
Expand Down
Loading