-
Notifications
You must be signed in to change notification settings - Fork 50
Expand file tree
/
Copy pathtests.hs
More file actions
132 lines (101 loc) · 4.05 KB
/
Copy pathtests.hs
File metadata and controls
132 lines (101 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Exception.Safe
import qualified Language.C.Inline.Cpp as C
import qualified Language.C.Inline.Cpp.Exceptions as C
import qualified Test.Hspec as Hspec
import Data.List (isInfixOf)
C.context C.cppCtx
C.include "<iostream>"
C.include "<stdexcept>"
main :: IO ()
main = Hspec.hspec $ do
Hspec.describe "Basic C++" $ do
Hspec.it "Hello World" $ do
let x = 3
[C.block| void {
std::cout << "Hello, world!" << $(int x) << std::endl;
} |]
Hspec.describe "Exception handling" $ do
Hspec.it "std::exceptions are caught" $ do
result <- try [C.catchBlock|
throw std::runtime_error("C++ error message");
|]
result `Hspec.shouldBe` Left (C.CppStdException "Exception: C++ error message; type: std::runtime_error")
Hspec.it "non-exceptions are caught (unsigned int)" $ do
result <- try [C.catchBlock|
throw 0xDEADBEEF;
|]
result `Hspec.shouldBe` Left (C.CppOtherException (Just "unsigned int"))
Hspec.it "non-exceptions are caught (std::string)" $ do
result <- try [C.catchBlock|
throw std::string("FOOBAR");
|]
case result of
Left (C.CppOtherException (Just ty)) | "string" `isInfixOf` ty -> return ()
_ -> error ("Expected Left CppOtherException with string type, but got " ++ show result)
Hspec.it "catch without return (pure)" $ do
result <- [C.tryBlock| void {
throw std::runtime_error("C++ error message");
}
|]
result `Hspec.shouldBe` Left (C.CppStdException "Exception: C++ error message; type: std::runtime_error")
Hspec.it "try and return without throwing (pure)" $ do
result <- [C.tryBlock| int {
return 123;
}
|]
result `Hspec.shouldBe` Right 123
Hspec.it "return maybe throwing (pure)" $ do
result <- [C.tryBlock| int {
if(1) return 123;
else throw std::runtime_error("C++ error message");
}
|]
result `Hspec.shouldBe` Right 123
Hspec.it "return definitely throwing (pure)" $ do
result <- [C.tryBlock| int {
if(0) return 123;
else throw std::runtime_error("C++ error message");
}
|]
result `Hspec.shouldBe` Left (C.CppStdException "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 `Hspec.shouldBe` Left (C.CppStdException "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 {
return 123;
}
|]
result `Hspec.shouldBe` Right 123
Hspec.it "return maybe throwing (throw)" $ do
result :: Either C.CppException C.CInt <- try [C.throwBlock| int {
if(1) return 123;
else throw std::runtime_error("C++ error message");
}
|]
result `Hspec.shouldBe` Right 123
Hspec.it "return definitely throwing (throw)" $ do
result <- try [C.throwBlock| int {
if(0) return 123;
else throw std::runtime_error("C++ error message");
}
|]
result `Hspec.shouldBe` Left (C.CppStdException "Exception: C++ error message; type: std::runtime_error")
Hspec.it "catch without return (throw)" $ do
result <- try [C.throwBlock| void {
throw std::runtime_error("C++ error message");
}
|]
result `Hspec.shouldBe` Left (C.CppStdException "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|
*$(int* resPtr) = 0xDEADBEEF;
|]
result `Hspec.shouldBe` Right 0xDEADBEEF
{- HLINT ignore main "Redundant do" -}