Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit tests #362

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,20 @@ include(Source/CMake/Properties.cmake)
include(Source/CMake/FindPackageOrBuild.cmake)
include(Source/CMake/HelperMethods.cmake)


set(BUILD_TESTS OFF CACHE BOOL "If true, build targets for running unit tests will be included in the output.")
if (BUILD_TESTS)
# Enables testing for this directory and below. See also the add_test
# command. Note that ctest expects to find a test file in the build
# directory root. Therefore, this command should be in the source
# directory root.
enable_testing()
endif()

add_subdirectory(Source)

# Options
set(SCRIPT_API "None" CACHE STRING "Which scripting API/language to use, if any. If no scripting API is chosen only native C++ bsf core will be built. If a scripting API is chosen, then a separate scripting layer on top of the core will be included in the build as well.")
set_property(CACHE SCRIPT_API PROPERTY STRINGS "None" "C#")

set(SCRIPT_BINDING_GENERATION OFF CACHE BOOL "If true, script binding generation will be supported through a specialized build target. Enable this if you plan on modifying the scripting API. Requires the SBGen tool dependency. Only relevant if you have selected a SCRIPT_API other than \"None\".")
set(SCRIPT_BINDING_GENERATION OFF CACHE BOOL "If true, script binding generation will be supported through a specialized build target. Enable this if you plan on modifying the scripting API. Requires the SBGen tool dependency. Only relevant if you have selected a SCRIPT_API other than \"None\".")
32 changes: 32 additions & 0 deletions Source/CMake/HelperMethods.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,38 @@ MACRO(end_find_package FOLDER_NAME MAIN_LIB_NAME)
set(${FOLDER_NAME}_INCLUDE_DIRS ${${FOLDER_NAME}_INCLUDE_DIR})
ENDMACRO()

# the purpose of bs_add_test is to allow for the local library path to be found by the tester.
# It's necessary to pass the environment variables because ctest will usually run with a clean environment.
# It was implemented to work for linux, as of July 2019 not tested on windows.
MACRO(bs_add_test)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of this macro vs. using add_test? Also, I'm seeing references to Debug and Release - does it work on other configs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i updated with commit for explanation. Esentially I was getting "found .so library" errors until I updated the tests. plus it's just useful to have add_test wrapper for future in case there's other common properties.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly don't know if it works for other configs. But it at least works for my needs at the moment.

cmake_parse_arguments(
PARSED_ARGS # prefix of output variables
"" # list of names of the boolean arguments (only defined ones will be true)
"NAME" # list of names of mono-valued arguments
"" # multivalue args
${ARGN} # arguments of the function to parse, here we take the all original ones
)

add_test(${ARGV})

if(NOT PARSED_ARGS_NAME)
message(FATAL_ERROR "You must provide a name for bs_add_test (bs_add_test(NAME name)")
endif(NOT PARSED_ARGS_NAME)

IF(CMAKE_BUILD_TYPE MATCHES Debug)
# windows
set_tests_properties( ${PARSED_ARGS_NAME} PROPERTIES ENVIRONMENT "PATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG};$ENV{PATH}" )
# linux
set_tests_properties( ${PARSED_ARGS_NAME} PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG};" )
elseif (CMAKE_BUILD_TYPE MATCHES Release)
# windows
set_tests_properties( ${PARSED_ARGS_NAME} PROPERTIES ENVIRONMENT "PATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE};$ENV{PATH}" )
# linux
set_tests_properties( ${PARSED_ARGS_NAME} PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE};" )
endif()

ENDMACRO()

function(install_dependency_binary FILE_PATH CONFIG)
if(NOT EXISTS ${FILE_PATH})
return()
Expand Down
8 changes: 2 additions & 6 deletions Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ set_property(CACHE RENDERER_MODULE PROPERTY STRINGS RenderBeast Null)

