Add more unit tests for buffer mode

This commit is contained in:
ado 2024-02-18 18:58:51 +01:00
parent 63a618957b
commit baf4317ffa
3 changed files with 67 additions and 57 deletions

View File

@ -5,6 +5,7 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
#include <ss/parser.hpp>
#ifdef CMAKE_GITHUB_CI #ifdef CMAKE_GITHUB_CI
#include <doctest/doctest.h> #include <doctest/doctest.h>
@ -134,4 +135,55 @@ std::vector<std::vector<T>> vector_combinations(const std::vector<T>& v,
} }
return ret; return ret;
} }
std::string make_buffer(const std::string& file_name) {
std::ifstream in{file_name, std::ios::binary};
std::string tmp;
std::string out;
auto copy_if_whitespaces = [&] {
std::string matches = "\n\r\t ";
while (std::any_of(matches.begin(), matches.end(),
[&](auto c) { return in.peek() == c; })) {
if (in.peek() == '\r') {
out += "\r\n";
in.ignore(2);
} else {
out += std::string{static_cast<char>(in.peek())};
in.ignore(1);
}
}
};
out.reserve(sizeof(out) + 1);
copy_if_whitespaces();
while (in >> tmp) {
out += tmp;
copy_if_whitespaces();
}
return out;
}
template <bool buffer_mode, typename... Ts>
std::tuple<ss::parser<Ts...>, std::string> make_parser(
const std::string& file_name, const std::string& delim = "") {
if (buffer_mode) {
auto buffer = make_buffer(file_name);
if (delim.empty()) {
return {ss::parser<Ts...>{buffer.data(), buffer.size()},
std::move(buffer)};
} else {
return {ss::parser<Ts...>{buffer.data(), buffer.size(), delim},
std::move(buffer)};
}
} else {
if (delim.empty()) {
return {ss::parser<Ts...>{file_name}, std::string{}};
} else {
return {ss::parser<Ts...>{file_name, delim}, std::string{}};
}
}
}
} /* namespace */ } /* namespace */

View File

@ -105,54 +105,4 @@ static void make_and_write(const std::string& file_name,
} }
} }
std::string make_buffer(const std::string& file_name) {
std::ifstream in{file_name, std::ios::binary};
std::string tmp;
std::string out;
auto copy_if_whitespaces = [&] {
std::string matches = "\n\r\t ";
while (std::any_of(matches.begin(), matches.end(),
[&](auto c) { return in.peek() == c; })) {
if (in.peek() == '\r') {
out += "\r\n";
in.ignore(2);
} else {
out += std::string{static_cast<char>(in.peek())};
in.ignore(1);
}
}
};
out.reserve(sizeof(out) + 1);
copy_if_whitespaces();
while (in >> tmp) {
out += tmp;
copy_if_whitespaces();
}
return out;
}
template <bool buffer_mode, typename... Ts>
std::tuple<ss::parser<Ts...>, std::string> make_parser(
const std::string& file_name, const std::string& delim = "") {
if (buffer_mode) {
auto buffer = make_buffer(file_name);
if (delim.empty()) {
return {ss::parser<Ts...>{buffer.data(), buffer.size()},
std::move(buffer)};
} else {
return {ss::parser<Ts...>{buffer.data(), buffer.size(), delim},
std::move(buffer)};
}
} else {
if (delim.empty()) {
return {ss::parser<Ts...>{file_name}, std::string{}};
} else {
return {ss::parser<Ts...>{file_name, delim}, std::string{}};
}
}
}
} /* namespace */ } /* namespace */

View File

@ -121,7 +121,7 @@ column make_column(const std::string& input_header,
} }
[[maybe_unused]] void replace_all2(std::string& s, const std::string& old_value, [[maybe_unused]] void replace_all2(std::string& s, const std::string& old_value,
const std::string& new_value) { const std::string& new_value) {
for (size_t i = 0; i < 999; ++i) { for (size_t i = 0; i < 999; ++i) {
size_t pos = s.find(old_value); size_t pos = s.find(old_value);
if (pos == std::string::npos) { if (pos == std::string::npos) {
@ -257,7 +257,8 @@ std::vector<std::string> generate_csv_data(const std::vector<field>& data,
} }
[[maybe_unused]] void write_to_file(const std::vector<std::string>& data, [[maybe_unused]] void write_to_file(const std::vector<std::string>& data,
const std::string& delim, const std::string& file_name) { const std::string& delim,
const std::string& file_name) {
std::ofstream out{file_name, std::ios_base::app}; std::ofstream out{file_name, std::ios_base::app};
std::string line; std::string line;
for (size_t i = 0; i < data.size(); ++i) { for (size_t i = 0; i < data.size(); ++i) {
@ -299,7 +300,7 @@ std::vector<std::string> generate_csv_data(const std::vector<field>& data,
CHECK(V1 == V2); \ CHECK(V1 == V2); \
} }
template <typename... Ts> template <bool buffer_mode, typename... Ts>
void test_data_combinations(const std::vector<column>& input_data, void test_data_combinations(const std::vector<column>& input_data,
const std::string& delim, bool include_header) { const std::string& delim, bool include_header) {
using setup = ss::setup<Ts...>; using setup = ss::setup<Ts...>;
@ -388,7 +389,7 @@ void test_data_combinations(const std::vector<column>& input_data,
} }
for (const auto& layout : unique_layout_combinations) { for (const auto& layout : unique_layout_combinations) {
ss::parser<setup> p{f.name, delim}; auto [p, _] = make_parser<buffer_mode, setup>(f.name, delim);
if (include_header && !setup::ignore_header) { if (include_header && !setup::ignore_header) {
std::vector<std::string> fields; std::vector<std::string> fields;
@ -409,7 +410,7 @@ void test_data_combinations(const std::vector<column>& input_data,
REQUIRE(p.valid()); REQUIRE(p.valid());
} }
auto check_error = [&p] { auto check_error = [&p = p] {
CHECK(p.valid()); CHECK(p.valid());
if (!p.valid()) { if (!p.valid()) {
if constexpr (setup::string_error) { if constexpr (setup::string_error) {
@ -570,8 +571,14 @@ void test_option_combinations() {
{columns0, columns1, columns2, columns3, columns4, columns5, {columns0, columns1, columns2, columns3, columns4, columns5,
columns6, columns7}) { columns6, columns7}) {
try { try {
test_data_combinations<Ts...>(columns, delimiter, false); test_data_combinations<false, Ts...>(columns, delimiter,
test_data_combinations<Ts...>(columns, delimiter, true); false);
test_data_combinations<false, Ts...>(columns, delimiter,
true);
test_data_combinations<true, Ts...>(columns, delimiter,
false);
test_data_combinations<true, Ts...>(columns, delimiter,
true);
} catch (std::exception& e) { } catch (std::exception& e) {
std::cout << typeid(ss::parser<Ts...>).name() << std::endl; std::cout << typeid(ss::parser<Ts...>).name() << std::endl;
FAIL_CHECK(std::string{e.what()}); FAIL_CHECK(std::string{e.what()});
@ -616,6 +623,7 @@ void test_option_combinations3() {
} /* namespace */ } /* namespace */
// Tests split into multiple compilation units
#if 0 #if 0
TEST_CASE("parser test various cases version 2 segment 1") { TEST_CASE("parser test various cases version 2 segment 1") {