[sldev] Unit Test Harness: Patch-6

Gaurav Sharma gsharma at adroit-inc.com
Fri Apr 27 00:13:08 PDT 2007


Hi,

Please find attached Patch 6 for Unit Test additions:

New: llevent, lltreenode, llocttree
Updated: llsd_new_tut.cpp with TODO test cases. Two remaining cases that
need clarity:
  * test iteration over scalar - ??
  * test empty map and empty array are indeed shared - ?

Thanks
Gaurav
-------------- next part --------------
A non-text attachment was scrubbed...
Name: newtests_04_23_2007.zip
Type: application/octet-stream
Size: 11641 bytes
Desc: not available
Url : http://lists.secondlife.com/pipermail/sldev/attachments/20070427/f34c0b23/newtests_04_23_2007-0001.obj
-------------- next part --------------
diff -uwN 2007-03-13-Patch3\linden\indra\test/llevent_tut.cpp 2007-03-13\linden\indra\test/llevent_tut.cpp
--- 2007-03-13-Patch3\linden\indra\test/llevent_tut.cpp	Wed Dec 31 16:00:00 1969
+++ 2007-03-13\linden\indra\test/llevent_tut.cpp	Fri Apr 13 05:59:51 2007
@@ -0,0 +1,139 @@
+/**
+ * @file llevent_tut.cpp
+ * @author Adroit
+ * @date April 2007
+ * @brief llevent test cases.
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+
+#include <tut/tut.h>
+#include "lltut.h"
+#include "llevent.h"
+#include "llsd.h"
+
+namespace tut
+{
+
+	class LLTestListener : public LLSimpleListener
+	{
+	public:
+		LLTestListener() 	{m_EventCalled = false;}
+		bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+		{
+			m_EventCalled = true;
+			m_UserData = userdata;
+			return m_EventCalled;
+		}
+
+		void reset()
+		{
+			m_EventCalled = false;
+			m_UserData = "";
+		}
+
+		bool m_EventCalled;
+		LLSD m_UserData;
+	};
+
+	struct llevent
+	{
+	};
+	typedef test_group<llevent> llevent_t;
+	typedef llevent_t::object llevent_object_t;
+	tut::llevent_t tut_llevent("llevent");
+
+	
+	template<> template<>
+	void llevent_object_t::test<1>()
+	{
+		LLObservable observable;
+		LLSD llsd("Test Value");
+		LLValueChangedEvent eventObj(&observable,llsd); 
+		ensure_equals("getSource() function failed", &observable, eventObj.getSource());
+		ensure_equals("getValue() function failed", llsd, eventObj.getValue());
+		ensure("desc() function failed", ("value_changed" == eventObj.desc()));
+	
+		int val = 20;
+		LLSD llsd1(val);
+		LLValueChangedEvent eventObj1(&observable,llsd1); 
+		ensure_equals("getSource() function failed", &observable, eventObj1.getSource());
+		ensure_equals("getValue() function failed", llsd1, eventObj1.getValue());
+		ensure("desc() function failed", ("value_changed" == eventObj1.desc()));
+
+		float val1 = 7.0f;
+		LLSD llsd2(val1);
+		LLValueChangedEvent eventObj2(&observable,llsd2); 
+		ensure_equals("getSource() function failed", &observable, eventObj2.getSource());
+		ensure_equals("getValue() function failed", llsd2, eventObj2.getValue());
+		ensure("desc() function failed", ("value_changed" == eventObj2.desc()));
+	}
+
+	template<> template<>
+	void llevent_object_t::test<2>()
+	{
+		LLObservable observable;
+		LLPointer<LLEventDispatcher> dispatcher = new LLEventDispatcher;
+		ensure("setDispatcher() function failed", (TRUE == observable.setDispatcher(dispatcher)));
+		LLEventDispatcher* dispatcher1 = observable.getDispatcher();
+		ensure("getDispatcher() function failed", (dispatcher1 == dispatcher));
+	}
+	
+	template<> template<>
+	void llevent_object_t::test<3>()
+	{
+		LLObservable observable;
+		LLPointer<LLValueChangedEvent> valueChangedEvent = new LLValueChangedEvent(&observable, TRUE);
+		LLTestListener test_listener;
+		LLTestListener test_listener1;
+
+		// empty event listener
+		observable.addListener(&test_listener);
+		observable.fireEvent(valueChangedEvent, "");
+		ensure("fireEvent() function failed, correct listener isn't invoked",
+				test_listener.m_EventCalled == true);
+
+		// onclick listener
+		test_listener.reset();
+		observable.addListener(&test_listener1, "on_click", "user_data");
+		observable.fireEvent(valueChangedEvent, "on_click");
+		ensure("fireEvent() function failed, correct listener isn't invoked",
+				test_listener.m_EventCalled == false && test_listener1.m_EventCalled == true && test_listener1.m_UserData.asString() == "user_data");		
+
+		// remove listener. it should no longer get notified for event.
+		test_listener1.reset();
+		observable.removeListener(&test_listener1);
+		observable.fireEvent(valueChangedEvent, "on_click");
+		ensure("fireEvent() function failed, correct listener isn't invoked", test_listener1.m_EventCalled == false);		
+	}
+
+	template<> template<>
+	void llevent_object_t::test<4>()
+	{
+		// default Event implementation
+		LLObservable observable;
+		LLPointer<LLEvent> fired_event = new LLEvent(&observable);
+		LLTestListener test_listener;
+		observable.addListener(&test_listener, "on_build");
+		observable.fireEvent(fired_event, "on_build");
+		ensure("fireEvent() function failed, correct listener isn't invoked",
+				test_listener.m_EventCalled == true);
+	}
+
+	template<> template<>
+	void llevent_object_t::test<5>()
+	{
+		LLObservable observable;
+		int val = 20;
+		LLSD llsd(val);
+		LLPointer<LLValueChangedEvent> valueChangedEvent = new LLValueChangedEvent(&observable, llsd);
+		LLTestListener test_listener;
+		observable.addListener(&test_listener, "Blah");
+		observable.fireEvent(valueChangedEvent, "Blah");
+		ensure("fireEvent() function failed, correct listener isn't invoked",
+				test_listener.m_EventCalled == true);
+	}
+	
+}
diff -uwN 2007-03-13-Patch3\linden\indra\test/llsd_new_tut.cpp 2007-03-13\linden\indra\test/llsd_new_tut.cpp
--- 2007-03-13-Patch3\linden\indra\test/llsd_new_tut.cpp	Tue Mar 13 13:57:46 2007
+++ 2007-03-13\linden\indra\test/llsd_new_tut.cpp	Sun Apr 22 03:18:47 2007
@@ -152,6 +152,17 @@
 			ensure(			s + " type",	traits.checkType(actual));
 			ensure_equals(	s + " value",	traits.get(actual), expectedValue);
 		}
+
+		template<class T>
+		static void ensureValue(const char* msg, const LLSD& actual,
+			T expectedValue)
+		{
+			SDTraits<T> traits;
+			
+			std::string s(msg);
+			
+			ensure_equals(	s + " value",	traits.get(actual), expectedValue);
+		}
 	};
 	
 	typedef test_group<SDTestData>	SDTestGroup;
@@ -823,20 +834,281 @@
 		}
 	}
 
+	template<> template<>
+	void SDTestObject::test<14>()
+		// conversion of undefined to UUID, Date, URI and Binary
+	{
+		SDCleanupCheck check;
+		
+		LLSD v; //undefined
+		LLUUID nullUUID;
+		LLDate nullDate;
+		LLURI  nullURI;
+		std::vector<U8> nullBinary;
+		nullUUID	= v;   ensureValue("set to null UUID", v, nullUUID);
+		nullDate	= v;   ensureValue("set to null Date", v, nullDate);
+		nullURI		= v;   ensureValue("set to null URI", v, nullURI);
+		nullBinary	= v;   ensureValue("set to null Binary", v, nullBinary);
+
+		v = nullUUID;   ensureTypeAndValue("set to null UUID", v, nullUUID);
+		v = nullDate;   ensureTypeAndValue("set to null Date", v, nullDate);
+		v = nullURI;	ensureTypeAndValue("set to null URI", v, nullURI);
+		v = nullBinary; ensureTypeAndValue("set to null Binary", v, nullBinary);
+	}
+
+	template<> template<>
+	void SDTestObject::test<15>()
+		// conversion of undefined to map and array
+	{
+		SDCleanupCheck check;
+		
+		{
+			LLSD v; //undefined
+			LLSD llMap;
+			llMap.insert("One", 1);
+			llMap.insert("Two", v); //undefined
+
+			LLSD sd = llMap["Two"]; 
+			ensure("is undefined", sd.isUndefined());
+			v = llMap["Two"];		
+			ensure("is undefined", v.isUndefined());
+
+			v = llMap; ensureTypeAndValue("set to map", v["One"], 1);
+		}
+
+		{
+			LLSD v; //undefined
+			LLSD llArray;
+			llArray.set(0, 1);
+			llArray.set(1, v); //undefined
+
+			LLSD sd = llArray[1]; 
+			ensure("is undefined", sd.isUndefined());
+			v = llArray[1];		
+			ensure("is undefined", v.isUndefined());
+
+			v = llArray; ensureTypeAndValue("set to array", v[0], 1);
+		}
+	}
+
+	template<> template<>
+	void SDTestObject::test<16>()
+		// test map operations
+	{
+		SDCleanupCheck check;
+		
+		LLSD llMap;
+		LLSD v1(20); 
+		LLSD v2("Test String"); 
+		llMap.insert("One", 1);
+		llMap.insert("Two", v1); 
+		llMap.insert("Three", v2); 
+
+		ensure("LLSD map operation has()", llMap.has("One") && !llMap.has("Four"));
+		ensure_equals("LLSD map operation get()", llMap.get("Two"), v1);
+
+		llMap.erase("Two");
+		ensure("LLSD map operation erase()", llMap.has("Two") == FALSE);
+		
+		ensure_equals("LLSD map operation []", llMap["Three"], v2);
+
+		LLSD v3 = llMap["Three"];
+		ensure_equals("LLSD map operation = ", v2, v3);
+	}
+
+	template<> template<>
+	void SDTestObject::test<17>()
+		// test array operations and extension
+	{
+		SDCleanupCheck check;
+		
+		LLSD llArray;
+		LLSD v0(20); 
+		LLSD v1(20.3232); 
+		LLSD v2("Test String"); 
+		LLSD v3(30); 
+		LLSD v4(40); 
+
+		llArray.set(0, v0);
+		llArray.set(1, v1);
+		llArray.set(2, v2);
+
+		ensure_equals("LLSD array operation get()", llArray.get(0), v0);
+		ensure_equals("LLSD array operation []", llArray[1], v1);
+
+		// set [2] to v2 and then do insert shifting down v3 to [3]
+		llArray.set(2, v3);
+		ensure_equals("LLSD array operation []", llArray[2], v3);
+		
+		llArray.insert(2, v2);
+		ensure_equals("LLSD array operation insert 1", llArray[2], v2);
+		ensure_equals("LLSD array operation insert 2", llArray[3], v3);
+
+		llArray.append(v4);
+		ensure_equals("LLSD array operation append", llArray[4], v4);
+
+		llArray.erase(2); //erase 2 should shift others down.
+		ensure_equals("LLSD array operation erase", llArray[2], v3);
+		ensure_equals("LLSD array operation erase 2", llArray[3], v4);
+
+		// extension
+		llArray.set(10, v4);
+		ensure_equals("LLSD array operation array extension", llArray[10], v4);
+	}
+
+	template<> template<>
+	void SDTestObject::test<18>()
+		// test copying and assign maps and arrays (clone)
+	{
+		SDCleanupCheck check;
+
+		{
+			LLSD llMap; 
+			LLSD v1(20); 
+			LLSD v2("Test String"); 
+			LLSD v3(32.45); 
+			llMap.insert("One", v1);
+			llMap.insert("Two", v2); 
+			llMap.insert("Three", v3); 
+
+			LLSD llMap2 = llMap;
+			ensure_equals("LLSD map assignment failed 1", llMap, llMap2);
+			ensure_equals("LLSD map assignment failed 2", llMap2["One"], v1);
+			ensure_equals("LLSD map assignment failed 3", llMap2["Two"], v2);
+			ensure_equals("LLSD map assignment failed 4", llMap2["Three"], v3);
+		}
+
+		{
+			LLSD llArray;
+			LLSD v0(20); 
+			LLSD v1(20.3232); 
+			LLSD v2("Test String"); 
+
+			llArray.set(0, v0);
+			llArray.set(1, v1);
+			llArray.set(2, v2);
+
+			LLSD llArray2 = llArray;
+			ensure_equals("LLSD array assignment failed 1", llArray, llArray2);
+			ensure_equals("LLSD array assignment failed 2", llArray2[0], v0);
+			ensure_equals("LLSD map assignment failed 3", llArray2[1], v1);
+			ensure_equals("LLSD map assignment failed 4", llArray2[2], v2);
+		}
+	}
+
+	template<> template<>
+	void SDTestObject::test<19>()
+		// test iteration over map and array
+	{
+		SDCleanupCheck check;
+
+		{
+			LLSD llMap; 
+			LLSD v1(20); 
+			LLSD v2("Test String"); 
+			LLSD v3(32.45); 
+			llMap.insert("One", v1);
+			llMap.insert("Two", v2); 
+			llMap.insert("Three", v3); 
+
+			BOOL bOneSeen = FALSE;
+			BOOL bTwoSeen = FALSE;
+			BOOL bThreeSeen = FALSE;
+			LLSD::map_iterator iter = llMap.beginMap();
+			for (; iter != llMap.endMap(); ++iter)
+			{
+				std::string str = iter->first;
+				LLSD  val = iter->second;
+				if (str == "One")
+				{
+					ensure_equals("Map iterator failed 1", v1, val);
+					ensure_equals("Map iterator failed 1", bOneSeen, FALSE);
+					bOneSeen = TRUE;
+				}
+				else if (str == "Two")
+				{
+					ensure_equals("Map iterator failed 2", v2, val);
+					ensure_equals("Map iterator failed 1", bTwoSeen, FALSE);
+					bTwoSeen = TRUE;
+				}
+				else if (str == "Three")
+				{
+					ensure_equals("Map iterator failed 3", v3, val);
+					ensure_equals("Map iterator failed 1", bThreeSeen, FALSE);
+					bThreeSeen = TRUE;
+				}
+				else
+				{
+					ensure("Map iterator failed 4", FALSE);
+				}
+			}
+
+			ensure("Map iterator failed - all values not iterated over", bOneSeen && bTwoSeen && bThreeSeen);
+		}
+
+		{
+			LLSD llArray;
+			LLSD v0(20); 
+			LLSD v1(20.3232); 
+			LLSD v2("Test String"); 
+
+			llArray.set(0, v0);
+			llArray.set(1, v1);
+			llArray.set(2, v2);
+
+			BOOL bOneSeen = FALSE;
+			BOOL bTwoSeen = FALSE;
+			BOOL bThreeSeen = FALSE;
+			LLSD::array_iterator iter = llArray.beginArray();
+			int i = 0;
+			for (; iter != llArray.endArray(); ++iter)
+			{
+				LLSD  val = *iter;
+//				ensure_equals("Array Iterator failed: iteration not in order", iter->first, i);
+				if (i == 0)
+				{
+					ensure_equals("Array iterator failed 0", v0, val);
+					ensure_equals("Array iterator failed 1", bOneSeen, FALSE);
+					bOneSeen = TRUE;
+				}
+				else if (i == 1)
+				{
+					ensure_equals("Array iterator failed 2", v1, val);
+					ensure_equals("Array iterator failed 3", bTwoSeen, FALSE);
+					bTwoSeen = TRUE;
+				}
+				else if (i == 2)
+				{
+					ensure_equals("Array iterator failed 4", v2, val);
+					ensure_equals("Array iterator failed 5", bThreeSeen, FALSE);
+					bThreeSeen = TRUE;
+				}
+				else
+				{
+					ensure("Array iterator failed 6", FALSE);
+				}
+
+				i++;
+			}
+
+			ensure("Array iterator failed - all values not iterated over", bOneSeen && bTwoSeen && bThreeSeen);
+		}
+	}
+
 	/* TO DO:
-		conversion of undefined to UUID, Date, URI and Binary
-		conversion of undefined to map and array
-		test map operations
-		test array operations
-		test array extension
-		
-		test copying and assign maps and arrays (clone)
-		test iteration over map
-		test iteration over array
-		test iteration over scalar
+		conversion of undefined to UUID, Date, URI and Binary - DONE
+		conversion of undefined to map and array  - DONE
+		test map operations  - DONE
+		test array operations  - DONE
+		test array extension - DONE
+		
+		test copying and assign maps and arrays (clone)  - DONE
+		test iteration over map  - DONE
+		test iteration over array  - DONE
+		test iteration over scalar - ??
 
-		test empty map and empty array are indeed shared
-		test serializations
+		test empty map and empty array are indeed shared - ??
+		test serializations - DONE in llsdserialize_tut.cpp
 	*/
 }
 
