|
|
@@ -8,6 +8,7 @@
|
|
|
#include "SpComm.hpp"
|
|
|
#include "SpUtility.hpp"
|
|
|
#include <vector>
|
|
|
+#include <typeinfo>
|
|
|
|
|
|
//helper macro for test temporary.
|
|
|
|
|
|
@@ -145,8 +146,8 @@ struct IMethodTestCase
|
|
|
{
|
|
|
virtual ErrorCodeEnum RunTest() = 0;
|
|
|
virtual ~IMethodTestCase() {};
|
|
|
- //void BindEntity(CEntityBase* const pEntity) { pEntityBase = pEntity; }
|
|
|
- //CEntityBase* pEntityBase = nullptr;
|
|
|
+ void BindEntity(CEntityBase* const pEntityT) { pEntityBase = pEntityT; }
|
|
|
+ CEntityBase* pEntityBase = nullptr;
|
|
|
};
|
|
|
|
|
|
template<typename TClass>
|
|
|
@@ -154,9 +155,28 @@ class MethodTestCase : public IMethodTestCase
|
|
|
{
|
|
|
public:
|
|
|
MethodTestCase(ErrorCodeEnum(TClass::* method)()) : m_method(method) {}
|
|
|
- virtual ErrorCodeEnum RunTest() {
|
|
|
+ virtual ErrorCodeEnum RunTest()
|
|
|
+ {
|
|
|
TClass obj;
|
|
|
- return (obj.*m_method)();
|
|
|
+ TClass* ptr = &obj;
|
|
|
+ if (pEntityBase != nullptr && typeid(*pEntityBase).hash_code() == typeid(obj).hash_code())
|
|
|
+ {
|
|
|
+ ptr = static_cast<TClass*>(pEntityBase);
|
|
|
+ Dbg("pEntityBase fulfill");
|
|
|
+ }
|
|
|
+ else if(pEntityBase != nullptr)
|
|
|
+ {
|
|
|
+ Dbg("pEntityBase hash code: %d, name: %s", typeid(*pEntityBase).hash_code(), typeid(*pEntityBase).name());
|
|
|
+ Dbg("obj hash code: %d, name: %s", typeid(obj).hash_code(), typeid(obj).name());
|
|
|
+
|
|
|
+ TClass *ptr2 = dynamic_cast<TClass *>(pEntityBase);
|
|
|
+ if (nullptr != ptr2)
|
|
|
+ {
|
|
|
+ Dbg("pEntityBase dynamic succ.");
|
|
|
+ ptr = ptr2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return (ptr->*m_method)();
|
|
|
//return Error_Succeed;
|
|
|
}
|
|
|
private:
|
|
|
@@ -178,22 +198,22 @@ private:
|
|
|
TestFunction m_func;
|
|
|
};
|
|
|
|
|
|
-template<typename TClass, class TReq, class TAns>
|
|
|
+template<typename TEntity, class TReq, class TAns>
|
|
|
struct TwoWayContextTestCaseT : public SpReqAnsContext<TReq, TAns>, public IMethodTestCase
|
|
|
{
|
|
|
using Pointer = CSmartPointer<SpReqAnsContext<TReq, TAns> >;
|
|
|
- using TestTwoWayFunc = ErrorCodeEnum(TClass::*)(Pointer ctx);
|
|
|
- using TestTwoWayFuncVoid = void(TClass::*)(Pointer ctx);
|
|
|
+ using TestTwoWayFunc = ErrorCodeEnum(TEntity::*)(Pointer ctx);
|
|
|
+ using TestTwoWayFuncVoid = void(TEntity::*)(Pointer ctx);
|
|
|
|
|
|
- TwoWayContextTestCaseT(TClass* testee, TestTwoWayFunc func, TestTwoWayFuncVoid funVoid)
|
|
|
+ TwoWayContextTestCaseT(TEntity* pEntityT, TestTwoWayFunc func, TestTwoWayFuncVoid funVoid)
|
|
|
:SpReqAnsContext<TReq, TAns>(CreateMockTransactionContext(nullptr))
|
|
|
- , m_obj(testee), m_func(func), m_voidFunc(funVoid), m_errorCode(Error_IgnoreAll), m_dwUserCode(0) {
|
|
|
+ , m_pEntity(pEntityT), m_func(func), m_voidFunc(funVoid), m_errorCode(Error_IgnoreAll), m_dwUserCode(0) {
|
|
|
}
|
|
|
|
|
|
- TwoWayContextTestCaseT(TClass* testee, TestTwoWayFunc func)
|
|
|
+ TwoWayContextTestCaseT(TEntity* pEntityT, TestTwoWayFunc func)
|
|
|
:TwoWayContextTestCaseT(nullptr, func, nullptr) {}
|
|
|
|
|
|
- TwoWayContextTestCaseT(TClass* testee, TestTwoWayFuncVoid func)
|
|
|
+ TwoWayContextTestCaseT(TEntity* pEntityT, TestTwoWayFuncVoid func)
|
|
|
:TwoWayContextTestCaseT(nullptr, nullptr, func) {}
|
|
|
|
|
|
TwoWayContextTestCaseT(TestTwoWayFunc func) :TwoWayContextTestCaseT(nullptr, func) { }
|
|
|
@@ -212,19 +232,23 @@ struct TwoWayContextTestCaseT : public SpReqAnsContext<TReq, TAns>, public IMeth
|
|
|
virtual ErrorCodeEnum RunTest()
|
|
|
{
|
|
|
ErrorCodeEnum result = Error_IgnoreAll;
|
|
|
- TClass obj;
|
|
|
+ TEntity entityInst;
|
|
|
bool flag = false;
|
|
|
|
|
|
- if (m_obj == nullptr)
|
|
|
- flag = !!(m_obj = &obj);
|
|
|
+ if (m_pEntity == nullptr)
|
|
|
+ flag = !!(m_pEntity = &entityInst);
|
|
|
+
|
|
|
+ if (flag && pEntityBase != nullptr) {
|
|
|
+ m_pEntity->MockEntityFunction(pEntityBase->GetFunction());
|
|
|
+ }
|
|
|
|
|
|
PreTest();
|
|
|
|
|
|
if (m_func != nullptr) {
|
|
|
- result = (m_obj->*m_func)(GetCtx());
|
|
|
+ result = (m_pEntity->*m_func)(GetCtx());
|
|
|
}
|
|
|
else if (m_voidFunc != nullptr) {
|
|
|
- (m_obj->*m_voidFunc)(GetCtx());
|
|
|
+ (m_pEntity->*m_voidFunc)(GetCtx());
|
|
|
result = Error_Succeed;
|
|
|
}
|
|
|
|
|
|
@@ -232,7 +256,7 @@ struct TwoWayContextTestCaseT : public SpReqAnsContext<TReq, TAns>, public IMeth
|
|
|
|
|
|
Dbg("TwoWayContextTestCaseT->errorCode: %s", SpStrError(result));
|
|
|
|
|
|
- if (flag) m_obj = nullptr;
|
|
|
+ if (flag) m_pEntity = nullptr;
|
|
|
|
|
|
return (((result == Error_Succeed) ? PostTest() : result));
|
|
|
}
|
|
|
@@ -263,7 +287,7 @@ private:
|
|
|
|
|
|
TestTwoWayFunc m_func;
|
|
|
TestTwoWayFuncVoid m_voidFunc;
|
|
|
- TClass* m_obj;
|
|
|
+ TEntity* m_pEntity;
|
|
|
|
|
|
ErrorCodeEnum m_errorCode;
|
|
|
DWORD m_dwUserCode;
|
|
|
@@ -309,9 +333,11 @@ public:
|
|
|
typedef T* TestObjectPointer;
|
|
|
|
|
|
template<class TReq, class TAns>
|
|
|
- struct TwoWayMethodTestCaseT : public TwoWayContextTestCaseT<T, TReq, TAns> {
|
|
|
- TwoWayMethodTestCaseT(T* pEntity, TestTwoWayFunc testFunc)
|
|
|
- :TwoWayContextTestCaseT(pEntity, testFunc) {}
|
|
|
+ struct TwoWayMethodTestCaseT : public TwoWayContextTestCaseT<T, TReq, TAns>
|
|
|
+ {
|
|
|
+ /** constructor*/
|
|
|
+ TwoWayMethodTestCaseT(T* pEntityT, TestTwoWayFunc testFunc):TwoWayContextTestCaseT(pEntityT, testFunc)
|
|
|
+ {/*empty*/}
|
|
|
};
|
|
|
|
|
|
typedef void(T::* TransMethodProto)(CSmartPointer<ITransactionContext> pTransactionContext);
|
|
|
@@ -608,6 +634,7 @@ public:
|
|
|
TestCase(IMethodTestCase* testCase, TestCaseInfo const& info): TestCaseInfo(info), m_testCase(testCase) {}
|
|
|
TestCase(TestCase const& other)
|
|
|
:TestCaseInfo(other), m_testCase(other.m_testCase) {}
|
|
|
+ ~TestCase() { m_testCase = nullptr; }
|
|
|
|
|
|
TestCaseInfo const& GetTestInfo() const { return *this; }
|
|
|
|
|
|
@@ -618,8 +645,9 @@ public:
|
|
|
return newCase;
|
|
|
}
|
|
|
|
|
|
- ErrorCodeEnum RunTest() const
|
|
|
+ ErrorCodeEnum RunTest(CEntityBase* pInvoker) const
|
|
|
{
|
|
|
+ m_testCase->BindEntity(pInvoker);
|
|
|
return m_testCase->RunTest();
|
|
|
}
|
|
|
private:
|
|
|
@@ -659,7 +687,7 @@ private:
|
|
|
|
|
|
#include <functional>
|
|
|
|
|
|
-//////////////////////////////////////////////////////////////////////////
|
|
|
+/////////////////////////Deprecate!!!!!/////////////////////////////////////////////////
|
|
|
|
|
|
#define TWO_WAY_CHECK_ANSWER_BEGIN(ansName) \
|
|
|
checkAnsFunc = [](TwoWayResultType const& ansName) -> ErrorCodeEnum {
|
|
|
@@ -676,7 +704,7 @@ private:
|
|
|
ErrorCodeEnum (ClassName::*testFunc)(SpReqAnsContext< ServiceName##_##ContextName##_Req, ServiceName##_##ContextName##_Ans>::Pointer);\
|
|
|
ErrorCodeEnum testRes; \
|
|
|
std::function<ErrorCodeEnum(ServiceName##_##ContextName##_Ans const&)> checkAnsFunc; \
|
|
|
- TestName():mMockTrans(CreateMockTransactionContext(this->GetFunction())), \
|
|
|
+ TestName():mMockTrans(CreateMockTransactionContext(nullptr)), \
|
|
|
mCtx(new SpReqAnsContext< ServiceName##_##ContextName##_Req, ServiceName##_##ContextName##_Ans>(mMockTrans)) \
|
|
|
, testFuncVoid(nullptr),testFunc(nullptr), testRes(Error_Succeed), checkAnsFunc(nullptr) { \
|
|
|
testFunc = &ClassName::TestFuncName; \
|
|
|
@@ -685,7 +713,7 @@ private:
|
|
|
ErrorCodeEnum PostTest_##ContextName() { \
|
|
|
return checkAnsFunc == nullptr ? Error_Succeed : checkAnsFunc(mCtx->Ans); \
|
|
|
} \
|
|
|
- ErrorCodeEnum Test_##ContextName() { \
|
|
|
+ ErrorCodeEnum Test() { \
|
|
|
PreTest_##ContextName(mCtx->Req); \
|
|
|
if(testFuncVoid != nullptr) { \
|
|
|
(this->*testFuncVoid)(mCtx); \
|
|
|
@@ -703,12 +731,8 @@ private:
|
|
|
testRes = Error_Succeed; \
|
|
|
return testRes; \
|
|
|
} \
|
|
|
- struct TwoWayContextReqAnsImpl : \
|
|
|
- public TwoWayContextTestCaseT<ClassName, ServiceName##_##ContextName##_Req, ServiceName##_##ContextName##_Ans> \
|
|
|
- { \
|
|
|
- }; \
|
|
|
}; \
|
|
|
- TestAutoReg RVC_INTERVAL_UNIQUE_NAME(testAutoReg)(&TestName::Test_##ContextName, RVC_INTERVAL_STRINGFY(ClassName), NameAndDesc(__VA_ARGS__), SP_INTERNAL_LINEINFO); \
|
|
|
+ TestAutoReg RVC_INTERVAL_UNIQUE_NAME(testAutoReg)(&TestName::Test, RVC_INTERVAL_STRINGFY(ClassName), NameAndDesc(__VA_ARGS__), SP_INTERNAL_LINEINFO); \
|
|
|
} \
|
|
|
void TestName::PreTest_##ContextName(ServiceName##_##ContextName##_Req& Req)
|
|
|
|
|
|
@@ -722,7 +746,7 @@ private:
|
|
|
namespace { \
|
|
|
struct TestName : ClassName { \
|
|
|
CSmartPointer<ITransactionContext> mMockTrans; \
|
|
|
- TestName():mMockTrans(CreateMockTransactionContext(this->GetFunction())){}; \
|
|
|
+ TestName():mMockTrans(CreateMockTransactionContext(nullptr)){}; \
|
|
|
ErrorCodeEnum Test() { \
|
|
|
TestContext(mMockTrans); \
|
|
|
DWORD dwUserCode = 0, dwNoUsed = 0; \
|
|
|
@@ -755,15 +779,33 @@ struct Matcher {
|
|
|
|
|
|
# define RVC_INTERNAL_STRINGIFY(expr) #expr
|
|
|
|
|
|
-#define INTERNAL_RVC_REGISTER_TEST_CASE_CONTEXT2(TestName, EntityClassName, ServiceName, ContextName, ...) \
|
|
|
+#define INTERNAL_TEST_CASE_ENTITY_CONTEXT2(TestName, SubEntityClassName, EntityClassName, ServiceName, ContextName, ...) \
|
|
|
namespace { \
|
|
|
- struct TestName : TwoWayContextTestCaseT<EntityClassName, ServiceName##_##ContextName##_Req, ServiceName##_##ContextName##_Ans> { \
|
|
|
+ struct SubEntityClassName : public EntityClassName { \
|
|
|
+ SubEntityClassName():m_pEntityFunctionDelegrate(nullptr){}\
|
|
|
+ CSmartPointer<IEntityFunction> GetFunction() { return m_pEntityFunctionDelegrate; } \
|
|
|
+ void MockEntityFunction(CSmartPointer<IEntityFunction> const& func) { m_pEntityFunctionDelegrate = func.GetRawPointer(); } \
|
|
|
+ private: \
|
|
|
+ IEntityFunction* m_pEntityFunctionDelegrate; \
|
|
|
+ }; \
|
|
|
+ struct TestName : public TwoWayContextTestCaseT<SubEntityClassName, ServiceName##_##ContextName##_Req, ServiceName##_##ContextName##_Ans> { \
|
|
|
TestName(TestTwoWayFunc func):TwoWayContextTestCaseT(func){ Initial(); }\
|
|
|
void Initial(); \
|
|
|
using TwoWayResultType = ServiceName##_##ContextName##_Ans; \
|
|
|
using AnsMatcher = Matcher<TwoWayResultType>; \
|
|
|
using AnsMachers = std::vector< AnsMatcher >; \
|
|
|
AnsMachers matchers; \
|
|
|
+ CSmartPointer<IEntityFunction> MockGetFunction() \
|
|
|
+ { \
|
|
|
+ LOG_FUNCTION(); \
|
|
|
+ if (pEntityBase != nullptr) { \
|
|
|
+ Dbg("Get function from entity."); \
|
|
|
+ return pEntityBase->GetFunction(); \
|
|
|
+ } \
|
|
|
+ else { \
|
|
|
+ return nullptr; \
|
|
|
+ } \
|
|
|
+ } \
|
|
|
ErrorCodeEnum PostTest() { \
|
|
|
ErrorCodeEnum result = Error_Succeed; \
|
|
|
for( AnsMachers::const_iterator it = matchers.begin(), itEnd = matchers.end(); it != itEnd;++it) { \
|
|
|
@@ -780,12 +822,12 @@ struct Matcher {
|
|
|
return result; \
|
|
|
} \
|
|
|
}; \
|
|
|
- TestAutoReg RVC_INTERVAL_UNIQUE_NAME(testAutoReg)( new TestName(&EntityClassName::ContextName) , RVC_INTERVAL_STRINGFY(EntityClassName), NameAndDesc(__VA_ARGS__), SP_INTERNAL_LINEINFO); \
|
|
|
+ TestAutoReg RVC_INTERVAL_UNIQUE_NAME(testAutoReg)( new TestName(&SubEntityClassName::ContextName) , RVC_INTERVAL_STRINGFY(EntityClassName), NameAndDesc(__VA_ARGS__), SP_INTERNAL_LINEINFO); \
|
|
|
} \
|
|
|
void TestName::Initial()
|
|
|
|
|
|
-#define INTERNAL_RVC_REGISTER_TEST_CASE_CONTEXT(EntityClassName, ServiceName, ContextName, ... ) \
|
|
|
- INTERNAL_RVC_REGISTER_TEST_CASE_CONTEXT2(RVC_INTERVAL_UNIQUE_NAME(CVRtxetnoCtseTduS), EntityClassName, ServiceName, ContextName, __VA_ARGS__)
|
|
|
+#define INTERNAL_TEST_CASE_ENTITY_CONTEXT(EntityClassName, ServiceName, ContextName, ... ) \
|
|
|
+ INTERNAL_TEST_CASE_ENTITY_CONTEXT2(RVC_INTERVAL_UNIQUE_NAME(CVRtxetnoCtseTduS), RVC_INTERVAL_UNIQUE_NAME(SubEntityClassName), EntityClassName, ServiceName, ContextName, __VA_ARGS__)
|
|
|
|
|
|
#define INNER_ANSWER_CHECK(Expression, Description, TolerateLevel) \
|
|
|
do { \
|
|
|
@@ -809,6 +851,6 @@ struct Matcher {
|
|
|
|
|
|
#define ANSWER_CHECK(expr) INNER_ANSWER_CHECK(expr, RVC_INTERNAL_STRINGIFY(expr), Tolerate::Ignore)
|
|
|
#define ANSWER_REQUIRE(expr) INNER_ANSWER_CHECK(expr, RVC_INTERNAL_STRINGIFY(expr), Tolerate::Strict)
|
|
|
-#define RVC_TEST_CASE_VOID_CONTEXT_TWO_WAY(entityClassName, serviceName, contextName, ... ) INTERNAL_RVC_REGISTER_TEST_CASE_CONTEXT(entityClassName, serviceName, contextName, __VA_ARGS__ )
|
|
|
+#define RVC_TEST_CASE_ENTITY_CONTEXT(entityClassName, serviceName, contextName, ... ) INTERNAL_TEST_CASE_ENTITY_CONTEXT(entityClassName, serviceName, contextName, __VA_ARGS__ )
|
|
|
|
|
|
#endif //_RVC_SPTEST_H__
|