From 78c87b848cef516dea46994c6cd8226013422859 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Wed, 26 Jun 2019 21:14:55 +0300 Subject: [PATCH] Added API in lightweight_test to obtain the number of test failures. The new API allows to check if the number of check failures satisfies a certain condition. The report_errors function returns test_report, which allows to obtain the error count. It also protects against unintended comparisons to the error count, which was a misconception before. Also added a get_error_count function to explicitly query for the current number of errors. --- doc/lightweight_test.qbk | 45 +++++++++++++++++-- include/boost/core/lightweight_test.hpp | 57 +++++++++++++++++++++++-- test/Jamfile.v2 | 4 +- test/lightweight_test_all_eq_test.cpp | 2 +- test/lightweight_test_all_with_fail.cpp | 2 +- test/lightweight_test_test5.cpp | 2 +- 6 files changed, 101 insertions(+), 11 deletions(-) diff --git a/doc/lightweight_test.qbk b/doc/lightweight_test.qbk index 4c1fa9d..bc24d5e 100644 --- a/doc/lightweight_test.qbk +++ b/doc/lightweight_test.qbk @@ -49,7 +49,9 @@ When using `lightweight_test.hpp`, *do not forget* to namespace boost { - int report_errors(); + class test_report; + int get_error_count(); + test_report report_errors(); } `` @@ -212,10 +214,47 @@ nothing and `expr` is not evaluated. [section report_errors] `` -int boost::report_errors() +boost::test_report boost::report_errors() `` -Return the error count from `main`. +Returns the test report. The report can be converted to an `int` to be returned from `main`. + +[endsect] + +[section test_report] + +`` +class test_report +{ +public: + int error_count() const noexcept; + operator int() const noexcept; +}; +`` + +Contains information about test results. + +`` +int test_report::error_count() const noexcept; +`` + +The method returns the number of failed checks. + +`` +test_report::operator int() const noexcept; +`` + +Returns 0 if there are no failed checks and 1 otherwise. This operator is suitable for obtaining result code to return from `main`. + +[endsect] + +[section get_error_count] + +`` +int boost::get_error_count(); +`` + +Returns the number of failed checks. [endsect] diff --git a/include/boost/core/lightweight_test.hpp b/include/boost/core/lightweight_test.hpp index 468c2ff..4e2c386 100644 --- a/include/boost/core/lightweight_test.hpp +++ b/include/boost/core/lightweight_test.hpp @@ -373,7 +373,58 @@ void test_all_with_impl(FormattedOutputFunction& output, } // namespace detail -inline int report_errors() +//! Testing report +class test_report +{ +private: + int m_error_count; + +public: + explicit test_report(int error_count) BOOST_NOEXCEPT : + m_error_count(error_count) + { + } + + //! Returns the number of test errors + int error_count() const BOOST_NOEXCEPT { return m_error_count; } + + //! Operator for converting to result of main() + operator int () const BOOST_NOEXCEPT { return m_error_count > 0 ? 1 : 0; } + + // Protection against comparing report_errors() with the number of errors. Earlier versions of report_errors() did not return + // the number of errors, so such comparisons used to give a wrong result and now cause a hard compile time error. + // Call report_errors().error_count() if you need to check the error count, but make sure you return the correct value from main(). + BOOST_DELETED_FUNCTION(bool operator== (int)) + BOOST_DELETED_FUNCTION(bool operator!= (int)) + BOOST_DELETED_FUNCTION(bool operator< (int)) + BOOST_DELETED_FUNCTION(bool operator> (int)) + BOOST_DELETED_FUNCTION(bool operator>= (int)) + BOOST_DELETED_FUNCTION(bool operator<= (int)) +}; + +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +#define BOOST_LIGHTWEIGHT_TEST_DELETED_FUNCTION_MARK = delete +#else +#define BOOST_LIGHTWEIGHT_TEST_DELETED_FUNCTION_MARK +#endif + +bool operator== (int, test_report const&) BOOST_LIGHTWEIGHT_TEST_DELETED_FUNCTION_MARK; +bool operator!= (int, test_report const&) BOOST_LIGHTWEIGHT_TEST_DELETED_FUNCTION_MARK; +bool operator< (int, test_report const&) BOOST_LIGHTWEIGHT_TEST_DELETED_FUNCTION_MARK; +bool operator> (int, test_report const&) BOOST_LIGHTWEIGHT_TEST_DELETED_FUNCTION_MARK; +bool operator<= (int, test_report const&) BOOST_LIGHTWEIGHT_TEST_DELETED_FUNCTION_MARK; +bool operator>= (int, test_report const&) BOOST_LIGHTWEIGHT_TEST_DELETED_FUNCTION_MARK; + +#undef BOOST_LIGHTWEIGHT_TEST_DELETED_FUNCTION_MARK + +//! Returns the number of test errors encountered +inline int get_error_count() BOOST_NOEXCEPT +{ + return boost::detail::test_results().errors(); +} + +//! Prints the number of test errors and returns test report suitable for returning from main() +inline test_report report_errors() { boost::detail::test_result& result = boost::detail::test_results(); result.done(); @@ -383,14 +434,14 @@ inline int report_errors() { BOOST_LIGHTWEIGHT_TEST_OSTREAM << "No errors detected." << std::endl; - return 0; } else { BOOST_LIGHTWEIGHT_TEST_OSTREAM << errors << " error" << (errors == 1? "": "s") << " detected." << std::endl; - return 1; } + + return test_report(errors); } } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 68e5f64..f703677 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -77,8 +77,8 @@ run lightweight_test_test3.cpp ; run lightweight_test_test4.cpp ; run lightweight_test_test5.cpp ; -run-fail lightweight_test_all_eq_test.cpp ; -run-fail lightweight_test_all_with_fail.cpp ; +run lightweight_test_all_eq_test.cpp ; +run lightweight_test_all_with_fail.cpp ; run-fail lightweight_test_fail.cpp ; run-fail lightweight_test_fail2.cpp ; diff --git a/test/lightweight_test_all_eq_test.cpp b/test/lightweight_test_all_eq_test.cpp index 46254e7..c325c2a 100644 --- a/test/lightweight_test_all_eq_test.cpp +++ b/test/lightweight_test_all_eq_test.cpp @@ -120,5 +120,5 @@ int main() ++test_cases; } - return boost::report_errors() == test_cases; + return boost::report_errors().error_count() == test_cases ? 0 : 1; } diff --git a/test/lightweight_test_all_with_fail.cpp b/test/lightweight_test_all_with_fail.cpp index 9a4a429..4fc5c4a 100644 --- a/test/lightweight_test_all_with_fail.cpp +++ b/test/lightweight_test_all_with_fail.cpp @@ -101,5 +101,5 @@ int main() test_cases += fail_vector(); test_cases += fail_tolerance_predicate(); - return boost::report_errors() == test_cases; + return boost::report_errors().error_count() == test_cases ? 0 : 1; } diff --git a/test/lightweight_test_test5.cpp b/test/lightweight_test_test5.cpp index fb3e0ac..d19fde5 100644 --- a/test/lightweight_test_test5.cpp +++ b/test/lightweight_test_test5.cpp @@ -64,5 +64,5 @@ int main() #endif - return boost::report_errors() == expected; + return boost::report_errors().error_count() == expected ? 0 : 1; }