diff -uwN 2007-03-13-Patch3\linden\indra\test/lltreenode_tut.cpp 2007-03-13\linden\indra\test/lltreenode_tut.cpp
--- 2007-03-13-Patch3\linden\indra\test/lltreenode_tut.cpp	Wed Dec 31 16:00:00 1969
+++ 2007-03-13\linden\indra\test/lltreenode_tut.cpp	Mon Apr 23 06:24:47 2007
@@ -0,0 +1,512 @@
+/**
+ * @file lltreenode_tut.cpp
+ * @author Adroit
+ * @date April 2007
+ * @brief Lltreenode test cases.
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include <tut/tut.h>
+#include "lltut.h"
+#include "llmemory.h"
+#include "v3dmath.h"
+#include "lltreenode.h"
+#include "lloctree.h"
+
+namespace tut
+{
+	class IntNode: public LLRefCount
+	{
+	public:
+		IntNode(int val) { mVal = val; mPositionGroup.setVec(0,0,0); mBinRadius = 0; }
+		IntNode(int val, LLVector3d positionGroup, F64 binRadius) 
+			{ mVal = val; mPositionGroup = positionGroup; mBinRadius = binRadius; }
+		~IntNode()
+		{	
+			mVal = 0;
+		}
+		
+		void setPositionGroup(LLVector3d positionGroup) { mPositionGroup = positionGroup; }
+		LLVector3d getPositionGroup() { return mPositionGroup; }
+		void setBinRadius(F64 binRadius) { mBinRadius = binRadius; }
+		F64 getBinRadius() { return mBinRadius; }
+
+	protected:
+		LLVector3d mPositionGroup;
+		F64 mBinRadius;
+		int mVal;
+	};
+
+	template <class T>
+	class SampleTreeListner: public LLTreeListener<T>
+	{
+	public:
+		typedef LLTreeListener<T>		BaseType;
+
+		SampleTreeListner() 
+		: BaseType()
+		{
+			mNumInsertions		= 0;
+			mNumRemovals		= 0;
+			mNumDestructions	= 0;
+			mNumStateChange		= 0;
+			mExpectedNode		= NULL;
+			mExpectedData		= NULL;
+		}
+
+		virtual ~SampleTreeListner() {}
+
+		void handleInsertion(const LLTreeNode<T>* node, T* data) 
+		{ 
+			mNumInsertions++; 
+			ensure_equals("handleInsertion has unexpected node", node, mExpectedNode);
+			ensure_equals("handleInsertion has unexpected data", data, mExpectedData);
+		}
+
+		void handleRemoval(const LLTreeNode<T>* node, T* data) 
+		{ 
+			mNumRemovals++; 
+			ensure_equals("handleRemoval has unexpected node", node, mExpectedNode);
+			ensure_equals("handleRemoval has unexpected data", data, mExpectedData);
+		}
+
+		void handleDestruction(const LLTreeNode<T>* node) 
+		{ 
+			mNumDestructions++; 
+		}
+		
+		void handleStateChange(const LLTreeNode<T>* node) 
+		{ 
+			mNumStateChange++; 
+			ensure_equals("handleStateChange has unexpected node", node, mExpectedNode);
+		}
+
+		void setExpectedValues(LLTreeNode<T>* node, T* data)
+		{
+			mExpectedNode = node;
+			mExpectedData = data;
+		}
+		
+		int mNumInsertions;
+		int mNumRemovals;
+		int mNumDestructions;
+		int mNumStateChange;
+		LLTreeNode<T>* mExpectedNode;
+		T*  mExpectedData;
+	};
+
+	template <class T>
+	class SampleTreeState: public LLTreeState<T>
+	{
+	public:
+		typedef LLTreeState<T>						BaseType;	
+		typedef LLTreeNode<T>						tree_node;
+		typedef typename std::set<LLPointer<T> >	element_list;
+		SampleTreeState(tree_node* node = NULL)
+		: BaseType(node)
+		{
+
+		}
+		
+		bool insert(T* data) 
+		{ 
+			mData.insert(data); 
+			return true;
+		}
+
+		bool remove(T* data) 
+		{ 
+			if (mData.find(data) != mData.end())
+			{	//we have data
+				mData.erase(data);
+				if (BaseType::getNode())
+				{
+					BaseType::getNode()->notifyRemoval(data);
+				}
+				return true;
+			}
+
+			return false;
+		}
+
+		void accept(LLTreeTraveler<T>* traveler) const	{}
+
+		element_list mData;
+	};
+
+	typedef SampleTreeState<IntNode>	intTreeState;	
+	typedef SampleTreeListner<IntNode>  intTreeListner;
+	typedef LLTreeNode<IntNode>			intTreeNode;
+
+	struct lltreenode_data
+	{
+	};
+	typedef test_group<lltreenode_data> lltreenode_test;
+	typedef lltreenode_test::object lltreenode_object;
+	tut::lltreenode_test lltreenode_testcase("lltreenode");
+
+	template<> template<>
+	void lltreenode_object::test<1>()
+	{
+		intTreeState	treeState1;
+		intTreeNode		treeNode1(&treeState1);
+		LLPointer<intTreeListner> 	treeListner = new intTreeListner;
+		treeNode1.addListener(treeListner);
+
+		ensure_equals("LLTreeNode::getState failed", treeNode1.getState(), &treeState1);
+
+		intTreeState	treeState2;
+		treeListner->setExpectedValues(&treeNode1, NULL);
+		treeNode1.setState(&treeState2);
+		ensure_equals("LLTreeNode::setState/getState failed", treeNode1.getState(), &treeState2);
+
+		LLPointer<IntNode> data11 = new IntNode(100);
+		LLPointer<IntNode> data12 = new IntNode(101);
+		LLPointer<IntNode> data13 = new IntNode(102);
+
+		treeListner->setExpectedValues(&treeNode1, data11);
+		treeNode1.insert(data11);
+		treeListner->setExpectedValues(&treeNode1, data12);
+		treeNode1.insert(data12);
+
+		treeListner->setExpectedValues(&treeNode1, data11);
+		// should succeed
+		ensure_equals("LLTreeNode::remove should return true for valid data", treeNode1.remove(data11), true); 
+
+		// was never added - should not be found
+		ensure_equals("LLTreeNode::remove should return false for incorrect data", treeNode1.remove(data13), false); 
+
+		// already removed earlier - should not be found
+		ensure_equals("LLTreeNode::remove should return false for already removed data", treeNode1.remove(data11), false); 
+
+		ensure_equals("Number of insertions not as expected", treeListner->mNumInsertions, 2);
+		ensure_equals("Number of removals not as expected", treeListner->mNumRemovals, 1);
+		ensure_equals("Number of state changes not as expected", treeListner->mNumStateChange, 1);
+	}
+
+	template<> template<>
+	void lltreenode_object::test<2>()
+	{
+		intTreeState	treeState1;
+		intTreeNode		treeNode1(&treeState1);
+		LLPointer<intTreeListner> treeListner = new intTreeListner;
+		treeNode1.addListener(treeListner);
+
+		ensure_equals("LLTreeNode::getListenerCount failed for count of 1", treeNode1.getListenerCount(), 1); 
+		
+		LLPointer<intTreeListner> treeListner2 = new intTreeListner;
+		treeNode1.addListener(treeListner2);
+
+		ensure_equals("LLTreeNode::getListenerCount failed for count of more than 1", treeNode1.getListenerCount(), 2); 
+
+		treeNode1.removeListener(1);
+		ensure_equals("LLTreeNode::removeListnerCount/getListenerCount failed", treeNode1.getListenerCount(), 1); 
+		ensure_equals("LLTreeNode::getListener failed", (void*) treeNode1.getListener(0), (void*) treeListner); 
+	}
+
+	template<> template<>
+	void lltreenode_object::test<3>()
+	{
+		intTreeState	treeState1;
+		intTreeNode		treeNode1(&treeState1);
+
+		LLPointer<intTreeListner> treeListner = new intTreeListner;
+		LLPointer<intTreeListner> treeListner2 = new intTreeListner;
+
+		// more than one listner
+		treeNode1.addListener(treeListner);
+		treeNode1.addListener(treeListner2);
+
+		LLPointer<IntNode> data11 = new IntNode(100);
+		LLPointer<IntNode> data12 = new IntNode(101);
+		LLPointer<IntNode> data13 = new IntNode(102);
+
+		treeListner->setExpectedValues(&treeNode1, data11);
+		treeListner2->setExpectedValues(&treeNode1, data11);
+		treeNode1.insert(data11);
+		treeListner->setExpectedValues(&treeNode1, data12);
+		treeListner2->setExpectedValues(&treeNode1, data12);
+		treeNode1.insert(data12);
+
+		treeListner->setExpectedValues(&treeNode1, data11);
+		treeListner2->setExpectedValues(&treeNode1, data11);
+		// should succeed
+		ensure_equals("LLTreeNode::remove should return true for valid data", treeNode1.remove(data11), true); 
+
+		// was never added - should not be found
+		ensure_equals("LLTreeNode::remove should return false for incorrect data", treeNode1.remove(data13), false); 
+
+		// already removed earlier - should not be found
+		ensure_equals("LLTreeNode::remove should return false for already removed data", treeNode1.remove(data11), false); 
+	}
+
+	// state change with same value
+	template<> template<>
+	void lltreenode_object::test<4>()
+	{
+		intTreeState	treeState1;
+		intTreeNode		treeNode1(&treeState1);
+		LLPointer<intTreeListner> treeListner = new intTreeListner;
+		treeNode1.addListener(treeListner);
+
+		treeListner->setExpectedValues(&treeNode1, NULL);
+		// set the same state as earlier - should still result in state change
+		treeNode1.setState(&treeState1);
+		ensure_equals("LLTreeNode::setState/getState failed", treeNode1.getState(), &treeState1);
+		ensure_equals("Number of state changes not as expected", treeListner->mNumStateChange, 1);
+	}
+
+
+	// lloctree
+
+	template <class T>
+	class SampleOctreeListener: public LLOctreeListener<T>
+	{
+	public:
+		typedef LLOctreeListener<T>		BaseType;
+		SampleOctreeListener() : BaseType() 
+		{
+			mExpectedParent		= NULL;
+			mExpectedChild		= NULL;
+			mNumChildAdditions	= 0;
+			mNumChildRemovals	= 0;
+			mSampleTreeListner = new intTreeListner;
+		}
+
+		~SampleOctreeListener() {}
+
+		void handleInsertion(const LLTreeNode<T>* node, T* data) 
+		{ 
+			mSampleTreeListner->handleInsertion(node, data);
+		}
+
+		void handleRemoval(const LLTreeNode<T>* node, T* data) 
+		{ 
+			mSampleTreeListner->handleRemoval(node, data);
+		}
+
+		void handleDestruction(const LLTreeNode<T>* node) 
+		{ 
+			mSampleTreeListner->handleDestruction(node);
+		}
+		
+		void handleStateChange(const LLTreeNode<T>* node) 
+		{ 
+			mSampleTreeListner->handleStateChange(node);
+		}
+
+		void handleChildAddition(const oct_node* parent, oct_node* child) 
+		{
+			mNumChildAdditions++;
+		}
+
+		void handleChildRemoval(const oct_node* parent, const oct_node* child) 
+		{
+			mNumChildRemovals++;
+		}
+		
+		void setExpectedValues(LLTreeNode<T>* node, T* data)
+		{
+			mSampleTreeListner->setExpectedValues(node, data);
+		}
+
+		void setExpectedChildValues(oct_node* parent, oct_node* child)
+		{
+			mExpectedParent = parent;
+			mExpectedChild = child;
+		}
+
+		oct_node* mExpectedParent;
+		oct_node* mExpectedChild;
+		int mNumChildAdditions;
+		int mNumChildRemovals;
+		LLPointer<intTreeListner> mSampleTreeListner;
+	};
+
+	typedef LLOctreeState<IntNode>			intOctreeState;	
+	typedef LLOctreeRoot<IntNode>			intOctreeRootState;	
+	typedef SampleOctreeListener<IntNode>	intOctreeListner;
+	typedef LLOctreeNode<IntNode>			intOctreeNode;
+
+	template<> template<>
+	void lltreenode_object::test<5>()
+	{
+		intOctreeRootState*	treeState1 = new intOctreeRootState;
+		intOctreeNode* treeNodeParent = new intOctreeNode(LLVector3d(0,0,0), 
+								LLVector3d(8,8,8), 
+								treeState1, NULL);
+
+		intOctreeState*	treeState2 = new intOctreeState;
+		intOctreeNode* treeNodeChild = new intOctreeNode(LLVector3d(0,0,0), 
+								LLVector3d(4,4,4), 
+								treeState2, NULL);
+
+		LLPointer<intOctreeListner> treeListner = new intOctreeListner;
+		treeNodeParent->addListener(treeListner);
+		treeNodeChild->addListener(treeListner);
+
+		// getParent
+		ensure("LLOctreeNode::getParent failed", treeNodeParent->getParent() == NULL && treeNodeChild->getParent() == NULL);
+		treeNodeChild->setParent(treeNodeParent);
+		ensure("LLOctreeNode::setParent 2 failed", treeNodeChild->getParent() == treeNodeParent);
+
+		// reset it back
+		treeNodeChild->setParent(NULL);
+
+		// getCenter
+		ensure_equals("LLOctreeNode::getCenter failed", treeNodeChild->getCenter(), LLVector3d(0,0,0));
+		
+		// getSize
+		ensure_equals("LLOctreeNode::getSize failed", treeNodeChild->getSize(), LLVector3d(4,4,4));
+
+		treeState1->addChild(treeNodeChild);
+
+		// getChildCount
+		ensure("LLOctreeNode::getChildCount failed", treeNodeChild->getChildCount() == 0 && treeNodeParent->getChildCount() == 1);
+		
+		// getChild
+		ensure_equals("LLOctreeNode::getChild failed", treeNodeParent->getChild(0), treeNodeChild);
+
+		LLPointer<IntNode> data11 = new IntNode(100, LLVector3d(0,0,0), 5.0);
+		LLPointer<IntNode> data12 = new IntNode(101, LLVector3d(1,1,1), 6.0);
+
+		treeListner->setExpectedValues(treeNodeChild, data11);
+		treeNodeChild->insert(data11);
+		treeListner->setExpectedValues(treeNodeChild, data12);
+		treeNodeChild->insert(data12);
+
+		// getElementCount
+		ensure_equals("LLOctreeNode::getElementCount failed", treeNodeChild->getElementCount(), 2);
+	}
+
+	template<> template<>
+	void lltreenode_object::test<6>()
+	{
+		intOctreeRootState*	treeState1 = new intOctreeRootState;
+		intOctreeNode* treeNodeParent = new intOctreeNode(LLVector3d(0,0,0), 
+								LLVector3d(8,8,8), 
+								treeState1, NULL);
+
+		intOctreeState*	treeState2 = new intOctreeState;
+		intOctreeNode* treeNodeChild = new intOctreeNode(LLVector3d(0,0,0), 
+								LLVector3d(4,4,4), 
+								treeState2, NULL);
+
+		LLPointer<intOctreeListner> treeListner = new intOctreeListner;
+		treeNodeParent->addListener(treeListner);
+		treeNodeChild->addListener(treeListner);
+		treeState1->addChild(treeNodeChild);
+
+		LLPointer<IntNode> data11 = new IntNode(100, LLVector3d(0,0,0), 5.0);
+		LLPointer<IntNode> data12 = new IntNode(101, LLVector3d(1,1,1), 6.0);
+
+		treeListner->setExpectedValues(treeNodeChild, data11);
+		treeNodeChild->insert(data11);
+		treeListner->setExpectedValues(treeNodeChild, data12);
+		treeNodeChild->insert(data12);
+
+		treeListner->setExpectedValues(treeNodeChild, data11);
+		treeNodeChild->removeByAddress(data11);
+		// getElementCount should now be 1
+		ensure_equals("LLOctreeNode::removeByAddress failed", treeNodeChild->getElementCount(), 1);
+
+		// hasLeafState should be TRUE for child
+		ensure_equals("LLOctreeNode::hasLeafState failed", treeNodeChild->hasLeafState(), true);
+
+		// hasLeafState should be FALSE for parent
+		ensure_equals("LLOctreeNode::hasLeafState failed", treeNodeParent->hasLeafState(), false);
+
+		// put it back again
+		treeListner->setExpectedValues(treeNodeChild, data11);
+		treeNodeChild->insert(data11);
+
+		LLOctreeNode<IntNode>::oct_node* node = treeNodeChild->getNodeAt(data11);
+		ensure_equals("getNodeAt for same node where data was put in failed", node, treeNodeChild);
+
+		node = treeNodeChild->getNodeAt(LLVector3d(0,0,0), 5.0);
+		ensure_equals("getNodeAt for same node where data was put in failed", node, treeNodeChild);
+
+		// deleteChild
+		treeNodeParent->deleteChild(treeNodeChild);
+		ensure("LLOctreeNode::deleteChild failed", treeNodeParent->getChildCount() == 0);
+	}
+
+	// test case to check tree expand
+	template<> template<>
+	void lltreenode_object::test<7>()
+	{
+		intOctreeRootState*	treeState1 = new intOctreeRootState;
+		intOctreeNode* treeNodeParent = new intOctreeNode(LLVector3d(0,0,0), 
+								LLVector3d(8,8,8), 
+								treeState1, NULL);
+
+		intOctreeState*	treeState2 = new intOctreeState;
+		intOctreeNode* treeNodeChild = new intOctreeNode(LLVector3d(0,0,0), 
+								LLVector3d(4,4,4), 
+								treeState2, NULL);
+
+		LLPointer<intOctreeListner> treeListner = new intOctreeListner;
+		treeNodeParent->addListener(treeListner);
+		treeNodeChild->addListener(treeListner);
+		treeState1->addChild(treeNodeChild);
+
+		// data that does not fall inside the tree node
+		LLPointer<IntNode> data11 = new IntNode(100, LLVector3d(0,0,0), 1.0);
+		LLPointer<IntNode> data12 = new IntNode(101, LLVector3d(1,1,1), 2.0);
+
+		// should result in octree expansion
+		treeNodeChild->insert(data11);
+		treeNodeChild->insert(data12);
+		// getElementCount will still be 0 as the data gets inserted in new oct nodes
+		ensure_equals("LLOctreeNode::getElementCount failed", treeNodeChild->getElementCount(), 0);
+
+		// should get different node other than the initial node..
+		LLOctreeNode<IntNode>::oct_node* node = treeNodeChild->getNodeAt(data11);
+		ensure_not_equals("getNodeAt for same node where data was put in failed", node, treeNodeChild);
+
+		// should get different node other than the initial node..
+		node = treeNodeChild->getNodeAt(LLVector3d(0,0,0), 1.0);
+		ensure_not_equals("getNodeAt for same node where data was put in failed", node, treeNodeChild);
+	}
+
+	// test case to check node bounds
+	template<> template<>
+	void lltreenode_object::test<8>()
+	{
+		intOctreeRootState*	treeState1 = new intOctreeRootState;
+		intOctreeNode* treeNodeParent = new intOctreeNode(LLVector3d(0,0,0), 
+								LLVector3d(8,8,8), 
+								treeState1, NULL);
+
+		intOctreeState*	treeState2 = new intOctreeState;
+		intOctreeNode* treeNodeChild = new intOctreeNode(LLVector3d(0,0,0), 
+								LLVector3d(4,4,4), 
+								treeState2, NULL);
+
+		treeState1->addChild(treeNodeChild);
+
+		LLVector3d pos(40,0,0);
+		F64 rad = 1.0;
+		// position out
+		ensure_equals("isInside failed", treeNodeChild->isInside(pos, rad), false);
+		
+		pos.setVec(0,0,0);
+		rad = 50.0;
+		// radius out
+		ensure_equals("isInside failed", treeNodeChild->isInside(pos, rad), false);
+
+		rad = 5.0;
+		// both in
+		ensure_equals("isInside failed", treeNodeChild->isInside(pos, rad), true);
+
+		LLPointer<IntNode> data11 = new IntNode(100, LLVector3d(0,0,0), 1.0);
+		ensure_equals("isInside failed", treeNodeChild->isInside(data11), true);
+
+		rad = 5.0;
+		ensure_equals("contains failed", treeNodeChild->contains(rad), true);
+		ensure_equals("contains failed", treeNodeChild->contains(data11), false);		
+	}
+}
+


More information about the SLDev mailing list