Skip to content

Commit

Permalink
Start adding tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Holt59 committed Jun 15, 2024
1 parent fce0630 commit 57d8b0a
Show file tree
Hide file tree
Showing 18 changed files with 578 additions and 16 deletions.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
139 changes: 139 additions & 0 deletions test/fixtures/usvfs_global_test/RedFileSystemTest/example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#include <filesystem>
#include <fstream>

std::filesystem::path storages_path;
std::filesystem::path hudpainter_path;
bool has_mo2;

// See below main() for implementation.
void request_directory(std::filesystem::path);
std::filesystem::path restrict_path(std::filesystem::path);
std::vector<std::filesystem::path> get_files();
std::string read_file(std::filesystem::path);
void write_file(std::filesystem::path);

// Expected path when not using MO2
int main()
{
// RedFileSystem plugin (DLL) is loaded.
has_mo2 = GetModuleHandle(TEXT("usvfs_x64.dll")) != nullptr;

// Setup paths
auto path = std::filesystem::absolute("."); // <GAME>\bin\x64
auto game_path = path.parent_path().parent_path(); // <GAME>

storages_path = game_path / "r6" / "storages"; // <GAME>\r6\storages

// Create storages directory if it is no present.
request_directory(storages_path); // <GAME>\r6\storages

// Game is running...

// HUD Painter request its storage endpoint.
hudpainter_path = storages_path / "HUDPainter";
request_directory(hudpainter_path); // <GAME>\r6\storages\HUDPainter

// HUD Painter request a file (present in archive).
auto default_path =
restrict_path("DEFAULT.json"); // <GAME>\r6\storages\HUDPainter\DEFAULT.json

// HUD Painter read file in `default_path` with success.
auto data = read_file(default_path); // <GAME>\r6\storages\HUDPainter\DEFAULT.json

// HUD Painter request another file.
auto test_path =
restrict_path("TEST.json"); // <GAME>\r6\storages\HUDPainter\TEST.json

// (Bug A) HUD Painter write file in `test_path`.
write_file(test_path); // <GAME>\r6\storages\HUDPainter\TEST.json
// file is created with workaround, not created otherwise.

// (Bug B) HUD Painter request list of files.
// TEST.json is successfully created when using workaround.
auto files = get_files(); // [0] <GAME>\r6\storages\HUDPainter\DEFAULT.json

// files.size() == 1

// Expect:
// files.size() == 2
//
// [0] <GAME>\r6\storages\HUDPainter\DEFAULT.json
// [1] <GAME>\r6\storages\HUDPainter\TEST.json
}

// Create directory if it is no present
void request_directory(std::filesystem::path path)
{
bool is_present = std::filesystem::exists(path);

if (is_present) {
return;
}
std::filesystem::create_directory(path);
}

// Resolve path for HUDPainter (security layer)
std::filesystem::path restrict_path(std::filesystem::path path)
{
auto real_path = std::filesystem::weakly_canonical(hudpainter_path / path);

// Workaround when using MO2
if (has_mo2) {
return real_path;
}
// Expected implementation without MO2
if (real_path.string().find(hudpainter_path.string() + "\\") != 0) {
// "throw" error
}
return real_path;
}

// List files in storage of HUDPainter.
std::vector<std::filesystem::path> get_files()
{
std::vector<std::filesystem::path> files;
auto entries = std::filesystem::directory_iterator(hudpainter_path);

for (const auto& entry : entries) {
if (entry.is_regular_file()) {
auto file_name = entry.path().filename();
auto file_path =
hudpainter_path /
file_name; // Culprit of bug B. When using entry.path() directly, it works.

files.emplace_back(file_path);
}
}
return files;
}

std::string read_file(std::filesystem::path path)
{
std::ifstream stream;

// With workaround:
// std::filesystem::create_directories(path.parent_path());
stream.open(path);
if (!stream.is_open()) {
return "";
}
std::stringstream data;

data << stream.rdbuf();
stream.close();
return data.str();
}

void write_file(std::filesystem::path path)
{
std::ofstream stream;

// With workaround:
// std::filesystem::create_directories(path.parent_path());
stream.open(path, std::ios_base::trunc);
if (!stream.is_open()) {
return;
}
stream << "<DATA>";
stream.close();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"propertiesDefault": [
{
"name": "MainColors.Red",
"red": 1.1761,
"green": 0.3809,
"blue": 0.3476,
"alpha": 1
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"propertiesDefault": [
{
"name": "MainColors.Red",
"red": 1.1761,
"green": 0.3809,
"blue": 0.3476,
"alpha": 1
}
]
}
7 changes: 0 additions & 7 deletions test/usvfs_global_test/main.cpp

This file was deleted.

71 changes: 71 additions & 0 deletions test/usvfs_global_test/usvfs_global_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <gtest/gtest.h>

#include <filesystem>
#include <fstream>

class
{
bool initialize(int argc, char* argv[])
{
// extract the data path
if (argc != 2) {
std::cerr << "missing data path, aborting\n";
return false;
}
m_data = std::filesystem::path{argv[1]};

if (!exists(m_data)) {
std::cerr << "data path '" << m_data.string() << "'does not exist\n";
return false;
}

return true;
}

friend int main(int argc, char* argv[]);
std::filesystem::path m_data;

public:
const auto& data() const { return m_data; }
} parameters;

TEST(BasicTest, SimpleTest)
{
const auto data = parameters.data();

ASSERT_TRUE(exists(data));
ASSERT_TRUE(exists(data / "docs"));
ASSERT_TRUE(exists(data / "empty"));
ASSERT_TRUE(exists(data / "docs" / "doc.txt"));
ASSERT_TRUE(exists(data / "readme.txt"));
}

TEST(RedFileSystemTest, RedFileSystemTest)
{
const auto data = parameters.data();

const auto storages_path = data / "r6" / "storages";
const auto hudpainter_path = storages_path / "HUDPainter";

ASSERT_TRUE(exists(hudpainter_path / "DEFAULT.json"));

{
std::ofstream of{hudpainter_path / "TEST.json"};
of << "{}\n";
}

// ASSERT_EQ(std::filesystem::path{}, weakly_canonical(hudpainter_path /
// "TEST.json"));
}

int main(int argc, char* argv[])
{
testing::InitGoogleTest(&argc, argv);

// initialize parameters from remaining arguments
if (!parameters.initialize(argc, argv)) {
return -1;
}

return RUN_ALL_TESTS();
}
3 changes: 0 additions & 3 deletions test/usvfs_global_test_runner/main.cpp

This file was deleted.

Loading

0 comments on commit 57d8b0a

Please sign in to comment.