mirror of
https://github.com/red0124/ssp.git
synced 2025-12-14 21:59:55 +01:00
Split parser tests into multiple files, add more tests for buffer mode
This commit is contained in:
151
test/test_parser1.hpp
Normal file
151
test/test_parser1.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#pragma once
|
||||
|
||||
#include "test_helpers.hpp"
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <ss/parser.hpp>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace {
|
||||
[[maybe_unused]] void replace_all(std::string& s, const std::string& from,
|
||||
const std::string& to) {
|
||||
if (from.empty()) return;
|
||||
size_t start_pos = 0;
|
||||
while ((start_pos = s.find(from, start_pos)) != std::string::npos) {
|
||||
s.replace(start_pos, from.length(), to);
|
||||
start_pos += to.length();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Ts>
|
||||
void expect_error_on_command(ss::parser<Ts...>& p,
|
||||
const std::function<void()> command) {
|
||||
if (ss::setup<Ts...>::throw_on_error) {
|
||||
try {
|
||||
command();
|
||||
} catch (const std::exception& e) {
|
||||
CHECK_FALSE(std::string{e.what()}.empty());
|
||||
}
|
||||
} else {
|
||||
command();
|
||||
CHECK(!p.valid());
|
||||
if constexpr (ss::setup<Ts...>::string_error) {
|
||||
CHECK_FALSE(p.error_msg().empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[maybe_unused]] void update_if_crlf(std::string& s) {
|
||||
#ifdef _WIN32
|
||||
replace_all(s, "\r\n", "\n");
|
||||
#else
|
||||
(void)(s);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct X {
|
||||
constexpr static auto delim = ",";
|
||||
constexpr static auto empty = "_EMPTY_";
|
||||
int i;
|
||||
double d;
|
||||
std::string s;
|
||||
|
||||
std::string to_string() const {
|
||||
if (s == empty) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return std::to_string(i)
|
||||
.append(delim)
|
||||
.append(std::to_string(d))
|
||||
.append(delim)
|
||||
.append(s);
|
||||
}
|
||||
auto tied() const {
|
||||
return std::tie(i, d, s);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<ss::has_m_tied_t<T>, bool> operator==(const T& lhs,
|
||||
const T& rhs) {
|
||||
return lhs.tied() == rhs.tied();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void make_and_write(const std::string& file_name,
|
||||
const std::vector<T>& data,
|
||||
const std::vector<std::string>& header = {}) {
|
||||
std::ofstream out{file_name};
|
||||
|
||||
#ifdef _WIN32
|
||||
std::vector<const char*> new_lines = {"\n"};
|
||||
#else
|
||||
std::vector<const char*> new_lines = {"\n", "\r\n"};
|
||||
#endif
|
||||
|
||||
for (const auto& i : header) {
|
||||
if (&i != &header.front()) {
|
||||
out << T::delim;
|
||||
}
|
||||
out << i;
|
||||
}
|
||||
|
||||
if (!header.empty()) {
|
||||
out << new_lines.front();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < data.size(); ++i) {
|
||||
out << data[i].to_string() << new_lines[i % new_lines.size()];
|
||||
}
|
||||
}
|
||||
|
||||
std::string make_buffer(const std::string& file_name) {
|
||||
std::ifstream in{file_name, std::ios::binary};
|
||||
std::string tmp;
|
||||
std::string out;
|
||||
out.reserve(sizeof(out) + 1);
|
||||
while (in >> tmp) {
|
||||
out += tmp;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 */
|
||||
Reference in New Issue
Block a user