Browse Source

change object to use u8string instead of string

master
Jessica James 3 years ago
parent
commit
f425b13797
  1. 40
      src/common/app_parameters.cpp
  2. 2
      src/common/object.cpp
  3. 41
      src/common/parsers/json.cpp
  4. 24
      src/include/jessilib/app_parameters.hpp
  5. 26
      src/include/jessilib/object.hpp
  6. 4
      src/include/jessilib/parser.hpp
  7. 112
      src/test/app_parameters.cpp
  8. 20
      src/test/config.cpp
  9. 186
      src/test/object.cpp
  10. 21
      src/test/parser.cpp
  11. 66
      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) {
// 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
if (in_argc <= 0 || in_argv == nullptr) {
return;
}
// Populate path
m_path = in_argv[0];
m_path = reinterpret_cast<const char8_t*>(in_argv[0]);
// Process args
std::string_view key;
std::string value;
std::u8string_view key;
std::u8string value;
auto flush_value = [&key, &value, this]() {
// This is the start of a key; flush what we were previously processing
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) {
const char* arg = in_argv[index];
const char8_t* arg = reinterpret_cast<const char8_t*>(in_argv[index]);
if (arg != nullptr && *arg != '\0') {
// Check if this is a key or value
if (*arg == '-') {
@ -66,7 +68,7 @@ app_parameters::app_parameters(int in_argc, const char** in_argv) {
// Parse key for any value denominator ('=')
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
value = key.substr(key_end + 1);
key = key.substr(0, key_end);
@ -91,30 +93,32 @@ app_parameters::app_parameters(int in_argc, const char** in_argv) {
flush_value();
// 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;
}
const std::vector<std::string_view>& app_parameters::arguments() const {
const std::vector<std::u8string_view>& app_parameters::arguments() const {
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;
}
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;
}
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;
}
object app_parameters::as_object() const {
using namespace std::literals;
// Null check
if (m_path.empty()
&& m_args.empty()) {
@ -122,19 +126,19 @@ object app_parameters::as_object() const {
return object{};
}
return std::map<std::string, object>{
{ "Path", m_path },
{ "Args", m_args },
{ "Switches", m_switches },
{ "Values", m_values }
return std::map<std::u8string, object>{
{ u8"Path"s, m_path },
{ u8"Args"s, m_args },
{ u8"Switches"s, m_switches },
{ 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();
}
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);
// Safety check

2
src/common/object.cpp

@ -28,7 +28,7 @@ object::object(object&& in_object) {
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 } } {
// Empty ctor body
}

41
src/common/parsers/json.cpp

@ -25,7 +25,7 @@ using namespace std::literals;
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;
result.reserve(in_string.size() + 2);
result = '\"';
@ -44,8 +44,8 @@ std::string make_json_string(std::string_view in_string) {
// overwrite last 2 zeroes with correct hexadecimal sequence
char* data_end = result.data() + result.size();
char* data = data_end - 2;
std::to_chars(data, data_end, in_string.front(), 16);
char* data = data_end - 2; // TODO: this isn't correct, is it? to_chars may only write 1 char in many cases
std::to_chars(data, data_end, static_cast<char>(in_string.front()), 16); // TODO: use decode_codepoint
}
else if ((in_string.front() & 0x80) != 0) { // UTF-8 sequence; copy to bypass above processing
if ((in_string.front() & 0x40) != 0) {
@ -62,7 +62,7 @@ std::string make_json_string(std::string_view in_string) {
}
// This is a 4-byte sequence
result += in_string.substr(0, 4);
result.append(reinterpret_cast<const char*>(in_string.data()), 4);
in_string.remove_prefix(4);
continue;
}
@ -73,7 +73,7 @@ std::string make_json_string(std::string_view in_string) {
}
// This is a 3-byte sequence
result += in_string.substr(0, 3);
result.append(reinterpret_cast<const char*>(in_string.data()), 3);
in_string.remove_prefix(3);
continue;
}
@ -84,7 +84,7 @@ std::string make_json_string(std::string_view in_string) {
}
// This is a 2-byte sequence
result += in_string.substr(0, 2);
result.append(reinterpret_cast<const char*>(in_string.data()), 2);
in_string.remove_prefix(2);
continue;
}
@ -94,7 +94,7 @@ std::string make_json_string(std::string_view in_string) {
}
else {
// Character in standard ASCII table
result += in_string.front();
result += static_cast<char>(in_string.front());
}
in_string.remove_prefix(1);
@ -132,8 +132,8 @@ uint16_t get_codepoint_from_hex(const std::string_view& in_data) {
return value;
}
std::string read_json_string(std::string_view& in_data) {
std::string result;
std::u8string read_json_string(std::string_view& in_data) {
std::u8string result;
// Remove leading quotation
in_data.remove_prefix(1);
@ -154,49 +154,49 @@ std::string read_json_string(std::string_view& in_data) {
// Quote
case '\"':
in_data.remove_prefix(1);
result += '\"';
result += u8'\"';
break;
// Backslash
case '\\':
in_data.remove_prefix(1);
result += '\\';
result += u8'\\';
break;
// Forward slash
case '/':
in_data.remove_prefix(1);
result += '/';
result += u8'/';
break;
// Backspace
case 'b':
in_data.remove_prefix(1);
result += '\b';
result += u8'\b';
break;
// Formfeed
case 'f':
in_data.remove_prefix(1);
result += '\f';
result += u8'\f';
break;
// Newline
case 'n':
in_data.remove_prefix(1);
result += '\n';
result += u8'\n';
break;
// Carriage return
case 'r':
in_data.remove_prefix(1);
result += '\r';
result += u8'\r';
break;
// Horizontal tab
case 't':
in_data.remove_prefix(1);
result += '\t';
result += u8'\t';
break;
// Unicode codepoint
@ -258,8 +258,7 @@ std::string read_json_string(std::string_view& in_data) {
}
// 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);
break;
}
@ -492,8 +491,8 @@ std::string json_parser::serialize(const object& in_object) {
case object::type::decimal:
return std::to_string(in_object.get<long double>());
case object::type::string:
return make_json_string(in_object.get<std::string>());
case object::type::text:
return make_json_string(in_object.get<std::u8string>());
case object::type::array: {
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, const char** in_argv);
std::string_view path() const;
const std::vector<std::string_view>& arguments() const;
const std::vector<std::string_view>& switches() const;
const std::unordered_set<std::string_view>& switches_set() const;
const std::unordered_map<std::string_view, std::string>& values() const;
std::u8string_view path() const;
const std::vector<std::u8string_view>& arguments() const;
const std::vector<std::u8string_view>& switches() const;
const std::unordered_set<std::u8string_view>& switches_set() const;
const std::unordered_map<std::u8string_view, std::u8string>& values() const;
jessilib::object as_object() const;
bool has_switch(std::string_view in_switch) const;
std::string_view get_value(std::string_view in_key, std::string_view in_default = {}) const;
bool has_switch(std::u8string_view in_switch) const;
std::u8string_view get_value(std::u8string_view in_key, std::u8string_view in_default = {}) const;
operator jessilib::object() const { return as_object(); }
private:
std::string_view m_path;
std::vector<std::string_view> m_args;
std::vector<std::string_view> m_switches;
std::unordered_set<std::string_view> m_switches_set;
std::unordered_map<std::string_view, std::string> m_values;
std::u8string_view m_path;
std::vector<std::u8string_view> m_args;
std::vector<std::u8string_view> m_switches;
std::unordered_set<std::u8string_view> m_switches_set;
std::unordered_map<std::u8string_view, std::u8string> m_values;
};
} // namespace jessilib

26
src/include/jessilib/object.hpp

@ -31,8 +31,12 @@ namespace jessilib {
class object {
public:
using array_type = std::vector<object>;
using string_type = std::string;
using string_view_type = std::string_view;
using text_char_type = char8_t;
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 index_type = std::size_t;
@ -86,7 +90,8 @@ public:
boolean,
integer,
decimal,
string, // TODO: consider separating into 'binary' (std::vector<std::byte>) and 'text' (string_type) types
text,
data,
array,
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);
// Comparison operators
@ -454,6 +459,17 @@ public:
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 {
return std::hash<T>{}(std::forward<decltype(value)>(value));
}
@ -464,7 +480,7 @@ private:
using null_variant_t = void*;
// 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
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
// OR, have every XML tag objects be a map, with all subobjects being in a "__values" array subobject or such

4
src/include/jessilib/parser.hpp

@ -38,9 +38,9 @@ public:
* @return A valid (possibly null) object
*/
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 std::string serialize(const object& in_object) = 0;
virtual std::string serialize(const object& in_object) = 0; // TODO: serialize to arbitrary unicode strings
}; // parser
template<typename T>

112
src/test/app_parameters.cpp

@ -75,7 +75,7 @@ TEST(AppParametersTest, path_only) {
ArgWrapper args{ "/path/to/exe" };
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.switches().empty());
EXPECT_TRUE(parameters.switches_set().empty());
@ -83,7 +83,7 @@ TEST(AppParametersTest, path_only) {
auto obj = parameters.as_object();
EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe");
EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
}
TEST(AppParametersTest, single_switch) {
@ -98,9 +98,9 @@ TEST(AppParametersTest, single_switch) {
auto obj = parameters.as_object();
EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe");
EXPECT_EQ(obj["Args"], object{ std::vector<std::string>{ "-switch" } });
EXPECT_EQ(obj["Switches"], object{ std::vector<std::string>{ "switch" } });
EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj[u8"Args"], object{ std::vector<std::u8string>{ u8"-switch" } });
EXPECT_EQ(obj[u8"Switches"], object{ std::vector<std::u8string>{ u8"switch" } });
}
TEST(AppParametersTest, double_switch) {
@ -114,12 +114,12 @@ TEST(AppParametersTest, double_switch) {
EXPECT_TRUE(parameters.values().empty());
auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-switch1", "--switch2" };
std::vector<std::string> expected_switches{ "switch1", "switch2" };
std::vector<std::u8string> expected_args{ u8"-switch1", u8"--switch2" };
std::vector<std::u8string> expected_switches{ u8"switch1", u8"switch2" };
EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args);
EXPECT_EQ(obj["Switches"], expected_switches);
EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj[u8"Switches"], expected_switches);
}
TEST(AppParametersTest, duplicate_switch) {
@ -133,12 +133,12 @@ TEST(AppParametersTest, duplicate_switch) {
EXPECT_TRUE(parameters.values().empty());
auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-switch", "--switch" };
std::vector<std::string> expected_switches{ "switch", "switch" };
std::vector<std::u8string> expected_args{ u8"-switch", u8"--switch" };
std::vector<std::u8string> expected_switches{ u8"switch", u8"switch" };
EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args);
EXPECT_EQ(obj["Switches"], expected_switches);
EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj[u8"Switches"], expected_switches);
}
TEST(AppParametersTest, single_value) {
@ -152,12 +152,12 @@ TEST(AppParametersTest, single_value) {
EXPECT_EQ(parameters.values().size(), 1U);
auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key", "value" };
std::map<std::string, object> expected_values{ { "key", "value" } };
std::vector<std::u8string> expected_args{ u8"-key", u8"value" };
std::map<std::u8string, object> expected_values{ { u8"key", u8"value" } };
EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values);
EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj[u8"Values"], expected_values);
}
TEST(AppParametersTest, single_value_eq) {
@ -171,12 +171,12 @@ TEST(AppParametersTest, single_value_eq) {
EXPECT_EQ(parameters.values().size(), 1U);
auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key=value" };
std::map<std::string, object> expected_values{ { "key", "value" } };
std::vector<std::u8string> expected_args{ u8"-key=value" };
std::map<std::u8string, object> expected_values{ { u8"key", u8"value" } };
EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values);
EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj[u8"Values"], expected_values);
}
TEST(AppParametersTest, multiword_value) {
@ -190,12 +190,12 @@ TEST(AppParametersTest, multiword_value) {
EXPECT_EQ(parameters.values().size(), 1U);
auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key", "valuePart1", "valuePart2" };
std::map<std::string, object> expected_values{ { "key", "valuePart1 valuePart2" } };
std::vector<std::u8string> expected_args{ u8"-key", u8"valuePart1", u8"valuePart2" };
std::map<std::u8string, object> expected_values{ { u8"key", u8"valuePart1 valuePart2" } };
EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values);
EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj[u8"Values"], expected_values);
}
TEST(AppParametersTest, multiword_value_eq) {
@ -209,12 +209,12 @@ TEST(AppParametersTest, multiword_value_eq) {
EXPECT_EQ(parameters.values().size(), 1U);
auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key=valuePart1", "valuePart2" };
std::map<std::string, object> expected_values{ { "key", "valuePart1 valuePart2" } };
std::vector<std::u8string> expected_args{ u8"-key=valuePart1", u8"valuePart2" };
std::map<std::u8string, object> expected_values{ { u8"key", u8"valuePart1 valuePart2" } };
EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values);
EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj[u8"Values"], expected_values);
}
TEST(AppParametersTest, double_value) {
@ -228,12 +228,12 @@ TEST(AppParametersTest, double_value) {
EXPECT_EQ(parameters.values().size(), 2U);
auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key", "value", "--key2", "value2" };
std::map<std::string, object> expected_values{ { "key", "value" }, { "key2", "value2" } };
std::vector<std::u8string> expected_args{ u8"-key", u8"value", u8"--key2", u8"value2" };
std::map<std::u8string, object> expected_values{ { u8"key", u8"value" }, { u8"key2", u8"value2" } };
EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values);
EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj[u8"Values"], expected_values);
}
TEST(AppParametersTest, double_value_eq) {
@ -247,12 +247,12 @@ TEST(AppParametersTest, double_value_eq) {
EXPECT_EQ(parameters.values().size(), 2U);
auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "-key=value", "--key2=value2" };
std::map<std::string, object> expected_values{ { "key", "value" }, { "key2", "value2" } };
std::vector<std::u8string> expected_args{ u8"-key=value", u8"--key2=value2" };
std::map<std::u8string, object> expected_values{ { u8"key", u8"value" }, { u8"key2", u8"value2" } };
EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args);
EXPECT_EQ(obj["Values"], expected_values);
EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj[u8"Values"], expected_values);
}
TEST(AppParametersTest, switch_and_value) {
@ -266,16 +266,16 @@ TEST(AppParametersTest, switch_and_value) {
EXPECT_EQ(parameters.values().size(), 1U);
auto obj = parameters.as_object();
std::vector<std::string> expected_args{ "--switch", "-key", "value" };
std::vector<std::string> expected_switches{ "switch" };
std::map<std::string, object> expected_values{ { "key", "value" } };
std::vector<std::u8string> expected_args{ u8"--switch", u8"-key", u8"value" };
std::vector<std::u8string> expected_switches{ u8"switch" };
std::map<std::u8string, object> expected_values{ { u8"key", u8"value" } };
EXPECT_FALSE(obj.null());
EXPECT_EQ(obj["Path"], "/path/to/exe");
EXPECT_EQ(obj["Args"], expected_args);
EXPECT_EQ(obj["Switches"], expected_switches);
EXPECT_EQ(obj["Values"], expected_values);
EXPECT_TRUE(parameters.has_switch("switch"));
EXPECT_FALSE(parameters.has_switch("switch2"));
EXPECT_EQ(parameters.get_value("key"), "value");
EXPECT_EQ(obj[u8"Path"], u8"/path/to/exe");
EXPECT_EQ(obj[u8"Args"], expected_args);
EXPECT_EQ(obj[u8"Switches"], expected_switches);
EXPECT_EQ(obj[u8"Values"], expected_values);
EXPECT_TRUE(parameters.has_switch(u8"switch"));
EXPECT_FALSE(parameters.has_switch(u8"switch2"));
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) {
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) {
std::filesystem::path file_path = make_tmp_file("write_object.test", "some_data");
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) {
@ -75,7 +75,7 @@ TEST(ConfigTest, load) {
l_config.load(file_path);
// 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.format(), "test");
}
@ -94,25 +94,25 @@ TEST(ConfigTest, reload) {
// Reload data from disk and compare
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) {
config l_config;
l_config.set_data("some_data");
EXPECT_EQ(l_config.data().get<std::string>(), "some_data");
l_config.set_data(u8"some_data");
EXPECT_EQ(l_config.data().get<std::u8string>(), u8"some_data");
}
TEST(ConfigTest, write) {
config l_config;
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.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) {
@ -125,12 +125,12 @@ TEST(ConfigTest, rewrite) {
l_config.load(file_path);
// Set some other data
l_config.set_data("some_other_data");
l_config.set_data(u8"some_other_data");
// Write data to disk
l_config.write();
// Reload from disk and verify
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_double_t = long double;
using map_str_str = std::map<std::string, std::string>;
using map_str_strv = std::map<std::string, std::string_view>;
using map_str_obj = std::map<std::string, object>;
using map_strv_str = std::map<std::string_view, std::string>;
using map_strv_strv = std::map<std::string_view, std::string_view>;
using map_strv_obj = std::map<std::string_view, object>;
using unordered_map_str_str = std::unordered_map<std::string, std::string>;
using unordered_map_str_strv = std::unordered_map<std::string, std::string_view>;
using unordered_map_str_obj = std::unordered_map<std::string, object>;
using unordered_map_strv_str = std::unordered_map<std::string_view, std::string>;
using unordered_map_strv_strv = std::unordered_map<std::string_view, std::string_view>;
using unordered_map_strv_obj = std::unordered_map<std::string_view, object>;
using map_str_str = std::map<std::u8string, std::u8string>;
using map_str_strv = std::map<std::u8string, std::u8string_view>;
using map_str_obj = std::map<std::u8string, object>;
using map_strv_str = std::map<std::u8string_view, std::u8string>;
using map_strv_strv = std::map<std::u8string_view, std::u8string_view>;
using map_strv_obj = std::map<std::u8string_view, object>;
using unordered_map_str_str = std::unordered_map<std::u8string, std::u8string>;
using unordered_map_str_strv = std::unordered_map<std::u8string, std::u8string_view>;
using unordered_map_str_obj = std::unordered_map<std::u8string, object>;
using unordered_map_strv_str = std::unordered_map<std::u8string_view, std::u8string>;
using unordered_map_strv_strv = std::unordered_map<std::u8string_view, std::u8string_view>;
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 */
@ -66,7 +66,7 @@ TEST(ObjectTest, basic_has) {
EXPECT_FALSE(obj.has<float>());
EXPECT_FALSE(obj.has<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::map_type>());
}
@ -85,7 +85,7 @@ TEST(ObjectTest, basic_has_vector) {
EXPECT_FALSE(obj.has<std::vector<float>>());
EXPECT_FALSE(obj.has<std::vector<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>>());
}
@ -103,7 +103,7 @@ TEST(ObjectTest, basic_has_list) {
EXPECT_FALSE(obj.has<std::list<float>>());
EXPECT_FALSE(obj.has<std::list<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>>());
}
@ -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<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>>());
}
@ -139,7 +139,7 @@ TEST(ObjectTest, basic_has_set) {
EXPECT_FALSE(obj.has<std::set<float>>());
EXPECT_FALSE(obj.has<std::set<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>>());
}
@ -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<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>>());
}
@ -199,7 +199,7 @@ TEST(ObjectTest, basic_get) {
EXPECT_EQ(obj.get<float>(), float{});
EXPECT_EQ(obj.get<double>(), double{});
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::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<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());
}
@ -236,7 +236,7 @@ TEST(ObjectTest, basic_get_list) {
EXPECT_TRUE(obj.get<std::list<float>>().empty());
EXPECT_TRUE(obj.get<std::list<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());
}
@ -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<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());
}
@ -272,7 +272,7 @@ TEST(ObjectTest, basic_get_set) {
EXPECT_TRUE(obj.get<std::set<float>>().empty());
EXPECT_TRUE(obj.get<std::set<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());
}
@ -290,7 +290,7 @@ TEST(ObjectTest, basic_get_multiset) {
EXPECT_TRUE(obj.get<std::multiset<float>>().empty());
EXPECT_TRUE(obj.get<std::multiset<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());
}
@ -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<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());
}
@ -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<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());
}
@ -351,21 +351,21 @@ TEST(ObjectTest, basic_value_constructor) {
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(float);
OBJECT_BASIC_VALUE_CONSTRUCTOR_TEST(double);
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);
// const char*
{
object obj{ "" };
EXPECT_TRUE(obj.has<std::string>());
EXPECT_EQ(obj.get<std::string>(), std::string{});
object obj{ u8"" };
EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
}
// std::string_view
// std::u8string_view
{
object obj{ ""sv };
EXPECT_TRUE(obj.has<std::string>());
EXPECT_EQ(obj.get<std::string>(), std::string{});
object obj{ u8""sv };
EXPECT_TRUE(obj.has<std::u8string>());
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<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>);
}
@ -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<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>);
}
@ -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<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>);
}
@ -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<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>);
}
@ -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<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>);
}
@ -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<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>);
}
@ -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<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>);
}
@ -502,18 +502,18 @@ TEST(ObjectTest, basic_set) {
OBJECT_BASIC_SET_TEST(obj, float);
OBJECT_BASIC_SET_TEST(obj, double);
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);
// const char*
obj.set("");
EXPECT_TRUE(obj.has<std::string>());
EXPECT_EQ(obj.get<std::string>(), std::string{});
obj.set(u8"");
EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
// std::string_view
obj.set(""sv);
EXPECT_TRUE(obj.has<std::string>());
EXPECT_EQ(obj.get<std::string>(), std::string{});
// std::u8string_view
obj.set(u8""sv);
EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
}
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<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>);
}
@ -548,7 +548,7 @@ TEST(ObjectTest, basic_set_list) {
OBJECT_BASIC_SET_TEST(obj, std::list<float>);
OBJECT_BASIC_SET_TEST(obj, std::list<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>);
}
@ -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<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>);
}
@ -584,7 +584,7 @@ TEST(ObjectTest, basic_set_set) {
OBJECT_BASIC_SET_TEST(obj, std::set<float>);
OBJECT_BASIC_SET_TEST(obj, std::set<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>);
}
@ -602,7 +602,7 @@ TEST(ObjectTest, basic_set_multiset) {
OBJECT_BASIC_SET_TEST(obj, std::multiset<float>);
OBJECT_BASIC_SET_TEST(obj, std::multiset<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>);
}
@ -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<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>);
}
@ -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<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>);
}
@ -663,18 +663,18 @@ TEST(ObjectTest, basic_assignment_operator) {
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, float);
OBJECT_BASIC_ASSIGNMENT_OPERATOR_TEST(obj, double);
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);
// const char*
obj = "";
EXPECT_TRUE(obj.has<std::string>());
EXPECT_EQ(obj.get<std::string>(), std::string{});
obj = u8"";
EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
// std::string_view
obj = ""sv;
EXPECT_TRUE(obj.has<std::string>());
EXPECT_EQ(obj.get<std::string>(), std::string{});
// std::u8string_view
obj = u8""sv;
EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::u8string>(), std::u8string{});
}
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<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>);
}
@ -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<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>);
}
@ -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<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>);
}
@ -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<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>);
}
@ -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<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>);
}
@ -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<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>);
}
@ -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<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>);
}
@ -808,17 +808,17 @@ TEST(ObjectTest, basic_assignment_operator_unordered_multiset) {
TEST(ObjectTest, basic_map_access_operator) {
object obj;
obj["test"] = 1234;
EXPECT_EQ(obj["test"].get<int>(), 1234);
EXPECT_EQ(obj["test2"].get<int>(), 0);
obj[u8"test"] = 1234;
EXPECT_EQ(obj[u8"test"].get<int>(), 1234);
EXPECT_EQ(obj[u8"test2"].get<int>(), 0);
obj["test"] = 4567;
EXPECT_EQ(obj["test"].get<int>(), 4567);
EXPECT_EQ(obj["test2"].get<int>(), 0);
obj[u8"test"] = 4567;
EXPECT_EQ(obj[u8"test"].get<int>(), 4567);
EXPECT_EQ(obj[u8"test2"].get<int>(), 0);
obj["test2"] = 1234;
EXPECT_EQ(obj["test"].get<int>(), 4567);
EXPECT_EQ(obj["test2"].get<int>(), 1234);
obj[u8"test2"] = 1234;
EXPECT_EQ(obj[u8"test"].get<int>(), 4567);
EXPECT_EQ(obj[u8"test2"].get<int>(), 1234);
}
TEST(ObjectTest, basic_array_access_operator) {
@ -914,31 +914,31 @@ TEST(ObjectTest, set_float) {
TEST(ObjectTest, set_string) {
object obj;
obj.set("Jessica");
obj.set(u8"Jessica");
EXPECT_TRUE(obj.has<std::string>());
EXPECT_EQ(obj.get<std::string>(), "Jessica");
EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::u8string>(), u8"Jessica");
EXPECT_FALSE(obj.has<bool>());
EXPECT_FALSE(obj.get<bool>());
obj.set("was"s);
obj.set(u8"was"s);
EXPECT_TRUE(obj.has<std::string>());
EXPECT_EQ(obj.get<std::string>(), "was");
EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::u8string>(), u8"was");
EXPECT_FALSE(obj.has<bool>());
EXPECT_FALSE(obj.get<bool>());
obj.set("here"sv);
obj.set(u8"here"sv);
EXPECT_TRUE(obj.has<std::string>());
EXPECT_EQ(obj.get<std::string>(), "here");
EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::u8string>(), u8"here");
EXPECT_FALSE(obj.has<bool>());
EXPECT_FALSE(obj.get<bool>());
obj.set("");
obj.set(u8"");
EXPECT_TRUE(obj.has<std::string>());
EXPECT_EQ(obj.get<std::string>(), "");
EXPECT_TRUE(obj.has<std::u8string>());
EXPECT_EQ(obj.get<std::u8string>(), u8"");
EXPECT_FALSE(obj.has<bool>());
EXPECT_FALSE(obj.get<bool>());
}

21
src/test/parser.cpp

@ -20,6 +20,7 @@
#include "test.hpp"
#include "jessilib/parser.hpp"
#include "jessilib/serialize.hpp"
#include "jessilib/unicode.hpp"
using namespace jessilib;
using namespace std::literals;
@ -45,15 +46,15 @@ public:
/** default serialize/deserialize implementations */
static std::string serialize_default(const object& in_object) {
if (in_object.has<std::string>()) {
return in_object.get<std::string>();
if (in_object.has<std::u8string>()) {
return string_cast<char>(in_object.get<std::u8string>());
}
return static_cast<std::string>(DEFAULT_SERIALIZE_RESULT);
}
static object deserialize_default(std::string_view in_data) {
return object{ in_data };
return object{ string_view_cast<char8_t>(in_data) };
}
/** static members */
@ -82,31 +83,31 @@ class ParserTest : public base_test {
/** Parser tests */
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_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);
}
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);
{
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_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);
}
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) {
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");
}

66
src/test/parsers/json.cpp

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

Loading…
Cancel
Save