diff options
Diffstat (limited to 'nihil.ucl/tests')
| -rw-r--r-- | nihil.ucl/tests/array.cc | 78 | ||||
| -rw-r--r-- | nihil.ucl/tests/boolean.cc | 62 | ||||
| -rw-r--r-- | nihil.ucl/tests/integer.cc | 65 | ||||
| -rw-r--r-- | nihil.ucl/tests/map.cc | 58 | ||||
| -rw-r--r-- | nihil.ucl/tests/real.cc | 32 | ||||
| -rw-r--r-- | nihil.ucl/tests/string.cc | 93 |
6 files changed, 367 insertions, 21 deletions
diff --git a/nihil.ucl/tests/array.cc b/nihil.ucl/tests/array.cc index 023b3bf..ce0976f 100644 --- a/nihil.ucl/tests/array.cc +++ b/nihil.ucl/tests/array.cc @@ -3,14 +3,36 @@ */ #include <algorithm> +#include <concepts> #include <ranges> #include <string> #include <catch2/catch_test_macros.hpp> +#include <ucl.h> import nihil.ucl; -TEST_CASE("ucl: array: construct", "[ucl]") +TEST_CASE("ucl: array: invariants", "[ucl]") +{ + using namespace nihil::ucl; + + REQUIRE(array<>::ucl_type == object_type::array); + REQUIRE(static_cast<::ucl_type>(array<>::ucl_type) == UCL_ARRAY); + + static_assert(std::destructible<array<>>); + static_assert(std::default_initializable<array<>>); + static_assert(std::move_constructible<array<>>); + static_assert(std::copy_constructible<array<>>); + static_assert(std::equality_comparable<array<>>); + static_assert(std::totally_ordered<array<>>); + static_assert(std::swappable<array<>>); + + static_assert(std::ranges::sized_range<array<integer>>); + static_assert(std::same_as<std::ranges::range_value_t<array<integer>>, + integer>); +} + +TEST_CASE("ucl: array: default construct", "[ucl]") { using namespace nihil::ucl; @@ -19,6 +41,42 @@ TEST_CASE("ucl: array: construct", "[ucl]") REQUIRE(str(arr.type()) == "array"); } +TEST_CASE("ucl: array: construct from range", "[ucl]") +{ + using namespace nihil::ucl; + + auto vec = std::vector{integer(1), integer(42)}; + auto arr = array<integer>(std::from_range, vec); + + REQUIRE(arr.size() == 2); + REQUIRE(arr[0] == 1); + REQUIRE(arr[1] == 42); +} + +TEST_CASE("ucl: array: construct from iterator pair", "[ucl]") +{ + using namespace nihil::ucl; + + auto vec = std::vector{integer(1), integer(42)}; + auto arr = array<integer>(std::ranges::begin(vec), + std::ranges::end(vec)); + + REQUIRE(arr.size() == 2); + REQUIRE(arr[0] == 1); + REQUIRE(arr[1] == 42); +} + +TEST_CASE("ucl: array: construct from initializer_list", "[ucl]") +{ + using namespace nihil::ucl; + + auto arr = array<integer>{integer(1), integer(42)}; + + REQUIRE(arr.size() == 2); + REQUIRE(arr[0] == 1); + REQUIRE(arr[1] == 42); +} + TEST_CASE("ucl: array: push_back", "[ucl]") { using namespace nihil::ucl; @@ -45,10 +103,9 @@ TEST_CASE("ucl: array: compare", "[ucl]") { using namespace nihil::ucl; - auto arr = array<integer>(); - arr.push_back(integer(1)); - arr.push_back(integer(42)); - arr.push_back(integer(666)); + auto arr = array<integer>{ + integer(1), integer(42), integer(666) + }; auto arr2 = array<integer>(); REQUIRE(arr != arr2); @@ -58,10 +115,10 @@ TEST_CASE("ucl: array: compare", "[ucl]") arr2.push_back(integer(666)); REQUIRE(arr == arr2); - auto arr3 = array<integer>(); - arr3.push_back(integer(1)); - arr3.push_back(integer(1)); - arr3.push_back(integer(1)); + auto arr3 = array<integer>{ + integer(1), integer(1), integer(1) + }; + REQUIRE(arr != arr3); } @@ -124,7 +181,6 @@ TEST_CASE("ucl: array is a sized_range", "[ucl]") using namespace nihil::ucl; auto arr = array<integer>{integer(1), integer(42), integer(666)}; - static_assert(std::ranges::sized_range<decltype(arr)>); auto size = std::ranges::size(arr); REQUIRE(size == 3); @@ -143,7 +199,7 @@ TEST_CASE("ucl: array is a sized_range", "[ucl]") auto arr_as_ints = arr | std::views::transform(&integer::value); - auto int_vec = std::vector<integer::value_type>(); + auto int_vec = std::vector<integer::contained_type>(); std::ranges::copy(arr_as_ints, std::back_inserter(int_vec)); REQUIRE(int_vec == std::vector<std::int64_t>{1, 42, 666}); diff --git a/nihil.ucl/tests/boolean.cc b/nihil.ucl/tests/boolean.cc index ed5e1d7..49dc408 100644 --- a/nihil.ucl/tests/boolean.cc +++ b/nihil.ucl/tests/boolean.cc @@ -2,16 +2,29 @@ * This source code is released into the public domain. */ +#include <concepts> #include <string> #include <catch2/catch_test_macros.hpp> +#include <ucl.h> import nihil.ucl; -TEST_CASE("ucl: boolean: construct", "[ucl]") +TEST_CASE("ucl: boolean: invariants", "[ucl]") { - auto b = nihil::ucl::boolean(true); - REQUIRE(b == true); + using namespace nihil::ucl; + + static_assert(std::same_as<bool, boolean::contained_type>); + REQUIRE(boolean::ucl_type == object_type::boolean); + REQUIRE(static_cast<::ucl_type>(boolean::ucl_type) == UCL_BOOLEAN); + + static_assert(std::destructible<boolean>); + static_assert(std::default_initializable<boolean>); + static_assert(std::move_constructible<boolean>); + static_assert(std::copy_constructible<boolean>); + static_assert(std::equality_comparable<boolean>); + static_assert(std::totally_ordered<boolean>); + static_assert(std::swappable<boolean>); } TEST_CASE("ucl: boolean: default construct", "[ucl]") @@ -20,6 +33,42 @@ TEST_CASE("ucl: boolean: default construct", "[ucl]") REQUIRE(b == false); } +TEST_CASE("ucl: boolean: construct from value", "[ucl]") +{ + auto b = nihil::ucl::boolean(true); + REQUIRE(b == true); +} + +TEST_CASE("ucl: boolean: swap", "[ucl]") +{ + // do not add using namespace nihil::ucl + + auto b1 = nihil::ucl::boolean(true); + auto b2 = nihil::ucl::boolean(false); + + swap(b1, b2); + + REQUIRE(b1 == false); + REQUIRE(b2 == true); +} + +TEST_CASE("ucl: boolean: value()", "[ucl]") +{ + auto b = nihil::ucl::boolean(true); + REQUIRE(b.value() == true); +} + +TEST_CASE("ucl: boolean: key()", "[ucl]") +{ + using namespace nihil::ucl; + + auto obj = parse("a_bool = true"); + REQUIRE(object_cast<boolean>(obj["a_bool"]).key() == "a_bool"); + + auto b = nihil::ucl::boolean(true); + REQUIRE(b.key() == ""); +} + TEST_CASE("ucl: boolean: operator==", "[ucl]") { auto b = nihil::ucl::boolean(true); @@ -54,6 +103,13 @@ TEST_CASE("ucl: boolean: parse", "[ucl]") TEST_CASE("ucl: boolean: emit", "[ucl]") { + auto b = nihil::ucl::boolean(true); + auto str = std::format("{}", b); + REQUIRE(str == "true"); +} + +TEST_CASE("ucl: boolean: parse and emit", "[ucl]") +{ auto ucl = nihil::ucl::parse("bool = true;"); auto output = std::string(); diff --git a/nihil.ucl/tests/integer.cc b/nihil.ucl/tests/integer.cc index ad513ca..811a864 100644 --- a/nihil.ucl/tests/integer.cc +++ b/nihil.ucl/tests/integer.cc @@ -2,16 +2,30 @@ * This source code is released into the public domain. */ +#include <concepts> +#include <cstdint> #include <string> #include <catch2/catch_test_macros.hpp> +#include <ucl.h> import nihil.ucl; -TEST_CASE("ucl: integer: construct", "[ucl]") +TEST_CASE("ucl: integer: invariants", "[ucl]") { - auto i = nihil::ucl::integer(42); - REQUIRE(i == 42); + using namespace nihil::ucl; + + static_assert(std::same_as<std::int64_t, integer::contained_type>); + REQUIRE(integer::ucl_type == object_type::integer); + REQUIRE(static_cast<::ucl_type>(integer::ucl_type) == UCL_INT); + + static_assert(std::destructible<integer>); + static_assert(std::default_initializable<integer>); + static_assert(std::move_constructible<integer>); + static_assert(std::copy_constructible<integer>); + static_assert(std::equality_comparable<integer>); + static_assert(std::totally_ordered<integer>); + static_assert(std::swappable<integer>); } TEST_CASE("ucl: integer: default construct", "[ucl]") @@ -20,6 +34,42 @@ TEST_CASE("ucl: integer: default construct", "[ucl]") REQUIRE(i == 0); } +TEST_CASE("ucl: integer: construct", "[ucl]") +{ + auto i = nihil::ucl::integer(42); + REQUIRE(i == 42); +} + +TEST_CASE("ucl: integer: swap", "[ucl]") +{ + // do not add using namespace nihil::ucl + + auto i1 = nihil::ucl::integer(1); + auto i2 = nihil::ucl::integer(2); + + swap(i1, i2); + + REQUIRE(i1 == 2); + REQUIRE(i2 == 1); +} + +TEST_CASE("ucl: integer: value()", "[ucl]") +{ + auto i = nihil::ucl::integer(42); + REQUIRE(i.value() == 42); +} + +TEST_CASE("ucl: integer: key()", "[ucl]") +{ + using namespace nihil::ucl; + + auto obj = parse("an_int = 42"); + REQUIRE(object_cast<integer>(obj["an_int"]).key() == "an_int"); + + auto i = nihil::ucl::integer(42); + REQUIRE(i.key() == ""); +} + TEST_CASE("ucl: integer: operator==", "[ucl]") { auto i = nihil::ucl::integer(42); @@ -42,7 +92,7 @@ TEST_CASE("ucl: integer: operator<=>", "[ucl]") REQUIRE(i > nihil::ucl::integer(1)); } -TEST_CASE("ucl: parse: integer", "[ucl]") +TEST_CASE("ucl: integer: parse", "[ucl]") { using namespace std::literals; @@ -54,6 +104,13 @@ TEST_CASE("ucl: parse: integer", "[ucl]") TEST_CASE("ucl: integer: emit", "[ucl]") { + auto i = nihil::ucl::integer(42); + auto str = std::format("{}", i); + REQUIRE(str == "42"); +} + +TEST_CASE("ucl: integer: parse and emit", "[ucl]") +{ auto ucl = nihil::ucl::parse("int = 42;"); auto output = std::string(); diff --git a/nihil.ucl/tests/map.cc b/nihil.ucl/tests/map.cc index d106c79..5d2fbe1 100644 --- a/nihil.ucl/tests/map.cc +++ b/nihil.ucl/tests/map.cc @@ -2,10 +2,33 @@ * This source code is released into the public domain. */ +#include <concepts> + #include <catch2/catch_test_macros.hpp> +#include <ucl.h> import nihil.ucl; +TEST_CASE("ucl: map: invariants", "[ucl]") +{ + using namespace nihil::ucl; + + REQUIRE(map<>::ucl_type == object_type::object); + REQUIRE(static_cast<::ucl_type>(map<>::ucl_type) == UCL_OBJECT); + + static_assert(std::destructible<map<>>); + static_assert(std::default_initializable<map<>>); + static_assert(std::move_constructible<map<>>); + static_assert(std::copy_constructible<map<>>); + static_assert(std::equality_comparable<map<>>); + static_assert(std::totally_ordered<map<>>); + static_assert(std::swappable<map<>>); + + static_assert(std::ranges::range<map<integer>>); + static_assert(std::same_as<std::pair<std::string_view, integer>, + std::ranges::range_value_t<map<integer>>>); +} + TEST_CASE("ucl: map: default construct", "[ucl]") { auto map = nihil::ucl::map<>(); @@ -27,6 +50,41 @@ TEST_CASE("ucl: map: construct from initializer_list", "[ucl]") REQUIRE(map["42"] == 42); } +TEST_CASE("ucl: map: construct from range", "[ucl]") +{ + using namespace nihil::ucl; + using namespace std::literals; + + auto vec = std::vector<std::pair<std::string_view, integer>>{ + {"1"sv, integer(1)}, + {"42"sv, integer(42)}, + }; + + auto map = nihil::ucl::map<integer>(std::from_range, vec); + + REQUIRE(str(map.type()) == "object"); + REQUIRE(map["1"] == 1); + REQUIRE(map["42"] == 42); +} + +TEST_CASE("ucl: map: construct from iterator pair", "[ucl]") +{ + using namespace nihil::ucl; + using namespace std::literals; + + auto vec = std::vector<std::pair<std::string_view, integer>>{ + {"1"sv, integer(1)}, + {"42"sv, integer(42)}, + }; + + auto map = nihil::ucl::map<integer>(std::ranges::begin(vec), + std::ranges::end(vec)); + + REQUIRE(str(map.type()) == "object"); + REQUIRE(map["1"] == 1); + REQUIRE(map["42"] == 42); +} + TEST_CASE("ucl: map: insert", "[ucl]") { using namespace nihil::ucl; diff --git a/nihil.ucl/tests/real.cc b/nihil.ucl/tests/real.cc index 4bd9b3f..b11c113 100644 --- a/nihil.ucl/tests/real.cc +++ b/nihil.ucl/tests/real.cc @@ -2,13 +2,32 @@ * This source code is released into the public domain. */ +#include <concepts> #include <string> #include <catch2/catch_test_macros.hpp> #include <catch2/matchers/catch_matchers_floating_point.hpp> +#include <ucl.h> import nihil.ucl; +TEST_CASE("ucl: real: invariants", "[ucl]") +{ + using namespace nihil::ucl; + + static_assert(std::same_as<double, real::contained_type>); + REQUIRE(real::ucl_type == object_type::real); + REQUIRE(static_cast<::ucl_type>(real::ucl_type) == UCL_FLOAT); + + static_assert(std::destructible<real>); + static_assert(std::default_initializable<real>); + static_assert(std::move_constructible<real>); + static_assert(std::copy_constructible<real>); + static_assert(std::equality_comparable<real>); + static_assert(std::totally_ordered<real>); + static_assert(std::swappable<real>); +} + TEST_CASE("ucl: real: construct", "[ucl]") { auto obj = nihil::ucl::real(42.1); @@ -22,6 +41,19 @@ TEST_CASE("ucl: real: default construct", "[ucl]") REQUIRE(i == 0); } +TEST_CASE("ucl: real: swap", "[ucl]") +{ + // do not add using namespace nihil::ucl + + auto r1 = nihil::ucl::real(1); + auto r2 = nihil::ucl::real(2); + + swap(r1, r2); + + REQUIRE(r1 == 2.); + REQUIRE(r2 == 1.); +} + TEST_CASE("ucl: real: operator==", "[ucl]") { auto i = nihil::ucl::real(42.5); diff --git a/nihil.ucl/tests/string.cc b/nihil.ucl/tests/string.cc index 19052cd..e7eb0ad 100644 --- a/nihil.ucl/tests/string.cc +++ b/nihil.ucl/tests/string.cc @@ -2,6 +2,7 @@ * This source code is released into the public domain. */ +#include <concepts> #include <list> #include <string> #include <vector> @@ -15,9 +16,20 @@ TEST_CASE("ucl: string: invariants", "[ucl]") { using namespace nihil::ucl; - static_assert(std::same_as<std::string_view, string::value_type>); + static_assert(std::same_as<std::string_view, string::contained_type>); REQUIRE(string::ucl_type == object_type::string); REQUIRE(static_cast<::ucl_type>(string::ucl_type) == UCL_STRING); + + static_assert(std::destructible<string>); + static_assert(std::default_initializable<string>); + static_assert(std::move_constructible<string>); + static_assert(std::copy_constructible<string>); + static_assert(std::equality_comparable<string>); + static_assert(std::totally_ordered<string>); + static_assert(std::swappable<string>); + + static_assert(std::ranges::contiguous_range<string>); + static_assert(std::same_as<char, std::ranges::range_value_t<string>>); } TEST_CASE("ucl: string: default construct", "[ucl]") @@ -74,6 +86,74 @@ TEST_CASE("ucl: string: construct from non-contiguous iterator", "[ucl]") REQUIRE(str == "testing"); } +TEST_CASE("ucl: string: swap", "[ucl]") +{ + // do not add using namespace nihil::ucl + + auto s1 = nihil::ucl::string("one"); + auto s2 = nihil::ucl::string("two"); + + swap(s1, s2); + + REQUIRE(s1 == "two"); + REQUIRE(s2 == "one"); +} + +TEST_CASE("ucl: string: value()", "[ucl]") +{ + auto s = nihil::ucl::string("te\"st"); + REQUIRE(s.value() == "te\"st"); +} + +TEST_CASE("ucl: string: key()", "[ucl]") +{ + using namespace nihil::ucl; + + auto obj = parse("a_string = \"test\""); + REQUIRE(object_cast<string>(obj["a_string"]).key() == "a_string"); + + auto s = nihil::ucl::string("test"); + REQUIRE(s.key() == ""); +} + +TEST_CASE("ucl: string: size", "[ucl]") +{ + using namespace nihil::ucl; + + REQUIRE(string().size() == 0); + REQUIRE(string("test").size() == 4); +} + +TEST_CASE("ucl: string: empty", "[ucl]") +{ + using namespace nihil::ucl; + + REQUIRE(string().empty() == true); + REQUIRE(string("test").empty() == false); +} + +TEST_CASE("ucl: string: iterator", "[ucl]") +{ + auto str = nihil::ucl::string("test"); + + auto begin = std::ranges::begin(str); + static_assert(std::contiguous_iterator<decltype(begin)>); + + auto end = std::ranges::end(str); + static_assert(std::sentinel_for<decltype(end), decltype(begin)>); + + REQUIRE(*begin == 't'); + ++begin; + REQUIRE(*begin == 'e'); + ++begin; + REQUIRE(*begin == 's'); + ++begin; + REQUIRE(*begin == 't'); + ++begin; + + REQUIRE(begin == end); +} + TEST_CASE("ucl: string: operator==", "[ucl]") { auto str = nihil::ucl::string("testing"); @@ -108,14 +188,21 @@ TEST_CASE("ucl: string: parse", "[ucl]") { using namespace std::literals; - auto obj = nihil::ucl::parse("value = \"str\""sv); + auto obj = nihil::ucl::parse("value = \"te\\\"st\""sv); auto v = obj["value"]; REQUIRE(v.key() == "value"); - REQUIRE(object_cast<nihil::ucl::string>(v) == "str"); + REQUIRE(object_cast<nihil::ucl::string>(v) == "te\"st"); } TEST_CASE("ucl: string: emit", "[ucl]") { + auto s = nihil::ucl::string("te\"st"); + auto str = std::format("{}", s); + REQUIRE(str == "\"te\\\"st\""); +} + +TEST_CASE("ucl: string: parse and emit", "[ucl]") +{ auto ucl = nihil::ucl::parse("str = \"te\\\"st\";"); auto output = std::string(); |
