[DEV] better stream and add exception nullptr

This commit is contained in:
Edouard DUPIN 2017-10-25 22:27:15 +02:00
parent dab27cb361
commit f1aea942d9
9 changed files with 127 additions and 37 deletions

View File

@ -169,6 +169,14 @@ bool etest::GenericTest::getError() const {
return m_haveError; 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, void etest::GenericTest::testResult(bool _result,
const etk::String& _test1Value, const etk::String& _test1Value,
const etk::String& _test1, const etk::String& _test1,
@ -179,13 +187,24 @@ void etest::GenericTest::testResult(bool _result,
return; return;
} }
ETEST_ERROR("Detect an error: " << m_file << ":" << _line << ":"); ETEST_ERROR("Detect an error: " << m_file << ":" << _line << ":");
ETEST_ERROR(" have: " << _test1 << " = " << _test1Value); if (_test1 != _test1Value) {
ETEST_ERROR(" expect: " << _test2 << " = " << _test2Value); 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_haveError = true;
m_numberCheckFail++;
} }
void etest::GenericTest::clearLocal() { void etest::GenericTest::clearLocal() {
m_haveError = false; m_haveError = false;
m_numberCheck = 0;
m_numberCheckFail = 0;
} }
etest::GenericTest* etest::g_currentTest = nullptr; etest::GenericTest* etest::g_currentTest = nullptr;
@ -195,6 +214,8 @@ int32_t etest::runAllTest() {
etk::Vector<etk::String> listGroup = getListGroupSpecific(runList); etk::Vector<etk::String> listGroup = getListGroupSpecific(runList);
ETEST_PRINT("[==========] Running " << runList.size() << " tests from " << listGroup.size() << " test group."); ETEST_PRINT("[==========] Running " << runList.size() << " tests from " << listGroup.size() << " test group.");
echrono::Steady tic = echrono::Steady::now(); echrono::Steady tic = echrono::Steady::now();
uint32_t nbTotalCheck = 0;
uint32_t nbTotalCheckFail = 0;
for (auto &itGroup: listGroup) { for (auto &itGroup: listGroup) {
int32_t count = 0; int32_t count = 0;
for (auto &it: getListOfTest()) { for (auto &it: getListOfTest()) {
@ -203,6 +224,8 @@ int32_t etest::runAllTest() {
} }
} }
ETEST_PRINT("[++++++++++] " << count << " test from " << itGroup << ":"); ETEST_PRINT("[++++++++++] " << count << " test from " << itGroup << ":");
uint32_t nbCheck = 0;
uint32_t nbCheckFail = 0;
echrono::Steady ticGroup = echrono::Steady::now(); echrono::Steady ticGroup = echrono::Steady::now();
for (auto &it: runList) { for (auto &it: runList) {
if (it->getTestGroup() != itGroup) { if (it->getTestGroup() != itGroup) {
@ -221,12 +244,14 @@ int32_t etest::runAllTest() {
echrono::Steady tocTest = echrono::Steady::now(); echrono::Steady tocTest = echrono::Steady::now();
g_currentTest = nullptr; g_currentTest = nullptr;
if (it->getError() == true) { if (it->getError() == true) {
ETEST_PRINT("[ FAIL ] " << itGroup << "." << it->getTestName() << " (" << (tocTest - ticTest) << ")"); ETEST_PRINT("[ FAIL ] " << itGroup << "." << it->getTestName() << " (" << (tocTest - ticTest) << ") " << it->getNumberCheckError() << " fails");
errorCount++; errorCount++;
localFail = true; localFail = true;
} else { } else {
ETEST_PRINT("[ OK ] " << itGroup << "." << it->getTestName() << " (" << (tocTest - ticTest) << ")"); ETEST_PRINT("[ OK ] " << itGroup << "." << it->getTestName() << " (" << (tocTest - ticTest) << ")");
} }
nbCheck += it->getNumberCheck();
nbCheckFail += it->getNumberCheckError();
} }
#if ETK_MEMORY_CHECKER > 0 #if ETK_MEMORY_CHECKER > 0
ETEST_DEBUG("[ MEM ] CHECK memory properties"); ETEST_DEBUG("[ MEM ] CHECK memory properties");
@ -234,21 +259,25 @@ int32_t etest::runAllTest() {
etk::memory::clearSnapshoot(memorySnapShoot); etk::memory::clearSnapshoot(memorySnapShoot);
memorySnapShoot = nullptr; memorySnapShoot = nullptr;
ETEST_DEBUG("[ MEM ] CHECK memory properties (done)"); ETEST_DEBUG("[ MEM ] CHECK memory properties (done)");
nbCheck++;
if (ret == false) { if (ret == false) {
if (localFail == false) { if (localFail == false) {
errorCount++; errorCount++;
} }
ETEST_PRINT("[ FAIL ] " << itGroup << "." << it->getTestName() << " ==> in memory LEAK test"); ETEST_PRINT("[ FAIL ] " << itGroup << "." << it->getTestName() << " ==> in memory LEAK test");
nbCheckFail++;
} }
#endif #endif
} }
echrono::Steady tocGroup = echrono::Steady::now(); 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(); 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) { if (errorCount != 0) {
ETEST_PRINT("[== FAIL ==] Have " << errorCount << " test fail"); ETEST_PRINT("[== FAIL ==] Have " << errorCount << " test fail ");
} }
ETK_MEM_SHOW_LOG(); ETK_MEM_SHOW_LOG();
return -errorCount; return -errorCount;

View File

@ -101,6 +101,9 @@ namespace etest {
etk::String m_testGroup; etk::String m_testGroup;
etk::String m_testName; etk::String m_testName;
bool m_haveError; bool m_haveError;
protected:
uint32_t m_numberCheck;
uint32_t m_numberCheckFail;
public: public:
GenericTest(const char* _file, GenericTest(const char* _file,
uint32_t _line, uint32_t _line,
@ -111,7 +114,24 @@ namespace etest {
uint32_t getFileLine() const; uint32_t getFileLine() const;
const etk::String& getTestGroup() const; const etk::String& getTestGroup() const;
const etk::String& getTestName() 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; 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, void testResult(bool _result,
const etk::String& _test1Value, const etk::String& _test1Value,
const etk::String& _test1, const etk::String& _test1,
@ -152,6 +172,7 @@ namespace etest {
#define EXPECT_EQ(element, result) \ #define EXPECT_EQ(element, result) \
do { \ do { \
etest::g_currentTest->addCheck(); \
ETEST_DEBUG(" [ SUB-RUN ] EXPECT_EQ(" << #element << ", " << #result << ");"); \ ETEST_DEBUG(" [ SUB-RUN ] EXPECT_EQ(" << #element << ", " << #result << ");"); \
bool ETEST_VARIABLE_TMP_res = ((element) == (result)); \ bool ETEST_VARIABLE_TMP_res = ((element) == (result)); \
if (etest::g_currentTest == nullptr) { \ if (etest::g_currentTest == nullptr) { \
@ -169,6 +190,7 @@ namespace etest {
#define EXPECT_NE(element, result) \ #define EXPECT_NE(element, result) \
do { \ do { \
etest::g_currentTest->addCheck(); \
ETEST_DEBUG(" [ SUB-RUN ] EXPECT_NE(" << #element << ", " << #result << ");"); \ ETEST_DEBUG(" [ SUB-RUN ] EXPECT_NE(" << #element << ", " << #result << ");"); \
bool ETEST_VARIABLE_TMP_res = ((element) != (result)); \ bool ETEST_VARIABLE_TMP_res = ((element) != (result)); \
if (etest::g_currentTest == nullptr) { \ if (etest::g_currentTest == nullptr) { \
@ -184,8 +206,30 @@ namespace etest {
ETEST_DEBUG(" [ SUB-DONE ]"); \ ETEST_DEBUG(" [ SUB-DONE ]"); \
} while (false) } 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) \ #define EXPECT_FLOAT_EQ_DELTA(element, result, delta) \
do { \ do { \
etest::g_currentTest->addCheck(); \
ETEST_DEBUG(" [ SUB-RUN ] EXPECT_FLOAT_EQ(" << #element << ", " << #result << ");"); \ ETEST_DEBUG(" [ SUB-RUN ] EXPECT_FLOAT_EQ(" << #element << ", " << #result << ");"); \
float ETEST_VARIABLE_TMP_res2 = (element) - (result); \ float ETEST_VARIABLE_TMP_res2 = (element) - (result); \
bool ETEST_VARIABLE_TMP_res = false; \ bool ETEST_VARIABLE_TMP_res = false; \

View File

@ -6,7 +6,7 @@
#include <etk/Allocator.hpp> #include <etk/Allocator.hpp>
#include <stdlib.h> #include <stdlib.h>
/*
void* operator new (size_t size) { void* operator new (size_t size) {
return malloc(size); return malloc(size);
} }
@ -23,7 +23,7 @@ void operator delete (void* ptr) {
void operator delete[] (void* ptr) { void operator delete[] (void* ptr) {
free(ptr); free(ptr);
} }
*/

View File

@ -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) {
}
};
} }
} }

View File

@ -7,6 +7,7 @@
#pragma once #pragma once
#include <etk/types.hpp> #include <etk/types.hpp>
#include <etk/String.hpp> #include <etk/String.hpp>
#include <etk/Exception.hpp>
// TO facilitate debug when have a problem ... // TO facilitate debug when have a problem ...
#define ETK_FUNCTION_DEBUG(...) do {} while(false) #define ETK_FUNCTION_DEBUG(...) do {} while(false)
@ -155,7 +156,7 @@ namespace etk {
if ( m_pointerPrivate == nullptr if ( m_pointerPrivate == nullptr
&& m_local == false) { && m_local == false) {
ETK_FUNCTION_DEBUG("[%d=0X%lx] call Function (With nullptr !!! ==> must assert ...)\n", m_pppppp, (uint64_t)this); 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); ETK_FUNCTION_DEBUG("[%d=0X%lx] call Function \n", m_pppppp, (uint64_t)this);
if (m_local == true) { if (m_local == true) {

View File

@ -21,58 +21,58 @@ etk::Stream& etk::Stream::operator<< (const char* _data) {
*m_data += _data; *m_data += _data;
return *this; return *this;
} }
etk::Stream& etk::Stream::operator<< (const bool _data) { etk::Stream& etk::Stream::operator<< (const bool& _data) {
*m_data += etk::toString(_data); *m_data += etk::toString(_data);
return *this; 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); *m_data += etk::toString(_data);
return *this; 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); *m_data += etk::toString(_data);
return *this; 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); *m_data += etk::toString(_data);
return *this; 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); *m_data += etk::toString(_data);
return *this; 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); *m_data += etk::toString(_data);
return *this; 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); *m_data += etk::toString(_data);
return *this; 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); *m_data += etk::toString(_data);
return *this; 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); *m_data += etk::toString(_data);
return *this; return *this;
} }
#if defined(__TARGET_OS__MacOs) \ #if defined(__TARGET_OS__MacOs) \
|| defined(__TARGET_OS__IOs) || 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); *m_data += etk::toString(_data);
return *this; return *this;
} }
#endif #endif
etk::Stream& etk::Stream::operator<< (const float _data) { etk::Stream& etk::Stream::operator<< (const float& _data) {
*m_data += etk::toString(_data); *m_data += etk::toString(_data);
return *this; return *this;
} }
etk::Stream& etk::Stream::operator<< (const double _data) { etk::Stream& etk::Stream::operator<< (const double& _data) {
*m_data += etk::toString(_data); *m_data += etk::toString(_data);
return *this; return *this;
} }
etk::Stream& etk::Stream::operator<< (etk::NullPtr _data) { etk::Stream& etk::Stream::operator<< (const etk::NullPtr& _data) {
*m_data += "nullptr"; *m_data += "nullptr";
return *this; return *this;
} }

View File

@ -20,22 +20,22 @@ namespace etk {
Stream(size_t _basicSize=0); Stream(size_t _basicSize=0);
~Stream(); ~Stream();
Stream& operator<< (const char* _data); Stream& operator<< (const char* _data);
Stream& operator<< (bool _data); Stream& operator<< (const bool& _data);
Stream& operator<< (int8_t _data); Stream& operator<< (const int8_t& _data);
Stream& operator<< (int16_t _data); Stream& operator<< (const int16_t& _data);
Stream& operator<< (int32_t _data); Stream& operator<< (const int32_t& _data);
Stream& operator<< (int64_t _data); Stream& operator<< (const int64_t& _data);
Stream& operator<< (uint8_t _data); Stream& operator<< (const uint8_t& _data);
Stream& operator<< (uint16_t _data); Stream& operator<< (const uint16_t& _data);
Stream& operator<< (uint32_t _data); Stream& operator<< (const uint32_t& _data);
Stream& operator<< (uint64_t _data); Stream& operator<< (const uint64_t& _data);
#if defined(__TARGET_OS__MacOs) \ #if defined(__TARGET_OS__MacOs) \
|| defined(__TARGET_OS__IOs) || defined(__TARGET_OS__IOs)
Stream& operator<< (size_t _data); Stream& operator<< (const size_t& _data);
#endif #endif
Stream& operator<< (float _data); Stream& operator<< (const float& _data);
Stream& operator<< (double _data); Stream& operator<< (const double& _data);
Stream& operator<< (etk::NullPtr _data); Stream& operator<< (const etk::NullPtr& _data);
const char* c_str() const; const char* c_str() const;
const etk::String& str() const; const etk::String& str() const;
const size_t size() const; const size_t size() const;

View File

@ -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 etk::String::extract(size_t _posStart, size_t _posEnd) const {
etk::String out; etk::String out;
if (_posEnd >= size()) {
_posEnd = size();
}
if (_posStart >= size()) { if (_posStart >= size()) {
return out; return out;
} }
if (_posEnd >= size()) { if (_posStart >= _posEnd) {
_posEnd = size(); return out;
} }
out.pushBack(&m_data[_posStart], _posEnd-_posStart); out.pushBack(&m_data[_posStart], _posEnd-_posStart);
return out; return out;

View File

@ -64,4 +64,5 @@ ETK_DECLARE_TYPE(etk::exception::UnderflowError);
ETK_DECLARE_TYPE(etk::exception::CastError); ETK_DECLARE_TYPE(etk::exception::CastError);
ETK_DECLARE_TYPE(etk::exception::AllocationError); ETK_DECLARE_TYPE(etk::exception::AllocationError);
ETK_DECLARE_TYPE(etk::exception::RuntimeError); ETK_DECLARE_TYPE(etk::exception::RuntimeError);
ETK_DECLARE_TYPE(etk::exception::NullPointerError);