set(INCLUDE_ALL_IN_WORKFLOW OFF CACHE BOOL "If true, all libraries (even those not selected) will be included in the generated workflow (e.g. Visual Studio solution). This is useful when working on engine internals with a need for easy access to all parts of it. Only relevant for workflow generators like Visual Studio or XCode.")

set(BUILD_TESTS OFF CACHE BOOL "If true, build targets for running unit tests will be included in the output.")

set(BUILD_BSL OFF CACHE BOOL "If true, build lexer & parser for BSL. Requires flex & bison dependencies.")

set(BUILD_ALL_RENDER_API OFF CACHE BOOL "If true, all supported render backends will be built, regardless of choice in RENDER_API_MODULE. Choice in RENDER_API_MODULE will still be used as the default.")
Expand Down Expand Up @@ -208,8 +206,6 @@ add_subdirectory(Plugins/bsfSL)

## Tests
if(BUILD_TESTS)
enable_testing()

add_executable(UtilityTest
Foundation/bsfUtility/Private/UnitTests/BsUtilityTest.cpp
Foundation/bsfUtility/Private/UnitTests/BsUtilityTestSuite.cpp
Expand All @@ -228,8 +224,8 @@ if(BUILD_TESTS)
set_property(TARGET UtilityTest PROPERTY FOLDER Tests)
set_property(TARGET CoreTest PROPERTY FOLDER Tests)

add_test(NAME UtilityTests COMMAND $<TARGET_FILE:UtilityTest>)
add_test(NAME CoreTests COMMAND $<TARGET_FILE:UtilityTest>)
bs_add_test(NAME UtilityTests COMMAND $<TARGET_FILE:UtilityTest>)
bs_add_test(NAME CoreTests COMMAND $<TARGET_FILE:UtilityTest>)
endif()

## Builtin resource preprocessing
Expand Down
1 change: 1 addition & 0 deletions Source/Foundation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "A
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
target_compile_options(bsf PUBLIC
-fno-exceptions
-msse4.1
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>)
else()
# TODO_OTHER_COMPILERS_GO_HERE
Expand Down
6 changes: 3 additions & 3 deletions Source/Foundation/bsfCore/Private/UnitTests/BsCoreTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace bs

void CoreTestSuite::testAnimCurveIntegration()
{
static constexpr float EPSILON = 0.0001f;
static constexpr float EPSILON = 0.001f;

// Construct some curves
TAnimationCurve<float> curveConstant(
Expand Down Expand Up @@ -113,7 +113,7 @@ namespace bs

void CoreTestSuite::testLookupTable()
{
static constexpr float EPSILON = 0.0001f;
static constexpr float EPSILON = 0.001f;

TAnimationCurve<Vector3> curve
({
Expand Down Expand Up @@ -155,4 +155,4 @@ int main()
tests->run(testOutput);

return 0;
}
}
1 change: 1 addition & 0 deletions Source/Foundation/bsfUtility/CMakeSources.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ set(BS_UTILITY_SRC_IMAGE
)

set(BS_UTILITY_SRC_UTILITY
"bsfUtility/Utility/BsBitStream.cpp"
"bsfUtility/Utility/BsDynLib.cpp"
"bsfUtility/Utility/BsDynLibManager.cpp"
"bsfUtility/Utility/BsMessageHandler.cpp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace bs
FileSystem::remove(mTestDirectory, true);
if (FileSystem::exists(mTestDirectory))
{
LOGERR("FileSystemTestSuite failed to delete '" + mTestDirectory.toString()
BS_LOG(Error, FileSystem, "FileSystemTestSuite failed to delete '" + mTestDirectory.toString()
+ "', you should remove it manually.");
}
}
Expand Down
36 changes: 35 additions & 1 deletion Source/Foundation/bsfUtility/Private/UnitTests/BsUtilityTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,48 @@
#include "Testing/BsConsoleTestOutput.h"
#include "Private/UnitTests/BsUtilityTestSuite.h"

#include "BsApplication.h"
Copy link
Member

@BearishSun BearishSun Jul 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally I organize the non-plugin code in layers. 'Utility' layer is the lowest one, and it shouldn't be referencing anything from the higher layers (this includes Application or CoreApplication). Are these tests failing without the Application started up? Ideally we can run them without it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm. well we could just change it to BsCoreApplication, which is the core layer, and therefore compatible with all other layers of testing for most part. I'll make the change and see if that works.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope nvm, CoreApplication can't be initialized by itself for running the utility tests. stuff like gProfiler still gets called

#include "BsEngineConfig.h"

using namespace bs;


START_UP_DESC testStartupDesc()
{
START_UP_DESC desc;

// Set up default plugins
desc.renderAPI = BS_RENDER_API_MODULE;
// desc.renderAPI = "NullRenderAPI"
desc.renderer = BS_RENDERER_MODULE;
// desc.renderer = "NullRenderer";
desc.audio = BS_AUDIO_MODULE;
desc.physics = BS_PHYSICS_MODULE;

desc.importers.push_back("bsfFreeImgImporter");
desc.importers.push_back("bsfFBXImporter");
desc.importers.push_back("bsfFontImporter");
desc.importers.push_back("bsfSL");

VideoMode mode;
desc.primaryWindowDesc.videoMode = mode;
desc.primaryWindowDesc.fullscreen = false;
desc.primaryWindowDesc.title = "test";
return desc;
}

int main()
{

auto desc = testStartupDesc();
bs::Application::startUp(desc);

SPtr<TestSuite> tests = UtilityTestSuite::create<UtilityTestSuite>();

ConsoleTestOutput testOutput;
tests->run(testOutput);

bs::Application::shutDown();

return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -466,85 +466,90 @@ namespace bs
BS_TEST_ASSERT(v3[3].a == 10);
BS_TEST_ASSERT(v3[3].b == 0);
}

bool approxNear(float a, float b, float EPS = 0.001f) {
bool result = std::abs(a - b) < EPS;
return result;
}

void UtilityTestSuite::testComplex()
{
Complex<float> c(10.0, 4.0);
BS_TEST_ASSERT(c.real() == 10.0);
BS_TEST_ASSERT(c.imag() == 4.0);
BS_TEST_ASSERT(approxNear(c.real(), 10.0));
BS_TEST_ASSERT(approxNear(c.imag(), 4.0));

Complex<float> c2(15.0, 5.0);
BS_TEST_ASSERT(c2.real() == 15.0);
BS_TEST_ASSERT(c2.imag() == 5.0);
BS_TEST_ASSERT(approxNear(c2.real(), 15.0));
BS_TEST_ASSERT(approxNear(c2.imag(), 5.0));

Complex<float> c3 = c + c2;
BS_TEST_ASSERT(c3.real() == 25.0);
BS_TEST_ASSERT(c3.imag() == 9.0);
BS_TEST_ASSERT(approxNear(c3.real(), 25.0));
BS_TEST_ASSERT(approxNear(c3.imag(), 9.0));

Complex<float> c4 = c - c2;
BS_TEST_ASSERT(c4.real() == -5.0);
BS_TEST_ASSERT(c4.imag() == -1.0);
BS_TEST_ASSERT(approxNear(c4.real(), -5.0));
BS_TEST_ASSERT(approxNear(c4.imag(), -1.0));

Complex<float> c5 = c * c2;
BS_TEST_ASSERT(c5.real() == 130.0);
BS_TEST_ASSERT(c5.imag() == 110.0);
BS_TEST_ASSERT(approxNear(c5.real(), 130.0));
BS_TEST_ASSERT(approxNear(c5.imag(), 110.0));

Complex<float> c6 = c / c2;
BS_TEST_ASSERT(c6.real() == 0.680000007f);
BS_TEST_ASSERT(c6.imag() == 0.0399999991f);
BS_TEST_ASSERT(approxNear(c6.real(), 0.680000007f));
BS_TEST_ASSERT(approxNear(c6.imag(), 0.0399999991f));

BS_TEST_ASSERT(Complex<float>::abs(c) == 10.7703295f);
BS_TEST_ASSERT(Complex<float>::arg(c) == 0.380506366f);
BS_TEST_ASSERT(Complex<float>::norm(c) == 116);
BS_TEST_ASSERT(approxNear(Complex<float>::abs(c), 10.7703295f));
BS_TEST_ASSERT(approxNear(Complex<float>::arg(c), 0.380506366f));
BS_TEST_ASSERT(approxNear(Complex<float>::norm(c), 116));

Complex<float> c7 = Complex<float>::conj(c);
BS_TEST_ASSERT(c7.real() == 10);
BS_TEST_ASSERT(c7.imag() == -4);
BS_TEST_ASSERT(approxNear(c7.real(), 10));
BS_TEST_ASSERT(approxNear(c7.imag(), -4));
c7 = 0;

c7 = Complex<float>::polar(2.0, 0.5);
BS_TEST_ASSERT(c7.real() == 1.75516510f);
BS_TEST_ASSERT(c7.imag() == 0.958851099f);
BS_TEST_ASSERT(approxNear(c7.real(), 1.75516510f));
BS_TEST_ASSERT(approxNear(c7.imag(), 0.958851099f));
c7 = 0;

c7 = Complex<float>::cos(c);
BS_TEST_ASSERT(c7.real() == -22.9135609f);
BS_TEST_ASSERT(c7.imag() == 14.8462915f);
BS_TEST_ASSERT(approxNear(c7.real(), -22.9135609f));
BS_TEST_ASSERT(approxNear(c7.imag(), 14.8462915f));
c7 = 0;

c7 = Complex<float>::cosh(c);
BS_TEST_ASSERT(c7.real() == -7198.72949f);
BS_TEST_ASSERT(c7.imag() == -8334.84180f);
BS_TEST_ASSERT(approxNear(c7.real(), -7198.72949f));
BS_TEST_ASSERT(approxNear(c7.imag(), -8334.84180f));
c7 = 0;

c7 = Complex<float>::exp(c);
BS_TEST_ASSERT(c7.real() == -14397.4580f);
BS_TEST_ASSERT(c7.imag() == -16669.6836f);
BS_TEST_ASSERT(approxNear(c7.real(), -14397.4580f));
BS_TEST_ASSERT(approxNear(c7.imag(), -16669.6836f));
c7 = 0;

c7 = Complex<float>::log(c);
BS_TEST_ASSERT(c7.real() == 2.37679505f);
BS_TEST_ASSERT(c7.imag() == 0.380506366f);
BS_TEST_ASSERT(approxNear(c7.real(), 2.37679505f));
BS_TEST_ASSERT(approxNear(c7.imag(), 0.380506366f));
c7 = 0;

c7 = Complex<float>::pow(c, 2.0);
BS_TEST_ASSERT(c7.real() == 84.0000000f);
BS_TEST_ASSERT(c7.imag() == 79.9999924f);
BS_TEST_ASSERT(approxNear(c7.real(), 84.0000000f));
BS_TEST_ASSERT(approxNear(c7.imag(), 79.9999924f));
c7 = 0;

c7 = Complex<float>::sin(c);
BS_TEST_ASSERT(c7.real() == -14.8562555f);
BS_TEST_ASSERT(c7.imag() == -22.8981915f);
BS_TEST_ASSERT(approxNear(c7.real(), -14.8562555f));
BS_TEST_ASSERT(approxNear(c7.imag(), -22.8981915f));
c7 = 0;

c7 = Complex<float>::sinh(c);
BS_TEST_ASSERT(c7.real() == -7198.72900f);
BS_TEST_ASSERT(c7.imag() == -8334.84277f);
BS_TEST_ASSERT(approxNear(c7.real(), -7198.72900f));
BS_TEST_ASSERT(approxNear(c7.imag(), -8334.84277f));
c7 = 0;

c7 = Complex<float>::sqrt(c);
BS_TEST_ASSERT(c7.real() == 3.22260213f);
BS_TEST_ASSERT(c7.imag() == 0.620616496f);
BS_TEST_ASSERT(approxNear(c7.real(), 3.22260213f));
BS_TEST_ASSERT(approxNear(c7.imag(), 0.620616496f));
c7 = 0;
}

Expand Down
2 changes: 1 addition & 1 deletion Source/Foundation/bsfUtility/Testing/BsTestSuite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace bs
for (auto& testEntry : mTests)
{
mActiveTestName = testEntry.name;

std::cout << mActiveTestName << std::endl;
(this->*(testEntry.test))();
}

Expand Down
8 changes: 8 additions & 0 deletions Source/Foundation/bsfUtility/Utility/BsBitStream.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "./BsBitstream.h"

namespace bs
{
uint32_t Bitstream::BYTES_PER_QUANT = sizeof(QuantType);
uint32_t Bitstream::BITS_PER_QUANT = BYTES_PER_QUANT * 8;
uint32_t Bitstream::BITS_PER_QUANT_LOG2 = Bitwise::bitsLog2(BITS_PER_QUANT);
} // namespace bs
6 changes: 3 additions & 3 deletions Source/Foundation/bsfUtility/Utility/BsBitstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,9 @@ namespace bs
QuantType* data() const { return mData; }

private:
static constexpr uint32_t BYTES_PER_QUANT = sizeof(QuantType);
static constexpr uint32_t BITS_PER_QUANT = BYTES_PER_QUANT * 8;
static constexpr uint32_t BITS_PER_QUANT_LOG2 = Bitwise::bitsLog2(BITS_PER_QUANT);
static uint32_t BYTES_PER_QUANT;
static uint32_t BITS_PER_QUANT;
static uint32_t BITS_PER_QUANT_LOG2;

/** Checks if the internal memory buffer needs to grow in order to accomodate @p numBits bits. */
void reallocIfNeeded(uint32_t numBits);
Expand Down
13 changes: 6 additions & 7 deletions Source/Foundation/bsfUtility/Utility/BsOctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,16 +380,16 @@ namespace bs
public:
/** Initializes the iterator, starting with the root octree node. */
NodeIterator(const Octree& tree)
:mCurrentNode(HNode(&tree.mRoot, tree.mRootBounds)), mStackAlloc(), mNodeStack(&mStackAlloc)
:mCurrentNode(HNode(&tree.mRoot, tree.mRootBounds))
{
mNodeStack.push_back(mCurrentNode);
mNodeStack.add(mCurrentNode);
}

/** Initializes the iterator using a specific node and its bounds. */
NodeIterator(const Node* node, const NodeBounds& bounds)
:mCurrentNode(HNode(node, bounds)), mStackAlloc(), mNodeStack(&mStackAlloc)
:mCurrentNode(HNode(node, bounds))
{
mNodeStack.push_back(mCurrentNode);
mNodeStack.add(mCurrentNode);
}

/**
Expand Down Expand Up @@ -423,13 +423,12 @@ namespace bs
Node* childNode = mCurrentNode.getNode()->getChild(child);
NodeBounds childBounds = mCurrentNode.getBounds().getChild(child);

mNodeStack.emplace_back(childNode, childBounds);
mNodeStack.add({childNode, childBounds});
}

private:
HNode mCurrentNode;
StaticAlloc<Options::MaxDepth * 8 * sizeof(HNode), FreeAlloc> mStackAlloc;
StaticVector<HNode, Options::MaxDepth * 8> mNodeStack;
SmallVector<HNode, Options::MaxDepth * 8> mNodeStack;
};

/** Iterator that iterates over all elements in a single node. */
Expand Down
Loading