From f1aea942d9f5ebf32caf83601a519fb8885e5c04 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Wed, 25 Oct 2017 22:27:15 +0200 Subject: [PATCH] [DEV] better stream and add exception nullptr --- etest/etest.cpp | 41 +++++++++++++++++++++++++++++++++++------ etest/etest.hpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ etk/Allocator.cpp | 4 ++-- etk/Exception.hpp | 12 ++++++++++++ etk/Function.hpp | 3 ++- etk/Stream.cpp | 26 +++++++++++++------------- etk/Stream.hpp | 26 +++++++++++++------------- etk/String.cpp | 7 +++++-- etk/typeInfo.cpp | 1 + 9 files changed, 127 insertions(+), 37 deletions(-) diff --git a/etest/etest.cpp b/etest/etest.cpp index 118442b..1759979 100644 --- a/etest/etest.cpp +++ b/etest/etest.cpp @@ -169,6 +169,14 @@ bool etest::GenericTest::getError() const { return m_haveError; } +uint32_t etest::GenericTest::getNumberCheck() const { + return m_numberCheck; +} + +uint32_t etest::GenericTest::getNumberCheckError() const { + return m_numberCheckFail; +} + void etest::GenericTest::testResult(bool _result, const etk::String& _test1Value, const etk::String& _test1, @@ -179,13 +187,24 @@ void etest::GenericTest::testResult(bool _result, return; } ETEST_ERROR("Detect an error: " << m_file << ":" << _line << ":"); - ETEST_ERROR(" have: " << _test1 << " = " << _test1Value); - ETEST_ERROR(" expect: " << _test2 << " = " << _test2Value); + if (_test1 != _test1Value) { + ETEST_ERROR(" have: " << _test1 << " = " << _test1Value); + } else { + ETEST_ERROR(" have: " << _test1); + } + if (_test2 != _test2Value) { + ETEST_ERROR(" expect: " << _test2 << " = " << _test2Value); + } else { + ETEST_ERROR(" expect: " << _test2); + } m_haveError = true; + m_numberCheckFail++; } void etest::GenericTest::clearLocal() { m_haveError = false; + m_numberCheck = 0; + m_numberCheckFail = 0; } etest::GenericTest* etest::g_currentTest = nullptr; @@ -195,6 +214,8 @@ int32_t etest::runAllTest() { etk::Vector listGroup = getListGroupSpecific(runList); ETEST_PRINT("[==========] Running " << runList.size() << " tests from " << listGroup.size() << " test group."); echrono::Steady tic = echrono::Steady::now(); + uint32_t nbTotalCheck = 0; + uint32_t nbTotalCheckFail = 0; for (auto &itGroup: listGroup) { int32_t count = 0; for (auto &it: getListOfTest()) { @@ -203,6 +224,8 @@ int32_t etest::runAllTest() { } } ETEST_PRINT("[++++++++++] " << count << " test from " << itGroup << ":"); + uint32_t nbCheck = 0; + uint32_t nbCheckFail = 0; echrono::Steady ticGroup = echrono::Steady::now(); for (auto &it: runList) { if (it->getTestGroup() != itGroup) { @@ -221,12 +244,14 @@ int32_t etest::runAllTest() { echrono::Steady tocTest = echrono::Steady::now(); g_currentTest = nullptr; if (it->getError() == true) { - ETEST_PRINT("[ FAIL ] " << itGroup << "." << it->getTestName() << " (" << (tocTest - ticTest) << ")"); + ETEST_PRINT("[ FAIL ] " << itGroup << "." << it->getTestName() << " (" << (tocTest - ticTest) << ") " << it->getNumberCheckError() << " fails"); errorCount++; localFail = true; } else { ETEST_PRINT("[ OK ] " << itGroup << "." << it->getTestName() << " (" << (tocTest - ticTest) << ")"); } + nbCheck += it->getNumberCheck(); + nbCheckFail += it->getNumberCheckError(); } #if ETK_MEMORY_CHECKER > 0 ETEST_DEBUG("[ MEM ] CHECK memory properties"); @@ -234,21 +259,25 @@ int32_t etest::runAllTest() { etk::memory::clearSnapshoot(memorySnapShoot); memorySnapShoot = nullptr; ETEST_DEBUG("[ MEM ] CHECK memory properties (done)"); + nbCheck++; if (ret == false) { if (localFail == false) { errorCount++; } ETEST_PRINT("[ FAIL ] " << itGroup << "." << it->getTestName() << " ==> in memory LEAK test"); + nbCheckFail++; } #endif } echrono::Steady tocGroup = echrono::Steady::now(); - ETEST_PRINT("[++++++++++] " << count << " test from " << itGroup << " (" << (tocGroup - ticGroup) << ")"); + ETEST_PRINT("[++++++++++] " << count << " test [" << nbCheck << " check / " << nbCheckFail << " fails] from " << itGroup << " (" << (tocGroup - ticGroup) << ")"); + nbTotalCheck += nbCheck; + nbTotalCheckFail += nbCheckFail; } echrono::Steady toc = echrono::Steady::now(); - ETEST_PRINT("[==========] All done in " << (toc - tic)); + ETEST_PRINT("[==========] All done [" << nbTotalCheck << " check / " << nbTotalCheckFail << " fails] in " << (toc - tic)); if (errorCount != 0) { - ETEST_PRINT("[== FAIL ==] Have " << errorCount << " test fail"); + ETEST_PRINT("[== FAIL ==] Have " << errorCount << " test fail "); } ETK_MEM_SHOW_LOG(); return -errorCount; diff --git a/etest/etest.hpp b/etest/etest.hpp index 37b52e4..f85f47f 100644 --- a/etest/etest.hpp +++ b/etest/etest.hpp @@ -101,6 +101,9 @@ namespace etest { etk::String m_testGroup; etk::String m_testName; bool m_haveError; + protected: + uint32_t m_numberCheck; + uint32_t m_numberCheckFail; public: GenericTest(const char* _file, uint32_t _line, @@ -111,7 +114,24 @@ namespace etest { uint32_t getFileLine() const; const etk::String& getTestGroup() const; const etk::String& getTestName() const; + /** + * @brief Get if an error occured during the test + * @return true an error occured, false otherwise + */ bool getError() const; + /** + * @brief Get the number of check done in the test + * @return simple count of test done + */ + uint32_t getNumberCheck() const; + /** + * @brief Get the number of check done in the test + * @return simple count of test done with error + */ + uint32_t getNumberCheckError() const; + void addCheck() { + m_numberCheck++; + } void testResult(bool _result, const etk::String& _test1Value, const etk::String& _test1, @@ -152,6 +172,7 @@ namespace etest { #define EXPECT_EQ(element, result) \ do { \ + etest::g_currentTest->addCheck(); \ ETEST_DEBUG(" [ SUB-RUN ] EXPECT_EQ(" << #element << ", " << #result << ");"); \ bool ETEST_VARIABLE_TMP_res = ((element) == (result)); \ if (etest::g_currentTest == nullptr) { \ @@ -169,6 +190,7 @@ namespace etest { #define EXPECT_NE(element, result) \ do { \ + etest::g_currentTest->addCheck(); \ ETEST_DEBUG(" [ SUB-RUN ] EXPECT_NE(" << #element << ", " << #result << ");"); \ bool ETEST_VARIABLE_TMP_res = ((element) != (result)); \ if (etest::g_currentTest == nullptr) { \ @@ -184,8 +206,30 @@ namespace etest { ETEST_DEBUG(" [ SUB-DONE ]"); \ } while (false) +#define ASSERT_NE(element, result) \ + do { \ + etest::g_currentTest->addCheck(); \ + ETEST_DEBUG(" [ SUB-RUN ] ASSERT_NE(" << #element << ", " << #result << ");"); \ + bool ETEST_VARIABLE_TMP_res = ((element) != (result)); \ + if (etest::g_currentTest == nullptr) { \ + ETEST_CRITICAL("Not in a test"); \ + } else { \ + etest::g_currentTest->testResult(ETEST_VARIABLE_TMP_res, \ + etest::exportResultToString(element), \ + #element, \ + etest::exportResultToString(result), \ + #result, \ + __LINE__); \ + } \ + ETEST_DEBUG(" [ SUB-DONE ]"); \ + if (ETEST_VARIABLE_TMP_res == true) { \ + return; \ + } \ + } while (false) + #define EXPECT_FLOAT_EQ_DELTA(element, result, delta) \ do { \ + etest::g_currentTest->addCheck(); \ ETEST_DEBUG(" [ SUB-RUN ] EXPECT_FLOAT_EQ(" << #element << ", " << #result << ");"); \ float ETEST_VARIABLE_TMP_res2 = (element) - (result); \ bool ETEST_VARIABLE_TMP_res = false; \ diff --git a/etk/Allocator.cpp b/etk/Allocator.cpp index d7217e3..717e58a 100644 --- a/etk/Allocator.cpp +++ b/etk/Allocator.cpp @@ -6,7 +6,7 @@ #include #include -/* + void* operator new (size_t size) { return malloc(size); } @@ -23,7 +23,7 @@ void operator delete (void* ptr) { void operator delete[] (void* ptr) { free(ptr); } -*/ + diff --git a/etk/Exception.hpp b/etk/Exception.hpp index 7277370..db7de3a 100644 --- a/etk/Exception.hpp +++ b/etk/Exception.hpp @@ -177,5 +177,17 @@ namespace etk { } }; + class NullPointerError : public etk::Exception { + public: + /** + * @brief Contructor of an generic Exception. + * @param[in] _what The explanation of the problem. + * @param[in] _function Function name to find faster the source od the problem. + */ + NullPointerError(const etk::String& _what, const char* _function = nullptr): + etk::Exception("NULL-POINTER-ERROR", _what, _function) { + + } + }; } } diff --git a/etk/Function.hpp b/etk/Function.hpp index af5520a..f82e7d7 100644 --- a/etk/Function.hpp +++ b/etk/Function.hpp @@ -7,6 +7,7 @@ #pragma once #include #include +#include // TO facilitate debug when have a problem ... #define ETK_FUNCTION_DEBUG(...) do {} while(false) @@ -155,7 +156,7 @@ namespace etk { if ( m_pointerPrivate == nullptr && m_local == false) { ETK_FUNCTION_DEBUG("[%d=0X%lx] call Function (With nullptr !!! ==> must assert ...)\n", m_pppppp, (uint64_t)this); - throw; + throw etk::exception::NullPointerError("etk::Function call empty pointer"); } ETK_FUNCTION_DEBUG("[%d=0X%lx] call Function \n", m_pppppp, (uint64_t)this); if (m_local == true) { diff --git a/etk/Stream.cpp b/etk/Stream.cpp index 2ff1a67..f01e5b9 100644 --- a/etk/Stream.cpp +++ b/etk/Stream.cpp @@ -21,58 +21,58 @@ etk::Stream& etk::Stream::operator<< (const char* _data) { *m_data += _data; return *this; } -etk::Stream& etk::Stream::operator<< (const bool _data) { +etk::Stream& etk::Stream::operator<< (const bool& _data) { *m_data += etk::toString(_data); return *this; } -etk::Stream& etk::Stream::operator<< (const int8_t _data) { +etk::Stream& etk::Stream::operator<< (const int8_t& _data) { *m_data += etk::toString(_data); return *this; } -etk::Stream& etk::Stream::operator<< (const int16_t _data) { +etk::Stream& etk::Stream::operator<< (const int16_t& _data) { *m_data += etk::toString(_data); return *this; } -etk::Stream& etk::Stream::operator<< (const int32_t _data) { +etk::Stream& etk::Stream::operator<< (const int32_t& _data) { *m_data += etk::toString(_data); return *this; } -etk::Stream& etk::Stream::operator<< (const int64_t _data) { +etk::Stream& etk::Stream::operator<< (const int64_t& _data) { *m_data += etk::toString(_data); return *this; } -etk::Stream& etk::Stream::operator<< (const uint8_t _data) { +etk::Stream& etk::Stream::operator<< (const uint8_t& _data) { *m_data += etk::toString(_data); return *this; } -etk::Stream& etk::Stream::operator<< (const uint16_t _data) { +etk::Stream& etk::Stream::operator<< (const uint16_t& _data) { *m_data += etk::toString(_data); return *this; } -etk::Stream& etk::Stream::operator<< (const uint32_t _data) { +etk::Stream& etk::Stream::operator<< (const uint32_t& _data) { *m_data += etk::toString(_data); return *this; } -etk::Stream& etk::Stream::operator<< (const uint64_t _data) { +etk::Stream& etk::Stream::operator<< (const uint64_t& _data) { *m_data += etk::toString(_data); return *this; } #if defined(__TARGET_OS__MacOs) \ || defined(__TARGET_OS__IOs) - etk::Stream& etk::Stream::operator<< (const size_t _data) { + etk::Stream& etk::Stream::operator<< (const size_t& _data) { *m_data += etk::toString(_data); return *this; } #endif -etk::Stream& etk::Stream::operator<< (const float _data) { +etk::Stream& etk::Stream::operator<< (const float& _data) { *m_data += etk::toString(_data); return *this; } -etk::Stream& etk::Stream::operator<< (const double _data) { +etk::Stream& etk::Stream::operator<< (const double& _data) { *m_data += etk::toString(_data); return *this; } -etk::Stream& etk::Stream::operator<< (etk::NullPtr _data) { +etk::Stream& etk::Stream::operator<< (const etk::NullPtr& _data) { *m_data += "nullptr"; return *this; } diff --git a/etk/Stream.hpp b/etk/Stream.hpp index 7405aac..e7c3a91 100644 --- a/etk/Stream.hpp +++ b/etk/Stream.hpp @@ -20,22 +20,22 @@ namespace etk { Stream(size_t _basicSize=0); ~Stream(); Stream& operator<< (const char* _data); - Stream& operator<< (bool _data); - Stream& operator<< (int8_t _data); - Stream& operator<< (int16_t _data); - Stream& operator<< (int32_t _data); - Stream& operator<< (int64_t _data); - Stream& operator<< (uint8_t _data); - Stream& operator<< (uint16_t _data); - Stream& operator<< (uint32_t _data); - Stream& operator<< (uint64_t _data); + Stream& operator<< (const bool& _data); + Stream& operator<< (const int8_t& _data); + Stream& operator<< (const int16_t& _data); + Stream& operator<< (const int32_t& _data); + Stream& operator<< (const int64_t& _data); + Stream& operator<< (const uint8_t& _data); + Stream& operator<< (const uint16_t& _data); + Stream& operator<< (const uint32_t& _data); + Stream& operator<< (const uint64_t& _data); #if defined(__TARGET_OS__MacOs) \ || defined(__TARGET_OS__IOs) - Stream& operator<< (size_t _data); + Stream& operator<< (const size_t& _data); #endif - Stream& operator<< (float _data); - Stream& operator<< (double _data); - Stream& operator<< (etk::NullPtr _data); + Stream& operator<< (const float& _data); + Stream& operator<< (const double& _data); + Stream& operator<< (const etk::NullPtr& _data); const char* c_str() const; const etk::String& str() const; const size_t size() const; diff --git a/etk/String.cpp b/etk/String.cpp index 6fa08cb..acf2cbc 100644 --- a/etk/String.cpp +++ b/etk/String.cpp @@ -341,11 +341,14 @@ void etk::String::eraseRange(size_t _pos, size_t _posEnd) { etk::String etk::String::extract(size_t _posStart, size_t _posEnd) const { etk::String out; + if (_posEnd >= size()) { + _posEnd = size(); + } if (_posStart >= size()) { return out; } - if (_posEnd >= size()) { - _posEnd = size(); + if (_posStart >= _posEnd) { + return out; } out.pushBack(&m_data[_posStart], _posEnd-_posStart); return out; diff --git a/etk/typeInfo.cpp b/etk/typeInfo.cpp index 02f3621..97272c3 100644 --- a/etk/typeInfo.cpp +++ b/etk/typeInfo.cpp @@ -64,4 +64,5 @@ ETK_DECLARE_TYPE(etk::exception::UnderflowError); ETK_DECLARE_TYPE(etk::exception::CastError); ETK_DECLARE_TYPE(etk::exception::AllocationError); ETK_DECLARE_TYPE(etk::exception::RuntimeError); +ETK_DECLARE_TYPE(etk::exception::NullPointerError);