#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include "doctest.h" #include "utility.hpp" #include #include #include #include #include #include #include #include #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif namespace toml { namespace detail { std::tm localtime_s(const std::time_t* src); std::tm gmtime_s(const std::time_t* src); } // detail } // toml TEST_CASE("testing toml::get with toml types") { using value_type = toml::value; using boolean_type = typename value_type::boolean_type ; using integer_type = typename value_type::integer_type ; using floating_type = typename value_type::floating_type ; using string_type = typename value_type::string_type ; using local_time_type = typename value_type::local_time_type ; using local_date_type = typename value_type::local_date_type ; using local_datetime_type = typename value_type::local_datetime_type ; using offset_datetime_type = typename value_type::offset_datetime_type; using array_type = typename value_type::array_type ; using table_type = typename value_type::table_type ; { value_type v(true); CHECK_EQ(true, toml::get(v)); toml::get(v) = false; CHECK_EQ(false, toml::get(v)); boolean_type x = toml::get(std::move(v)); CHECK_EQ(false, x); } { value_type v(42); CHECK_EQ(integer_type(42), toml::get(v)); toml::get(v) = 54; CHECK_EQ(integer_type(54), toml::get(v)); integer_type x = toml::get(std::move(v)); CHECK_EQ(integer_type(54), x); } { value_type v(3.14); CHECK_EQ(floating_type(3.14), toml::get(v)); toml::get(v) = 2.71; CHECK_EQ(floating_type(2.71), toml::get(v)); floating_type x = toml::get(std::move(v)); CHECK_EQ(floating_type(2.71), x); } { value_type v("foo"); CHECK_EQ("foo", toml::get(v)); toml::get(v) += "bar"; CHECK_EQ("foobar", toml::get(v)); string_type x = toml::get(std::move(v)); CHECK_EQ("foobar", x); } { local_date_type d(2018, toml::month_t::Apr, 22); value_type v(d); CHECK_EQ(d, toml::get(v)); toml::get(v).year = 2017; d.year = 2017; CHECK_EQ(d, toml::get(v)); local_date_type x = toml::get(std::move(v)); CHECK_EQ(d, x); } { local_time_type t(12, 30, 45); value_type v(t); CHECK_EQ(t, toml::get(v)); toml::get(v).hour = 9; t.hour = 9; CHECK_EQ(t, toml::get(v)); local_time_type x = toml::get(std::move(v)); CHECK_EQ(t, x); } { local_datetime_type dt(toml::local_date(2018, toml::month_t::Apr, 22), toml::local_time(12, 30, 45)); value_type v(dt); CHECK_EQ(dt, toml::get(v)); toml::get(v).date.year = 2017; dt.date.year = 2017; CHECK_EQ(dt, toml::get(v)); toml::local_datetime x = toml::get(std::move(v)); CHECK_EQ(dt, x); } { offset_datetime_type dt(toml::local_datetime( toml::local_date(2018, toml::month_t::Apr, 22), toml::local_time(12, 30, 45)), toml::time_offset(9, 0)); value_type v(dt); CHECK_EQ(dt, toml::get(v)); toml::get(v).date.year = 2017; dt.date.year = 2017; CHECK_EQ(dt, toml::get(v)); offset_datetime_type x = toml::get(std::move(v)); CHECK_EQ(dt, x); } { array_type vec; vec.push_back(value_type(42)); vec.push_back(value_type(54)); value_type v(vec); CHECK_EQ(vec, toml::get(v)); toml::get(v).push_back(value_type(123)); vec.push_back(value_type(123)); CHECK_EQ(vec, toml::get(v)); array_type x = toml::get(std::move(v)); CHECK_EQ(vec, x); } { table_type tab; tab["key1"] = value_type(42); tab["key2"] = value_type(3.14); value_type v(tab); CHECK_EQ(tab, toml::get(v)); toml::get(v)["key3"] = value_type(123); tab["key3"] = value_type(123); CHECK_EQ(tab, toml::get(v)); table_type x = toml::get(std::move(v)); CHECK_EQ(tab, x); } { value_type v1(42); CHECK_EQ(v1, toml::get(v1)); value_type v2(54); toml::get(v1) = v2; CHECK_EQ(v2, toml::get(v1)); value_type x = toml::get(std::move(v1)); CHECK_EQ(v2, x); } } TEST_CASE("testing toml::get") { using value_type = toml::value; { value_type v(42); CHECK_EQ(int(42), toml::get(v)); CHECK_EQ(short(42), toml::get(v)); CHECK_EQ(char(42), toml::get(v)); CHECK_EQ(unsigned(42), toml::get(v)); CHECK_EQ(long(42), toml::get(v)); CHECK_EQ(std::int64_t(42), toml::get(v)); CHECK_EQ(std::uint64_t(42), toml::get(v)); CHECK_EQ(std::int16_t(42), toml::get(v)); CHECK_EQ(std::uint16_t(42), toml::get(v)); CHECK_EQ(int(42), toml::get(as_const(v))); CHECK_EQ(short(42), toml::get(as_const(v))); CHECK_EQ(char(42), toml::get(as_const(v))); CHECK_EQ(unsigned(42), toml::get(as_const(v))); CHECK_EQ(long(42), toml::get(as_const(v))); CHECK_EQ(std::int64_t(42), toml::get(as_const(v))); CHECK_EQ(std::uint64_t(42), toml::get(as_const(v))); CHECK_EQ(std::int16_t(42), toml::get(as_const(v))); CHECK_EQ(std::uint16_t(42), toml::get(as_const(v))); value_type v1(v); value_type v2(v); value_type v3(v); value_type v4(v); value_type v5(v); value_type v6(v); value_type v7(v); value_type v8(v); value_type v9(v); CHECK_EQ(int(42), toml::get(v1)); CHECK_EQ(short(42), toml::get(v2)); CHECK_EQ(char(42), toml::get(v3)); CHECK_EQ(unsigned(42), toml::get(v4)); CHECK_EQ(long(42), toml::get(v5)); CHECK_EQ(std::int64_t(42), toml::get(v6)); CHECK_EQ(std::uint64_t(42), toml::get(v7)); CHECK_EQ(std::int16_t(42), toml::get(v8)); CHECK_EQ(std::uint16_t(42), toml::get(v9)); } } TEST_CASE("testing toml::get") { using value_type = toml::value; { const double ref(3.14); value_type v(ref); CHECK_EQ(static_cast(ref), toml::get(v)); CHECK_EQ( ref , toml::get(v)); CHECK_EQ(static_cast(ref), toml::get(v)); value_type v1(ref); value_type v2(ref); value_type v3(ref); CHECK_EQ(static_cast(ref), toml::get(std::move(v1))); CHECK_EQ( ref , toml::get(std::move(v2))); CHECK_EQ(static_cast(ref), toml::get(std::move(v3))); } } #if defined(TOML11_HAS_CHAR8_T) TEST_CASE("testing toml::get") { using value_type = toml::value; { value_type v("foo"); CHECK_EQ(u8"foo", toml::get(v)); } } #endif #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L TEST_CASE("testing toml::get") { using value_type = toml::value; { value_type v("foo"); CHECK_EQ("foo", toml::get(v)); } } #endif TEST_CASE("testing toml::get") { using value_type = toml::value; { const value_type v(toml::array{42, 54, 69, 72}); const std::vector vec = toml::get>(v); const std::list lst = toml::get>(v); const std::deque deq = toml::get>(v); CHECK_EQ(42, vec.at(0)); CHECK_EQ(54, vec.at(1)); CHECK_EQ(69, vec.at(2)); CHECK_EQ(72, vec.at(3)); std::list::const_iterator iter = lst.begin(); CHECK_EQ(static_cast(42), *(iter++)); CHECK_EQ(static_cast(54), *(iter++)); CHECK_EQ(static_cast(69), *(iter++)); CHECK_EQ(static_cast(72), *(iter++)); CHECK_EQ(static_cast(42), deq.at(0)); CHECK_EQ(static_cast(54), deq.at(1)); CHECK_EQ(static_cast(69), deq.at(2)); CHECK_EQ(static_cast(72), deq.at(3)); std::array ary = toml::get>(v); CHECK_EQ(42, ary.at(0)); CHECK_EQ(54, ary.at(1)); CHECK_EQ(69, ary.at(2)); CHECK_EQ(72, ary.at(3)); std::tuple tpl = toml::get>(v); CHECK_EQ( 42 , std::get<0>(tpl)); CHECK_EQ(static_cast(54), std::get<1>(tpl)); CHECK_EQ(static_cast(69), std::get<2>(tpl)); CHECK_EQ(static_cast(72), std::get<3>(tpl)); const value_type p(toml::array{3.14, 2.71}); std::pair pr = toml::get >(p); CHECK_EQ(3.14, pr.first); CHECK_EQ(2.71, pr.second); } { value_type v(toml::array{42, 54, 69, 72}); const std::vector vec = toml::get>(std::move(v)); CHECK_EQ(42, vec.at(0)); CHECK_EQ(54, vec.at(1)); CHECK_EQ(69, vec.at(2)); CHECK_EQ(72, vec.at(3)); } { value_type v(toml::array{42, 54, 69, 72}); const std::deque deq = toml::get>(std::move(v)); CHECK_EQ(42, deq.at(0)); CHECK_EQ(54, deq.at(1)); CHECK_EQ(69, deq.at(2)); CHECK_EQ(72, deq.at(3)); } { value_type v(toml::array{42, 54, 69, 72}); const std::list lst = toml::get>(std::move(v)); std::list::const_iterator iter = lst.begin(); CHECK_EQ(42, *(iter++)); CHECK_EQ(54, *(iter++)); CHECK_EQ(69, *(iter++)); CHECK_EQ(72, *(iter++)); } { value_type v(toml::array{42, 54, 69, 72}); std::array ary = toml::get>(std::move(v)); CHECK_EQ(42, ary.at(0)); CHECK_EQ(54, ary.at(1)); CHECK_EQ(69, ary.at(2)); CHECK_EQ(72, ary.at(3)); } { value_type v(toml::array{42, 54, 69, 72}); std::tuple tpl = toml::get>(std::move(v)); CHECK_EQ( 42 , std::get<0>(tpl)); CHECK_EQ(static_cast(54), std::get<1>(tpl)); CHECK_EQ(static_cast(69), std::get<2>(tpl)); CHECK_EQ(static_cast(72), std::get<3>(tpl)); } } TEST_CASE("testing toml::get") { using value_type = toml::value; { const value_type v1(toml::array{42, 54, 69, 72}); const value_type v2(toml::array{"foo", "bar", "baz"}); const value_type v (toml::array{v1, v2}); std::pair, std::vector> p = toml::get, std::vector>>(v); CHECK_EQ(p.first.size(), 4u); CHECK_EQ(p.first.at(0), 42); CHECK_EQ(p.first.at(1), 54); CHECK_EQ(p.first.at(2), 69); CHECK_EQ(p.first.at(3), 72); CHECK_EQ(p.second.size(), 3u); CHECK_EQ(p.second.at(0), "foo"); CHECK_EQ(p.second.at(1), "bar"); CHECK_EQ(p.second.at(2), "baz"); std::tuple, std::vector> t = toml::get, std::vector>>(v); CHECK_EQ(std::get<0>(t).at(0), 42); CHECK_EQ(std::get<0>(t).at(1), 54); CHECK_EQ(std::get<0>(t).at(2), 69); CHECK_EQ(std::get<0>(t).at(3), 72); CHECK_EQ(std::get<1>(t).at(0), "foo"); CHECK_EQ(std::get<1>(t).at(1), "bar"); CHECK_EQ(std::get<1>(t).at(2), "baz"); } { const value_type v1(toml::array{42, 54, 69, 72}); const value_type v2(toml::array{"foo", "bar", "baz"}); value_type v (toml::array{v1, v2}); std::pair, std::vector> p = toml::get, std::vector>>(std::move(v)); CHECK_EQ(p.first.size(), 4u); CHECK_EQ(p.first.at(0), 42); CHECK_EQ(p.first.at(1), 54); CHECK_EQ(p.first.at(2), 69); CHECK_EQ(p.first.at(3), 72); CHECK_EQ(p.second.size(), 3u); CHECK_EQ(p.second.at(0), "foo"); CHECK_EQ(p.second.at(1), "bar"); CHECK_EQ(p.second.at(2), "baz"); } } TEST_CASE("testing toml::get") { using value_type = toml::value; { const value_type v1(toml::table{ {"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4} }); const auto v = toml::get>(v1); CHECK_EQ(v.at("key1"), 1); CHECK_EQ(v.at("key2"), 2); CHECK_EQ(v.at("key3"), 3); CHECK_EQ(v.at("key4"), 4); } { value_type v1(toml::table{ {"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4} }); const auto v = toml::get>(std::move(v1)); CHECK_EQ(v.at("key1"), 1); CHECK_EQ(v.at("key2"), 2); CHECK_EQ(v.at("key3"), 3); CHECK_EQ(v.at("key4"), 4); } } TEST_CASE("testing toml::get(local_date)") { using value_type = toml::value; value_type v1(toml::local_date{2018, toml::month_t::Apr, 1}); const auto date = std::chrono::system_clock::to_time_t( toml::get(v1)); std::tm t; t.tm_year = 2018 - 1900; t.tm_mon = 4 - 1; t.tm_mday = 1; t.tm_hour = 0; t.tm_min = 0; t.tm_sec = 0; t.tm_isdst = -1; const auto c = std::mktime(&t); CHECK_EQ(c, date); } TEST_CASE("testing toml::get") { using value_type = toml::value; value_type v1(toml::local_time{12, 30, 45}); const auto time = toml::get(v1); const bool result = time == std::chrono::hours(12) + std::chrono::minutes(30) + std::chrono::seconds(45); CHECK_UNARY(result); } TEST_CASE("testing toml::get(local_datetime)") { using value_type = toml::value; value_type v1(toml::local_datetime( toml::local_date{2018, toml::month_t::Apr, 1}, toml::local_time{12, 30, 45})); const auto date = std::chrono::system_clock::to_time_t( toml::get(v1)); std::tm t; t.tm_year = 2018 - 1900; t.tm_mon = 4 - 1; t.tm_mday = 1; t.tm_hour = 12; t.tm_min = 30; t.tm_sec = 45; t.tm_isdst = -1; const auto c = std::mktime(&t); CHECK_EQ(c, date); } TEST_CASE("testing toml::get(offset_datetime)") { using value_type = toml::value; { value_type v1(toml::offset_datetime( toml::local_date{2018, toml::month_t::Apr, 1}, toml::local_time{12, 30, 0}, toml::time_offset{9, 0})); // 2018-04-01T12:30:00+09:00 // == 2018-04-01T03:30:00Z const auto date = toml::get(v1); const auto timet = std::chrono::system_clock::to_time_t(date); // get time_t as gmtime (2018-04-01T03:30:00Z) const auto tm = toml::detail::gmtime_s(std::addressof(timet)); CHECK_EQ(tm.tm_year + 1900, 2018); CHECK_EQ(tm.tm_mon + 1, 4); CHECK_EQ(tm.tm_mday, 1); CHECK_EQ(tm.tm_hour, 3); CHECK_EQ(tm.tm_min, 30); CHECK_EQ(tm.tm_sec, 0); } { value_type v1(toml::offset_datetime( toml::local_date{2018, toml::month_t::Apr, 1}, toml::local_time{12, 30, 0}, toml::time_offset{-8, 0})); // 2018-04-01T12:30:00-08:00 //, 2018-04-01T20:30:00Z const auto date = toml::get(v1); const auto timet = std::chrono::system_clock::to_time_t(date); // get time_t as gmtime (2018-04-01T03:30:00Z) const auto tm = toml::detail::gmtime_s(std::addressof(timet)); CHECK_EQ(tm.tm_year + 1900, 2018); CHECK_EQ(tm.tm_mon + 1, 4); CHECK_EQ(tm.tm_mday, 1); CHECK_EQ(tm.tm_hour, 20); CHECK_EQ(tm.tm_min, 30); CHECK_EQ(tm.tm_sec, 0); } }