Implemented ASSERT macro
This commit is contained in:
parent
9572cf9ea7
commit
cce24dd64b
1
assert/AssertFailed.cpp
Normal file
1
assert/AssertFailed.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "AssertFailed.h"
|
23
assert/AssertFailed.h
Normal file
23
assert/AssertFailed.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CPP_UTILS_ASSERT_ASSERTFAILED_H
|
||||
#define MESSMER_CPP_UTILS_ASSERT_ASSERTFAILED_H
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace cpputils {
|
||||
|
||||
class AssertFailed : public std::exception {
|
||||
public:
|
||||
AssertFailed(const std::string &message) : _message(message) { }
|
||||
|
||||
const char *what() const throw() override {
|
||||
return _message.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string _message;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
39
assert/assert.h
Normal file
39
assert/assert.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CPP_UTILS_ASSERT_ASSERT_H
|
||||
#define MESSMER_CPP_UTILS_ASSERT_ASSERT_H
|
||||
|
||||
/**
|
||||
* This implements an ASSERT(expr, msg) macro.
|
||||
* In a debug build, it will crash and halt the program on an assert failure.
|
||||
* In a release build, it will throw an AssertFailed exception instead, which can then be caught.
|
||||
*/
|
||||
|
||||
#include "AssertFailed.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace cpputils {
|
||||
namespace _assert {
|
||||
inline std::string format(const char *expr, const char *message, const char *file, int line) {
|
||||
return std::string()+"Assertion ["+expr+"] failed in "+file+":"+std::to_string(line)+": "+message;
|
||||
}
|
||||
|
||||
inline void assert_fail_release(const char *expr, const char *message, const char *file, int line) {
|
||||
throw AssertFailed(format(expr, message, file, line));
|
||||
}
|
||||
|
||||
inline void assert_fail_debug(const char *expr, const char *message, const char *file, int line) {
|
||||
std::cerr << format(expr, message, file, line) << std::endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
//TODO Check whether disabling assertions in prod affects speed.
|
||||
# define ASSERT(expr, msg) (void)((expr) || (cpputils::_assert::assert_fail_release(#expr, msg, __FILE__, __LINE__),0))
|
||||
#else
|
||||
# define ASSERT(expr, msg) (void)((expr) || (cpputils::_assert::assert_fail_debug(#expr, msg, __FILE__, __LINE__),0))
|
||||
#endif
|
||||
|
||||
#endif
|
@ -6,6 +6,7 @@
|
||||
#include <cryptopp/cryptopp/osrng.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include "../assert/assert.h"
|
||||
|
||||
namespace cpputils {
|
||||
|
||||
@ -67,7 +68,7 @@ FixedSizeData<SIZE> FixedSizeData<SIZE>::CreateOSRandom() {
|
||||
|
||||
template<unsigned int SIZE>
|
||||
FixedSizeData<SIZE> FixedSizeData<SIZE>::FromString(const std::string &data) {
|
||||
assert(data.size() == STRING_LENGTH);
|
||||
ASSERT(data.size() == STRING_LENGTH, "Wrong string size for parsing FixedSizeData");
|
||||
FixedSizeData<SIZE> result;
|
||||
CryptoPP::StringSource(data, true,
|
||||
new CryptoPP::HexDecoder(
|
||||
@ -85,7 +86,7 @@ std::string FixedSizeData<SIZE>::ToString() const {
|
||||
new CryptoPP::StringSink(result)
|
||||
)
|
||||
);
|
||||
assert(result.size() == STRING_LENGTH);
|
||||
ASSERT(result.size() == STRING_LENGTH, "Created wrongly sized string");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
26
test/assert/assert_debug_test.cpp
Normal file
26
test/assert/assert_debug_test.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include <google/gtest/gtest.h>
|
||||
#include <google/gmock/gmock.h>
|
||||
|
||||
//Include the ASSERT macro for a debug build
|
||||
#undef NDEBUG
|
||||
#include "../../assert/assert.h"
|
||||
|
||||
using testing::MatchesRegex;
|
||||
|
||||
TEST(AssertTest_DebugBuild, DoesntDieIfTrue) {
|
||||
ASSERT(true, "bla");
|
||||
}
|
||||
|
||||
TEST(AssertTest_DebugBuild, DiesIfFalse) {
|
||||
EXPECT_DEATH(
|
||||
ASSERT(false, "bla"),
|
||||
""
|
||||
);
|
||||
}
|
||||
|
||||
TEST(AssertTest_DebugBuild, AssertMessage) {
|
||||
EXPECT_DEATH(
|
||||
ASSERT(2==5, "my message"),
|
||||
"Assertion \\[2==5\\] failed in .*/assert_debug_test.cpp:25: my message"
|
||||
);
|
||||
}
|
30
test/assert/assert_release_test.cpp
Normal file
30
test/assert/assert_release_test.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include <google/gtest/gtest.h>
|
||||
#include <google/gmock/gmock.h>
|
||||
|
||||
//Include the ASSERT macro for a release build
|
||||
#define NDEBUG
|
||||
#include "../../assert/assert.h"
|
||||
|
||||
using testing::MatchesRegex;
|
||||
|
||||
TEST(AssertTest_ReleaseBuild, DoesntThrowIfTrue) {
|
||||
ASSERT(true, "bla");
|
||||
}
|
||||
|
||||
TEST(AssertTest_ReleaseBuild, ThrowsIfFalse) {
|
||||
EXPECT_THROW(
|
||||
ASSERT(false, "bla"),
|
||||
cpputils::AssertFailed
|
||||
);
|
||||
}
|
||||
|
||||
TEST(AssertTest_ReleaseBuild, AssertMessage) {
|
||||
try {
|
||||
ASSERT(2==5, "my message");
|
||||
FAIL();
|
||||
} catch (const cpputils::AssertFailed &e) {
|
||||
EXPECT_THAT(e.what(), MatchesRegex(
|
||||
"Assertion \\[2==5\\] failed in .*/assert_release_test.cpp:23: my message"
|
||||
));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user