Browse Source

Z991239-632 #comment importantgit commit -m Z991239-632

gifur 5 years ago
parent
commit
365a1091ea

+ 1 - 1
Common/SpBase.h

@@ -978,7 +978,7 @@ public:
 	virtual ~CEntityBase() { if(m_pEntityFunction != nullptr) delete m_pEntityFunction; }
 
 	/** get entity service function */
-	CSmartPointer<IEntityFunction> GetFunction() { return m_pEntityFunction; }
+	virtual CSmartPointer<IEntityFunction> GetFunction() { return m_pEntityFunction; }
 
 #ifdef _WIN32
 #if (!defined(SPABASE_LINKED_AS_STATIC_LIBRARY) && !defined(SPBASE_EXPORTS))

+ 79 - 37
Common/SpTest.h

@@ -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__

+ 25 - 1
test/module/mod_sample/mod_SampleEntity.cpp

@@ -58,7 +58,7 @@ RVC_TEST_CASE_CONTEXT_TWO_WAY(CSampleEntity, SampleService, TwoWayFuncOverlap, "
 	TWO_WAY_CHECK_ANSWER_END()
 }
 
-RVC_TEST_CASE_VOID_CONTEXT_TWO_WAY(CSampleEntity, SampleService, TwoWayFuncNormal, "TwoWayFuncNormal", "XXXXX")
+RVC_TEST_CASE_ENTITY_CONTEXT(CSampleEntity, SampleService, TwoWayFuncNormal, "TwoWayFuncNormal", "XXXXX")
 {
 	Req.tbool = true;
 	Req.tchar = 'I';
@@ -81,6 +81,30 @@ RVC_TEST_CASE_VOID_CONTEXT_TWO_WAY(CSampleEntity, SampleService, TwoWayFuncNorma
 	ANSWER_CHECK(Ans.sarray_string[2] == "String3");    /*this would not be invoked ever*/
 }
 
+
+RVC_TEST_CASE_ENTITY_CONTEXT(CSampleEntity, SampleService, TwoWayFuncNormal, "TwoWayFuncNormal", "YYYY")
+{
+	Req.tbool = true;
+	Req.tchar = 'I';
+	Req.tint = 123;
+	Req.tuint = 123;
+	Req.tshort = 123;
+	Req.tushort = 123;
+	Req.tuchar = 'I';
+	Req.tstring = "SampleService_TwoWayFuncNormal_Req::tstring::xclvmsdiofjweoij3r283908u238925j4ioijn;klgnfakjsfsfhffjeoiwjhoi";
+	Req.twstring = "SampleService_TwoWayFuncNormal_Req::twstring::xclvmsdiofjweoij3r283908u238925j4ioijn;klgnfakjsfsfhffjeoiwjhoi";
+	Req.tfloat = 123.456f;
+	Req.tdouble = 123.456;
+	Req.tblob.Clear();
+	Req.tint64 = 123;
+	Req.tuint64 = 123;
+
+	ANSWER_CHECK(Ans.sarray_string.GetCount() == 3);  
+	ANSWER_REQUIRE(Ans.sarray_string[0] == "String1"); 
+	ANSWER_REQUIRE(Ans.sarray_string[1] == "String2"); 
+	ANSWER_CHECK(Ans.sarray_string[2] == "String3");
+}
+
 SP_BEGIN_ENTITY_MAP()
 	SP_ENTITY(CSampleEntity)
 SP_END_ENTITY_MAP()

+ 14 - 5
test/module/mod_sample/mod_SampleEntity.h

@@ -168,6 +168,9 @@ public:
 
 	void TestCaseDemo()
 	{
+
+#if 0
+
 		/** simple test way, user declare and implement the test method*/
 		AddTransMethod(&CSampleEntity::TestTwoWayFuncWithID);
 
@@ -192,7 +195,6 @@ public:
 		struct TwoWayFuncOverlapTestCase :
 			public TwoWayMethodTestCaseT<SampleService_TwoWayFuncOverlap_Req, SampleService_TwoWayFuncOverlap_Ans>
 		{
-			//TwoWayFuncOverlapTestCase(CSampleEntity* ent, TestTwoWayFunc testFunc) :TwoWayMethodTestCaseT(ent, testFunc) {}
 			using TwoWayMethodTestCaseT::TwoWayMethodTestCaseT;
 
 			void PreTest() override
@@ -216,22 +218,23 @@ public:
 		};
 
 		AddMethodTestCase(new TwoWayFuncOverlapTestCase(this, &CSampleEntity::TwoWayFuncOverlap));
+
+#endif
+
 	}
 
 #if 0
 	TESTCASE_OVERRIDE_ON_EXAM_AND_IMPLEMENT()
-
 #else
-
 	void OnExam(CSmartPointer<ITransactionContext> pTransactionContext) override
 	{
 		LOG_FUNCTION();
-		TestConfig defaultConfig;
+		TestConfig defaultConfig{this->GetEntityName()};
 		std::vector<TestCase> const& allTestCases = GetRegistryHub().GetTestCaseRegistry().getAllTests(defaultConfig);
 		ErrorCodeEnum result = (allTestCases.size() > 0) ? Error_Succeed : Error_IgnoreAll;
 		for (std::vector<TestCase>::const_iterator itStart = allTestCases.begin(), itEnd = allTestCases.end(); itStart != itEnd; ++itStart) {
 			TestCaseInfo const& testCaseInfo = itStart->GetTestInfo();
-			ErrorCodeEnum testResult = itStart->RunTest();
+			ErrorCodeEnum testResult = itStart->RunTest(this);
 			if (testResult != Error_Succeed) {
 				ERR("TestCase<%s %s> %s failed the test, return %s.",
 					testCaseInfo.strName.c_str(), 
@@ -352,6 +355,12 @@ public:
 		ErrorCodeEnum ec = Error_Succeed;
 
 		ctx->Answer(__CheckTwoWayFuncNormal(ctx));
+
+		Dbg("To GetFunction");
+		if (GetFunction() == nullptr) {
+			return Error_Null;
+		}
+		Dbg("To GetFunction succeed.");
 		return ec;
 	}