Skip to content

Commit

Permalink
#5108: Start rigging some unit tests that are checking that map loadi…
Browse files Browse the repository at this point in the history
…ng extracts all the elements we expect
  • Loading branch information
codereader committed Nov 21, 2020
1 parent 6e5b0f3 commit f5b63f2
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/Makefile.am
Expand Up @@ -33,6 +33,7 @@ drtest_SOURCES = math/Matrix4.cpp \
HeadlessOpenGLContext.cpp \
FacePlane.cpp \
FileTypes.cpp \
MapSavingLoading.cpp \
Materials.cpp \
MapExport.cpp \
MessageBus.cpp \
Expand Down
128 changes: 128 additions & 0 deletions test/MapSavingLoading.cpp
@@ -0,0 +1,128 @@
#include "RadiantTest.h"

#include "imap.h"
#include "iradiant.h"
#include "iselectiongroup.h"
#include "ilightnode.h"
#include "icommandsystem.h"
#include "messages/FileSelectionRequest.h"
#include "algorithm/Scene.h"

namespace test
{

using MapLoadingTest = RadiantTest;

TEST_F(MapLoadingTest, openMapWithEmptyStringAsksForPath)
{
bool eventFired = false;

// Subscribe to the event we expect to be fired
auto msgSubscription = GlobalRadiantCore().getMessageBus().addListener(
radiant::IMessage::Type::FileSelectionRequest,
radiant::TypeListener<radiant::FileSelectionRequest>(
[&](radiant::FileSelectionRequest& msg)
{
eventFired = true;
}));

// Calling OpenMap with no arguments will send a message to the UI
GlobalCommandSystem().executeCommand("OpenMap");

EXPECT_TRUE(eventFired) << "OpenMap didn't ask for a map file as expected";

GlobalRadiantCore().getMessageBus().removeListener(msgSubscription);
}

void checkAltarScene()
{
auto root = GlobalMapModule().getRoot();
auto worldspawn = GlobalMapModule().findOrInsertWorldspawn();

// Check a specific spawnarg on worldspawn
EXPECT_EQ(Node_getEntity(worldspawn)->getKeyValue("_color"), "0.286 0.408 0.259");

// Check if all entities are present
auto knownEntities = { "func_static_153", "func_static_154", "func_static_156",
"func_static_155", "func_static_63", "func_static_66", "func_static_70",
"func_static_164", "func_static_165", "light_torchflame_13", "religious_symbol_1" };

for (auto entity : knownEntities)
{
EXPECT_TRUE(algorithm::getEntityByName(root, entity));
}

// Check number of patches
auto isPatchDef3 = [](const scene::INodePtr& node) { return Node_isPatch(node) && Node_getIPatch(node)->subdivisionsFixed(); };
auto isPatchDef2 = [](const scene::INodePtr& node) { return Node_isPatch(node) && !Node_getIPatch(node)->subdivisionsFixed(); };

EXPECT_EQ(algorithm::getChildCount(worldspawn, isPatchDef3), 110); // 110 patchDef3
EXPECT_EQ(algorithm::getChildCount(worldspawn, isPatchDef2), 16); // 16 patchDef2

// Check number of brushes
auto isBrush = [](const scene::INodePtr& node) { return Node_isBrush(node); };

EXPECT_EQ(algorithm::getChildCount(root, isBrush), 37); // 37 brushes in total
EXPECT_EQ(algorithm::getChildCount(worldspawn, isBrush), 21); // 21 worldspawn brushes
EXPECT_EQ(algorithm::getChildCount(algorithm::getEntityByName(root, "func_static_66"), isBrush), 4); // 4 child brushes
EXPECT_EQ(algorithm::getChildCount(algorithm::getEntityByName(root, "func_static_70"), isBrush), 4); // 4 child brushes
EXPECT_EQ(algorithm::getChildCount(algorithm::getEntityByName(root, "func_static_164"), isBrush), 4); // 4 child brushes
EXPECT_EQ(algorithm::getChildCount(algorithm::getEntityByName(root, "func_static_165"), isBrush), 4); // 4 child brushes

// Check the lights
auto isLight = [](const scene::INodePtr& node) { return Node_getLightNode(node) != nullptr; };
EXPECT_EQ(algorithm::getChildCount(root, isLight), 1); // 1 light

// Check a specific model
auto religiousSymbol = Node_getEntity(algorithm::getEntityByName(root, "religious_symbol_1"));
EXPECT_EQ(religiousSymbol->getKeyValue("classname"), "altar_moveable_loot_religious_symbol");
EXPECT_EQ(religiousSymbol->getKeyValue("origin"), "-0.0448253 12.0322 -177");

// Check layers
EXPECT_TRUE(root->getLayerManager().getLayerID("Default") != -1);
EXPECT_TRUE(root->getLayerManager().getLayerID("Windows") != -1);
EXPECT_TRUE(root->getLayerManager().getLayerID("Lights") != -1);
EXPECT_TRUE(root->getLayerManager().getLayerID("Ceiling") != -1);

// Check map property
EXPECT_EQ(root->getProperty("LastShaderClipboardMaterial"), "textures/tiles01");

// Check selection group profile
std::size_t numGroups = 0;
std::multiset<std::size_t> groupCounts;
root->getSelectionGroupManager().foreachSelectionGroup([&](const selection::ISelectionGroup& group)
{
++numGroups;
groupCounts.insert(group.size());
});

EXPECT_EQ(numGroups, 4);
EXPECT_EQ(groupCounts.count(2), 1); // 1 group with 2 members
EXPECT_EQ(groupCounts.count(3), 2); // 2 groups with 3 members
EXPECT_EQ(groupCounts.count(12), 1); // 1 group with 12 members
}

TEST_F(MapLoadingTest, openMapFromAbsolutePath)
{
// Generate an absolute path to a map in a temporary folder
fs::path mapPath = _context.getTestResourcePath();
mapPath /= "maps/altar.map";
auto drFilePath = mapPath;
drFilePath.replace_extension("darkradiant");

// Copy to temp/
fs::path temporaryMap = _context.getTemporaryDataPath();
temporaryMap /= "temp_altar.map";
auto temporaryDrFile = temporaryMap;
temporaryDrFile.replace_extension("darkradiant");

ASSERT_TRUE(fs::copy_file(mapPath, temporaryMap));
ASSERT_TRUE(fs::copy_file(drFilePath, temporaryDrFile));

GlobalCommandSystem().executeCommand("OpenMap", temporaryMap.string());

// Check if the scene contains what we expect
checkAltarScene();
}

}
20 changes: 20 additions & 0 deletions test/TestContext.h
Expand Up @@ -16,6 +16,7 @@ class TestContext :
{
private:
std::string _settingsFolder;
std::string _tempDataPath;

public:
TestContext()
Expand All @@ -28,6 +29,13 @@ class TestContext :
os::removeDirectory(_settingsFolder);
os::makeDirectory(_settingsFolder);

auto tempDataFolder = os::getTemporaryPath() / "dr_temp_data";

_tempDataPath = os::standardPathWithSlash(tempDataFolder.string());

os::removeDirectory(_tempDataPath);
os::makeDirectory(_tempDataPath);

setErrorHandlingFunction([&](const std::string& title, const std::string& message)
{
std::cerr << "Fatal error " << title << "\n" << message << std::endl;
Expand All @@ -41,6 +49,11 @@ class TestContext :
{
os::removeDirectory(_settingsFolder);
}

if (!_tempDataPath.empty())
{
os::removeDirectory(_tempDataPath);
}
}

// Returns the path to the test/resources/ folder shipped with the DR sources
Expand All @@ -67,6 +80,13 @@ class TestContext :
return _settingsFolder;
}

// Path to a directory where any stuff can be written to
// This folder will be purged once on context destruction
std::string getTemporaryDataPath() const
{
return _tempDataPath;
}

std::vector<std::string> getLibraryPaths() const override
{
auto libBasePath = os::standardPathWithSlash(getLibraryBasePath());
Expand Down
19 changes: 19 additions & 0 deletions test/algorithm/Scene.h
Expand Up @@ -142,4 +142,23 @@ inline model::ModelNodePtr findChildModel(const scene::INodePtr& parent)
return candidate;
}

// Returns the number of children of the given parent node matching the given predicate
inline std::size_t getChildCount(const scene::INodePtr& parent,
const std::function<bool(const scene::INodePtr&)>& predicate)
{
std::size_t count = 0;

parent->foreachNode([&](const scene::INodePtr& node)
{
if (predicate(node))
{
++count;
}

return true;
});

return count;
}

}
1 change: 1 addition & 0 deletions tools/msvc/Tests/Tests.vcxproj
Expand Up @@ -72,6 +72,7 @@
<ClCompile Include="..\..\..\test\FileTypes.cpp" />
<ClCompile Include="..\..\..\test\HeadlessOpenGLContext.cpp" />
<ClCompile Include="..\..\..\test\MapExport.cpp" />
<ClCompile Include="..\..\..\test\MapSavingLoading.cpp" />
<ClCompile Include="..\..\..\test\Materials.cpp" />
<ClCompile Include="..\..\..\test\math\Matrix4.cpp" />
<ClCompile Include="..\..\..\test\math\Plane3.cpp" />
Expand Down
1 change: 1 addition & 0 deletions tools/msvc/Tests/Tests.vcxproj.filters
Expand Up @@ -28,6 +28,7 @@
<ClCompile Include="..\..\..\test\Selection.cpp" />
<ClCompile Include="..\..\..\test\FileTypes.cpp" />
<ClCompile Include="..\..\..\test\MessageBus.cpp" />
<ClCompile Include="..\..\..\test\MapSavingLoading.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\test\HeadlessOpenGLContext.h" />
Expand Down

0 comments on commit f5b63f2

Please sign in to comment.