-
Notifications
You must be signed in to change notification settings - Fork 98
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
add checks for exceptions #19
Conversation
Thanks for the PR. But I tend to think that try {
code
} catch(std::exception& e) {
TEST_CHECK(e.what() == "xxx");
} ... is more readable; more intuitive (can you guess from the name of When it comes to Last but not least, it would be great if you can add some comments documenting the new macros, similarly to the other public macros and add something into examples/cpp-example.cc to show it in action. |
Maybe I should start with issue... If the implementation fits, I'll add comments and examples. |
Well, I see Also your macros would break easily if used in some situations. Consider for example this: if(some_condition)
TEST_CHECK_EXC(call_something(1, 2), std::logic_error);
else
TEST_CHECK_EXC(call_something(3, 4), std::logic_error); Given your implementation in the form if(some_condition)
{ .... };;
else
{ .... };; There is one trick which is commonly used to make complex macros friendly for their natural usage in C/C++. It is based on wrapping the macro implementation in extra
Every single expert was in some previous period of time nothing more then a beginner. ;-) |
Another thought: do you actually need to check for any other exceptions? The test driver does that already. Edit: to clarify, you should be able to just check for your expected exception, and let |
@gahr That's exactly what's this PR about, isn't it? The macros make the test fail if it does not throw or if it throws something different then expected. |
Well, what I'm mildly disputing is the code-path when the test throws an exception different than the expected one.
In my opinion, if the test throws anything else, it should end up in the same code path as any other test throwing an unexpected exception, namely |
@gahr the problem is that the text |
I see. It's true it would simplify the code. But on the other side, if someone writes tests for explicit testing of exception behavior, then it's imho likely better to not make the failure to abort rest of the test on the 1st failing check. |
That is fair enough, thanks for sharing you thoughts. |
@sakateka Please revert 9252107 .
|
This reverts commit 9252107.
I'm sorry, I wanted to make it better. |
No problem. I understand the learning curve can be nowadays steep, probably much steeper then in the time when I started to code. |
I tested it in run-time, and I do not like how the output looks like.
I guess that fixing all of those points would lead to even more complicated beast then the macros already are, and whether something much more simplistic (even though it provides less info) would not be sufficient in the practice: #define TEST_CHECK_EXC(code, exctype) \
do { \
bool exc_ok__ = false; \
try { \
code; \
} catch(const exctype&) { \
exc_ok__= true; \
} catch(...) { \
} \
\
test_check__(exc_ok__, __FILE__, __LINE__, #code " throws " #exctype); \
} while(0) Interested in your opinions. |
Maybe like this? #ifdef __cplusplus
#define TEST_CATCH_EXC(code, exctype) \
do { \
bool exc_ok__ = false; \
const char *msg = #code " throws " #exctype; \
try { \
code; \
} catch(const exctype &) { \
exc_ok__= true; \
} catch(...) { \
msg = #code " threw not " #exctype; \
} \
test_check__(exc_ok__, __FILE__, __LINE__, msg); \
} while(0)
#define TEST_CATCH_EXC_(code, exctype, fmt, ...) \
do { \
bool exc_ok__ = false; \
const char *alt_fmt = fmt; \
try { \
code; \
} catch(const exctype &) { \
exc_ok__= true; \
} catch(...) { \
alt_fmt = fmt " (threw not " #exctype ")"; \
} \
test_check__(exc_ok__, __FILE__, __LINE__, alt_fmt, __VA_ARGS__); \
} while(0)
#endif |
Well, almost. I would still keep the message for #define TEST_CATCH_EXC(code, exctype) \
do { \
bool exc_ok__ = false; \
const char *msg__ = NULL; \
try { \
code; \
msg__ = "No exception thrown."; \
} catch(const exctype &) { \
exc_ok__= true; \
} catch(...) { \
msg__ = "Unexpected exception thrown."; \
} \
test_check__(exc_ok__, __FILE__, __LINE__, #code " throws " #exctype); \
if(msg__ != NULL) \
test_message__("%s", msg__); \
} while(0) And similarly the other macro: That would just pass the custom message into |
|
Thanks. Merged. |
I made some changes to it.
|
I don't think this is a good idea. I would expect the API to take the exact type thrown, not the type you could use to bind it to a variable. What flexibility do you have in mind? |
It is uncommon, but this is still valid C++: void func()
{
const char* err = "foo";
throw err;
} Then it is natural to write: CHECK_EXCEPTION(func(), const char*); It would break if there is yet another |
How about changing the expansion to |
You want to take the type that is thrown |
Ohh yeah, that seems to be the solution. Thanks. |
No description provided.