Compare commits

...

3 Commits

  1. 40
      src/common/app_parameters.cpp
  2. 2
      src/common/object.cpp
  3. 98
      src/common/parsers/json.cpp
  4. 24
      src/include/jessilib/app_parameters.hpp
  5. 2
      src/include/jessilib/http_query.hpp
  6. 26
      src/include/jessilib/object.hpp
  7. 6
      src/include/jessilib/parser.hpp
  8. 12
      src/include/jessilib/unicode.hpp
  9. 32
      src/include/jessilib/unicode_base.hpp
  10. 12
      src/include/jessilib/unicode_compare.hpp
  11. 2
      src/include/jessilib/unicode_sequence.hpp
  12. 8
      src/include/jessilib/unicode_syntax.hpp
  13. 112
      src/test/app_parameters.cpp
  14. 20
      src/test/config.cpp
  15. 186
      src/test/object.cpp
  16. 21
      src/test/parser.cpp
  17. 67
      src/test/parsers/json.cpp

40
src/common/app_parameters.cpp

@ -26,17 +26,19 @@ app_parameters::app_parameters(int in_argc, char** in_argv)
} }
app_parameters::app_parameters(int in_argc, const char** in_argv) { app_parameters::app_parameters(int in_argc, const char** in_argv) {
// TODO: discard argc/argv and use GetCommandLineW on Windows
// TODO: not assume argv is utf-8; it often will not be
// Sanity safety check; should never happen // Sanity safety check; should never happen
if (in_argc <= 0 || in_argv == nullptr) { if (in_argc <= 0 || in_argv == nullptr) {
return; return;
} }
// Populate path // Populate path
m_path = in_argv[0]; m_path = reinterpret_cast<const char8_t*>(in_argv[0]);
// Process args // Process args
std::string_view key; std::u8string_view key;
std::string value; std::u8string value;
auto flush_value = [&key, &value, this]() { auto flush_value = [&key, &value, this]() {
// This is the start of a key; flush what we were previously processing // This is the start of a key; flush what we were previously processing
if (!key.empty()) { if (!key.empty()) {
@ -51,7 +53,7 @@ app_parameters::app_parameters(int in_argc, const char** in_argv) {
}; };
for (int index = 1; index < in_argc; ++index) { for (int index = 1; index < in_argc; ++index) {
const char* arg = in_argv[index]; const char8_t* arg = reinterpret_cast<const char8_t*>(in_argv[index]);
if (arg != nullptr && *arg != '\0') { if (arg != nullptr && *arg != '\0') {
// Check if this is a key or value // Check if this is a key or value
if (*arg == '-') { if (*arg == '-') {
@ -66,7 +68,7 @@ app_parameters::app_parameters(int in_argc, const char** in_argv) {
// Parse key for any value denominator ('=') // Parse key for any value denominator ('=')
size_t key_end = key.find('='); size_t key_end = key.find('=');
if (key_end != std::string_view::npos) { if (key_end != std::u8string_view::npos) {
// arg contains start of a value // arg contains start of a value
value = key.substr(key_end + 1); value = key.substr(key_end + 1);
key = key.substr(0, key_end); key = key.substr(0, key_end);
@ -91,30 +93,32 @@ app_parameters::app_parameters(int in_argc, const char** in_argv) {
flush_value(); flush_value();
// Populate m_switches_set from m_switches // Populate m_switches_set from m_switches
m_switches_set = std::unordered_set<std::string_view>{ m_switches.begin(), m_switches.end() }; m_switches_set = std::unordered_set<std::u8string_view>{ m_switches.begin(), m_switches.end() };
} }
std::string_view app_parameters::path() const { std::u8string_view app_parameters::path() const {
return m_path; return m_path;
} }
const std::vector<std::string_view>& app_parameters::arguments() const { const std::vector<std::u8string_view>& app_parameters::arguments() const {
return m_args; return m_args;
} }
const std::vector<std::string_view>& app_parameters::switches() const { const std::vector<std::u8string_view>& app_parameters::switches() const {
return m_switches; return m_switches;
} }
const std::unordered_set<std::string_view>& app_parameters::switches_set() const { const std::unordered_set<std::u8string_view>& app_parameters::switches_set() const {
return m_switches_set; return m_switches_set;
} }
const std::unordered_map<std::string_view, std::string>& app_parameters::values() const { const std::unordered_map<std::u8string_view, std::u8string>& app_parameters::values() const {
return m_values; return m_values;
} }
object app_parameters::as_object() const { object app_parameters::as_object() const {
using namespace std::literals;
// Null check // Null check
if (m_path.empty() if (m_path.empty()
&& m_args.empty()) { && m_args.empty()) {
@ -122,19 +126,19 @@ object app_parameters::as_object() const {
return object{}; return object{};
} }
return std::map<std::string, object>{ return std::map<std::u8string, object>{
{ "Path", m_path }, { u8"Path"s, m_path },
{ "Args", m_args }, { u8"Args"s, m_args },
{ "Switches", m_switches }, { u8"Switches"s, m_switches },
{ "Values", m_values } { u8"Values"s, m_values }
}; };
} }
bool app_parameters::has_switch(std::string_view in_switch) const { bool app_parameters::has_switch(std::u8string_view in_switch) const {
return m_switches_set.find(in_switch) != m_switches_set.end(); return m_switches_set.find(in_switch) != m_switches_set.end();
} }
std::string_view app_parameters::get_value(std::string_view in_key, std::string_view in_default) const { std::u8string_view app_parameters::get_value(std::u8string_view in_key, std::u8string_view in_default) const {
auto result = m_values.find(in_key); auto result = m_values.find(in_key);
// Safety check // Safety check

2
src/common/object.cpp

@ -28,7 +28,7 @@ object::object(object&& in_object) {
m_value = std::move(in_object.m_value); m_value = std::move(in_object.m_value);
} }
object::object(const char* in_str) object::object(const text_char_type* in_str)
: m_value{ string_type{ in_str } } { : m_value{ string_type{ in_str } } {
// Empty ctor body // Empty ctor body
} }

98
src/common/parsers/json.cpp

@ -25,79 +25,42 @@ using namespace std::literals;
namespace jessilib { namespace jessilib {
std::string make_json_string(std::string_view in_string) { std::string make_json_string(std::u8string_view in_string) {
std::string result; std::string result;
result.reserve(in_string.size() + 2); result.reserve(in_string.size() + 2);
result = '\"'; result = '\"';
while (!in_string.empty()) { decode_result decode;
if (in_string.front() == '\\') { // backslash while ((decode = decode_codepoint(in_string)).units != 0) {
if (decode.codepoint == U'\\') { // backslash
result += '\\'; result += '\\';
result += '\\'; result += '\\';
} }
else if (in_string.front() == '\"') { // quotation else if (decode.codepoint == U'\"') { // quotation
result += '\\'; result += '\\';
result += '\"'; result += '\"';
} }
else if (in_string.front() < 0x20) { // control characters else if (decode.codepoint < 0x20) { // control characters
result += "\\u0000"sv; result += "\\u0000"sv;
// overwrite last 2 zeroes with correct hexadecimal sequence // overwrite last 2 zeroes with correct hexadecimal sequence
char* data_end = result.data() + result.size(); char* data_end = result.data() + result.size();
char* data = data_end - 2; char* data = data_end - 2; // Will only ever use 2 chars
std::to_chars(data, data_end, in_string.front(), 16); auto to_chars_result = std::to_chars(data, data_end, static_cast<uint32_t>(decode.codepoint), 16);
} if (to_chars_result.ec == std::errc{} && to_chars_result.ptr != data_end) {
else if ((in_string.front() & 0x80) != 0) { // UTF-8 sequence; copy to bypass above processing // Only 1 byte written; shift it over
if ((in_string.front() & 0x40) != 0) { *to_chars_result.ptr = *(to_chars_result.ptr - 1);
// this is a 2+ byte sequence
// And fill in the zeroes
if ((in_string.front() & 0x20) != 0) { *(to_chars_result.ptr - 1) = '0';
// this is a 3+ byte sequence
if ((in_string.front() & 0x10) != 0) {
// this is a 4 byte sequence
if (in_string.size() < 4) {
// Invalid sequence encountered (first byte indicates 4 bytes, but less than 4 available)
break;
}
// This is a 4-byte sequence
result += in_string.substr(0, 4);
in_string.remove_prefix(4);
continue;
}
if (in_string.size() < 3) {
// Invalid sequence encountered (first byte indicates 3 bytes, but less than 3 available)
break;
}
// This is a 3-byte sequence
result += in_string.substr(0, 3);
in_string.remove_prefix(3);
continue;
}
if (in_string.size() < 2) {
// Invalid sequence encountered (first byte indicates 2 bytes, but less than 2 available)
break;
}
// This is a 2-byte sequence
result += in_string.substr(0, 2);
in_string.remove_prefix(2);
continue;
} }
// Invalid sequence encountered (first bit is 1, but not second)
break;
} }
else { else {
// Character in standard ASCII table // Valid UTF-8 sequence; copy it over
result += in_string.front(); result.append(reinterpret_cast<const char*>(in_string.data()), decode.units);
} }
in_string.remove_prefix(1); in_string.remove_prefix(decode.units);
} }
result += '\"'; result += '\"';
@ -132,8 +95,8 @@ uint16_t get_codepoint_from_hex(const std::string_view& in_data) {
return value; return value;
} }
std::string read_json_string(std::string_view& in_data) { std::u8string read_json_string(std::string_view& in_data) {
std::string result; std::u8string result;
// Remove leading quotation // Remove leading quotation
in_data.remove_prefix(1); in_data.remove_prefix(1);
@ -154,49 +117,49 @@ std::string read_json_string(std::string_view& in_data) {
// Quote // Quote
case '\"': case '\"':
in_data.remove_prefix(1); in_data.remove_prefix(1);
result += '\"'; result += u8'\"';
break; break;
// Backslash // Backslash
case '\\': case '\\':
in_data.remove_prefix(1); in_data.remove_prefix(1);
result += '\\'; result += u8'\\';
break; break;
// Forward slash // Forward slash
case '/': case '/':
in_data.remove_prefix(1); in_data.remove_prefix(1);
result += '/'; result += u8'/';
break; break;
// Backspace // Backspace
case 'b': case 'b':
in_data.remove_prefix(1); in_data.remove_prefix(1);
result += '\b'; result += u8'\b';
break; break;
// Formfeed // Formfeed
case 'f': case 'f':
in_data.remove_prefix(1); in_data.remove_prefix(1);
result += '\f'; result += u8'\f';
break; break;
// Newline // Newline
case 'n': case 'n':
in_data.remove_prefix(1); in_data.remove_prefix(1);
result += '\n'; result += u8'\n';
break; break;
// Carriage return // Carriage return
case 'r': case 'r':
in_data.remove_prefix(1); in_data.remove_prefix(1);
result += '\r'; result += u8'\r';
break; break;
// Horizontal tab // Horizontal tab
case 't': case 't':
in_data.remove_prefix(1); in_data.remove_prefix(1);
result += '\t'; result += u8'\t';
break; break;
// Unicode codepoint // Unicode codepoint
@ -258,8 +221,7 @@ std::string read_json_string(std::string_view& in_data) {
} }
// Valid unicode sequence // Valid unicode sequence
result += in_data.substr(0, codepoint.units); result.append(reinterpret_cast<const char8_t*>(in_data.data()), codepoint.units);
//result.append(reinterpret_cast<const char8_t*>(in_data.data()), codepoint.units);
in_data.remove_prefix(codepoint.units); in_data.remove_prefix(codepoint.units);
break; break;
} }
@ -492,8 +454,8 @@ std::string json_parser::serialize(const object& in_object) {
case object::type::decimal: case object::type::decimal:
return std::to_string(in_object.get<long double>()); return std::to_string(in_object.get<long double>());
case object::type::string: case object::type::text:
return make_json_string(in_object.get<std::string>()); return make_json_string(in_object.get<std::u8string>());
case object::type::array: { case object::type::array: {
if (in_object.size() == 0) { if (in_object.size() == 0) {

24
src/include/jessilib/app_parameters.hpp

@ -25,24 +25,24 @@ public:
app_parameters(int in_argc, char** in_argv); app_parameters(int in_argc, char** in_argv);
app_parameters(int in_argc, const char** in_argv); app_parameters(int in_argc, const char** in_argv);
std::string_view path() const; std::u8string_view path() const;
const std::vector<std::string_view>& arguments() const; const std::vector<std::u8string_view>& arguments() const;
const std::vector<std::string_view>& switches() const; const std::vector<std::u8string_view>& switches() const;
const std::unordered_set<std::string_view>& switches_set() const; const std::unordered_set<std::u8string_view>& switches_set() const;
const std::unordered_map<std::string_view, std::string>& values() const; const std::unordered_map<std::u8string_view, std::u8string>& values() const;
jessilib::object as_object() const; jessilib::object as_object() const;
bool has_switch(std::string_view in_switch) const; bool has_switch(std::u8string_view in_switch) const;
std::string_view get_value(std::string_view in_key, std::string_view in_default = {}) const; std::u8string_view get_value(std::u8string_view in_key, std::u8string_view in_default = {}) const;
operator jessilib::object() const { return as_object(); } operator jessilib::object() const { return as_object(); }
private: private:
std::string_view m_path; std::u8string_view m_path;
std::vector<std::string_view> m_args; std::vector<std::u8string_view> m_args;
std::vector<std::string_view> m_switches; std::vector<std::u8string_view> m_switches;
std::unordered_set<std::string_view> m_switches_set; std::unordered_set<std::u8string_view> m_switches_set;
std::unordered_map<std::string_view, std::string> m_values; std::unordered_map<std::u8string_view, std::u8string> m_values;
}; };
} // namespace jessilib } // namespace jessilib

2
src/include/jessilib/http_query.hpp

@ -144,7 +144,7 @@ constexpr syntax_tree_member<CharT, ContextT> make_simple_shrink_pair() {
} }
template<typename CharT, typename ContextT> template<typename CharT, typename ContextT>
bool html_form_default_action(get_endpoint_result decode, ContextT& inout_context, std::basic_string_view<CharT>& inout_read_view) { bool html_form_default_action(decode_result decode, ContextT& inout_context, std::basic_string_view<CharT>& inout_read_view) {
// A regular character; copy it and advance the read/write heads // A regular character; copy it and advance the read/write heads
CharT*& write_head = inout_context.write_head; CharT*& write_head = inout_context.write_head;
CharT* write_end = write_head + decode.units; CharT* write_end = write_head + decode.units;

26
src/include/jessilib/object.hpp

@ -31,8 +31,12 @@ namespace jessilib {
class object { class object {
public: public:
using array_type = std::vector<object>; using array_type = std::vector<object>;
using string_type = std::string; using text_char_type = char8_t;
using string_view_type = std::string_view; using text_type = std::basic_string<text_char_type>;
using text_view_type = std::basic_string_view<text_char_type>;
using data_type = std::vector<unsigned char>;
using string_type = text_type;
using string_view_type = text_view_type;
using map_type = std::map<string_type, object>; using map_type = std::map<string_type, object>;
using index_type = std::size_t; using index_type = std::size_t;
@ -86,7 +90,8 @@ public:
boolean, boolean,
integer, integer,
decimal, decimal,
string, // TODO: consider separating into 'binary' (std::vector<std::byte>) and 'text' (string_type) types text,
data,
array, array,
map map
}; };
@ -152,7 +157,7 @@ public:
} }
} }
object(const char* in_str); object(const text_char_type* in_str);
object(const string_view_type& in_str); object(const string_view_type& in_str);
// Comparison operators // Comparison operators
@ -454,6 +459,17 @@ public:
return result; return result;
} }
else if constexpr (std::is_same<T, data_type>::value) {
// TODO: pull this into a separate method
uint64_t hash = 14695981039346656037ULL;
for (auto byte : value) {
hash = hash ^ byte;
hash = hash * 1099511628211ULL;
}
return hash;
}
else { else {
return std::hash<T>{}(std::forward<decltype(value)>(value)); return std::hash<T>{}(std::forward<decltype(value)>(value));
} }
@ -464,7 +480,7 @@ private:
using null_variant_t = void*; using null_variant_t = void*;
// TODO: consider replacing std::string with std::u8string (for strings) & std::vector<unsigned char> (for data) // TODO: consider replacing std::string with std::u8string (for strings) & std::vector<unsigned char> (for data)
// TODO: consider some more generic mechanism for underlying string type, to support utf-16 & utf-32 strings // TODO: consider some more generic mechanism for underlying string type, to support utf-16 & utf-32 strings
std::variant<null_variant_t, bool, intmax_t, long double, string_type, array_type, map_type> m_value; std::variant<null_variant_t, bool, intmax_t, long double, text_type, data_type, array_type, map_type> m_value;
// TODO: note for future self, just use either first or last element in array_type to hold XML attributes // TODO: note for future self, just use either first or last element in array_type to hold XML attributes
// OR, have every XML tag objects be a map, with all subobjects being in a "__values" array subobject or such // OR, have every XML tag objects be a map, with all subobjects being in a "__values" array subobject or such

6
src/include/jessilib/parser.hpp

@ -38,9 +38,9 @@ public:
* @return A valid (possibly null) object * @return A valid (possibly null) object
*/ */
virtual object deserialize(std::istream& in_stream); virtual object deserialize(std::istream& in_stream);
virtual object deserialize(std::string_view in_data) = 0; virtual object deserialize(std::string_view in_data) = 0; // TODO: serialize from arbitrary unicode strings
virtual void serialize(std::ostream& in_stream, const object& in_object); virtual void serialize(std::ostream& in_stream, const object& in_object);
virtual std::string serialize(const object& in_object) = 0; virtual std::string serialize(const object& in_object) = 0; // TODO: serialize to arbitrary unicode strings
}; // parser }; // parser
template<typename T> template<typename T>
@ -57,4 +57,4 @@ public:
impl::parser_manager::id m_id; impl::parser_manager::id m_id;
}; // parser_registration }; // parser_registration
} // namespace jessilib } // namespace jessilib

12
src/include/jessilib/unicode.hpp

@ -89,7 +89,7 @@ bool is_valid(const InT& in_string) {
InViewT in_string_view = static_cast<InViewT>(in_string); InViewT in_string_view = static_cast<InViewT>(in_string);
while (!in_string_view.empty()) { while (!in_string_view.empty()) {
get_endpoint_result string_front = decode_codepoint(in_string_view); decode_result string_front = decode_codepoint(in_string_view);
if (string_front.units == 0) { if (string_front.units == 0) {
return false; return false;
} }
@ -163,7 +163,7 @@ std::basic_string<OutCharT> string_cast(const InT& in_string) {
} }
while (!in_string_view.empty()) { while (!in_string_view.empty()) {
get_endpoint_result string_front = decode_codepoint(in_string_view); decode_result string_front = decode_codepoint(in_string_view);
if (string_front.units == 0) { if (string_front.units == 0) {
return {}; return {};
} }
@ -199,7 +199,7 @@ size_t find(std::basic_string_view<LhsCharT> in_string, char32_t in_codepoint) {
size_t codepoints_removed{}; size_t codepoints_removed{};
while (!in_string.empty()) { while (!in_string.empty()) {
std::basic_string_view<LhsCharT> string = in_string; std::basic_string_view<LhsCharT> string = in_string;
get_endpoint_result string_front = decode_codepoint(string); decode_result string_front = decode_codepoint(string);
if (string_front.units == 0) { if (string_front.units == 0) {
// Failed to decode front codepoint; bad unicode sequence // Failed to decode front codepoint; bad unicode sequence
@ -267,12 +267,12 @@ size_t find(std::basic_string_view<LhsCharT> in_string, std::basic_string_view<R
std::basic_string_view<LhsCharT> string = in_string; std::basic_string_view<LhsCharT> string = in_string;
std::basic_string_view<RhsCharT> substring = in_substring; std::basic_string_view<RhsCharT> substring = in_substring;
get_endpoint_result string_front; decode_result string_front;
do { do {
// TODO: optimize this for when in_string and in_substring are same type, by only decoding in_string, solely // TODO: optimize this for when in_string and in_substring are same type, by only decoding in_string, solely
// to determine number of data units to compare // to determine number of data units to compare
string_front = decode_codepoint(string); string_front = decode_codepoint(string);
get_endpoint_result prefix_front = decode_codepoint(substring); decode_result prefix_front = decode_codepoint(substring);
if (string_front.units == 0 if (string_front.units == 0
|| prefix_front.units == 0) { || prefix_front.units == 0) {
@ -386,7 +386,7 @@ constexpr void join_append(OutT& out_string, InT&& in_string, ArgsT&&... in_args
} }
else { else {
// Append over all the codepoints // Append over all the codepoints
get_endpoint_result decode; decode_result decode;
std::basic_string_view<InCharT> in_view = in_string; std::basic_string_view<InCharT> in_view = in_string;
while ((decode = decode_codepoint(in_view)).units != 0) { while ((decode = decode_codepoint(in_view)).units != 0) {
encode_codepoint(out_string, decode.codepoint); encode_codepoint(out_string, decode.codepoint);

32
src/include/jessilib/unicode_base.hpp

@ -74,7 +74,7 @@ std::wstring encode_codepoint_w(char32_t in_codepoint); // ASSUMES UTF-16 OR UTF
/** decode_codepoint */ /** decode_codepoint */
struct get_endpoint_result { struct decode_result {
char32_t codepoint{}; // Codepoint char32_t codepoint{}; // Codepoint
size_t units{}; // Number of data units codepoint was represented by, or 0 size_t units{}; // Number of data units codepoint was represented by, or 0
}; };
@ -86,17 +86,17 @@ struct get_endpoint_result {
* @return A struct containing a valid codepoint and the number of representative data units on success, zero otherwise. * @return A struct containing a valid codepoint and the number of representative data units on success, zero otherwise.
*/ */
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint_utf8(std::basic_string_view<CharT> in_string); // UTF-8 constexpr decode_result decode_codepoint_utf8(std::basic_string_view<CharT> in_string); // UTF-8
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint_utf16(std::basic_string_view<CharT> in_string); // UTF-16 constexpr decode_result decode_codepoint_utf16(std::basic_string_view<CharT> in_string); // UTF-16
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint_utf32(std::basic_string_view<CharT> in_string); // UTF-32 constexpr decode_result decode_codepoint_utf32(std::basic_string_view<CharT> in_string); // UTF-32
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint(std::basic_string_view<CharT> in_string); // ASSUMES UTF-16 OR UTF-32 constexpr decode_result decode_codepoint(std::basic_string_view<CharT> in_string); // ASSUMES UTF-16 OR UTF-32
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint(const CharT* in_begin, size_t in_length); constexpr decode_result decode_codepoint(const CharT* in_begin, size_t in_length);
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint(const CharT* in_begin, const CharT* in_end); constexpr decode_result decode_codepoint(const CharT* in_begin, const CharT* in_end);
/** advance_codepoint */ /** advance_codepoint */
@ -125,7 +125,7 @@ bool is_valid_codepoint(const std::basic_string_view<T>& in_string) {
constexpr bool is_high_surrogate(char32_t in_codepoint); constexpr bool is_high_surrogate(char32_t in_codepoint);
constexpr bool is_low_surrogate(char32_t in_codepoint); constexpr bool is_low_surrogate(char32_t in_codepoint);
constexpr get_endpoint_result decode_surrogate_pair(char16_t in_high_surrogate, char16_t in_low_surrogate); constexpr decode_result decode_surrogate_pair(char16_t in_high_surrogate, char16_t in_low_surrogate);
template<typename CharT> template<typename CharT>
struct unicode_traits : std::false_type {}; struct unicode_traits : std::false_type {};
@ -365,8 +365,8 @@ constexpr size_t encode_codepoint(CharT* out_buffer, char32_t in_codepoint) {
/** decode_codepoint */ /** decode_codepoint */
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint_utf8(std::basic_string_view<CharT> in_string) { constexpr decode_result decode_codepoint_utf8(std::basic_string_view<CharT> in_string) {
get_endpoint_result result{ 0, 0 }; decode_result result{ 0, 0 };
if (in_string.empty()) { if (in_string.empty()) {
return result; return result;
@ -426,7 +426,7 @@ constexpr get_endpoint_result decode_codepoint_utf8(std::basic_string_view<CharT
} }
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint_utf16(std::basic_string_view<CharT> in_string) { constexpr decode_result decode_codepoint_utf16(std::basic_string_view<CharT> in_string) {
if (in_string.empty()) { if (in_string.empty()) {
return { 0, 0 }; return { 0, 0 };
} }
@ -449,7 +449,7 @@ constexpr get_endpoint_result decode_codepoint_utf16(std::basic_string_view<Char
} }
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint_utf32(std::basic_string_view<CharT> in_string) { constexpr decode_result decode_codepoint_utf32(std::basic_string_view<CharT> in_string) {
if (in_string.empty()) { if (in_string.empty()) {
return { 0, 0 }; return { 0, 0 };
} }
@ -458,7 +458,7 @@ constexpr get_endpoint_result decode_codepoint_utf32(std::basic_string_view<Char
} }
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint(std::basic_string_view<CharT> in_string) { constexpr decode_result decode_codepoint(std::basic_string_view<CharT> in_string) {
if constexpr (std::is_same_v<CharT, char8_t>) { if constexpr (std::is_same_v<CharT, char8_t>) {
return decode_codepoint_utf8(in_string); return decode_codepoint_utf8(in_string);
} }
@ -482,12 +482,12 @@ constexpr get_endpoint_result decode_codepoint(std::basic_string_view<CharT> in_
} }
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint(const CharT* in_begin, size_t in_length) { constexpr decode_result decode_codepoint(const CharT* in_begin, size_t in_length) {
return decode_codepoint<CharT>(std::basic_string_view<CharT>{in_begin, in_length}); return decode_codepoint<CharT>(std::basic_string_view<CharT>{in_begin, in_length});
} }
template<typename CharT> template<typename CharT>
constexpr get_endpoint_result decode_codepoint(const CharT* in_begin, const CharT* in_end) { constexpr decode_result decode_codepoint(const CharT* in_begin, const CharT* in_end) {
return decode_codepoint<CharT>(std::basic_string_view<CharT>{in_begin, static_cast<size_t>(in_end - in_begin)}); return decode_codepoint<CharT>(std::basic_string_view<CharT>{in_begin, static_cast<size_t>(in_end - in_begin)});
} }
@ -499,7 +499,7 @@ constexpr bool is_low_surrogate(char32_t in_codepoint) {
return in_codepoint >= 0xDC00 && in_codepoint <= 0xDFFF; return in_codepoint >= 0xDC00 && in_codepoint <= 0xDFFF;
} }
constexpr get_endpoint_result decode_surrogate_pair(char16_t in_high_surrogate, char16_t in_low_surrogate) { constexpr decode_result decode_surrogate_pair(char16_t in_high_surrogate, char16_t in_low_surrogate) {
if (is_high_surrogate(in_high_surrogate) if (is_high_surrogate(in_high_surrogate)
&& is_low_surrogate((in_low_surrogate))) { && is_low_surrogate((in_low_surrogate))) {
// We have a valid surrogate pair; decode it into a codepoint and return // We have a valid surrogate pair; decode it into a codepoint and return

12
src/include/jessilib/unicode_compare.hpp

@ -145,8 +145,8 @@ size_t starts_with_length(std::basic_string_view<LhsCharT> in_string, std::basic
size_t codepoints_removed{}; size_t codepoints_removed{};
while (!in_string.empty() && !in_prefix.empty()) { while (!in_string.empty() && !in_prefix.empty()) {
get_endpoint_result string_front = decode_codepoint(in_string); decode_result string_front = decode_codepoint(in_string);
get_endpoint_result prefix_front = decode_codepoint(in_prefix); decode_result prefix_front = decode_codepoint(in_prefix);
if (string_front.units == 0 if (string_front.units == 0
|| prefix_front.units == 0) { || prefix_front.units == 0) {
@ -195,8 +195,8 @@ size_t starts_with_lengthi(std::basic_string_view<LhsCharT> in_string, std::basi
size_t codepoints_removed{}; size_t codepoints_removed{};
while (!in_string.empty() && !in_prefix.empty()) { while (!in_string.empty() && !in_prefix.empty()) {
get_endpoint_result string_front = decode_codepoint(in_string); decode_result string_front = decode_codepoint(in_string);
get_endpoint_result prefix_front = decode_codepoint(in_prefix); decode_result prefix_front = decode_codepoint(in_prefix);
if (string_front.units == 0 if (string_front.units == 0
|| prefix_front.units == 0) { || prefix_front.units == 0) {
@ -270,7 +270,7 @@ struct text_hash {
static uint64_t hash(const CharT* data, const CharT* end) { static uint64_t hash(const CharT* data, const CharT* end) {
uint64_t hash = 14695981039346656037ULL; uint64_t hash = 14695981039346656037ULL;
get_endpoint_result decode; decode_result decode;
while (data != end) { while (data != end) {
decode = decode_codepoint(data, end); decode = decode_codepoint(data, end);
if (decode.units == 0) { if (decode.units == 0) {
@ -355,7 +355,7 @@ struct text_hashi {
static uint64_t hash(const CharT* data, const CharT* end) { static uint64_t hash(const CharT* data, const CharT* end) {
uint64_t hash = 14695981039346656037ULL; uint64_t hash = 14695981039346656037ULL;
get_endpoint_result decode; decode_result decode;
while (data != end) { while (data != end) {
decode = decode_codepoint(data, end - data); decode = decode_codepoint(data, end - data);
if (decode.units == 0) { if (decode.units == 0) {

2
src/include/jessilib/unicode_sequence.hpp

@ -89,7 +89,7 @@ constexpr bool apply_shrink_sequence_tree(std::basic_string<CharT>& inout_string
std::basic_string_view<CharT> read_view = inout_string; std::basic_string_view<CharT> read_view = inout_string;
CharT* write_head = inout_string.data(); CharT* write_head = inout_string.data();
get_endpoint_result decode; decode_result decode;
constexpr auto SubTreeEnd = SequenceTreeBegin + SequenceTreeSize; constexpr auto SubTreeEnd = SequenceTreeBegin + SequenceTreeSize;
while ((decode = decode_codepoint(read_view)).units != 0) { while ((decode = decode_codepoint(read_view)).units != 0) {

8
src/include/jessilib/unicode_syntax.hpp

@ -37,7 +37,7 @@ template<typename CharT, typename ContextT>
using syntax_tree_action = bool(*)(ContextT& inout_context, std::basic_string_view<CharT>& inout_read_view); using syntax_tree_action = bool(*)(ContextT& inout_context, std::basic_string_view<CharT>& inout_read_view);
template<typename CharT, typename ContextT> template<typename CharT, typename ContextT>
using default_syntax_tree_action = bool(*)(get_endpoint_result in_codepoint, ContextT& inout_context, std::basic_string_view<CharT>& inout_read_view); using default_syntax_tree_action = bool(*)(decode_result in_codepoint, ContextT& inout_context, std::basic_string_view<CharT>& inout_read_view);
template<typename CharT, typename ContextT> template<typename CharT, typename ContextT>
using syntax_tree = const std::pair<char32_t, syntax_tree_action<CharT, ContextT>>[]; using syntax_tree = const std::pair<char32_t, syntax_tree_action<CharT, ContextT>>[];
@ -73,12 +73,12 @@ constexpr bool is_sorted() {
} }
template<typename CharT, typename ContextT> template<typename CharT, typename ContextT>
bool fail_action(get_endpoint_result, ContextT&, std::basic_string_view<CharT>&) { bool fail_action(decode_result, ContextT&, std::basic_string_view<CharT>&) {
return false; return false;
} }
template<typename CharT, typename ContextT> template<typename CharT, typename ContextT>
bool noop_action(get_endpoint_result decode, ContextT&, std::basic_string_view<CharT>& inout_read_view) { bool noop_action(decode_result decode, ContextT&, std::basic_string_view<CharT>& inout_read_view) {
inout_read_view.remove_prefix(decode.units); inout_read_view.remove_prefix(decode.units);
return true; return true;
} }
@ -111,7 +111,7 @@ constexpr bool apply_syntax_tree(ContextT& inout_context, std::basic_string_view
return true; return true;
} }
get_endpoint_result decode; decode_result decode;
constexpr auto SubTreeEnd = SequenceTreeBegin + SequenceTreeSize; constexpr auto SubTreeEnd = SequenceTreeBegin + SequenceTreeSize;
while ((decode = decode_codepoint(inout_read_view)).units != 0) { while ((decode = decode_codepoint(inout_read_view)).units != 0) {
auto parser = std::lower_bound(SequenceTreeBegin, SubTreeEnd, decode.codepoint, &syntax_tree_member_compare<CharT, ContextT>); auto parser = std::lower_bound(SequenceTreeBegin, SubTreeEnd, decode.codepoint, &syntax_tree_member_compare<CharT, ContextT>);

112
src/test/app_parameters.cpp

@ -75,7 +75,7 @@ TEST(AppParametersTest, path_only) {
ArgWrapper args{ "/path/to/exe" }; ArgWrapper args{ "/path/to/exe" };
app_parameters parameters{ args.argc(), args.argv() }; app_parameters parameters{ args.argc(), args.argv() };
EXPECT_EQ(parameters.path(), "/path/to/exe"); EXPECT_EQ(parameters.path(), u8"/path/to/exe");
EXPECT_TRUE(parameters.arguments().empty()); EXPECT_TRUE(parameters.arguments().empty());
EXPECT_TRUE(parameters.switches().empty()); EXPECT_TRUE(parameters.switches().empty());
EXPECT_TRUE(parameters.switches_set().empty()); EXPECT_TRUE(parameters.switches_set().empty());
@ -83,7 +83,7 @@ TEST(AppParametersTest, path_only) {
auto obj = parameters.as_object(); auto obj = parameters.as_object();
EXPECT_FALSE(obj.null()); EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe"); EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
} }
TEST(AppParametersTest, single_switch) { TEST(AppParametersTest, single_switch) {
@ -98,9 +98,9 @@ TEST(AppParametersTest, single_switch) {
auto obj = parameters.as_object(); auto obj = parameters.as_object();
EXPECT_FALSE(obj.null()); EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe"); EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj["Args"], object{ std::vector<std::string>{ "-switch" } }); EXPECT_EQ(obj[u8"Args"], object{ std::vector<std::u8string>{ u8"-switch" } });
EXPECT_EQ(obj["Switches"], object{ std::vector<std::string>{ "switch" } }); EXPECT_EQ(obj[u8"Switches"], object{ std::vector<std::u8string>{ u8"switch" } });
} }
TEST(AppParametersTest, double_switch) { TEST(AppParametersTest, double_switch) {
@ -114,12 +114,12 @@ TEST(AppParametersTest, double_switch) {
EXPECT_TRUE(parameters.values().empty()); EXPECT_TRUE(parameters.values().empty());
auto obj = parameters.as_object(); auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-switch1", "--switch2" }; std::vector<std::u8string> expected_args{ u8"-switch1", u8"--switch2" };
std::vector<std::string> expected_switches{ "switch1", "switch2" }; std::vector<std::u8string> expected_switches{ u8"switch1", u8"switch2" };
EXPECT_FALSE(obj.null()); EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe"); EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args); EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj["Switches"], expected_switches); EXPECT_EQ(obj[u8"Switches"], expected_switches);
} }
TEST(AppParametersTest, duplicate_switch) { TEST(AppParametersTest, duplicate_switch) {
@ -133,12 +133,12 @@ TEST(AppParametersTest, duplicate_switch) {
EXPECT_TRUE(parameters.values().empty()); EXPECT_TRUE(parameters.values().empty());
auto obj = parameters.as_object(); auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-switch", "--switch" }; std::vector<std::u8string> expected_args{ u8"-switch", u8"--switch" };
std::vector<std::string> expected_switches{ "switch", "switch" }; std::vector<std::u8string> expected_switches{ u8"switch", u8"switch" };
EXPECT_FALSE(obj.null()); EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe"); EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args); EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj["Switches"], expected_switches); EXPECT_EQ(obj[u8"Switches"], expected_switches);
} }
TEST(AppParametersTest, single_value) { TEST(AppParametersTest, single_value) {
@ -152,12 +152,12 @@ TEST(AppParametersTest, single_value) {
EXPECT_EQ(parameters.values().size(), 1U); EXPECT_EQ(parameters.values().size(), 1U);
auto obj = parameters.as_object(); auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key", "value" }; std::vector<std::u8string> expected_args{ u8"-key", u8"value" };
std::map<std::string, object> expected_values{ { "key", "value" } }; std::map<std::u8string, object> expected_values{ { u8"key", u8"value" } };
EXPECT_FALSE(obj.null()); EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe"); EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args); EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values); EXPECT_EQ(obj[u8"Values"], expected_values);
} }
TEST(AppParametersTest, single_value_eq) { TEST(AppParametersTest, single_value_eq) {
@ -171,12 +171,12 @@ TEST(AppParametersTest, single_value_eq) {
EXPECT_EQ(parameters.values().size(), 1U); EXPECT_EQ(parameters.values().size(), 1U);
auto obj = parameters.as_object(); auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key=value" }; std::vector<std::u8string> expected_args{ u8"-key=value" };
std::map<std::string, object> expected_values{ { "key", "value" } }; std::map<std::u8string, object> expected_values{ { u8"key", u8"value" } };
EXPECT_FALSE(obj.null()); EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe"); EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args); EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values); EXPECT_EQ(obj[u8"Values"], expected_values);
} }
TEST(AppParametersTest, multiword_value) { TEST(AppParametersTest, multiword_value) {
@ -190,12 +190,12 @@ TEST(AppParametersTest, multiword_value) {
EXPECT_EQ(parameters.values().size(), 1U); EXPECT_EQ(parameters.values().size(), 1U);
auto obj = parameters.as_object(); auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key", "valuePart1", "valuePart2" }; std::vector<std::u8string> expected_args{ u8"-key", u8"valuePart1", u8"valuePart2" };
std::map<std::string, object> expected_values{ { "key", "valuePart1 valuePart2" } }; std::map<std::u8string, object> expected_values{ { u8"key", u8"valuePart1 valuePart2" } };
EXPECT_FALSE(obj.null()); EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe"); EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args); EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values); EXPECT_EQ(obj[u8"Values"], expected_values);
} }
TEST(AppParametersTest, multiword_value_eq) { TEST(AppParametersTest, multiword_value_eq) {
@ -209,12 +209,12 @@ TEST(AppParametersTest, multiword_value_eq) {
EXPECT_EQ(parameters.values().size(), 1U); EXPECT_EQ(parameters.values().size(), 1U);
auto obj = parameters.as_object(); auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key=valuePart1", "valuePart2" }; std::vector<std::u8string> expected_args{ u8"-key=valuePart1", u8"valuePart2" };
std::map<std::string, object> expected_values{ { "key", "valuePart1 valuePart2" } }; std::map<std::u8string, object> expected_values{ { u8"key", u8"valuePart1 valuePart2" } };
EXPECT_FALSE(obj.null()); EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe"); EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args); EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values); EXPECT_EQ(obj[u8"Values"], expected_values);
} }
TEST(AppParametersTest, double_value) { TEST(AppParametersTest, double_value) {
@ -228,12 +228,12 @@ TEST(AppParametersTest, double_value) {
EXPECT_EQ(parameters.values().size(), 2U); EXPECT_EQ(parameters.values().size(), 2U);
auto obj = parameters.as_object(); auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key", "value", "--key2", "value2" }; std::vector<std::u8string> expected_args{ u8"-key", u8"value", u8"--key2", u8"value2" };
std::map<std::string, object> expected_values{ { "key", "value" }, { "key2", "value2" } }; std::map<std::u8string, object> expected_values{ { u8"key", u8"value" }, { u8"key2", u8"value2" } };
EXPECT_FALSE(obj.null()); EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe"); EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args); EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values); EXPECT_EQ(obj[u8"Values"], expected_values);
} }
TEST(AppParametersTest, double_value_eq) { TEST(AppParametersTest, double_value_eq) {
@ -247,12 +247,12 @@ TEST(AppParametersTest, double_value_eq) {
EXPECT_EQ(parameters.values().size(), 2U); EXPECT_EQ(parameters.values().size(), 2U);
auto obj = parameters.as_object(); auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key=value", "--key2=value2" }; std::vector<std::u8string> expected_args{ u8"-key=value", u8"--key2=value2" };
std::map<std::string, object> expected_values{ { "key", "value" }, { "key2", "value2" } }; std::map<std::u8string, object> expected_values{ { u8"key", u8"value" }, { u8"key2", u8"value2" } };
EXPECT_FALSE(obj.null()); EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe"); EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args); EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values); EXPECT_EQ(obj[u8"Values"], expected_values);
} }
TEST(AppParametersTest, switch_and_value) { TEST(AppParametersTest, switch_and_value) {
@ -266,16 +266,16 @@ TEST(AppParametersTest, switch_and_value) {
EXPECT_EQ(parameters.values().size(), 1U); EXPECT_EQ(parameters.values().size(), 1U);
auto obj = parameters.as_object(); auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "--switch", "-key", "value" }; std::vector<std::u8string> expected_args{ u8"--switch", u8"-key", u8"value" };
std::vector<std::string> expected_switches{ "switch" }; std::vector<std::u8string> expected_switches{ u8"switch" };
std::map<std::string, object> expected_values{ { "key", "value" } }; std::map<std::u8string, object> expected_values{ { u8"key", u8"value" } };
EXPECT_FALSE(obj.null()); EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe"); EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args); EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj["Switches"], expected_switches); EXPECT_EQ(obj[u8"Switches"], expected_switches);
EXPECT_EQ(obj["Values"], expected_values); EXPECT_EQ(obj[u8"Values"], expected_values);
EXPECT_TRUE(parameters.has_switch("switch")); EXPECT_TRUE(parameters.has_switch(u8"switch"));
EXPECT_FALSE(parameters.has_switch("switch2")); EXPECT_FALSE(parameters.has_switch(u8"switch2"));
EXPECT_EQ(parameters.get_value("key"), "value"); EXPECT_EQ(parameters.get_value(u8"key"), u8"value");
} }

20
src/test/config.cpp

@ -55,14 +55,14 @@ TEST(ConfigTest, get_format) {
TEST(ConfigTest, read_object) { TEST(ConfigTest, read_object) {
std::filesystem::path file_path = make_tmp_file("read_object.test", "some_data"); std::filesystem::path file_path = make_tmp_file("read_object.test", "some_data");
EXPECT_EQ(config::read_object(file_path).get<std::string>(), "some_data"); EXPECT_EQ(config::read_object(file_path).get<std::u8string>(), u8"some_data");
} }
TEST(ConfigTest, write_object) { TEST(ConfigTest, write_object) {
std::filesystem::path file_path = make_tmp_file("write_object.test", "some_data"); std::filesystem::path file_path = make_tmp_file("write_object.test", "some_data");
config::write_object(object{}, file_path); config::write_object(object{}, file_path);
EXPECT_EQ(config::read_object(file_path).get<std::string>(), "serialize_result"); EXPECT_EQ(config::read_object(file_path).get<std::u8string>(), u8"serialize_result");
} }
TEST(ConfigTest, load) { TEST(ConfigTest, load) {
@ -75,7 +75,7 @@ TEST(ConfigTest, load) {
l_config.load(file_path); l_config.load(file_path);
// Verify // Verify
EXPECT_EQ(l_config.data().get<std::string>(), "some_data"); EXPECT_EQ(l_config.data().get<std::u8string>(), u8"some_data");
EXPECT_EQ(l_config.filename(), file_path); EXPECT_EQ(l_config.filename(), file_path);
EXPECT_EQ(l_config.format(), "test"); EXPECT_EQ(l_config.format(), "test");
} }
@ -94,25 +94,25 @@ TEST(ConfigTest, reload) {
// Reload data from disk and compare // Reload data from disk and compare
l_config.reload(); l_config.reload();
EXPECT_EQ(l_config.data().get<std::string>(), "some_other_data"); EXPECT_EQ(l_config.data().get<std::u8string>(), u8"some_other_data");
} }
TEST(ConfigTest, set_data) { TEST(ConfigTest, set_data) {
config l_config; config l_config;
l_config.set_data("some_data"); l_config.set_data(u8"some_data");
EXPECT_EQ(l_config.data().get<std::string>(), "some_data"); EXPECT_EQ(l_config.data().get<std::u8string>(), u8"some_data");
} }
TEST(ConfigTest, write) { TEST(ConfigTest, write) {
config l_config; config l_config;
std::filesystem::path file_path = make_tmp_file("write.test", ""); std::filesystem::path file_path = make_tmp_file("write.test", "");
l_config.set_data("some_data"); l_config.set_data(u8"some_data");
l_config.write(file_path); l_config.write(file_path);
l_config.reload(); l_config.reload();
EXPECT_EQ(l_config.data().get<std::string>(), "some_data"); EXPECT_EQ(l_config.data().get<std::u8string>(), u8"some_data");
} }
TEST(ConfigTest, rewrite) { TEST(ConfigTest, rewrite) {
@ -125,12 +125,12 @@ TEST(ConfigTest, rewrite) {
l_config.load(file_path); l_config.load(file_path);
// Set some other data // Set some other data
l_config.set_data("some_other_data"); l_config.set_data(u8"some_other_data");
// Write data to disk // Write data to disk
l_config.write(); l_config.write();
// Reload from disk and verify // Reload from disk and verify
l_config.reload(); l_config.reload();
EXPECT_EQ(l_config.data().get<std::string>(), "some_other_data"); EXPECT_EQ(l_config.data().get<std::u8string>(), u8"some_other_data");
} }

186
src/test/object.cpp

@ -27,19 +27,19 @@ using unsigned_char_t = unsigned char;
using long_long_t = long long; using long_long_t = long long;
using long_double_t = long double; using long_double_t = long double;
using map_str_str = std::map<std::string, std::string>; using map_str_str = std::map<std::u8string, std::u8string>;
using map_str_strv = std::map<std::string, std::string_view>; using map_str_strv = std::map<std::u8string, std::u8string_view>;
using map_str_obj = std::map<std::string, object>; using map_str_obj = std::map<std::u8string, object>;
using map_strv_str = std::map<std::string_view, std::string>; using map_strv_str = std::map<std::u8string_view, std::u8string>;
using map_strv_strv = std::map<std::string_view, std::string_view>; using map_strv_strv = std::map<std::u8string_view, std::u8string_view>;
using map_strv_obj = std::map<std::string_view, object>; using map_strv_obj = std::map<std::u8string_view, object>;
using unordered_map_str_str = std::unordered_map<std::string, std::string>; using unordered_map_str_str = std::unordered_map<std::u8string, std::u8string>;
using unordered_map_str_strv = std::unordered_map<std::string, std::string_view>; using unordered_map_str_strv = std::unordered_map<std::u8string, std::u8string_view>;
using unordered_map_str_obj = std::unordered_map<std::string, object>; using unordered_map_str_obj = std::unordered_map<std::u8string, object>;
using unordered_map_strv_str = std::unordered_map<std::string_view, std::string>; using unordered_map_strv_str = std::unordered_map<std::u8string_view, std::u8string>;
using unordered_map_strv_strv = std::unordered_map<std::string_view, std::string_view>; using unordered_map_strv_strv = std::unordered_map<std::u8string_view, std::u8string_view>;
using unordered_map_strv_obj = std::unordered_map<std::string_view, object>; using unordered_map_strv_obj = std::unordered_map<std::u8string_view, object>;
/** basic tests; these test function calls against null objects and heavily test for compilation errors */ /** basic tests; these test function calls against null objects and heavily test for compilation errors */
@ -66,7 +66,7 @@ TEST(ObjectTest, basic_has) {
EXPECT_FALSE(obj.has<float>()); EXPECT_FALSE(obj.has<float>());
EXPECT_FALSE(obj.has<double>()); EXPECT_FALSE(obj.has<double>());
EXPECT_FALSE(obj.has<long double>()); EXPECT_FALSE(obj.has<long double>());
EXPECT_FALSE(obj.has<std::string>()); EXPECT_FALSE(obj.has<std::u8string>());
EXPECT_FALSE(obj.has<object::array_type>()); EXPECT_FALSE(obj.has<object::array_type>());
EXPECT_FALSE(obj.has<object::map_type>()); EXPECT_FALSE(obj.has<object::map_type>());
} }
@ -85,7 +85,7 @@ TEST(ObjectTest, basic_has_vector) {
EXPECT_FALSE(obj.has<std::vector<float>>()); EXPECT_FALSE(obj.has<std::vector<float>>());
EXPECT_FALSE(obj.has<std::vector<double>>()); EXPECT_FALSE(obj.has<std::vector<double>>());
EXPECT_FALSE(obj.has<std::vector<long double>>()); EXPECT_FALSE(obj.has<std::vector<long double>>());
EXPECT_FALSE(obj.has<std::vector<std::string>>()); EXPECT_FALSE(obj.has<std::vector<std::u8string>>());
EXPECT_FALSE(obj.has<std::vector<object>>()); EXPECT_FALSE(obj.has<std::vector<object>>());
} }
@ -103,7 +103,7 @@ TEST(ObjectTest, basic_has_list) {
EXPECT_FALSE(obj.has<std::list<float>>()); EXPECT_FALSE(obj.has<std::list<float>>());
EXPECT_FALSE(obj.has<std::list<double>>()); EXPECT_FALSE(obj.has<std::list<double>>());
EXPECT_FALSE(obj.has<std::list<long double>>()); EXPECT_FALSE(obj.has<std::list<long double>>());
EXPECT_FALSE(obj.has<std::list<std::string>>()); EXPECT_FALSE(obj.has<std::list<std::u8string>>());
EXPECT_FALSE(obj.has<std::list<object>>()); EXPECT_FALSE(obj.has<std::list<object>>());
} }
@ -121,7 +121,7 @@ TEST(ObjectTest, basic_has_forward_list) {
EXPECT_FALSE(obj.has<std::forward_list<float>>()); EXPECT_FALSE(obj.has<std::forward_list<float>>());
EXPECT_FALSE(obj.has<std::forward_list<double>>()); EXPECT_FALSE(obj.has<std::forward_list<double>>());
EXPECT_FALSE(obj.has<std::forward_list<long double>>()); EXPECT_FALSE(obj.has<std::forward_list<long double>>());
EXPECT_FALSE(obj.has<std::forward_list<std::string>>()); EXPECT_FALSE(obj.has<std::forward_list<std::u8string>>());
EXPECT_FALSE(obj.has<std::forward_list<object>>()); EXPECT_FALSE(obj.has<std::forward_list<object>>());
} }
@ -139,7 +139,7 @@ TEST(ObjectTest, basic_has_set) {
EXPECT_FALSE(obj.has<std::set<float>>()); EXPECT_FALSE(obj.has<std::set<float>>());
EXPECT_FALSE(obj.has<std::set<double>>()); EXPECT_FALSE(obj.has<std::set<double>>());
EXPECT_FALSE(obj.has<std::set<long double>>()); EXPECT_FALSE(obj.has<std::set<long double>>());
EXPECT_FALSE(obj.has<std::set<std::string>>()); EXPECT_FALSE(obj.has<std::set<std::u8string>>());
EXPECT_FALSE(obj.has<std::set<object>>()); EXPECT_FALSE(obj.has<std::set<object>>());
} }
@ -157,7 +157,7 @@ TEST(ObjectTest, basic_has_unordered_set) {
EXPECT_FALSE(obj.has<std::unordered_set<float>>()); EXPECT_FALSE(obj.has<std::unordered_set<float>>());
EXPECT_FALSE(obj.has<std::unordered_set<double>>()); EXPECT_FALSE(obj.has<std::unordered_set<double>>());
EXPECT_FALSE(obj.has<std::unordered_set<long double>>()); EXPECT_FALSE(obj.has<std::unordered_set<long double>>());
EXPECT_FALSE(obj.has<std::unordered_set<std::string>>()); EXPECT_FALSE(obj.has<std::unordered_set<std::u8string>>());
EXPECT_FALSE(obj.has<std::unordered_set<object>>()); EXPECT_FALSE(obj.has<std::unordered_set<object>>());
} }
@ -199,7 +199,7 @@ TEST(ObjectTest, basic_get) {
EXPECT_EQ(obj.get<float>(), float{}); EXPECT_EQ(obj.get<float>(), float{});
EXPECT_EQ(obj.get<double>(), double{}); EXPECT_EQ(obj.get<double>(), double{});
EXPECT_EQ(obj.get<long double>(), long_double_t{}); EXPECT_EQ(obj.get<long double>(), long_double_t{});
EXPECT_EQ(obj.get<std::string>(), std::string{}); EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
EXPECT_TRUE(obj.get<object::array_type>().empty()); EXPECT_TRUE(obj.get<object::array_type>().empty());
EXPECT_TRUE(obj.get<object::map_type>().empty()); EXPECT_TRUE(obj.get<object::map_type>().empty());
} }
@ -218,7 +218,7 @@ TEST(ObjectTest, basic_get_vector) {
EXPECT_TRUE(obj.get<std::vector<float>>().empty()); EXPECT_TRUE(obj.get<std::vector<float>>().empty());
EXPECT_TRUE(obj.get<std::vector<double>>().empty()); EXPECT_TRUE(obj.get<std::vector<double>>().empty());
EXPECT_TRUE(obj.get<std::vector<long double>>().empty()); EXPECT_TRUE(obj.get<std::vector<long double>>().empty());
EXPECT_TRUE(obj.get<std::vector<std::string>>().empty()); EXPECT_TRUE(obj.get<std::vector<std::u8string>>().empty());
EXPECT_TRUE(obj.get<std::vector<object>>().empty()); EXPECT_TRUE(obj.get<std::vector<object>>().empty());
} }
@ -236,7 +236,7 @@ TEST(ObjectTest, basic_get_list) {
EXPECT_TRUE(obj.get<std::list<float>>().empty()); EXPECT_TRUE(obj.get<std::list<float>>().empty());
EXPECT_TRUE(obj.get<std::list<double>>().empty()); EXPECT_TRUE(obj.get<std::list<double>>().empty());
EXPECT_TRUE(obj.get<std::list<long double>>().empty()); EXPECT_TRUE(obj.get<std::list<long double>>().empty());
EXPECT_TRUE(obj.get<std::list<std::string>>().empty()); EXPECT_TRUE(obj.get<std::list<std::u8string>>().empty());
EXPECT_TRUE(obj.get<std::list<object>>().empty()); EXPECT_TRUE(obj.get<std::list<object>>().empty());
} }
@ -254,7 +254,7 @@ TEST(ObjectTest, basic_get_forward_list) {
EXPECT_TRUE(obj.get<std::forward_list<float>>().empty()); EXPECT_TRUE(obj.get<std::forward_list<float>>().empty());
EXPECT_TRUE(obj.get<std::forward_list<double>>().empty()); EXPECT_TRUE(obj.get<std::forward_list<double>>().empty());
EXPECT_TRUE(obj.get<std::forward_list<long double>>().empty()); EXPECT_TRUE(obj.get<std::forward_list<long double>>().empty());
EXPECT_TRUE(obj.get<std::forward_list<std::string>>().empty()); EXPECT_TRUE(obj.get<std::forward_list<std::u8string>>().empty());
EXPECT_TRUE(obj.get<std::forward_list<object>>().empty()); EXPECT_TRUE(obj.get<std::forward_list<object>>().empty());
} }
@ -272,7 +272,7 @@ TEST(ObjectTest, basic_get_set) {
EXPECT_TRUE(obj.get<std::set<float>>().empty()); EXPECT_TRUE(obj.get<std::set<float>>().empty());
EXPECT_TRUE(obj.get<std::set<double>>().empty()); EXPECT_TRUE(obj.get<std::set<double>>().empty());
EXPECT_TRUE(obj.get<std::set<long double>>().empty()); EXPECT_TRUE(obj.get<std::set<long double>>().empty());
EXPECT_TRUE(obj.get<std::set<std::string>>().empty()); EXPECT_TRUE(obj.get<std::set<std::u8string>>().empty());
EXPECT_TRUE(obj.get<std::set<object>>().empty()); EXPECT_TRUE(obj.get<std::set<object>>().empty());
} }
@ -290,7 +290,7 @@ TEST(ObjectTest, basic_get_multiset) {
EXPECT_TRUE(obj.get<std::multiset<float>>().empty()); EXPECT_TRUE(obj.get<std::multiset<float>>().empty());
EXPECT_TRUE(obj.get<std::multiset<double>>().empty()); EXPECT_TRUE(obj.get<std::multiset<double>>().empty());
EXPECT_TRUE(obj.get<std::multiset<long double>>().empty()); EXPECT_TRUE(obj.get<std::multiset<long double>>().empty());
EXPECT_TRUE(obj.get<std::multiset<std::string>>().empty()); EXPECT_TRUE(obj.get<std::multiset<std::u8string>>().empty());
EXPECT_TRUE(obj.get<std::multiset<object>>().empty()); EXPECT_TRUE(obj.get<std::multiset<object>>().empty());
} }
@ -308,7 +308,7 @@ TEST(ObjectTest, basic_get_unordered_set) {
EXPECT_TRUE(obj.get<std::unordered_set<float>>().empty()); EXPECT_TRUE(obj.get<std::unordered_set<float>>().empty());
EXPECT_TRUE(obj.get<std::unordered_set<double>>().empty()); EXPECT_TRUE(obj.get<std::unordered_set<double>>().empty());
EXPECT_TRUE(obj.get<std::unordered_set<long double>>().empty()); EXPECT_TRUE(obj.get<std::unordered_set<long double>>().empty());
EXPECT_TRUE(obj.get<std::unordered_set<std::string>>().empty()); EXPECT_TRUE(obj.get<std::unordered_set<std::u8string>>().empty());
EXPECT_TRUE(obj.get<std::unordered_set<object>>().empty()); EXPECT_TRUE(obj.get<std::unordered_set<object>>().empty());
} }
@ -326,7 +326,7 @@ TEST(ObjectTest, basic_get_unordered_multiset) {
EXPECT_TRUE(obj.get<std::unordered_multiset<float>>().empty()); EXPECT_TRUE(obj.get<std::unordered_multiset<float>>().empty());
EXPECT_TRUE(obj.get<std::unordered_multiset<double>>().empty()); EXPECT_TRUE(obj.get<std::unordered_multiset<double>>().empty());
EXPECT_TRUE(obj.get<std::unordered_multiset<long double>>().empty()); EXPECT_TRUE(obj.get<std::unordered_multiset<long double>>().empty());
EXPECT_TRUE(obj.get<std::unordered_multiset<std::string>>().empty()); EXPECT_TRUE(obj.get<std::unordered_multiset<std::u8string>>().empty());
EXPECT_TRUE(obj.get<std::unordered_set<object>>().empty()); EXPECT_TRUE(obj.get<std::unordered_set<object>>().empty());
} }
@ -351,21 +351,21 @@ TEST(ObjectTest, basic_value_constructor) {
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(float); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(float);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(double); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(double);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(long_double_t); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(long_double_t);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::string); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::u8string);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(object::array_type); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(object::array_type);
// const char* // const char*
{ {
object obj{ "" }; object obj{ u8"" };
EXPECT_TRUE(obj.has<std::string>()); EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::string>(), std::string{}); EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
} }
// std::string_view // std::u8string_view
{ {
object obj{ ""sv }; object obj{ u8""sv };
EXPECT_TRUE(obj.has<std::string>()); EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::string>(), std::string{}); EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
} }
} }
@ -381,7 +381,7 @@ TEST(ObjectTest, basic_value_constructor_vector) {
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::vector<float>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::vector<float>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::vector<double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::vector<double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::vector<long double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::vector<long double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::vector<std::string>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::vector<std::u8string>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::vector<object>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::vector<object>);
} }
@ -397,7 +397,7 @@ TEST(ObjectTest, basic_value_constructor_list) {
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::list<float>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::list<float>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::list<double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::list<double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::list<long double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::list<long double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::list<std::string>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::list<std::u8string>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::list<object>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::list<object>);
} }
@ -413,7 +413,7 @@ TEST(ObjectTest, basic_value_constructor_forward_list) {
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::forward_list<float>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::forward_list<float>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::forward_list<double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::forward_list<double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::forward_list<long double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::forward_list<long double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::forward_list<std::string>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::forward_list<std::u8string>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::forward_list<object>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::forward_list<object>);
} }
@ -429,7 +429,7 @@ TEST(ObjectTest, basic_value_constructor_set) {
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::set<float>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::set<float>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::set<double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::set<double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::set<long double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::set<long double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::set<std::string>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::set<std::u8string>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::set<object>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::set<object>);
} }
@ -445,7 +445,7 @@ TEST(ObjectTest, basic_value_constructor_multiset) {
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::multiset<float>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::multiset<float>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::multiset<double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::multiset<double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::multiset<long double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::multiset<long double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::multiset<std::string>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::multiset<std::u8string>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::multiset<object>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::multiset<object>);
} }
@ -461,7 +461,7 @@ TEST(ObjectTest, basic_value_constructor_unordered_set) {
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<float>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<float>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<long double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<long double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<std::string>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<std::u8string>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<object>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<object>);
} }
@ -477,7 +477,7 @@ TEST(ObjectTest, basic_value_constructor_unordered_multiset) {
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_multiset<float>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_multiset<float>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_multiset<double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_multiset<double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_multiset<long double>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_multiset<long double>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_multiset<std::string>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_multiset<std::u8string>);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<object>); OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(std::unordered_set<object>);
} }
@ -502,18 +502,18 @@ TEST(ObjectTest, basic_set) {
OBJECT_BASIC_SET_TEST(obj, float); OBJECT_BASIC_SET_TEST(obj, float);
OBJECT_BASIC_SET_TEST(obj, double); OBJECT_BASIC_SET_TEST(obj, double);
OBJECT_BASIC_SET_TEST(obj, long_double_t); OBJECT_BASIC_SET_TEST(obj, long_double_t);
OBJECT_BASIC_SET_TEST(obj, std::string); OBJECT_BASIC_SET_TEST(obj, std::u8string);
OBJECT_BASIC_SET_TEST(obj, object::array_type); OBJECT_BASIC_SET_TEST(obj, object::array_type);
// const char* // const char*
obj.set(""); obj.set(u8"");
EXPECT_TRUE(obj.has<std::string>()); EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::string>(), std::string{}); EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
// std::string_view // std::u8string_view
obj.set(""sv); obj.set(u8""sv);
EXPECT_TRUE(obj.has<std::string>()); EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::string>(), std::string{}); EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
} }
TEST(ObjectTest, basic_set_vector) { TEST(ObjectTest, basic_set_vector) {
@ -530,7 +530,7 @@ TEST(ObjectTest, basic_set_vector) {
OBJECT_BASIC_SET_TEST(obj, std::vector<float>); OBJECT_BASIC_SET_TEST(obj, std::vector<float>);
OBJECT_BASIC_SET_TEST(obj, std::vector<double>); OBJECT_BASIC_SET_TEST(obj, std::vector<double>);
OBJECT_BASIC_SET_TEST(obj, std::vector<long double>); OBJECT_BASIC_SET_TEST(obj, std::vector<long double>);
OBJECT_BASIC_SET_TEST(obj, std::vector<std::string>); OBJECT_BASIC_SET_TEST(obj, std::vector<std::u8string>);
OBJECT_BASIC_SET_TEST(obj, std::vector<object>); OBJECT_BASIC_SET_TEST(obj, std::vector<object>);
} }
@ -548,7 +548,7 @@ TEST(ObjectTest, basic_set_list) {
OBJECT_BASIC_SET_TEST(obj, std::list<float>); OBJECT_BASIC_SET_TEST(obj, std::list<float>);
OBJECT_BASIC_SET_TEST(obj, std::list<double>); OBJECT_BASIC_SET_TEST(obj, std::list<double>);
OBJECT_BASIC_SET_TEST(obj, std::list<long double>); OBJECT_BASIC_SET_TEST(obj, std::list<long double>);
OBJECT_BASIC_SET_TEST(obj, std::list<std::string>); OBJECT_BASIC_SET_TEST(obj, std::list<std::u8string>);
OBJECT_BASIC_SET_TEST(obj, std::list<object>); OBJECT_BASIC_SET_TEST(obj, std::list<object>);
} }
@ -566,7 +566,7 @@ TEST(ObjectTest, basic_set_forward_list) {
OBJECT_BASIC_SET_TEST(obj, std::forward_list<float>); OBJECT_BASIC_SET_TEST(obj, std::forward_list<float>);
OBJECT_BASIC_SET_TEST(obj, std::forward_list<double>); OBJECT_BASIC_SET_TEST(obj, std::forward_list<double>);
OBJECT_BASIC_SET_TEST(obj, std::forward_list<long double>); OBJECT_BASIC_SET_TEST(obj, std::forward_list<long double>);
OBJECT_BASIC_SET_TEST(obj, std::forward_list<std::string>); OBJECT_BASIC_SET_TEST(obj, std::forward_list<std::u8string>);
OBJECT_BASIC_SET_TEST(obj, std::forward_list<object>); OBJECT_BASIC_SET_TEST(obj, std::forward_list<object>);
} }
@ -584,7 +584,7 @@ TEST(ObjectTest, basic_set_set) {
OBJECT_BASIC_SET_TEST(obj, std::set<float>); OBJECT_BASIC_SET_TEST(obj, std::set<float>);
OBJECT_BASIC_SET_TEST(obj, std::set<double>); OBJECT_BASIC_SET_TEST(obj, std::set<double>);
OBJECT_BASIC_SET_TEST(obj, std::set<long double>); OBJECT_BASIC_SET_TEST(obj, std::set<long double>);
OBJECT_BASIC_SET_TEST(obj, std::set<std::string>); OBJECT_BASIC_SET_TEST(obj, std::set<std::u8string>);
OBJECT_BASIC_SET_TEST(obj, std::set<object>); OBJECT_BASIC_SET_TEST(obj, std::set<object>);
} }
@ -602,7 +602,7 @@ TEST(ObjectTest, basic_set_multiset) {
OBJECT_BASIC_SET_TEST(obj, std::multiset<float>); OBJECT_BASIC_SET_TEST(obj, std::multiset<float>);
OBJECT_BASIC_SET_TEST(obj, std::multiset<double>); OBJECT_BASIC_SET_TEST(obj, std::multiset<double>);
OBJECT_BASIC_SET_TEST(obj, std::multiset<long double>); OBJECT_BASIC_SET_TEST(obj, std::multiset<long double>);
OBJECT_BASIC_SET_TEST(obj, std::multiset<std::string>); OBJECT_BASIC_SET_TEST(obj, std::multiset<std::u8string>);
OBJECT_BASIC_SET_TEST(obj, std::multiset<object>); OBJECT_BASIC_SET_TEST(obj, std::multiset<object>);
} }
@ -620,7 +620,7 @@ TEST(ObjectTest, basic_set_unordered_set) {
OBJECT_BASIC_SET_TEST(obj, std::unordered_set<float>); OBJECT_BASIC_SET_TEST(obj, std::unordered_set<float>);
OBJECT_BASIC_SET_TEST(obj, std::unordered_set<double>); OBJECT_BASIC_SET_TEST(obj, std::unordered_set<double>);
OBJECT_BASIC_SET_TEST(obj, std::unordered_set<long double>); OBJECT_BASIC_SET_TEST(obj, std::unordered_set<long double>);
OBJECT_BASIC_SET_TEST(obj, std::unordered_set<std::string>); OBJECT_BASIC_SET_TEST(obj, std::unordered_set<std::u8string>);
OBJECT_BASIC_SET_TEST(obj, std::unordered_set<object>); OBJECT_BASIC_SET_TEST(obj, std::unordered_set<object>);
} }
@ -638,7 +638,7 @@ TEST(ObjectTest, basic_set_unordered_multiset) {
OBJECT_BASIC_SET_TEST(obj, std::unordered_multiset<float>); OBJECT_BASIC_SET_TEST(obj, std::unordered_multiset<float>);
OBJECT_BASIC_SET_TEST(obj, std::unordered_multiset<double>); OBJECT_BASIC_SET_TEST(obj, std::unordered_multiset<double>);
OBJECT_BASIC_SET_TEST(obj, std::unordered_multiset<long double>); OBJECT_BASIC_SET_TEST(obj, std::unordered_multiset<long double>);
OBJECT_BASIC_SET_TEST(obj, std::unordered_multiset<std::string>); OBJECT_BASIC_SET_TEST(obj, std::unordered_multiset<std::u8string>);
OBJECT_BASIC_SET_TEST(obj, std::unordered_set<object>); OBJECT_BASIC_SET_TEST(obj, std::unordered_set<object>);
} }
@ -663,18 +663,18 @@ TEST(ObjectTest, basic_assignment_operator) {
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, float); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, float);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, double); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, double);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, long_double_t); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, long_double_t);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::string); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::u8string);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, object::array_type); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, object::array_type);
// const char* // const char*
obj = ""; obj = u8"";
EXPECT_TRUE(obj.has<std::string>()); EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::string>(), std::string{}); EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
// std::string_view // std::u8string_view
obj = ""sv; obj = u8""sv;
EXPECT_TRUE(obj.has<std::string>()); EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::string>(), std::string{}); EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
} }
TEST(ObjectTest, basic_assignment_operator_vector) { TEST(ObjectTest, basic_assignment_operator_vector) {
@ -691,7 +691,7 @@ TEST(ObjectTest, basic_assignment_operator_vector) {
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::vector<float>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::vector<float>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::vector<double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::vector<double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::vector<long double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::vector<long double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::vector<std::string>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::vector<std::u8string>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::vector<object>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::vector<object>);
} }
@ -709,7 +709,7 @@ TEST(ObjectTest, basic_assignment_operator_list) {
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::list<float>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::list<float>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::list<double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::list<double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::list<long double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::list<long double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::list<std::string>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::list<std::u8string>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::list<object>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::list<object>);
} }
@ -727,7 +727,7 @@ TEST(ObjectTest, basic_assignment_operator_forward_list) {
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::forward_list<float>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::forward_list<float>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::forward_list<double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::forward_list<double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::forward_list<long double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::forward_list<long double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::forward_list<std::string>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::forward_list<std::u8string>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::forward_list<object>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::forward_list<object>);
} }
@ -745,7 +745,7 @@ TEST(ObjectTest, basic_assignment_operator_set) {
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::set<float>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::set<float>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::set<double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::set<double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::set<long double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::set<long double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::set<std::string>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::set<std::u8string>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::set<object>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::set<object>);
} }
@ -763,7 +763,7 @@ TEST(ObjectTest, basic_assignment_operator_multiset) {
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::multiset<float>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::multiset<float>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::multiset<double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::multiset<double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::multiset<long double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::multiset<long double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::multiset<std::string>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::multiset<std::u8string>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::multiset<object>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::multiset<object>);
} }
@ -781,7 +781,7 @@ TEST(ObjectTest, basic_assignment_operator_unordered_set) {
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<float>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<float>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<long double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<long double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<std::string>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<std::u8string>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<object>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<object>);
} }
@ -799,7 +799,7 @@ TEST(ObjectTest, basic_assignment_operator_unordered_multiset) {
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_multiset<float>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_multiset<float>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_multiset<double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_multiset<double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_multiset<long double>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_multiset<long double>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_multiset<std::string>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_multiset<std::u8string>);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<object>); OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, std::unordered_set<object>);
} }
@ -808,17 +808,17 @@ TEST(ObjectTest, basic_assignment_operator_unordered_multiset) {
TEST(ObjectTest, basic_map_access_operator) { TEST(ObjectTest, basic_map_access_operator) {
object obj; object obj;
obj["test"] = 1234; obj[u8"test"] = 1234;
EXPECT_EQ(obj["test"].get<int>(), 1234); EXPECT_EQ(obj[u8"test"].get<int>(), 1234);
EXPECT_EQ(obj["test2"].get<int>(), 0); EXPECT_EQ(obj[u8"test2"].get<int>(), 0);
obj["test"] = 4567; obj[u8"test"] = 4567;
EXPECT_EQ(obj["test"].get<int>(), 4567); EXPECT_EQ(obj[u8"test"].get<int>(), 4567);
EXPECT_EQ(obj["test2"].get<int>(), 0); EXPECT_EQ(obj[u8"test2"].get<int>(), 0);
obj["test2"] = 1234; obj[u8"test2"] = 1234;
EXPECT_EQ(obj["test"].get<int>(), 4567); EXPECT_EQ(obj[u8"test"].get<int>(), 4567);
EXPECT_EQ(obj["test2"].get<int>(), 1234); EXPECT_EQ(obj[u8"test2"].get<int>(), 1234);
} }
TEST(ObjectTest, basic_array_access_operator) { TEST(ObjectTest, basic_array_access_operator) {
@ -914,31 +914,31 @@ TEST(ObjectTest, set_float) {
TEST(ObjectTest, set_string) { TEST(ObjectTest, set_string) {
object obj; object obj;
obj.set("Jessica"); obj.set(u8"Jessica");
EXPECT_TRUE(obj.has<std::string>()); EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::string>(), "Jessica"); EXPECT_EQ(obj.get<std::u8string>(), u8"Jessica");
EXPECT_FALSE(obj.has<bool>()); EXPECT_FALSE(obj.has<bool>());
EXPECT_FALSE(obj.get<bool>()); EXPECT_FALSE(obj.get<bool>());
obj.set("was"s); obj.set(u8"was"s);
EXPECT_TRUE(obj.has<std::string>()); EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::string>(), "was"); EXPECT_EQ(obj.get<std::u8string>(), u8"was");
EXPECT_FALSE(obj.has<bool>()); EXPECT_FALSE(obj.has<bool>());
EXPECT_FALSE(obj.get<bool>()); EXPECT_FALSE(obj.get<bool>());
obj.set("here"sv); obj.set(u8"here"sv);
EXPECT_TRUE(obj.has<std::string>()); EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::string>(), "here"); EXPECT_EQ(obj.get<std::u8string>(), u8"here");
EXPECT_FALSE(obj.has<bool>()); EXPECT_FALSE(obj.has<bool>());
EXPECT_FALSE(obj.get<bool>()); EXPECT_FALSE(obj.get<bool>());
obj.set(""); obj.set(u8"");
EXPECT_TRUE(obj.has<std::string>()); EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::string>(), ""); EXPECT_EQ(obj.get<std::u8string>(), u8"");
EXPECT_FALSE(obj.has<bool>()); EXPECT_FALSE(obj.has<bool>());
EXPECT_FALSE(obj.get<bool>()); EXPECT_FALSE(obj.get<bool>());
} }

21
src/test/parser.cpp

@ -20,6 +20,7 @@
#include "test.hpp" #include "test.hpp"
#include "jessilib/parser.hpp" #include "jessilib/parser.hpp"
#include "jessilib/serialize.hpp" #include "jessilib/serialize.hpp"
#include "jessilib/unicode.hpp"
using namespace jessilib; using namespace jessilib;
using namespace std::literals; using namespace std::literals;
@ -45,15 +46,15 @@ public:
/** default serialize/deserialize implementations */ /** default serialize/deserialize implementations */
static std::string serialize_default(const object& in_object) { static std::string serialize_default(const object& in_object) {
if (in_object.has<std::string>()) { if (in_object.has<std::u8string>()) {
return in_object.get<std::string>(); return string_cast<char>(in_object.get<std::u8string>());
} }
return static_cast<std::string>(DEFAULT_SERIALIZE_RESULT); return static_cast<std::string>(DEFAULT_SERIALIZE_RESULT);
} }
static object deserialize_default(std::string_view in_data) { static object deserialize_default(std::string_view in_data) {
return object{ in_data }; return object{ string_view_cast<char8_t>(in_data) };
} }
/** static members */ /** static members */
@ -82,31 +83,31 @@ class ParserTest : public base_test {
/** Parser tests */ /** Parser tests */
TEST_F(ParserTest, find_parser) { TEST_F(ParserTest, find_parser) {
EXPECT_NO_THROW(serialize_object("test_data", "test")); EXPECT_NO_THROW(serialize_object(u8"test_data", "test"));
EXPECT_NO_THROW(deserialize_object("test_data"sv, "test")); EXPECT_NO_THROW(deserialize_object("test_data"sv, "test"));
EXPECT_THROW(serialize_object("test_data", "invalid_format_test"), format_not_available); EXPECT_THROW(serialize_object(u8"test_data", "invalid_format_test"), format_not_available);
EXPECT_THROW(deserialize_object("test_data"sv, "invalid_format_test"), format_not_available); EXPECT_THROW(deserialize_object("test_data"sv, "invalid_format_test"), format_not_available);
} }
TEST_F(ParserTest, temp_parser) { TEST_F(ParserTest, temp_parser) {
EXPECT_THROW(serialize_object("test_data", "test_tmp"), format_not_available); EXPECT_THROW(serialize_object(u8"test_data", "test_tmp"), format_not_available);
EXPECT_THROW(deserialize_object("test_data"sv, "test_tmp"), format_not_available); EXPECT_THROW(deserialize_object("test_data"sv, "test_tmp"), format_not_available);
{ {
parser_registration<test_parser> test_tmp_registration{ "test_tmp" }; parser_registration<test_parser> test_tmp_registration{ "test_tmp" };
EXPECT_NO_THROW(serialize_object("test_data", "test_tmp")); EXPECT_NO_THROW(serialize_object(u8"test_data", "test_tmp"));
EXPECT_NO_THROW(deserialize_object("test_data"sv, "test_tmp")); EXPECT_NO_THROW(deserialize_object("test_data"sv, "test_tmp"));
} }
EXPECT_THROW(serialize_object("test_data", "test_tmp"), format_not_available); EXPECT_THROW(serialize_object(u8"test_data", "test_tmp"), format_not_available);
EXPECT_THROW(deserialize_object("test_data"sv, "test_tmp"), format_not_available); EXPECT_THROW(deserialize_object("test_data"sv, "test_tmp"), format_not_available);
} }
TEST_F(ParserTest, serialize) { TEST_F(ParserTest, serialize) {
EXPECT_EQ(serialize_object("test_data", "test"), "test_data"); EXPECT_EQ(serialize_object(u8"test_data", "test"), "test_data");
} }
TEST_F(ParserTest, deserialize) { TEST_F(ParserTest, deserialize) {
EXPECT_EQ(deserialize_object("test_data"sv, "test").get<std::string>(), "test_data"); EXPECT_EQ(deserialize_object("test_data"sv, "test").get<std::u8string>(), u8"test_data");
} }

67
src/test/parsers/json.cpp

@ -56,9 +56,10 @@ void expect_eq(LeftT in_left, RightT in_right) {
TEST(JsonParser, serialize_string) { TEST(JsonParser, serialize_string) {
json_parser parser; json_parser parser;
EXPECT_EQ(parser.serialize("text"), R"json("text")json"); EXPECT_EQ(parser.serialize(u8"text"), R"json("text")json");
expect_eq(parser.serialize("\"text\""), R"json("\"text\"")json"); expect_eq(parser.serialize(u8"\"text\""), R"json("\"text\"")json");
expect_eq(parser.serialize("\"te\x10xt\""), R"json("\"te\u0010xt\"")json"); expect_eq(parser.serialize(u8"\"te\x01xt\""), R"json("\"te\u0001xt\"")json");
expect_eq(parser.serialize(u8"\"te\x10xt\""), R"json("\"te\u0010xt\"")json");
} }
TEST(JsonParser, serialize_array) { TEST(JsonParser, serialize_array) {
@ -66,7 +67,7 @@ TEST(JsonParser, serialize_array) {
std::vector<object> array { std::vector<object> array {
true, true,
1234, 1234,
"text", u8"text",
object{} object{}
}; };
@ -78,10 +79,10 @@ TEST(JsonParser, serialize_map) {
json_parser parser; json_parser parser;
object obj; object obj;
obj["some_bool"] = true; obj[u8"some_bool"] = true;
obj["some_int"] = 1234; obj[u8"some_int"] = 1234;
obj["some_string"] = "text"; obj[u8"some_string"] = u8"text";
obj["some_null"]; obj[u8"some_null"];
EXPECT_EQ(parser.serialize(obj), EXPECT_EQ(parser.serialize(obj),
R"json({"some_bool":true,"some_int":1234,"some_null":null,"some_string":"text"})json"); R"json({"some_bool":true,"some_int":1234,"some_null":null,"some_string":"text"})json");
@ -120,7 +121,7 @@ TEST(JsonParser, deserialize_decimal) {
TEST(JsonParser, deserialize_string) { TEST(JsonParser, deserialize_string) {
json_parser parser; json_parser parser;
EXPECT_EQ(parser.deserialize(R"json("text")json"sv), "text"); EXPECT_EQ(parser.deserialize(R"json("text")json"sv), u8"text");
} }
TEST(JsonParser, deserialize_array) { TEST(JsonParser, deserialize_array) {
@ -142,7 +143,7 @@ TEST(JsonParser, deserialize_array) {
EXPECT_EQ(array[2], 1234); EXPECT_EQ(array[2], 1234);
EXPECT_DOUBLE_EQ(array[3].get<double>(), 12.34); EXPECT_DOUBLE_EQ(array[3].get<double>(), 12.34);
EXPECT_DOUBLE_EQ(array[4].get<double>(), 0.1234); EXPECT_DOUBLE_EQ(array[4].get<double>(), 0.1234);
EXPECT_EQ(array[5], "text"); EXPECT_EQ(array[5], u8"text");
} }
TEST(JsonParser, deserialize_array_nested) { TEST(JsonParser, deserialize_array_nested) {
@ -174,11 +175,11 @@ TEST(JsonParser, deserialize_array_nested) {
EXPECT_EQ(array[4].size(), 0U); EXPECT_EQ(array[4].size(), 0U);
EXPECT_FALSE(array[5].null()); EXPECT_FALSE(array[5].null());
ASSERT_EQ(array[5].size(), 1U); ASSERT_EQ(array[5].size(), 1U);
EXPECT_EQ(array[5], std::vector<object>{ " text " }); EXPECT_EQ(array[5], std::vector<object>{ u8" text " });
EXPECT_EQ(array[5], std::vector<std::string>{ " text " }); EXPECT_EQ(array[5], std::vector<std::u8string>{ u8" text " });
EXPECT_DOUBLE_EQ(array[6].get<double>(), 12.34); EXPECT_DOUBLE_EQ(array[6].get<double>(), 12.34);
EXPECT_DOUBLE_EQ(array[7].get<double>(), 0.1234); EXPECT_DOUBLE_EQ(array[7].get<double>(), 0.1234);
EXPECT_EQ(array[8], "text"); EXPECT_EQ(array[8], u8"text");
auto nested_array = array[3].get<std::vector<object>>(); auto nested_array = array[3].get<std::vector<object>>();
ASSERT_EQ(nested_array.size(), 6U); ASSERT_EQ(nested_array.size(), 6U);
@ -186,7 +187,7 @@ TEST(JsonParser, deserialize_array_nested) {
EXPECT_EQ(nested_array[1], 2); EXPECT_EQ(nested_array[1], 2);
EXPECT_EQ(nested_array[2], 3); EXPECT_EQ(nested_array[2], 3);
EXPECT_TRUE(nested_array[3].null()); EXPECT_TRUE(nested_array[3].null());
EXPECT_EQ(nested_array[4], "text"); EXPECT_EQ(nested_array[4],u8"text");
std::vector<int> expected{ 5, 6, 7 }; std::vector<int> expected{ 5, 6, 7 };
EXPECT_EQ(nested_array[5], expected); EXPECT_EQ(nested_array[5], expected);
} }
@ -205,12 +206,12 @@ TEST(JsonParser, deserialize_map) {
object obj = parser.deserialize(json_data); object obj = parser.deserialize(json_data);
EXPECT_EQ(obj.size(), 6U); EXPECT_EQ(obj.size(), 6U);
EXPECT_EQ(obj["some_true"], true); EXPECT_EQ(obj[u8"some_true"], true);
EXPECT_EQ(obj["some_false"], false); EXPECT_EQ(obj[u8"some_false"], false);
EXPECT_EQ(obj["some_int"], 1234); EXPECT_EQ(obj[u8"some_int"], 1234);
EXPECT_DOUBLE_EQ(obj["some_double"].get<double>(), 12.34); EXPECT_DOUBLE_EQ(obj[u8"some_double"].get<double>(), 12.34);
EXPECT_DOUBLE_EQ(obj["some_other_double"].get<double>(), 0.1234); EXPECT_DOUBLE_EQ(obj[u8"some_other_double"].get<double>(), 0.1234);
EXPECT_EQ(obj["some_text"], "text"); EXPECT_EQ(obj[u8"some_text"], u8"text");
} }
TEST(JsonParser, deserialize_map_nested) { TEST(JsonParser, deserialize_map_nested) {
@ -233,21 +234,21 @@ TEST(JsonParser, deserialize_map_nested) {
object obj = parser.deserialize(json_data); object obj = parser.deserialize(json_data);
EXPECT_EQ(obj.size(), 4U); EXPECT_EQ(obj.size(), 4U);
EXPECT_EQ(obj["some_text"], "text"); EXPECT_EQ(obj[u8"some_text"], u8"text");
EXPECT_EQ(obj["some other text"], " asdf "); EXPECT_EQ(obj[u8"some other text"], u8" asdf ");
// some_object // some_object
EXPECT_FALSE(obj["some_object"].null()); EXPECT_FALSE(obj[u8"some_object"].null());
EXPECT_EQ(obj["some_object"].size(), 1U); EXPECT_EQ(obj[u8"some_object"].size(), 1U);
EXPECT_FALSE(obj["some_object"]["some_null_object"].null()); EXPECT_FALSE(obj[u8"some_object"][u8"some_null_object"].null());
EXPECT_EQ(obj["some_object"]["some_null_object"].size(), 0U); EXPECT_EQ(obj[u8"some_object"][u8"some_null_object"].size(), 0U);
// some_other_object // some_other_object
EXPECT_FALSE(obj["some_other_object"].null()); EXPECT_FALSE(obj[u8"some_other_object"].null());
EXPECT_EQ(obj["some_other_object"].size(), 1U); EXPECT_EQ(obj[u8"some_other_object"].size(), 1U);
EXPECT_FALSE(obj["some_other_object"]["beans"].null()); EXPECT_FALSE(obj[u8"some_other_object"][u8"beans"].null());
EXPECT_EQ(obj["some_other_object"]["beans"].size(), 3U); EXPECT_EQ(obj[u8"some_other_object"][u8"beans"].size(), 3U);
EXPECT_EQ(obj["some_other_object"]["beans"]["fruit"], true); EXPECT_EQ(obj[u8"some_other_object"][u8"beans"][u8"fruit"], true);
EXPECT_EQ(obj["some_other_object"]["beans"]["magical"], true); EXPECT_EQ(obj[u8"some_other_object"][u8"beans"][u8"magical"], true);
EXPECT_EQ(obj["some_other_object"]["beans"]["makes toot"], true); EXPECT_EQ(obj[u8"some_other_object"][u8"beans"][u8"makes toot"], true);
} }

Loading…
Cancel
Save