Skip to content
Open
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
81 changes: 44 additions & 37 deletions include/tap++/tap++.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
#pragma warning( disable : 4290 ) // MSVC: https://msdn.microsoft.com/en-us/library/sa28fef8.aspx
#endif

#if __cplusplus >= 201103L
#define NOEXCEPT noexcept(true)
#else
#define NOEXCEPT throw()
#endif


namespace TAP {
namespace details {
struct skip_all_type {};
Expand All @@ -20,7 +27,7 @@ namespace TAP {

/* Return the variant of "Failed test" or "Failed */
/* (TODO) test" required by whether the current test is a todo test */
char const * failed_test_msg() throw();
char const * failed_test_msg() NOEXCEPT;
}
class fatal_exception : public std::exception {
std::string message;
Expand All @@ -30,64 +37,64 @@ namespace TAP {
const char* what() const throw() {
return message.c_str();
}
~fatal_exception() throw() {
~fatal_exception() NOEXCEPT {
}
};
extern const details::skip_all_type skip_all;
extern const details::no_plan_type no_plan;
void plan(unsigned) throw(fatal_exception);
void plan(const details::skip_all_type&, const std::string& = "") throw(fatal_exception);
void plan(const details::no_plan_type&) throw();
void done_testing() throw(fatal_exception);
void done_testing(unsigned) throw(fatal_exception);
void plan(unsigned);
void plan(const details::skip_all_type&, const std::string& = "");
void plan(const details::no_plan_type&) NOEXCEPT;
void done_testing();
void done_testing(unsigned);

unsigned planned() throw();
unsigned encountered() throw();
unsigned planned() NOEXCEPT;
unsigned encountered() NOEXCEPT;

bool ok(bool, const std::string& = "") throw();
bool not_ok(bool, const std::string& = "") throw();
bool ok(bool, const std::string& = "") NOEXCEPT;
bool not_ok(bool, const std::string& = "") NOEXCEPT;

bool pass(const std::string& = "") throw();
bool fail(const std::string& = "") throw();
bool pass(const std::string& = "") NOEXCEPT;
bool fail(const std::string& = "") NOEXCEPT;

void skip(unsigned, const std::string& = "") throw();
void bail_out(const std::string& reason) throw();
void skip(unsigned, const std::string& = "") NOEXCEPT;
void bail_out(const std::string& reason) NOEXCEPT;

int exit_status() throw();
bool summary() throw();
int exit_status() NOEXCEPT;
bool summary() NOEXCEPT;

void set_output(std::ostream&) throw(fatal_exception);
void set_error(std::ostream&) throw(fatal_exception);
void set_output(std::ostream&);
void set_error(std::ostream&);

template<typename T> void diag(const T& first) throw() {
template<typename T> void diag(const T& first) NOEXCEPT {
*details::error << "# " << first << std::endl;
}
template<typename T1, typename T2> void diag(const T1& first, const T2& second) throw() {
template<typename T1, typename T2> void diag(const T1& first, const T2& second) NOEXCEPT {
*details::error << "# " << first << second << std::endl;
}
template<typename T1, typename T2, typename T3> void diag(const T1& first, const T2& second, const T3& third) throw() {
template<typename T1, typename T2, typename T3> void diag(const T1& first, const T2& second, const T3& third) NOEXCEPT {
*details::error << "# " << first << second << third << std::endl;
}
template<typename T1, typename T2, typename T3, typename T4> void diag(const T1& first, const T2& second, const T3& third, const T4& fourth) throw() {
template<typename T1, typename T2, typename T3, typename T4> void diag(const T1& first, const T2& second, const T3& third, const T4& fourth) NOEXCEPT {
*details::error << "# " << first << second << third << fourth << std::endl;
}
template<typename T1, typename T2, typename T3, typename T4, typename T5> void diag(const T1& first, const T2& second, const T3& third, const T4& fourth, const T5& fifth) throw() {
template<typename T1, typename T2, typename T3, typename T4, typename T5> void diag(const T1& first, const T2& second, const T3& third, const T4& fourth, const T5& fifth) NOEXCEPT {
*details::error << "# " << first << second << third << fourth << fifth << std::endl;
}

template<typename T> void note(const T& first) throw() {
template<typename T> void note(const T& first) NOEXCEPT {
*details::output << "# " << first << std::endl;
}
template<typename T1, typename T2> void note(const T1& first, const T2& second) throw() {
template<typename T1, typename T2> void note(const T1& first, const T2& second) NOEXCEPT {
*details::output << "# " << first << second << std::endl;
}
template<typename T1, typename T2, typename T3> void note(const T1& first, const T2& second, const T3& third) throw() {
template<typename T1, typename T2, typename T3> void note(const T1& first, const T2& second, const T3& third) NOEXCEPT {
*details::output << "# " << first << second << third << std::endl;
}
template<typename T1, typename T2, typename T3, typename T4> void note(const T1& first, const T2& second, const T3& third, const T4& fourth) throw() {
template<typename T1, typename T2, typename T3, typename T4> void note(const T1& first, const T2& second, const T3& third, const T4& fourth) NOEXCEPT {
*details::output << "# " << first << second << third << fourth << std::endl;
}
template<typename T1, typename T2, typename T3, typename T4, typename T5> void note(const T1& first, const T2& second, const T3& third, const T4& fourth, const T5& fifth) throw() {
template<typename T1, typename T2, typename T3, typename T4, typename T5> void note(const T1& first, const T2& second, const T3& third, const T4& fourth, const T5& fifth) NOEXCEPT {
*details::output << "# " << first << second << third << fourth << fifth << std::endl;
}

Expand Down Expand Up @@ -246,8 +253,8 @@ namespace TAP {
class todo_guard {
const std::string value;
public:
todo_guard() throw();
~todo_guard() throw();
todo_guard() NOEXCEPT;
~todo_guard() NOEXCEPT;
};
}

Expand All @@ -257,22 +264,22 @@ namespace TAP {
namespace details {
struct Skip_exception {
const std::string reason;
Skip_exception(const std::string& _reason) throw() : reason(_reason) {
Skip_exception(const std::string& _reason) NOEXCEPT : reason(_reason) {
}
};
struct Todo_exception {
const std::string reason;
Todo_exception(const std::string& _reason) throw() : reason(_reason) {
Todo_exception(const std::string& _reason) NOEXCEPT : reason(_reason) {
}
};

void start_block(unsigned) throw();
unsigned stop_block() throw(fatal_exception);
void start_block(unsigned) NOEXCEPT;
unsigned stop_block();

}

void skip(const std::string& reason) throw(details::Skip_exception);
void skip_todo(const std::string& reason) throw(details::Todo_exception);
void skip(const std::string& reason);
void skip_todo(const std::string& reason);
}

#define TRY(action, name) do {\
Expand Down
58 changes: 29 additions & 29 deletions src/tap++.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace TAP {
unsigned counter = 0;
unsigned not_oks = 0;

std::string todo_test() throw() {
std::string todo_test() NOEXCEPT {
if (TODO == "") {
return TODO;
}
Expand All @@ -27,26 +27,26 @@ namespace TAP {
}
}

bool is_todo_test() throw() { return TODO != ""; }
bool is_todo_test() NOEXCEPT { return TODO != ""; }

bool is_planned = false;
bool no_planned = false;
bool has_output_plan = false;

void output_plan(unsigned tests, const std::string& extra = "") throw(fatal_exception) {
void output_plan(unsigned tests, const std::string& extra = "") {
if (has_output_plan) {
throw fatal_exception("Can't plan twice");
}
*details::output << "1.." << tests << extra << std::endl;
has_output_plan = true;
}
inline const std::string to_string(unsigned num) throw() {
inline const std::string to_string(unsigned num) NOEXCEPT {
std::stringstream out;
out << num;
return out.str();
}

inline void _done_testing(unsigned tests) throw(fatal_exception) {
inline void _done_testing(unsigned tests) {
static bool is_done = false;
if (is_done) {
fail("done_testing() was already called");
Expand All @@ -68,40 +68,40 @@ namespace TAP {

}

void plan(unsigned tests) throw(fatal_exception) {
void plan(unsigned tests) {
if (is_planned) {
bail_out("Can't plan again!");
}
is_planned = true;
output_plan(tests);
expected = tests;
}
void plan(const details::skip_all_type&, const std::string& reason) throw(fatal_exception) {
void plan(const details::skip_all_type&, const std::string& reason) {
output_plan(0, " #skip " + reason);
std::exit(0);
}
void plan(const details::no_plan_type&) throw() {
void plan(const details::no_plan_type&) NOEXCEPT {
is_planned = true;
no_planned = true;
}

void done_testing() throw(fatal_exception) {
void done_testing() {
_done_testing(encountered());
}

void done_testing(unsigned tests) throw(fatal_exception) {
void done_testing(unsigned tests) {
no_planned = false;
_done_testing(tests);
}

unsigned planned() throw() {
unsigned planned() NOEXCEPT {
return expected;
}
unsigned encountered() throw() {
unsigned encountered() NOEXCEPT {
return counter;
}

int exit_status() throw () {
int exit_status() NOEXCEPT {
// bool passing;
if (!is_planned && encountered()) {
diag("Tests were run but no plan was declared and done_testing() was not seen.");
Expand All @@ -117,80 +117,80 @@ namespace TAP {
return 255;
}
}
bool summary() throw() {
bool summary() NOEXCEPT {
return (not_oks != 0);
}

void bail_out(const std::string& reason) throw() {
void bail_out(const std::string& reason) NOEXCEPT {
*details::output << "Bail out! " << reason << std::endl;
std::exit(255); // Does not unwind stack!
}

bool ok(bool is_ok, const std::string& message) throw() {
bool ok(bool is_ok, const std::string& message) NOEXCEPT {
const char* hot_or_not = is_ok ? "" : "not ";
*details::output << hot_or_not << "ok " << ++counter<< " - " << message << todo_test() << std::endl;
if (!is_ok && !is_todo_test()) {
++not_oks;
}
return is_ok;
}
bool not_ok(bool is_not_ok, const std::string& message) throw() {
bool not_ok(bool is_not_ok, const std::string& message) NOEXCEPT {
return !ok(!is_not_ok, message);
}

bool pass(const std::string& message) throw() {
bool pass(const std::string& message) NOEXCEPT {
return ok(true, message);
}
bool fail(const std::string& message) throw() {
bool fail(const std::string& message) NOEXCEPT {
return ok(false, message);
}

void skip(unsigned num, const std::string& reason) throw () {
void skip(unsigned num, const std::string& reason) NOEXCEPT {
for(unsigned i = 0; i < num; ++i) {
pass(" # skip " + reason);
}
}

void set_output(std::ostream& new_output) throw (fatal_exception) {
void set_output(std::ostream& new_output) {
if (is_planned) {
throw fatal_exception("Can't set output after plan()");
}
details::output = &new_output;
}
void set_error(std::ostream& new_error) throw(fatal_exception) {
void set_error(std::ostream& new_error) {
if (is_planned) {
throw fatal_exception("Can't set error after plan()");
}
details::error = &new_error;
}
todo_guard::todo_guard() throw() : value(TODO) {
todo_guard::todo_guard() NOEXCEPT : value(TODO) {
}
todo_guard::~todo_guard() throw() {
todo_guard::~todo_guard() NOEXCEPT {
TODO = value;
}
namespace details {
std::ostream* output = &std::cout;
std::ostream* error = &std::cout;
static std::stack<unsigned> block_expected;
void start_block(unsigned expected) throw() {
void start_block(unsigned expected) NOEXCEPT {
block_expected.push(encountered() + expected);
}
unsigned stop_block() throw(fatal_exception) {
unsigned stop_block() {
unsigned ret = block_expected.top();
block_expected.pop();
return ret;
}

char const * failed_test_msg() throw() {
char const * failed_test_msg() NOEXCEPT {
return is_todo_test()?"Failed (TODO) test":"Failed test";
}

}

void skip(const std::string& reason) throw(details::Skip_exception) {
void skip(const std::string& reason) {
throw details::Skip_exception(reason);
}
void skip_todo(const std::string& reason) throw(details::Todo_exception) {
void skip_todo(const std::string& reason) {
throw details::Todo_exception(reason);
}

Expand Down