Skip to content
Snippets Groups Projects
Commit 7e73fa32 authored by Imdad Sardharwalla's avatar Imdad Sardharwalla Committed by GitHub Enterprise
Browse files

REFORM-1168 Create additional test macros and rename existing ones (#66)

parent 19c6cfaa
No related branches found
No related tags found
1 merge request!14Merge latest changes to Base from ReForm
......@@ -63,6 +63,7 @@ int collect(const int _argc, const char* const* _argv)
int framework_argc = _argc;
// The first argument is the process name
if (_argc > 0)
process_name_ = _argv[0];
for (int i = 1; i < _argc; i++)
......
......@@ -72,7 +72,7 @@ Condition condition;
}//Checksum
void check_condition(
void record_condition(
const char* const _cndt, const Base::CodeLink& _lnk, const bool _rslt)
{
TEST(condition, record(_cndt, _lnk, _rslt));
......
......@@ -43,18 +43,18 @@ extern Condition condition;
} // namespace Checksum
void check_condition(
void record_condition(
const char* const _cndt, const Base::CodeLink& _lnk, const bool _rslt);
} // namespace Test
// Write a Condition checksum to record the outcome of CONDITION.
#define CHECK_CONDITION(CONDITION) \
::Test::check_condition(#CONDITION, BASE_CODELINK, CONDITION)
#define TEST_CONDITION_RECORD(CONDITION) \
::Test::record_condition(#CONDITION, BASE_CODELINK, CONDITION)
#else // defined(TEST_ON)
#define CHECK_CONDITION(CONDITION)
#define TEST_CONDITION_RECORD(CONDITION)
#endif // defined(TEST_ON)
......
......@@ -26,61 +26,79 @@ void record_and_handle_unexpected(
TEST(outcome, record(_call, _oc.ok(), _oc.error_description().c_str()));
if (_unexpected)
_oc.handle_unexpected();
_oc.unexpected_handler();
}
} // namespace
Outcome::Outcome(bool _ok, const std::string& _error_code,
const std::string& _error_message,
const UnexpectedHandler& _unexpected_handler)
: ok_(_ok), error_code_(_error_code), error_message_(_error_message),
unexpected_handler_(_unexpected_handler)
Outcome::Outcome() : ok_(true), error_code_("0"), error_message_("Success") {}
Outcome::Outcome(
bool _ok, const std::string& _error_code, const std::string& _error_message)
: ok_(_ok), error_code_(_error_code), error_message_(_error_message)
{
}
Outcome::Outcome(bool _ok, const int _error_code,
const std::string& _error_message,
const UnexpectedHandler& _unexpected_handler)
Outcome::Outcome(
bool _ok, const int _error_code, const std::string& _error_message)
: ok_(_ok), error_code_(std::to_string(_error_code)),
error_message_(_error_message), unexpected_handler_(_unexpected_handler)
error_message_(_error_message)
{
}
const std::string Outcome::error_description() const
{
return ok() ? error_message() : "[" + error_code() + "] " + error_message();
}
void ignore_unstable_outcome(const char* const _call)
Outcome::UnexpectedHandler Outcome::unexpected_handler = []
{
TEST_THROW_ERROR(TEST_OUTCOME_UNEXPECTED);
};
const Outcome& record_outcome(const char* const _call, const Outcome& _oc)
{
std::cout
<< "-----------------------\n"
"Info: Unstable outcome from the following call has been ignored:"
"\n\n " << _call << "\n\n"
"Replace IGNORE_UNSTABLE_OUTCOME() with CHECK_OUTCOME() once "
"the functionality is stable.\n"
"-----------------------"
<< std::endl;
// Never call unexpected-outcome handler
record_and_handle_unexpected(_call, _oc, false);
return _oc;
}
void check_outcome(const char* const _call, const Outcome& _oc)
void expect_success(const char* const _call, const Outcome& _oc)
{
// Call unexpected-outcome handler if the call *failed*
record_and_handle_unexpected(_call, _oc, !_oc.ok());
}
void expect_failed_outcome(
void expect_outcome(
const char* const _call, const Outcome& _oc, const char* const _error_code)
{
// Call unexpected-outcome handler if the error code is not correct
record_and_handle_unexpected(_call, _oc, _oc.error_code() != _error_code);
}
void expect_outcome(
const char* const _call, const Outcome& _oc, const int _error_code)
{
expect_outcome(_call, _oc, std::to_string(_error_code).c_str());
}
void expect_failure(const char* const _call, const Outcome& _oc)
{
// If _oc represents a failure, replace it with a generic failure outcome
auto oc = _oc.ok() ? _oc : Outcome(_oc.ok(), "FAILURE", "Failure");
// Call unexpected-outcome handler if the call *succeeds*
record_and_handle_unexpected(_call, _oc, _oc.ok());
record_and_handle_unexpected(_call, oc, oc.ok());
}
const Outcome::UnexpectedHandler Outcome::default_unexpected_handler = []
void ignore_outcome(const char* const _call, const char* const _reason)
{
TEST_THROW_ERROR(TEST_OUTCOME_UNEXPECTED);
};
// Write an "Ignored Outcome" checksum to the report
const auto message = std::string("[IGNORED] ") + _reason;
record_outcome(_call, Outcome(true, "", message.c_str()));
}
// Pass-through function for Test::Outcome
TEST_OUTCOME_ADD_TYPE(Test::Outcome) { return _oc; }
} // namespace Test
......
......@@ -10,32 +10,55 @@
#include <functional>
#include <string>
// If CALL is unstable on different platforms/architectures (it fails on some
// platforms/architectures but not others), use IGNORE_UNSTABLE_OUTCOME(CALL)
// instead of CHECK_OUTCOME(CALL). This will prevent an unstable checksum being
// written for CALL and will write to stdout to note that this is happening.
#define IGNORE_UNSTABLE_OUTCOME(CALL) \
(CALL); \
::Test::ignore_unstable_outcome(#CALL)
// Write an Outcome checksum to record the outcome of CALL. Returns the outcome.
#define TEST_OUTCOME_RECORD(CALL) \
::Test::record_outcome(#CALL, ::Test::Outcome::make(CALL))
// If CALL *fails*, exit the current function and return the outcome.
#define TEST_OUTCOME_RETURN(CALL) \
{ \
const auto oc = ::Test::Outcome::make(CALL); \
if (!oc.ok()) \
return oc; \
}
// Write an Outcome checksum to record the outcome of CALL. If CALL *fails*,
// exit the current function and return the outcome.
#define TEST_OUTCOME_RECORD_AND_RETURN(CALL) \
{ \
const auto oc = TEST_OUTCOME_RECORD(CALL); \
if (!oc.ok()) \
return oc; \
}
// Write an Outcome checksum to record the outcome of CALL. An
// unexpected-outcome handler is called if CALL *fails*.
#define CHECK_OUTCOME(CALL) \
::Test::check_outcome(#CALL, ::Test::Outcome::make(CALL))
#define TEST_OUTCOME_SUCCESS(CALL) \
::Test::expect_success(#CALL, ::Test::Outcome::make(CALL))
// Write an Outcome checksum to record the outcome of CALL. An
// unexpected-outcome handler is called if the error code associated with the
// outcome is not equal to ERROR_CODE. This is intended to be used for failures
// that occur by design.
#define EXPECT_FAILED_OUTCOME(ERROR_CODE, CALL) \
::Test::expect_failed_outcome(#CALL, ::Test::Outcome::make(CALL), #ERROR_CODE)
// outcome is not equal to ERROR_CODE.
#define TEST_OUTCOME_EXPECT(CALL, ERROR_CODE) \
::Test::expect_outcome(#CALL, ::Test::Outcome::make(CALL), ERROR_CODE)
// Write an Outcome checksum to record the outcome of CALL. An
// unexpected-outcome handler is called if CALL *succeeds*. This is intended to
// be used for failures that are caused by a known (but unresolved) bug.
#define EXPECT_FAILURE(CALL) \
// Write a success/failure Outcome checksum to record the outcome of CALL. An
// unexpected-outcome handler is called if CALL *succeeds*.
#define TEST_OUTCOME_FAILURE(CALL) \
::Test::expect_failure(#CALL, ::Test::Outcome::make(CALL))
// Write an Outcome checksum to record that the outcome of CALL was ignored and
// the REASON why.
#define TEST_OUTCOME_IGNORE(CALL, REASON) \
(CALL); \
::Test::ignore_outcome(#CALL, REASON)
// Write an Outcome checksum to record that the outcome of CALL was ignored and
// that it is unstable (i.e. gives different outcomes on different
// platforms/architectures).
#define TEST_OUTCOME_IGNORE_UNSTABLE(CALL) \
TEST_OUTCOME_IGNORE(CALL, "Unstable outcome")
/* Use the following macro to add a new outcome type. It defines a
* specialisation for Test::Outcome::make<TYPE>(const TYPE& _oc), and must
* return a Test::Outcome object.
......@@ -65,36 +88,37 @@ namespace Test
/* A generic outcome class that is intended to be a wrapper for all other
* outcome classes. It has the following member functions:
*
* - make<T>(): Creates an Outcome object from an object of type T. A
* template specialisation should be added for each T
* - constructor: Calling the constructor with no arguments creates a
* successful outcome.
*
* - make<T>(): Creates an Outcome object from an object of type T.
* A template specialisation should be added for each T
* that is required by the consuming project (see
* TEST_OUTCOME_ADD_TYPE() macro).
*
* - ok(): Returns whether the outcome was a success;
* - ok(): Returns whether the outcome was a success.
*
* - error_code(): Returns the associated error code as a std::string&;
* - error_code(): Returns the associated error code as a std::string&.
*
* - error_message(): Returns the associated error message;
* - error_message(): Returns the associated error message.
*
* - error_description(): Returns a concatenation of the error code and error
* message;
* message.
*
* - handle_unexpected(): A function that can be called if the outcome is not
* what was expected.
* It also contains the static variable unexpected_handler, a std::function that
* can be called if the outcome is not what was expected.
*/
class Outcome
{
public:
typedef std::function<void()> UnexpectedHandler;
Outcome(); // Construct successful outcome
Outcome(bool _ok, const std::string& _error_code,
const std::string& _error_message,
const UnexpectedHandler& _unexpected_handler =
default_unexpected_handler);
const std::string& _error_message);
Outcome(bool _ok, const int _error_code, const std::string& _error_message,
const UnexpectedHandler& _unexpected_handler =
default_unexpected_handler);
Outcome(bool _ok, const int _error_code, const std::string& _error_message);
template <class T> static Outcome make(const T& _oc);
......@@ -104,31 +128,31 @@ public:
const std::string& error_message() const { return error_message_; }
const std::string error_description() const
{
return ok() ? error_message() : "[" + error_code() + "] " + error_message();
}
void handle_unexpected() const { unexpected_handler_(); }
const std::string error_description() const;
static const UnexpectedHandler default_unexpected_handler;
static UnexpectedHandler unexpected_handler;
private:
bool ok_;
std::string error_code_;
std::string error_message_;
UnexpectedHandler unexpected_handler_;
};
void ignore_unstable_outcome(const char* const _call);
const Outcome& record_outcome(const char* const _call, const Outcome& _oc);
void check_outcome(const char* const _call, const Outcome& _oc);
void expect_success(const char* const _call, const Outcome& _oc);
void expect_failed_outcome(
void expect_outcome(
const char* const _call, const Outcome& _oc, const char* const _error_code);
void expect_outcome(
const char* const _call, const Outcome& _oc, const int _error_code);
void expect_failure(const char* const _call, const Outcome& _oc);
void ignore_outcome(const char* const _call, const char* const _reason);
} // namespace Test
#endif // TEST_ON
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment