unit tests: coverage, settings
This commit is contained in:
20
tests/data/test-scan-1.txt
Normal file
20
tests/data/test-scan-1.txt
Normal 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
187
tests/settings_test.cpp
Normal 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
36
tests/trim_test.cpp
Normal 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 ¶m = 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{"", ""}
|
||||
)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user