1
0

unit tests: coverage, settings

This commit is contained in:
2026-02-21 14:15:08 +02:00
parent ad55b1109d
commit 753a6e0e1d
7 changed files with 305 additions and 3 deletions

View File

@@ -0,0 +1,20 @@
# Command
v 0.1 0.2 0.3
v 0.2 0.3 0.4
v 0.3 0.4 0.5
v 1.1 1.2 1.3
v 1.2 1.3 1.4
v 1.3 1.4 1.5
v 2.1 2.2 2.3
v 2.2 2.3 2.4
v 2.3 2.4 2.5
vn 0.15 0.25 0.35
vn 0.25 0.35 0.45
vn 0.35 0.45 0.55
vt 0.9 0.8
vt 0.8 0.7
f 1/1/1 2/2/2 3/3/2
o test
f 4/3/2 5/2/1 6/1/2
g test
f 7/2/2 8/3/2 9/1/1

187
tests/settings_test.cpp Normal file
View File

@@ -0,0 +1,187 @@
#include <filesystem>
#include <fstream>
#include <random>
#include <sstream>
#include <string>
#include <gtest/gtest.h>
#include "settings.hpp"
namespace {
class ScopedFileCleanup {
public:
explicit ScopedFileCleanup(std::filesystem::path path) : path_(std::move(path)) {}
ScopedFileCleanup(const ScopedFileCleanup &) = delete;
ScopedFileCleanup &operator=(const ScopedFileCleanup &) = delete;
ScopedFileCleanup(ScopedFileCleanup &&) = delete;
ScopedFileCleanup &operator=(ScopedFileCleanup &&) = delete;
~ScopedFileCleanup() {
if (!path_.empty()) {
std::error_code error;
std::filesystem::remove(path_, error);
}
}
private:
std::filesystem::path path_;
};
std::string random_token(std::size_t length) {
static const char charset[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
std::string result;
result.reserve(length);
std::mt19937 engine{std::random_device{}()};
std::uniform_int_distribution<std::size_t> dist(0, sizeof(charset) - 2);
for (std::size_t i = 0; i < length; ++i) {
result.push_back(charset[dist(engine)]);
}
return result;
}
TEST(SettingsBuilder, DefaultsToStdStreamsAndFlagsOff) {
wavefront::SettingsBuilder builder;
EXPECT_EQ(&builder.input(), &std::cin);
EXPECT_EQ(&builder.output(), &std::cout);
EXPECT_FALSE(builder.with_normals());
EXPECT_FALSE(builder.with_texcoords());
EXPECT_FALSE(builder.use_float64());
wavefront::Settings settings = builder.build();
EXPECT_EQ(&settings.input(), &std::cin);
EXPECT_EQ(&settings.output(), &std::cout);
EXPECT_FALSE(settings.extract_normals());
EXPECT_FALSE(settings.extract_texcoords());
EXPECT_FALSE(settings.use_float64());
EXPECT_TRUE(settings.selected_objects().empty());
EXPECT_TRUE(settings.selected_groups().empty());
}
TEST(SettingsBuilder, AppliesConfigurationAndSelection) {
std::istringstream input("dummy");
std::ostringstream output;
wavefront::SettingsBuilder builder;
builder.input(input)
.output(output)
.with_normals(true)
.with_texcoords(true)
.use_float64(true);
builder.selected_objects().push_back("object_a");
builder.selected_groups().push_back("group_a");
EXPECT_EQ(&builder.input(), &input);
EXPECT_EQ(&builder.output(), &output);
EXPECT_TRUE(builder.with_normals());
EXPECT_TRUE(builder.with_texcoords());
EXPECT_TRUE(builder.use_float64());
wavefront::Settings settings = builder.build();
EXPECT_EQ(&settings.input(), &input);
EXPECT_EQ(&settings.output(), &output);
EXPECT_TRUE(settings.extract_normals());
EXPECT_TRUE(settings.extract_texcoords());
EXPECT_TRUE(settings.use_float64());
ASSERT_EQ(settings.selected_objects().size(), 1u);
EXPECT_EQ(settings.selected_objects()[0], "object_a");
ASSERT_EQ(settings.selected_groups().size(), 1u);
EXPECT_EQ(settings.selected_groups()[0], "group_a");
}
TEST(SettingsBuilder, CanOpenFileFromString) {
const auto temp_dir = std::filesystem::temp_directory_path();
const auto token = random_token(12);
const auto input_path = temp_dir / std::filesystem::path("dragiyski-wavefront-parser-test-settings-input-" + token + ".txt");
const auto output_path = temp_dir / std::filesystem::path("dragiyski-wavefront-parser-test-settings-output-" + token + ".txt");
const ScopedFileCleanup input_cleanup(input_path);
const ScopedFileCleanup output_cleanup(output_path);
{
std::ofstream seed(input_path);
seed << token;
}
wavefront::SettingsBuilder builder;
builder.input(input_path.string())
.output(output_path.string());
wavefront::Settings settings = builder.build();
EXPECT_NE(&settings.input(), &std::cin);
EXPECT_NE(&settings.output(), &std::cout);
auto *input_stream = dynamic_cast<std::ifstream *>(&settings.input());
ASSERT_NE(input_stream, nullptr);
EXPECT_TRUE(input_stream->is_open());
std::string input_contents;
*input_stream >> input_contents;
EXPECT_EQ(input_contents, token);
auto *output_stream = dynamic_cast<std::ofstream *>(&settings.output());
ASSERT_NE(output_stream, nullptr);
EXPECT_TRUE(output_stream->is_open());
*output_stream << token;
output_stream->flush();
std::ifstream verify(output_path);
std::string output_contents;
verify >> output_contents;
EXPECT_EQ(output_contents, token);
}
TEST(SettingsBuilder, CanOpenFileFromMovedStreams) {
const auto temp_dir = std::filesystem::temp_directory_path();
const auto token = random_token(12);
const auto input_path = temp_dir / std::filesystem::path("dragiyski-wavefront-parser-test-settings-input-move-" + token + ".txt");
const auto output_path = temp_dir / std::filesystem::path("dragiyski-wavefront-parser-test-settings-output-move-" + token + ".txt");
const ScopedFileCleanup input_cleanup(input_path);
const ScopedFileCleanup output_cleanup(output_path);
{
std::ofstream seed(input_path);
seed << token;
}
std::ifstream input_stream(input_path);
std::ofstream output_stream(output_path);
wavefront::SettingsBuilder builder;
builder.input(std::move(input_stream))
.output(std::move(output_stream));
wavefront::Settings settings = builder.build();
EXPECT_NE(&settings.input(), &std::cin);
EXPECT_NE(&settings.output(), &std::cout);
auto *input_file = dynamic_cast<std::ifstream *>(&settings.input());
ASSERT_NE(input_file, nullptr);
EXPECT_TRUE(input_file->is_open());
std::string input_contents;
*input_file >> input_contents;
EXPECT_EQ(input_contents, token);
auto *output_file = dynamic_cast<std::ofstream *>(&settings.output());
ASSERT_NE(output_file, nullptr);
EXPECT_TRUE(output_file->is_open());
*output_file << token;
output_file->flush();
std::ifstream verify(output_path);
std::string output_contents;
verify >> output_contents;
EXPECT_EQ(output_contents, token);
}
}

36
tests/trim_test.cpp Normal file
View File

@@ -0,0 +1,36 @@
#include <string>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "trim.hpp"
namespace {
using ::testing::StrEq;
struct TrimCase {
const char *source;
const char *expected;
};
class TrimTest : public ::testing::TestWithParam<TrimCase> {
};
TEST_P(TrimTest, ReturnsTrimmedString) {
const auto &param = GetParam();
std::string_view result = wavefront::trim(param.source);
EXPECT_THAT(std::string(result), StrEq(param.expected));
}
INSTANTIATE_TEST_SUITE_P(
TrimCases,
TrimTest,
::testing::Values(
TrimCase{" hello world ", "hello world"},
TrimCase{"\t\n spaced\t\n", "spaced"},
TrimCase{"trimmed", "trimmed"},
TrimCase{" ", ""},
TrimCase{"", ""}
)
);
}