Răsfoiți Sursa

Build: Unit tests now use CMake's test system
- Also added a unit test for the new Octree class

BearishSun 8 ani în urmă
părinte
comite
ee3e99cee9

+ 0 - 3
Source/BansheeUtility/CMakeLists.txt

@@ -34,9 +34,6 @@ include_directories(${BansheeUtility_INC})
 # Target
 add_library(BansheeUtility SHARED ${BS_BANSHEEUTILITY_SRC})
 
-add_executable(BansheeUtilityTest BsUtilityTest.cpp)
-target_link_libraries(BansheeUtilityTest BansheeUtility)
-
 # Defines
 target_compile_definitions(BansheeUtility PRIVATE -DBS_UTILITY_EXPORTS)
 

+ 0 - 2
Source/BansheeUtility/CMakeSources.cmake

@@ -168,14 +168,12 @@ set(BS_BANSHEEUTILITY_SRC_MATH
 )
 
 set(BS_BANSHEEUTILITY_INC_TESTING
-	"Testing/BsFileSystemTestSuite.h"
 	"Testing/BsTestSuite.h"
 	"Testing/BsTestOutput.h"
 	"Testing/BsConsoleTestOutput.h"
 )
 
 set(BS_BANSHEEUTILITY_SRC_TESTING
-	"Testing/BsFileSystemTestSuite.cpp"
 	"Testing/BsTestSuite.cpp"
 	"Testing/BsTestOutput.cpp"
 	"Testing/BsConsoleTestOutput.cpp"

+ 1 - 1
Source/BansheeUtility/Testing/BsFileSystemTestSuite.cpp → Source/BansheeUtility/UnitTests/BsFileSystemTestSuite.cpp

@@ -1,6 +1,6 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "Testing/BsFileSystemTestSuite.h"
+#include "UnitTests/BsFileSystemTestSuite.h"
 
 #include "Debug/BsDebug.h"
 #include "Error/BsException.h"

+ 1 - 1
Source/BansheeUtility/Testing/BsFileSystemTestSuite.h → Source/BansheeUtility/UnitTests/BsFileSystemTestSuite.h

@@ -6,7 +6,7 @@
 
 namespace bs
 {
-	class BS_UTILITY_EXPORT FileSystemTestSuite : public TestSuite
+	class FileSystemTestSuite : public TestSuite
 	{
 	public:
 		FileSystemTestSuite();

+ 5 - 4
Source/BansheeUtility/BsUtilityTest.cpp → Source/BansheeUtility/UnitTests/BsUtilityTest.cpp

@@ -1,15 +1,16 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "Testing/BsFileSystemTestSuite.h"
+//**************** Copyright (c) 2017 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "Testing/BsConsoleTestOutput.h"
+#include "UnitTests/BsUtilityTestSuite.h"
 
 using namespace bs;
 
 int main()
 {
-	SPtr<TestSuite> tests = FileSystemTestSuite::create<FileSystemTestSuite>();
+	SPtr<TestSuite> tests = UtilityTestSuite::create<UtilityTestSuite>();
+
 	ConsoleTestOutput testOutput;
 	tests->run(testOutput);
 
 	return 0;
-}
+}

+ 146 - 0
Source/BansheeUtility/UnitTests/BsUtilityTestSuite.cpp

@@ -0,0 +1,146 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "UnitTests/BsUtilityTestSuite.h"
+#include "UnitTests/BsFileSystemTestSuite.h"
+#include "Utility/BsOctree.h"
+
+namespace bs
+{
+	struct DebugOctreeElem
+	{
+		AABox box;
+		mutable OctreeElementId octreeId;
+	};
+
+	struct DebugOctreeData
+	{
+		Vector<DebugOctreeElem> elements;
+	};
+
+	struct DebugOctreeOptions
+	{
+		enum { LoosePadding = 16 };
+		enum { MinElementsPerNode = 8 };
+		enum { MaxElementsPerNode = 16 };
+		enum { MaxDepth = 12};
+
+		static simd::AABox getBounds(UINT32 elem, void* context)
+		{
+			DebugOctreeData* octreeData = (DebugOctreeData*)context;
+			return simd::AABox(octreeData->elements[elem].box);
+		}
+
+		static void setElementId(UINT32 elem, const OctreeElementId& id, void* context)
+		{
+			DebugOctreeData* octreeData = (DebugOctreeData*)context;
+			octreeData->elements[elem].octreeId = id;
+		}
+	};
+
+	typedef Octree<UINT32, DebugOctreeOptions> DebugOctree;
+	void UtilityTestSuite::startUp()
+	{
+		SPtr<TestSuite> fileSystemTests = create<FileSystemTestSuite>();
+		add(fileSystemTests);
+	}
+
+	void UtilityTestSuite::shutDown()
+	{
+	}
+
+	UtilityTestSuite::UtilityTestSuite()
+	{
+		BS_ADD_TEST(UtilityTestSuite::testOctree);
+	}
+
+	void UtilityTestSuite::testOctree()
+	{
+		DebugOctreeData octreeData;
+		DebugOctree octree(Vector3::ZERO, 800.0f, &octreeData);
+
+		struct SizeAndCount
+		{
+			float sizeMin;
+			float sizeMax;
+			UINT32 count;
+		};
+
+		SizeAndCount types[]
+		{
+			{ 0.02f, 0.2f, 2000 }, // Very small objects
+			{ 0.2f, 1.0f, 2000 }, // Small objects
+			{ 1.0f, 5.0f, 5000 }, // Medium sized objects
+			{ 5.0f, 30.0f, 4000 }, // Large objects
+			{ 30.0f, 100.0f, 2000 } // Very large objects
+		};
+
+		float placementExtents = 750.0f;
+		for(UINT32 i = 0; i < sizeof(types)/sizeof(types[0]); i++)
+		{
+			for (UINT32 j = 0; j < types[i].count; j++)
+			{
+				Vector3 position(
+					((rand() / (float)RAND_MAX) * 2.0f - 1.0f) * placementExtents,
+					((rand() / (float)RAND_MAX) * 2.0f - 1.0f) * placementExtents,
+					((rand() / (float)RAND_MAX) * 2.0f - 1.0f) * placementExtents
+				);
+
+				Vector3 extents(
+					types[i].sizeMin + ((rand() / (float)RAND_MAX)) * (types[i].sizeMax - types[i].sizeMin) * 0.5f,
+					types[i].sizeMin + ((rand() / (float)RAND_MAX)) * (types[i].sizeMax - types[i].sizeMin) * 0.5f,
+					types[i].sizeMin + ((rand() / (float)RAND_MAX)) * (types[i].sizeMax - types[i].sizeMin) * 0.5f
+				);
+
+				DebugOctreeElem elem;
+				elem.box = AABox(position - extents, position + extents);
+
+				UINT32 elemIdx = (UINT32)octreeData.elements.size();
+				octreeData.elements.push_back(elem);
+				octree.addElement(elemIdx);
+			}
+		}
+
+		DebugOctreeElem manualElems[3];
+		manualElems[0].box = AABox(Vector3(100.0f, 100.0f, 100.f), Vector3(110.0f, 115.0f, 110.0f));
+		manualElems[1].box = AABox(Vector3(200.0f, 100.0f, 100.f), Vector3(250.0f, 150.0f, 150.0f));
+		manualElems[2].box = AABox(Vector3(90.0f, 90.0f, 90.f), Vector3(105.0f, 105.0f, 110.0f));
+
+		
+		for(UINT32 i = 0; i < 3; i++)
+		{
+			UINT32 elemIdx = (UINT32)octreeData.elements.size();
+			octreeData.elements.push_back(manualElems[i]);
+			octree.addElement(elemIdx);
+		}
+
+		AABox queryBounds = manualElems[0].box;
+		DebugOctree::BoxIntersectIterator interIter(octree, queryBounds);
+
+		Vector<UINT32> overlapElements;
+		while(interIter.moveNext())
+		{
+			UINT32 element = interIter.getElement();
+			overlapElements.push_back(element);
+
+			// Manually check for intersections
+			BS_TEST_ASSERT(octreeData.elements[element].box.intersects(queryBounds));
+		}
+
+		// Ensure that all we have found all possible overlaps by manually testing all elements
+		UINT32 elemIdx = 0;
+		for(auto& entry : octreeData.elements)
+		{
+			if(entry.box.intersects(queryBounds))
+			{
+				auto iterFind = std::find(overlapElements.begin(), overlapElements.end(), elemIdx);
+				BS_TEST_ASSERT(iterFind != overlapElements.end());
+			}
+
+			elemIdx++;
+		}
+
+		// Ensure nothing goes wrong during element removal
+		for(auto& entry : octreeData.elements)
+			octree.removeElement(entry.octreeId);
+	}
+}

+ 19 - 0
Source/BansheeUtility/UnitTests/BsUtilityTestSuite.h

@@ -0,0 +1,19 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2017 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "Testing/BsTestSuite.h"
+
+namespace bs
+{
+	class UtilityTestSuite : public TestSuite
+	{
+	public:
+		UtilityTestSuite();
+		void startUp() override;
+		void shutDown() override;
+
+	private:
+		void testOctree();
+	};
+}

+ 19 - 0
Source/CMakeLists.txt

@@ -55,6 +55,8 @@ set(INCLUDE_ALL_IN_WORKFLOW OFF CACHE BOOL "If true, all libraries (even those n
 
 set(GENERATE_SCRIPT_BINDINGS ON CACHE BOOL "If true, script binding files will be generated. Script bindings are required for the project to build properly, however they take a while to generate. If you are sure the script bindings are up to date, you can turn off their generation (temporarily) to speed up the build.")
 
+set(BUILD_TESTS OFF CACHE BOOL "If true, build targets for running unit tests will be included in the output.")
+
 if(BUILD_SCOPE MATCHES "Runtime")
 	set(BUILD_EDITOR ON)
 else()
@@ -374,3 +376,20 @@ if(BUILD_EDITOR)
 		add_dependencies(Game BuildManaged)
 	endif()
 endif()
+
+## Tests
+if(BUILD_TESTS)
+	enable_testing()
+
+	add_executable(UtilityTest 
+		BansheeUtility/UnitTests/BsUtilityTest.cpp 
+		BansheeUtility/UnitTests/BsUtilityTestSuite.cpp
+		BansheeUtility/UnitTests/BsFileSystemTestSuite.cpp)
+		
+	target_link_libraries(UtilityTest BansheeUtility)
+	target_include_directories(UtilityTest PRIVATE "BansheeUtility")
+	
+	set_property(TARGET UtilityTest PROPERTY FOLDER Tests)
+
+	add_test(NAME FrameworkTests COMMAND $<TARGET_FILE:UtilityTest>)
+endif()