diff options
author | Andrei Karas <akaras@inbox.ru> | 2017-08-29 04:08:27 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2017-08-29 04:08:27 +0300 |
commit | 5fa6db36789bcf49fad5cd6b75d4f2e831dc41ab (patch) | |
tree | b2f9eb3a47c06397a7594e80d8d791d8548c2c6f | |
parent | 33eb02117105d3fd3b9f78a137e199ef58d14d9c (diff) | |
download | plus-5fa6db36789bcf49fad5cd6b75d4f2e831dc41ab.tar.gz plus-5fa6db36789bcf49fad5cd6b75d4f2e831dc41ab.tar.bz2 plus-5fa6db36789bcf49fad5cd6b75d4f2e831dc41ab.tar.xz plus-5fa6db36789bcf49fad5cd6b75d4f2e831dc41ab.zip |
Update doctest from dev branch.
-rw-r--r-- | src/unittests/doctest.h | 275 |
1 files changed, 96 insertions, 179 deletions
diff --git a/src/unittests/doctest.h b/src/unittests/doctest.h index 695c271b5..10ecf5158 100644 --- a/src/unittests/doctest.h +++ b/src/unittests/doctest.h @@ -465,6 +465,11 @@ namespace std #endif // DOCTEST_CONFIG_WITH_NULLPTR #ifndef DOCTEST_CONFIG_DISABLE + +#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS +#include <type_traits> +#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + namespace doctest { namespace detail @@ -572,10 +577,12 @@ public: // GCC 4.9/5/6 report Wstrict-overflow when optimizations are ON and it got inlined in the vector class somewhere... // see commit 574ef95f0cd379118be5011704664e4b5351f1e0 and build https://travis-ci.org/onqtam/doctest/builds/230671611 DOCTEST_NOINLINE String& operator=(const String& other) { - if(!isOnStack()) - delete[] data.ptr; + if(this != &other) { + if(!isOnStack()) + delete[] data.ptr; - copy(other); + copy(other); + } return *this; } @@ -649,123 +656,13 @@ namespace detail } // namespace static_assert_impl #endif // DOCTEST_CONFIG_WITH_STATIC_ASSERT - namespace traits - { - template <typename T> - struct remove_const - { typedef T type; }; - - template <typename T> - struct remove_const<const T> - { typedef T type; }; - - template <typename T> - struct remove_volatile - { typedef T type; }; - - template <typename T> - struct remove_volatile<volatile T> - { typedef T type; }; - - template <typename T> - struct remove_cv - { typedef typename remove_volatile<typename remove_const<T>::type>::type type; }; - - template <typename T> - struct is_pointer_helper - { static const bool value = false; }; - - template <typename T> - struct is_pointer_helper<T*> - // cppcheck-suppress unusedStructMember - { static const bool value = true; }; - - template <typename T> - struct is_pointer - // cppcheck-suppress unusedStructMember - { static const bool value = is_pointer_helper<typename remove_cv<T>::type>::value; }; - - template <bool CONDITION, typename TYPE = void> - struct enable_if - {}; - - template <typename TYPE> - struct enable_if<true, TYPE> - { typedef TYPE type; }; - - template <typename T> - struct remove_reference - { typedef T type; }; - - template <typename T> - struct remove_reference<T&> - { typedef T type; }; - - template <typename T, typename AT_1 = void> - class is_constructible_impl - { - private: - template <typename C_T, typename C_AT_1> - static bool test(typename enable_if< //!OCLINT avoid private static members - sizeof(C_T) == - sizeof(C_T(static_cast<C_AT_1>( - *static_cast<typename remove_reference<C_AT_1>::type*>( - 0))))>::type*); - - template <typename, typename> - static int test(...); //!OCLINT avoid private static members - - public: - static const bool value = sizeof(test<T, AT_1>(0)) == sizeof(bool); - }; - - template <typename T> - class is_constructible_impl<T, void> - { - private: - template <typename C_T> - static C_T testFun(C_T); //!OCLINT avoid private static members - - template <typename C_T> - static bool test(typename enable_if< //!OCLINT avoid private static members - sizeof(C_T) == sizeof(testFun(C_T()))>::type*); - - template <typename> - static int test(...); //!OCLINT avoid private static members - - public: - static const bool value = sizeof(test<T>(0)) == sizeof(bool); - }; + template <bool CONDITION, typename TYPE = void> + struct enable_if + {}; -// is_constructible<> taken from here: http://stackoverflow.com/a/40443701/3162383 -// for GCC/Clang gives the same results as std::is_constructible<> - see here: https://wandbox.org/permlink/bNWr7Ii2fuz4Vf7A -// modifications: -// - reworked to support only 1 argument (mainly because of MSVC...) -// - removed pointer support -// MSVC support: -// - for versions before 2012 read the CAUTION comment below -// currently intended for use only in the Approx() helper for strong typedefs of double - see issue #62 -#ifndef _MSC_VER - template <typename T, typename AT_1 = void> - class is_constructible - { - public: - static const bool value = is_pointer<typename remove_reference<T>::type>::value ? - false : - is_constructible_impl<T, AT_1>::value; - }; -#elif defined(_MSC_VER) && (_MSC_VER >= 1700) - template <typename T, typename AT_1> - struct is_constructible - { static const bool value = __is_constructible(T, AT_1); }; -#elif defined(_MSC_VER) - // !!! USE WITH CAUTION !!! - // will always return false - unable to implement this for versions of MSVC older than 2012 for now... - template <typename T, typename AT_1> - struct is_constructible - { static const bool value = false; }; -#endif // _MSC_VER - } // namespace traits + template <typename TYPE> + struct enable_if<true, TYPE> + { typedef TYPE type; }; template <typename T> struct deferred_false @@ -1016,13 +913,14 @@ public: return approx; } +#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS template <typename T> explicit Approx(const T& value, - typename detail::traits::enable_if< - detail::traits::is_constructible<double, T>::value>::type* = + typename detail::enable_if<std::is_constructible<double, T>::value>::type* = static_cast<T*>(detail::getNull())) { *this = Approx(static_cast<double>(value)); } +#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS // clang-format off // overloads for double - the first one is necessary as it is in the implementation part of doctest @@ -1040,8 +938,9 @@ public: friend bool operator> (double lhs, Approx const& rhs) { return lhs > rhs.m_value && lhs != rhs; } friend bool operator> (Approx const& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; } +#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS #define DOCTEST_APPROX_PREFIX \ - template <typename T> friend typename detail::traits::enable_if<detail::traits::is_constructible<double, T>::value, bool>::type + template <typename T> friend typename detail::enable_if<std::is_constructible<double, T>::value, bool>::type DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(double(lhs), rhs); } DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); } @@ -1056,33 +955,37 @@ public: DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value && lhs != rhs; } DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) && lhs != rhs; } #undef DOCTEST_APPROX_PREFIX +#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + // clang-format on Approx& epsilon(double newEpsilon) { - m_epsilon = (newEpsilon); + m_epsilon = newEpsilon; return *this; } +#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS template <typename T> - typename detail::traits::enable_if<detail::traits::is_constructible<double, T>::value, - Approx&>::type - epsilon(const T& newEpsilon) { + typename detail::enable_if<std::is_constructible<double, T>::value, Approx&>::type epsilon( + const T& newEpsilon) { m_epsilon = static_cast<double>(newEpsilon); return *this; } +#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS Approx& scale(double newScale) { - m_scale = (newScale); + m_scale = newScale; return *this; } +#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS template <typename T> - typename detail::traits::enable_if<detail::traits::is_constructible<double, T>::value, - Approx&>::type - scale(const T& newScale) { + typename detail::enable_if<std::is_constructible<double, T>::value, Approx&>::type scale( + const T& newScale) { m_scale = static_cast<double>(newScale); return *this; } +#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS String toString() const; @@ -1367,7 +1270,7 @@ namespace detail #ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING #define DOCTEST_COMPARISON_RETURN_TYPE bool #else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_COMPARISON_RETURN_TYPE typename traits::enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type +#define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); } inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); } inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); } @@ -1728,9 +1631,9 @@ namespace detail return res; } - struct DOCTEST_INTERFACE IExceptionTranslator //!OCLINT destructor of virtual class + struct DOCTEST_INTERFACE IExceptionTranslator { - virtual ~IExceptionTranslator(); + virtual ~IExceptionTranslator() {} virtual bool translate(String&) const = 0; }; @@ -1823,8 +1726,11 @@ namespace detail DOCTEST_INTERFACE void toStream(std::ostream* stream, int long long unsigned in); #endif // DOCTEST_CONFIG_WITH_LONG_LONG - struct IContextScope //!OCLINT destructor of virtual class - { virtual void build(std::ostream*) = 0; }; + struct IContextScope + { + virtual ~IContextScope() {} + virtual void build(std::ostream*) = 0; + }; DOCTEST_INTERFACE void addToContexts(IContextScope* ptr); DOCTEST_INTERFACE void popFromContexts(); @@ -1835,8 +1741,11 @@ namespace detail { friend class ContextScope; - struct ICapture //!OCLINT destructor of virtual class - { virtual void toStream(std::ostream*) const = 0; }; + struct ICapture + { + virtual ~ICapture() {} + virtual void toStream(std::ostream*) const = 0; + }; template <typename T> struct Capture : ICapture //!OCLINT destructor of virtual class @@ -1846,7 +1755,7 @@ namespace detail explicit Capture(const T* in) : capture(in) {} virtual void toStream(std::ostream* stream) const { // override - doctest::detail::toStream(stream, *capture); + detail::toStream(stream, *capture); } }; @@ -1892,6 +1801,8 @@ namespace detail unsigned(int(sizeof(Chunk)) * DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK)); } + ContextBuilder& operator=(const ContextBuilder&); // NOLINT + public: // cppcheck-suppress uninitMemberVar DOCTEST_NOINLINE ContextBuilder() // NOLINT @@ -1945,7 +1856,7 @@ namespace detail #endif // DOCTEST_CONFIG_WITH_RVALUE_REFERENCES }; - class ContextScope : public IContextScope //!OCLINT destructor of virtual class + class ContextScope : public IContextScope { ContextBuilder contextBuilder; bool built; @@ -1971,18 +1882,18 @@ namespace detail class DOCTEST_INTERFACE MessageBuilder { - std::ostream* m_stream; - const char* m_file; - int m_line; - doctest::detail::assertType::Enum m_severity; + std::ostream* m_stream; + const char* m_file; + int m_line; + assertType::Enum m_severity; public: - MessageBuilder(const char* file, int line, doctest::detail::assertType::Enum severity); + MessageBuilder(const char* file, int line, assertType::Enum severity); ~MessageBuilder(); template <typename T> MessageBuilder& operator<<(const T& in) { - doctest::detail::toStream(m_stream, in); + toStream(m_stream, in); return *this; } @@ -2456,7 +2367,7 @@ constexpr T to_lvalue = x; DOCTEST_TOSTR(DOCTEST_HANDLE_BRACED_VA_ARGS(as))); \ try { \ expr; \ - } catch(DOCTEST_HANDLE_BRACED_VA_ARGS(as)) { \ + } catch(const DOCTEST_HANDLE_BRACED_VA_ARGS(as)&) { \ _DOCTEST_RB.m_threw = true; \ _DOCTEST_RB.m_threw_as = true; \ } catch(...) { _DOCTEST_RB.unexpectedExceptionOccurred(); } \ @@ -3284,7 +3195,7 @@ namespace detail #define DOCTEST_LOG_START() \ do { \ if(!contextState->hasLoggedCurrentTestStart) { \ - doctest::detail::logTestStart(*contextState->currentTest); \ + logTestStart(*contextState->currentTest); \ contextState->hasLoggedCurrentTestStart = true; \ } \ } while(false) @@ -3329,7 +3240,7 @@ namespace detail // case insensitive strcmp int stricmp(char const* a, char const* b) { for(;; a++, b++) { - int d = tolower(*a) - tolower(*b); + const int d = tolower(*a) - tolower(*b); if(d != 0 || !*a) return d; } @@ -3516,9 +3427,9 @@ String::String(const char* in) { } String& String::operator+=(const String& other) { - unsigned my_old_size = size(); - unsigned other_size = other.size(); - unsigned total_size = my_old_size + other_size; + const unsigned my_old_size = size(); + const unsigned other_size = other.size(); + const unsigned total_size = my_old_size + other_size; if(isOnStack()) { if(total_size < len) { // append to the current stack space @@ -3572,11 +3483,13 @@ String::String(String&& other) { } String& String::operator=(String&& other) { - if(!isOnStack()) - delete[] data.ptr; - detail::my_memcpy(buf, other.buf, len); - other.buf[0] = '\0'; - other.setLast(); + if(this != &other) { + if(!isOnStack()) + delete[] data.ptr; + detail::my_memcpy(buf, other.buf, len); + other.buf[0] = '\0'; + other.setLast(); + } return *this; } #endif // DOCTEST_CONFIG_WITH_RVALUE_REFERENCES @@ -3719,7 +3632,7 @@ int Context::run() { return 0; } #define DOCTEST_PRINTF_COLORED(buffer, color) \ do { \ - doctest::detail::Color col(color); \ + Color col(color); \ std::printf("%s", buffer); \ } while((void)0, 0) @@ -3834,7 +3747,7 @@ namespace detail bool TestCase::operator<(const TestCase& other) const { if(m_line != other.m_line) return m_line < other.m_line; - int file_cmp = std::strcmp(m_file, other.m_file); + const int file_cmp = std::strcmp(m_file, other.m_file); if(file_cmp != 0) return file_cmp < 0; return m_template_id < other.m_template_id; @@ -4122,9 +4035,9 @@ namespace detail #ifdef _MSC_VER // this is needed because MSVC gives different case for drive letters // for __FILE__ when evaluated in a header and a source file - int res = stricmp(lhs->m_file, rhs->m_file); + const int res = stricmp(lhs->m_file, rhs->m_file); #else // _MSC_VER - int res = std::strcmp(lhs->m_file, rhs->m_file); + const int res = std::strcmp(lhs->m_file, rhs->m_file); #endif // _MSC_VER if(res != 0) return res; @@ -4136,7 +4049,7 @@ namespace detail const TestCase* lhs = *static_cast<TestCase* const*>(a); const TestCase* rhs = *static_cast<TestCase* const*>(b); - int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite); + const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite); if(res != 0) return res; return fileOrderComparator(a, b); @@ -4147,7 +4060,7 @@ namespace detail const TestCase* lhs = *static_cast<TestCase* const*>(a); const TestCase* rhs = *static_cast<TestCase* const*>(b); - int res_name = std::strcmp(lhs->m_name, rhs->m_name); + const int res_name = std::strcmp(lhs->m_name, rhs->m_name); if(res_name != 0) return res_name; return suiteOrderComparator(a, b); @@ -4285,8 +4198,6 @@ namespace detail #endif // DOCTEST_CONFIG_COLORS_WINDOWS } - IExceptionTranslator::~IExceptionTranslator() {} - std::vector<const IExceptionTranslator*>& getExceptionTranslators() { static std::vector<const IExceptionTranslator*> data; return data; @@ -4351,6 +4262,10 @@ namespace detail void addToContexts(IContextScope* ptr) { contextState->contexts.push_back(ptr); } void popFromContexts() { contextState->contexts.pop_back(); } +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable : 4996) // std::uncaught_exception is deprecated in C++17 +#endif void useContextIfExceptionOccurred(IContextScope* ptr) { if(std::uncaught_exception()) { std::ostringstream stream; @@ -4358,6 +4273,9 @@ namespace detail contextState->exceptionalContexts.push_back(stream.str()); } } +#if defined(_MSC_VER) +#pragma warning(pop) +#endif void printSummary(); @@ -4745,7 +4663,7 @@ namespace detail getAssertString(assert_type), decomposition); } - bool isWarn = assert_type & assertType::is_warn; + const bool isWarn = assert_type & assertType::is_warn; DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); DOCTEST_PRINTF_COLORED(msg, passed ? Color::BrightGreen : isWarn ? Color::Yellow : Color::Red); @@ -4779,7 +4697,7 @@ namespace detail if(!threw) DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), "didn't throw at all\n"); - bool isWarn = assert_type & assertType::is_warn; + const bool isWarn = assert_type & assertType::is_warn; DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); DOCTEST_PRINTF_COLORED(msg, threw ? Color::BrightGreen : isWarn ? Color::Yellow : Color::Red); @@ -4819,7 +4737,7 @@ namespace detail DOCTEST_SNPRINTF(info3, DOCTEST_COUNTOF(info3), " %s\n", exception.c_str()); } - bool isWarn = assert_type & assertType::is_warn; + const bool isWarn = assert_type & assertType::is_warn; DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); DOCTEST_PRINTF_COLORED(msg, threw_as ? Color::BrightGreen : isWarn ? Color::Yellow : Color::Red); @@ -4856,7 +4774,7 @@ namespace detail DOCTEST_SNPRINTF(info3, DOCTEST_COUNTOF(info3), " %s\n", exception.c_str()); } - bool isWarn = assert_type & assertType::is_warn; + const bool isWarn = assert_type & assertType::is_warn; DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); DOCTEST_PRINTF_COLORED(msg, threw ? isWarn ? Color::Yellow : Color::Red : Color::BrightGreen); @@ -4939,8 +4857,7 @@ namespace detail throwException(); } - MessageBuilder::MessageBuilder(const char* file, int line, - doctest::detail::assertType::Enum severity) + MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) : m_stream(createStream()) , m_file(file) , m_line(line) @@ -4949,10 +4866,10 @@ namespace detail bool MessageBuilder::log() { DOCTEST_LOG_START(); - bool is_warn = m_severity & doctest::detail::assertType::is_warn; + const bool isWarn = m_severity & assertType::is_warn; // warn is just a message in this context so we dont treat it as an assert - if(!is_warn) { + if(!isWarn) { contextState->numAssertionsForCurrentTestcase++; addFailedAssert(m_severity); } @@ -4962,10 +4879,10 @@ namespace detail lineForOutput(m_line)); char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " %s!\n", - is_warn ? "MESSAGE" : getFailString(m_severity)); + isWarn ? "MESSAGE" : getFailString(m_severity)); DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); - DOCTEST_PRINTF_COLORED(msg, is_warn ? Color::Yellow : Color::Red); + DOCTEST_PRINTF_COLORED(msg, isWarn ? Color::Yellow : Color::Red); String info = getStreamResult(m_stream); if(info.size()) { @@ -4980,7 +4897,7 @@ namespace detail printToDebugConsole(String(loc) + msg + " " + info.c_str() + "\n" + context.c_str() + "\n"); - return isDebuggerActive() && !contextState->no_breaks && !is_warn; // break into debugger + return isDebuggerActive() && !contextState->no_breaks && !isWarn; // break into debugger } void MessageBuilder::react() { @@ -5037,7 +4954,7 @@ namespace detail } if(noBadCharsFound && argv[i][0] == '-') { temp += my_strlen(pattern); - unsigned len = my_strlen(temp); + const unsigned len = my_strlen(temp); if(len) { res = temp; return true; @@ -5211,7 +5128,7 @@ namespace detail std::printf("test suites with unskipped test cases passing the current filters: %u\n", p->numTestSuitesPassingFilters); } else { - bool anythingFailed = p->numFailed > 0 || p->numFailedAssertions > 0; + const bool anythingFailed = p->numFailed > 0 || p->numFailedAssertions > 0; char buff[DOCTEST_SNPRINTF_BUFFER_LENGTH]; @@ -5236,8 +5153,8 @@ namespace detail DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | "); DOCTEST_PRINTF_COLORED(buff, Color::None); if(p->no_skipped_summary == false) { - int numSkipped = static_cast<unsigned>(getRegisteredTests().size()) - - p->numTestsPassingFilters; + const int numSkipped = static_cast<unsigned>(getRegisteredTests().size()) - + p->numTestsPassingFilters; DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%6d skipped", numSkipped); DOCTEST_PRINTF_COLORED(buff, numSkipped == 0 ? Color::None : Color::Yellow); } |