Skip to content

Commit

Permalink
#6467: Add unit test checking serialising/deserialising entity key va…
Browse files Browse the repository at this point in the history
…lues with double quotes. Deduplicate file loading code.
  • Loading branch information
codereader committed Jan 27, 2024
1 parent 530f7b1 commit 2319e6e
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 34 deletions.
7 changes: 2 additions & 5 deletions test/Brush.cpp
Expand Up @@ -5,6 +5,7 @@
#include "iselection.h"
#include "itransformable.h"
#include "scenelib.h"
#include "algorithm/FileUtils.h"
#include "math/Quaternion.h"
#include "algorithm/Scene.h"
#include "algorithm/Primitives.h"
Expand Down Expand Up @@ -289,11 +290,7 @@ TEST_F(Quake3BrushTest, SaveAxisAlignedBrushWithTransform)

EXPECT_TRUE(fs::exists(tempPath)) << "File still doesn't exist: " << tempPath;

std::ifstream tempFile(tempPath);
std::stringstream content;
content << tempFile.rdbuf();

auto savedContent = content.str();
auto savedContent = algorithm::loadFileToString(tempPath);

// This is checking the actual face string as written by the LegacyBrushDefExporter
// including whitespace and all the syntax details
Expand Down
12 changes: 3 additions & 9 deletions test/MapExport.cpp
Expand Up @@ -97,11 +97,7 @@ std::string exportDefaultBrushUsingFormat(const std::string& gameType, const std

EXPECT_TRUE(fs::exists(exportPath)) << "File still doesn't exist";

std::ifstream tempFile(exportPath);
std::stringstream content;
content << tempFile.rdbuf();

return content.str();
return algorithm::loadFileToString(exportPath);
}

TEST_F(MapExportTest, exportDoom3Brush)
Expand Down Expand Up @@ -320,11 +316,9 @@ void runExportWithEmptyFileExtension(const std::string& temporaryDataPath,const

EXPECT_TRUE(fs::exists(tempPath)) << "File still doesn't exist";

std::ifstream tempFile(tempPath);
std::stringstream content;
content << tempFile.rdbuf();
auto content = algorithm::loadFileToString(tempPath);

EXPECT_NE(content.str().find("brushDef3"), std::string::npos) << "Couldn't find the brush keyword in the export";
EXPECT_NE(content.find("brushDef3"), std::string::npos) << "Couldn't find the brush keyword in the export";
}

}
Expand Down
45 changes: 41 additions & 4 deletions test/MapSavingLoading.cpp
Expand Up @@ -25,6 +25,7 @@
#include "testutil/FileSelectionHelper.h"
#include "testutil/FileSaveConfirmationHelper.h"
#include "registry/registry.h"
#include "testutil/TemporaryFile.h"

using namespace std::chrono_literals;

Expand Down Expand Up @@ -1185,11 +1186,9 @@ TEST_F(MapSavingTest, saveWarnsAboutOverwriteAndUserCancels)
EXPECT_TRUE(overwriteHelper.messageReceived());

// File should not have been replaced
std::ifstream writtenFile(tempPath);
std::stringstream contents;
contents << writtenFile.rdbuf();
auto contents = algorithm::loadFileToString(tempPath);

EXPECT_EQ(contents.str(), tempContents);
EXPECT_EQ(contents, tempContents);
}

// #5729: Autosaver overwrites the stored filename that has been previously used for "Save Copy As"
Expand Down Expand Up @@ -1623,4 +1622,42 @@ TEST_F(MapLoadingTest, WarningAboutMissingInfoFile)
<< "Didn't receive a warning about the missing .darkradiant file";
}

TEST_F(MapSavingTest, EscapeCharactersInEntityKeyValues)
{
auto mapContent = R"(Version 2
// entity 0
{
"classname" "light"
"name" "light"
"origin" "0.160161 72.1389 24.7429"
"test" "Test \"quoted\" test"
"with\"quote" "--"
}
)";
string::replace_all_copy(mapContent, "\r\n", "\n"); // don't be fooled by platform-specific line breaks

fs::path mapPath = _context.getTemporaryDataPath();
mapPath /= "keyvalue_escaping.map";
TemporaryFile tempFile(mapPath.string(), mapContent);

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

auto entity = algorithm::findFirstEntity(GlobalMapModule().getRoot(), [](auto&) { return true; });

EXPECT_EQ(Node_getEntity(entity)->getKeyValue("name"), "light") << "Wrong entity found after loading";

// Check the quoted keyvalue pairs
EXPECT_EQ(Node_getEntity(entity)->getKeyValue("with\"quote"), "--") << "Failed to deserialise quoted entity key";
EXPECT_EQ(Node_getEntity(entity)->getKeyValue("test"), "Test \"quoted\" test") << "Failed to deserialise quoted entity key value";

// Save the map
GlobalCommandSystem().executeCommand("SaveMapCopyAs", mapPath.string());

auto savedContent = algorithm::loadFileToString(mapPath);

// Exact same
string::replace_all_copy(savedContent, "\r\n", "\n"); // normalise line breaks
EXPECT_EQ(savedContent, mapContent) << "Failed to serialise quoted entity key values";
}

}
8 changes: 3 additions & 5 deletions test/Settings.cpp
@@ -1,6 +1,8 @@
#include "gtest/gtest.h"

#include <fstream>

#include "algorithm/FileUtils.h"
#include "settings/MajorMinorVersion.h"
#include "settings/SettingsManager.h"
#include "module/ApplicationContextBase.h"
Expand Down Expand Up @@ -218,11 +220,7 @@ inline std::string loadSettingsFile(const IApplicationContext& context, const st

if (existingFile.empty()) return {};

std::ifstream file(existingFile);
std::stringstream content;
content << file.rdbuf();

return content.str();
return algorithm::loadFileToString(existingFile);
}

// Checks that the version/base settings folders are respecting the version sort order
Expand Down
8 changes: 2 additions & 6 deletions test/algorithm/FileUtils.h
Expand Up @@ -87,12 +87,8 @@ inline std::string loadFileToString(const fs::path& path)
// True if the file (full physical path) contains the given text (ignoring CRLF vs. LF line break differences)
inline bool fileContainsText(const fs::path& path, const std::string& textToFind)
{
std::stringstream contentStream;
std::ifstream input(path);

contentStream << input.rdbuf();

std::string contents = string::replace_all_copy(contentStream.str(), "\r\n", "\n");
auto rawContents = loadFileToString(path);
auto contents = string::replace_all_copy(rawContents, "\r\n", "\n");

return contents.find(textToFind) != std::string::npos;
}
Expand Down
8 changes: 3 additions & 5 deletions test/algorithm/XmlUtils.h
Expand Up @@ -3,6 +3,8 @@
#include "gtest/gtest.h"
#include <fstream>
#include <sstream>

#include "FileUtils.h"
#include "string/predicate.h"

namespace test
Expand All @@ -20,11 +22,7 @@ inline void assertStringIsMapxFile(const std::string& content)
// Very rough check to see if path points to a file that looks like an XML document
inline void assertFileIsMapxFile(const std::string& path)
{
std::ifstream tempFile(path);
std::stringstream content;
content << tempFile.rdbuf();

assertStringIsMapxFile(content.str());
assertStringIsMapxFile(loadFileToString(path));
}

}
Expand Down

0 comments on commit 2319e6e

Please sign in to comment.