mirror of
https://github.com/red0124/ssp.git
synced 2025-01-23 04:55:20 +01:00
Add extended tests with no new line at eof
This commit is contained in:
parent
57ba23c574
commit
3ea8adedfd
@ -12,7 +12,7 @@ using string_range = std::pair<const char*, const char*>;
|
|||||||
using split_data = std::vector<string_range>;
|
using split_data = std::vector<string_range>;
|
||||||
|
|
||||||
constexpr inline auto default_delimiter = ",";
|
constexpr inline auto default_delimiter = ",";
|
||||||
constexpr static auto get_line_initial_buffer_size = 128;
|
constexpr inline auto get_line_initial_buffer_size = 128;
|
||||||
|
|
||||||
template <bool StringError>
|
template <bool StringError>
|
||||||
inline void assert_string_error_defined() {
|
inline void assert_string_error_defined() {
|
||||||
@ -31,7 +31,7 @@ inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) {
|
|||||||
return getline(lineptr, n, stream);
|
return getline(lineptr, n, stream);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// TODO set ERRNO ?
|
|
||||||
using ssize_t = int64_t;
|
using ssize_t = int64_t;
|
||||||
inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) {
|
inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) {
|
||||||
size_t pos;
|
size_t pos;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include "extract.hpp"
|
#include "extract.hpp"
|
||||||
#include "restrictions.hpp"
|
#include "restrictions.hpp"
|
||||||
|
#include <cerrno>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@ -742,7 +743,6 @@ private:
|
|||||||
reader(const reader& other) = delete;
|
reader(const reader& other) = delete;
|
||||||
reader& operator=(const reader& other) = delete;
|
reader& operator=(const reader& other) = delete;
|
||||||
|
|
||||||
// TODO set error numbers on error
|
|
||||||
ssize_t get_line_buffer(char** lineptr, size_t* n,
|
ssize_t get_line_buffer(char** lineptr, size_t* n,
|
||||||
const char* const buffer, size_t csv_data_size,
|
const char* const buffer, size_t csv_data_size,
|
||||||
size_t& curr_char) {
|
size_t& curr_char) {
|
||||||
@ -812,6 +812,9 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ssize == -1) {
|
if (ssize == -1) {
|
||||||
|
if (errno == ENOMEM) {
|
||||||
|
throw std::bad_alloc{};
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
ssp.hpp
37
ssp.hpp
@ -1,5 +1,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cerrno>
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
@ -625,7 +626,7 @@ using string_range = std::pair<const char*, const char*>;
|
|||||||
using split_data = std::vector<string_range>;
|
using split_data = std::vector<string_range>;
|
||||||
|
|
||||||
constexpr inline auto default_delimiter = ",";
|
constexpr inline auto default_delimiter = ",";
|
||||||
constexpr static auto get_line_initial_buffer_size = 128;
|
constexpr inline auto get_line_initial_buffer_size = 128;
|
||||||
|
|
||||||
template <bool StringError>
|
template <bool StringError>
|
||||||
inline void assert_string_error_defined() {
|
inline void assert_string_error_defined() {
|
||||||
@ -644,6 +645,7 @@ inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) {
|
|||||||
return getline(lineptr, n, stream);
|
return getline(lineptr, n, stream);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
using ssize_t = int64_t;
|
using ssize_t = int64_t;
|
||||||
inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) {
|
inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) {
|
||||||
size_t pos;
|
size_t pos;
|
||||||
@ -2495,20 +2497,22 @@ public:
|
|||||||
|
|
||||||
template <typename U, typename... Us, typename Fun = none>
|
template <typename U, typename... Us, typename Fun = none>
|
||||||
void try_convert_and_invoke(std::optional<U>& value, Fun&& fun) {
|
void try_convert_and_invoke(std::optional<U>& value, Fun&& fun) {
|
||||||
if (!parser_.valid()) {
|
if (parser_.valid()) {
|
||||||
auto tuple_output = try_same<Us...>();
|
return;
|
||||||
if (!parser_.valid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (!std::is_same_v<U, decltype(tuple_output)>) {
|
|
||||||
value = to_object<U>(std::move(tuple_output));
|
|
||||||
} else {
|
|
||||||
value = std::move(tuple_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
parser_.try_invoke(*value, std::forward<Fun>(fun));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto tuple_output = try_same<Us...>();
|
||||||
|
if (!parser_.valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (!std::is_same_v<U, decltype(tuple_output)>) {
|
||||||
|
value = to_object<U>(std::move(tuple_output));
|
||||||
|
} else {
|
||||||
|
value = std::move(tuple_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_.try_invoke(*value, std::forward<Fun>(fun));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U, typename... Us>
|
template <typename U, typename... Us>
|
||||||
@ -2936,6 +2940,9 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ssize == -1) {
|
if (ssize == -1) {
|
||||||
|
if (errno == ENOMEM) {
|
||||||
|
throw std::bad_alloc{};
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3067,7 +3074,7 @@ private:
|
|||||||
buffer_size = first_size + second_size + 3;
|
buffer_size = first_size + second_size + 3;
|
||||||
auto new_first = static_cast<char*>(
|
auto new_first = static_cast<char*>(
|
||||||
realloc(static_cast<void*>(first), buffer_size));
|
realloc(static_cast<void*>(first), buffer_size));
|
||||||
if (!first) {
|
if (!new_first) {
|
||||||
throw std::bad_alloc{};
|
throw std::bad_alloc{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,20 +258,22 @@ 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& delim,
|
||||||
const std::string& file_name) {
|
const std::string& file_name,
|
||||||
|
bool add_new_line = true) {
|
||||||
std::ofstream out{file_name, std::ios_base::app};
|
std::ofstream out{file_name, std::ios_base::app};
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|
||||||
// TODO remove new line at eof randomly
|
|
||||||
for (size_t i = 0; i < data.size(); ++i) {
|
for (size_t i = 0; i < data.size(); ++i) {
|
||||||
line += data[i];
|
line += data[i];
|
||||||
if (i != data.size() - 1) {
|
if (i != data.size() - 1) {
|
||||||
line += delim;
|
line += delim;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out << line << std::endl;
|
out << line;
|
||||||
|
if (add_new_line) {
|
||||||
|
out << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_EQ_CRLF(V1, V2) \
|
#define CHECK_EQ_CRLF(V1, V2) \
|
||||||
@ -333,7 +335,11 @@ void test_data_combinations(const std::vector<column>& input_data,
|
|||||||
|
|
||||||
if (include_header) {
|
if (include_header) {
|
||||||
auto header_data = generate_csv_data<Ts...>(field_header, delim);
|
auto header_data = generate_csv_data<Ts...>(field_header, delim);
|
||||||
write_to_file(header_data, delim, f.name);
|
if (input_data.size() == 0 && rand() % 10 == 0) {
|
||||||
|
write_to_file(header_data, delim, f.name, false);
|
||||||
|
} else {
|
||||||
|
write_to_file(header_data, delim, f.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> layout;
|
std::vector<int> layout;
|
||||||
@ -358,15 +364,12 @@ void test_data_combinations(const std::vector<column>& input_data,
|
|||||||
|
|
||||||
expected_data.push_back(raw_data);
|
expected_data.push_back(raw_data);
|
||||||
auto data = generate_csv_data<Ts...>(raw_data, delim);
|
auto data = generate_csv_data<Ts...>(raw_data, delim);
|
||||||
write_to_file(data, delim, f.name);
|
|
||||||
|
|
||||||
/*
|
if (i + 1 == n && rand() % 10 == 0) {
|
||||||
std::cout << "[.";
|
write_to_file(data, delim, f.name, false);
|
||||||
for (const auto& el : data) {
|
} else {
|
||||||
std::cout << el << '.';
|
write_to_file(data, delim, f.name);
|
||||||
}
|
}
|
||||||
std::cout << "]" << std::endl;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto layout_combinations = include_header && !setup::ignore_header
|
auto layout_combinations = include_header && !setup::ignore_header
|
||||||
@ -430,7 +433,6 @@ void test_data_combinations(const std::vector<column>& input_data,
|
|||||||
auto s0 = p.template get_next<std::string>();
|
auto s0 = p.template get_next<std::string>();
|
||||||
if (i < n) {
|
if (i < n) {
|
||||||
check_error();
|
check_error();
|
||||||
// std::cout << s0 << std::endl;
|
|
||||||
CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value);
|
CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value);
|
||||||
} else {
|
} else {
|
||||||
CHECK(p.eof());
|
CHECK(p.eof());
|
||||||
@ -443,7 +445,6 @@ void test_data_combinations(const std::vector<column>& input_data,
|
|||||||
p.template get_next<std::string, std::string>();
|
p.template get_next<std::string, std::string>();
|
||||||
if (i < n) {
|
if (i < n) {
|
||||||
check_error();
|
check_error();
|
||||||
// std::cout << s0 << ' ' << s1 << std::endl;
|
|
||||||
CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value);
|
CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value);
|
||||||
CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value);
|
CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value);
|
||||||
} else {
|
} else {
|
||||||
@ -458,8 +459,6 @@ void test_data_combinations(const std::vector<column>& input_data,
|
|||||||
std::string>();
|
std::string>();
|
||||||
if (i < n) {
|
if (i < n) {
|
||||||
check_error();
|
check_error();
|
||||||
// std::cout << s0 << ' ' << s1 << ' ' << s2 <<
|
|
||||||
// std::endl;
|
|
||||||
CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value);
|
CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value);
|
||||||
CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value);
|
CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value);
|
||||||
CHECK_EQ_CRLF(s2, expected_data[i][layout[2]].value);
|
CHECK_EQ_CRLF(s2, expected_data[i][layout[2]].value);
|
||||||
@ -475,10 +474,6 @@ void test_data_combinations(const std::vector<column>& input_data,
|
|||||||
std::string, std::string>();
|
std::string, std::string>();
|
||||||
if (i < n) {
|
if (i < n) {
|
||||||
check_error();
|
check_error();
|
||||||
/*
|
|
||||||
std::cout << s0 << ' ' << s1 << ' ' << s2 << ' ' << s3
|
|
||||||
<< std::endl;
|
|
||||||
*/
|
|
||||||
CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value);
|
CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value);
|
||||||
CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value);
|
CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value);
|
||||||
CHECK_EQ_CRLF(s2, expected_data[i][layout[2]].value);
|
CHECK_EQ_CRLF(s2, expected_data[i][layout[2]].value);
|
||||||
@ -496,9 +491,6 @@ void test_data_combinations(const std::vector<column>& input_data,
|
|||||||
std::string>();
|
std::string>();
|
||||||
if (i < n) {
|
if (i < n) {
|
||||||
check_error();
|
check_error();
|
||||||
// std::cout << s0 << ' ' << s1 << ' ' << s2 << ' ' <<
|
|
||||||
// s3
|
|
||||||
// << ' ' << s4 << std::endl;
|
|
||||||
CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value);
|
CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value);
|
||||||
CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value);
|
CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value);
|
||||||
CHECK_EQ_CRLF(s2, expected_data[i][layout[2]].value);
|
CHECK_EQ_CRLF(s2, expected_data[i][layout[2]].value);
|
||||||
|
Loading…
Reference in New Issue
Block a user