diff options
Diffstat (limited to 'nihil.ucl/tests')
| -rw-r--r-- | nihil.ucl/tests/CMakeLists.txt | 20 | ||||
| -rw-r--r-- | nihil.ucl/tests/array.cc | 478 | ||||
| -rw-r--r-- | nihil.ucl/tests/boolean.cc | 224 | ||||
| -rw-r--r-- | nihil.ucl/tests/emit.cc | 93 | ||||
| -rw-r--r-- | nihil.ucl/tests/integer.cc | 247 | ||||
| -rw-r--r-- | nihil.ucl/tests/map.cc | 192 | ||||
| -rw-r--r-- | nihil.ucl/tests/object.cc | 44 | ||||
| -rw-r--r-- | nihil.ucl/tests/parse.cc | 55 | ||||
| -rw-r--r-- | nihil.ucl/tests/real.cc | 248 | ||||
| -rw-r--r-- | nihil.ucl/tests/string.cc | 415 |
10 files changed, 0 insertions, 2016 deletions
diff --git a/nihil.ucl/tests/CMakeLists.txt b/nihil.ucl/tests/CMakeLists.txt deleted file mode 100644 index 13f30fa..0000000 --- a/nihil.ucl/tests/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# This source code is released into the public domain. - -add_executable(nihil.ucl.test - emit.cc - parse.cc - - object.cc - array.cc - boolean.cc - integer.cc - map.cc - real.cc - string.cc -) - -target_link_libraries(nihil.ucl.test PRIVATE nihil.ucl Catch2::Catch2WithMain) - -include(CTest) -include(Catch) -catch_discover_tests(nihil.ucl.test) diff --git a/nihil.ucl/tests/array.cc b/nihil.ucl/tests/array.cc deleted file mode 100644 index 866fa45..0000000 --- a/nihil.ucl/tests/array.cc +++ /dev/null @@ -1,478 +0,0 @@ -/* - * This source code is released into the public domain. - */ - -#include <algorithm> -#include <concepts> -#include <expected> -#include <ranges> -#include <string> - -#include <catch2/catch_test_macros.hpp> -#include <ucl.h> - -import nihil.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: constructor", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("default") { - auto arr = array<integer>(); - REQUIRE(arr.size() == 0); - REQUIRE(str(arr.type()) == "array"); - } - - SECTION("from range") { - 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); - } - - SECTION("from iterator pair") { - 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); - } - - SECTION("from initializer_list") { - auto arr = array<integer>{integer(1), integer(42)}; - - REQUIRE(arr.size() == 2); - REQUIRE(arr[0] == 1); - REQUIRE(arr[1] == 42); - } -} - -TEST_CASE("ucl: array: construct from UCL object", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("ref, correct type") { - auto uarr = ::ucl_object_typed_new(UCL_ARRAY); - auto uint = ::ucl_object_fromint(42); - ::ucl_array_append(uarr, uint); - - auto arr = array<integer>(ref, uarr); - REQUIRE(arr[0] == 42); - - ::ucl_object_unref(uarr); - } - - SECTION("noref, correct type") { - auto uarr = ::ucl_object_typed_new(UCL_ARRAY); - auto uint = ::ucl_object_fromint(42); - ::ucl_array_append(uarr, uint); - - auto arr = array<integer>(noref, uarr); - REQUIRE(arr[0] == 42); - } - - SECTION("ref, wrong element type") { - auto uarr = ::ucl_object_typed_new(UCL_ARRAY); - auto uint = ::ucl_object_frombool(true); - ::ucl_array_append(uarr, uint); - - auto arr = array<integer>(noref, uarr); - REQUIRE_THROWS_AS(arr[0], type_mismatch); - } - - SECTION("ref, wrong type") { - auto uobj = ::ucl_object_frombool(true); - - REQUIRE_THROWS_AS(array(ref, uobj), type_mismatch); - - ::ucl_object_unref(uobj); - } - - SECTION("noref, wrong type") { - auto uobj = ::ucl_object_frombool(true); - - REQUIRE_THROWS_AS(array(noref, uobj), type_mismatch); - - ::ucl_object_unref(uobj); - } -} - -TEST_CASE("ucl: array: swap", "[ucl]") -{ - // do not add using namespace nihil::ucl - - auto arr1 = nihil::ucl::array<nihil::ucl::integer>{ - nihil::ucl::integer(1), - nihil::ucl::integer(2) - }; - - auto arr2 = nihil::ucl::array<nihil::ucl::integer>{ - nihil::ucl::integer(3), - }; - - swap(arr1, arr2); - - REQUIRE(arr1.size() == 1); - REQUIRE(arr1[0] == 3); - - REQUIRE(arr2.size() == 2); - REQUIRE(arr2[0] == 1); -} - -TEST_CASE("ucl: array: push_back", "[ucl]") -{ - using namespace nihil::ucl; - - auto arr = array<integer>(); - REQUIRE(arr.size() == 0); - - arr.push_back(integer(1)); - arr.push_back(integer(42)); - arr.push_back(integer(666)); - - REQUIRE(arr.size() == 3); - REQUIRE(arr[0] == 1); - REQUIRE(arr[1] == 42); - REQUIRE(arr[2] == 666); - - REQUIRE_THROWS_AS(arr[3], std::out_of_range); - - REQUIRE(arr.front() == 1); - REQUIRE(arr.back() == 666); -} - -TEST_CASE("ucl: array: compare", "[ucl]") -{ - using namespace nihil::ucl; - - auto arr = array<integer>{ - integer(1), integer(42), integer(666) - }; - - auto arr2 = array<integer>(); - REQUIRE(arr != arr2); - - arr2.push_back(integer(1)); - arr2.push_back(integer(42)); - arr2.push_back(integer(666)); - REQUIRE(arr == arr2); - - auto arr3 = array<integer>{ - integer(1), integer(1), integer(1) - }; - - REQUIRE(arr != arr3); -} - -TEST_CASE("ucl: array: iterator", "[ucl]") -{ - using namespace nihil::ucl; - - auto arr = array<integer>{integer(1), integer(42), integer(666)}; - - auto it = arr.begin(); - REQUIRE(*it == 1); - auto end = arr.end(); - REQUIRE(it != end); - REQUIRE(it < end); - - ++it; - REQUIRE(*it == 42); - - ++it; - REQUIRE(*it == 666); - - --it; - REQUIRE(*it == 42); - - ++it; - REQUIRE(it != end); - ++it; - REQUIRE(it == end); -} - -TEST_CASE("ucl: array: parse", "[ucl]") -{ - using namespace std::literals; - using namespace nihil::ucl; - - auto obj = parse("value = [1, 42, 666]"sv).value(); - - auto arr = object_cast<array<integer>>(obj["value"]).value(); - - REQUIRE(arr.size() == 3); - REQUIRE(arr[0] == 1); - REQUIRE(arr[1] == 42); - REQUIRE(arr[2] == 666); -} - -TEST_CASE("ucl: array: emit", "[ucl]") -{ - using namespace nihil::ucl; - - auto ucl = parse("array = [1, 42, 666];").value(); - - auto output = std::format("{:c}", ucl); - REQUIRE(output == -"array [\n" -" 1,\n" -" 42,\n" -" 666,\n" -"]\n"); -} - -TEST_CASE("ucl: array: format", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("empty array") { - auto arr = array<integer>(); - REQUIRE(std::format("{}", arr) == "[]"); - } - - SECTION("bare array") { - auto arr = array<integer>{ - integer(1), integer(42), integer(666) - }; - - auto output = std::format("{}", arr); - REQUIRE(output == "[1, 42, 666]"); - } - - SECTION("parsed array") { - auto ucl = parse("array = [1, 42, 666];").value(); - auto arr = object_cast<array<integer>>(ucl["array"]).value(); - - auto output = std::format("{}", arr); - REQUIRE(output == "[1, 42, 666]"); - } -} - -TEST_CASE("ucl: array: print to ostream", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("empty array") { - auto arr = array<integer>(); - auto strm = std::ostringstream(); - strm << arr; - - REQUIRE(strm.str() == "[]"); - } - - SECTION("bare array") { - auto arr = array<integer>{ - integer(1), integer(42), integer(666) - }; - auto strm = std::ostringstream(); - strm << arr; - - REQUIRE(strm.str() == "[1, 42, 666]"); - } - - SECTION("parsed array") { - auto ucl = parse("array = [1, 42, 666];").value(); - auto arr = object_cast<array<integer>>(ucl["array"]).value(); - auto strm = std::ostringstream(); - strm << arr; - - REQUIRE(strm.str() == "[1, 42, 666]"); - } -} - -TEST_CASE("ucl: array is a sized_range", "[ucl]") -{ - using namespace nihil::ucl; - - auto arr = array<integer>{integer(1), integer(42), integer(666)}; - - auto size = std::ranges::size(arr); - REQUIRE(size == 3); - - auto begin = std::ranges::begin(arr); - static_assert(std::random_access_iterator<decltype(begin)>); - - auto end = std::ranges::end(arr); - static_assert(std::sentinel_for<decltype(end), decltype(begin)>); - - REQUIRE(std::distance(begin, end) == 3); - - auto vec = std::vector<integer>(); - std::ranges::copy(arr, std::back_inserter(vec)); - REQUIRE(std::ranges::equal(arr, vec)); - - auto arr_as_ints = - arr | std::views::transform(&integer::value); - 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}); - -} - -TEST_CASE("ucl: array: bad object_cast", "[ucl]") -{ - using namespace nihil::ucl; - - auto arr = array<integer>(); - - auto cast_ok = object_cast<integer>(arr); - REQUIRE(!cast_ok); -} - -TEST_CASE("ucl: array: heterogeneous elements", "[ucl]") -{ - using namespace std::literals; - using namespace nihil::ucl; - - auto obj_err = parse("array [ 42, true, \"test\" ];"); - REQUIRE(obj_err); - auto obj = *obj_err; - - auto err = object_cast<array<>>(obj["array"]); - REQUIRE(err); - - auto arr = *err; - REQUIRE(arr.size() == 3); - - auto int_obj = object_cast<integer>(arr[0]); - REQUIRE(int_obj); - REQUIRE(*int_obj == 42); - - auto bool_obj = object_cast<boolean>(arr[1]); - REQUIRE(bool_obj); - REQUIRE(*bool_obj == true); - - auto string_obj = object_cast<string>(arr[2]); - REQUIRE(string_obj); - REQUIRE(*string_obj == "test"); -} - -TEST_CASE("ucl: array: heterogenous cast", "[ucl]") -{ - using namespace nihil::ucl; - - auto arr = array<>(); - arr.push_back(integer(42)); - arr.push_back(boolean(true)); - - // Converting to an array<integer> should fail. - auto cast_ok = object_cast<array<integer>>(arr); - REQUIRE(!cast_ok); - - // Converting to array<object> should succeed. - auto err = object_cast<array<object>>(arr); - REQUIRE(err); - - auto obj_arr = *err; - REQUIRE(obj_arr[0] == integer(42)); -} - -TEST_CASE("ucl: array: homogeneous cast", "[ucl]") -{ - using namespace nihil::ucl; - - auto arr = array<>(); - arr.push_back(integer(1)); - arr.push_back(integer(42)); - - auto obj = object(ref, arr.get_ucl_object()); - - // Converting to array<string> should fail. - auto cast_ok = object_cast<array<string>>(obj); - REQUIRE(!cast_ok); - - // Converting to an array<integer> should succeed. - auto err = object_cast<array<integer>>(obj); - REQUIRE(err); - - auto obj_arr = *err; - REQUIRE(obj_arr[0] == 1); - REQUIRE(obj_arr[1] == 42); -} - -TEST_CASE("array iterator: empty iterator", "[ucl]") -{ - using namespace nihil::ucl; - - auto it = array_iterator<integer>(); - - REQUIRE_THROWS_AS(*it, std::logic_error); - REQUIRE_THROWS_AS(it[0], std::logic_error); - REQUIRE_THROWS_AS(it++, std::logic_error); - REQUIRE_THROWS_AS(++it, std::logic_error); - - auto it2 = array_iterator<integer>(); - REQUIRE(it == it2); - REQUIRE((it < it2) == false); - REQUIRE((it > it2) == false); -} - -TEST_CASE("array iterator: invalid operations", "[ucl]") -{ - using namespace nihil::ucl; - - auto arr = array<integer>{ integer(42) }; - auto it = arr.begin(); - - SECTION("decrement before start") { - REQUIRE_THROWS_AS(--it, std::logic_error); - REQUIRE_THROWS_AS(it--, std::logic_error); - REQUIRE_THROWS_AS(it - 1, std::logic_error); - } - - SECTION("increment past end") { - ++it; - REQUIRE(it == arr.end()); - - REQUIRE_THROWS_AS(++it, std::logic_error); - REQUIRE_THROWS_AS(it++, std::logic_error); - REQUIRE_THROWS_AS(it + 1, std::logic_error); - } - - SECTION("dereference iterator at end") { - REQUIRE_THROWS_AS(it[1], std::logic_error); - - ++it; - REQUIRE(it == arr.end()); - - REQUIRE_THROWS_AS(*it, std::logic_error); - } - - SECTION("compare with different array") { - auto arr2 = array<integer>{ integer(42) }; - REQUIRE_THROWS_AS(it == arr2.begin(), std::logic_error); - REQUIRE_THROWS_AS(it > arr2.begin(), std::logic_error); - REQUIRE_THROWS_AS(it - arr2.begin(), std::logic_error); - } - - SECTION("compare with empty iterator") { - auto it2 = array_iterator<integer>(); - REQUIRE_THROWS_AS(it == it2, std::logic_error); - REQUIRE_THROWS_AS(it > it2, std::logic_error); - REQUIRE_THROWS_AS(it - it2, std::logic_error); - } -} diff --git a/nihil.ucl/tests/boolean.cc b/nihil.ucl/tests/boolean.cc deleted file mode 100644 index f7ef95e..0000000 --- a/nihil.ucl/tests/boolean.cc +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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: invariants", "[ucl]") -{ - 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: constructor", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("default") { - auto b = boolean(); - REQUIRE(b == false); - } - - SECTION("with value") { - auto b = boolean(true); - REQUIRE(b == true); - } -} - -TEST_CASE("ucl: boolean: construct from UCL object", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("ref, correct type") { - auto uobj = ::ucl_object_frombool(true); - - auto i = boolean(ref, uobj); - REQUIRE(i == true); - - ::ucl_object_unref(uobj); - } - - SECTION("noref, correct type") { - auto uobj = ::ucl_object_frombool(true); - - auto i = boolean(noref, uobj); - REQUIRE(i == true); - } - - SECTION("ref, wrong type") { - auto uobj = ::ucl_object_fromint(1); - - REQUIRE_THROWS_AS(boolean(ref, uobj), type_mismatch); - - ::ucl_object_unref(uobj); - } - - SECTION("noref, wrong type") { - auto uobj = ::ucl_object_fromint(1); - - REQUIRE_THROWS_AS(boolean(noref, uobj), type_mismatch); - - ::ucl_object_unref(uobj); - } -} - -TEST_CASE("ucl: boolean: make_boolean", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("default value") { - auto b = make_boolean().value(); - REQUIRE(b == false); - } - - SECTION("explicit value") { - auto b = make_boolean(true).value(); - 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 err = parse("a_bool = true"); - REQUIRE(err); - - auto obj = *err; - REQUIRE(object_cast<boolean>(obj["a_bool"])->key() == "a_bool"); - - auto b = nihil::ucl::boolean(true); - REQUIRE(b.key() == ""); -} - -TEST_CASE("ucl: boolean: comparison", "[ucl]") -{ - using namespace nihil::ucl; - - auto b = boolean(true); - - SECTION("operator==") { - REQUIRE(b == true); - REQUIRE(b == boolean(true)); - } - - SECTION("operator!=") { - REQUIRE(b != false); - REQUIRE(b != boolean(false)); - } - - SECTION("operator<") { - REQUIRE(b <= true); - REQUIRE(b <= nihil::ucl::boolean(true)); - } - - SECTION("operator>") { - REQUIRE(b > false); - REQUIRE(b > nihil::ucl::boolean(false)); - } -} - -TEST_CASE("ucl: boolean: parse", "[ucl]") -{ - using namespace nihil::ucl; - - auto obj = parse("value = true").value(); - - auto v = obj["value"]; - REQUIRE(v.key() == "value"); - REQUIRE(object_cast<boolean>(v).value() == true); -} - -TEST_CASE("ucl: boolean: parse and emit", "[ucl]") -{ - using namespace nihil::ucl; - - auto ucl = parse("bool = true;").value(); - - auto output = std::string(); - emit(ucl, nihil::ucl::emitter::configuration, - std::back_inserter(output)); - - REQUIRE(output == "bool = true;\n"); -} - -TEST_CASE("ucl: boolean: format", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("bare boolean") { - auto str = std::format("{}", boolean(true)); - REQUIRE(str == "true"); - } - - SECTION("parsed boolean") { - auto obj = parse("bool = true;").value(); - auto b = object_cast<boolean>(obj["bool"]).value(); - - auto str = std::format("{}", b); - REQUIRE(str == "true"); - } - - SECTION("with format string") { - auto str = std::format("{: >5}", boolean(true)); - REQUIRE(str == " true"); - } -} - -TEST_CASE("ucl: boolean: print to ostream", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("bare boolean") { - auto strm = std::ostringstream(); - strm << boolean(true); - - REQUIRE(strm.str() == "true"); - } - - SECTION("parsed boolean") { - auto obj = parse("bool = true;").value(); - auto i = object_cast<boolean>(obj["bool"]).value(); - - auto strm = std::ostringstream(); - strm << i; - - REQUIRE(strm.str() == "true"); - } -} diff --git a/nihil.ucl/tests/emit.cc b/nihil.ucl/tests/emit.cc deleted file mode 100644 index a7dcd71..0000000 --- a/nihil.ucl/tests/emit.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This source code is released into the public domain. - */ - -#include <format> -#include <sstream> - -#include <catch2/catch_test_macros.hpp> - -import nihil.ucl; - -TEST_CASE("ucl: emit to std::ostream", "[ucl]") -{ - using namespace std::literals; - - auto obj = nihil::ucl::parse("int = [1, 42, 666]"sv); - REQUIRE(obj); - - auto strm = std::ostringstream(); - strm << *obj; - - // The ostream emitter produces JSON. - REQUIRE(strm.str() == std::format("{:j}", *obj)); -} - -TEST_CASE("ucl: emit JSON with std::format", "[ucl]") -{ - using namespace std::literals; - - auto obj = nihil::ucl::parse("int = [1, 42, 666]"sv); - REQUIRE(obj); - - auto str = std::format("{:j}", *obj); - - REQUIRE(str == -"{\n" -" \"int\": [\n" -" 1,\n" -" 42,\n" -" 666\n" -" ]\n" -"}"); - - // Make sure JSON is the default format. - auto str2 = std::format("{}", *obj); - REQUIRE(str == str2); -} - -TEST_CASE("ucl: emit compact JSON with std::format", "[ucl]") -{ - using namespace std::literals; - - auto obj = nihil::ucl::parse("int = [1, 42, 666]"sv); - REQUIRE(obj); - - auto str = std::format("{:J}", *obj); - - REQUIRE(str == "{\"int\":[1,42,666]}"); -} - -TEST_CASE("ucl: emit configuration with std::format", "[ucl]") -{ - using namespace std::literals; - - auto obj = nihil::ucl::parse("int = [1, 42, 666]"sv); - REQUIRE(obj); - - auto str = std::format("{:c}", *obj); - - REQUIRE(str == -"int [\n" -" 1,\n" -" 42,\n" -" 666,\n" -"]\n"); -} - -TEST_CASE("ucl: emit YAML with std::format", "[ucl]") -{ - using namespace std::literals; - - auto obj = nihil::ucl::parse("int = [1, 42, 666]"sv); - REQUIRE(obj); - - auto str = std::format("{:y}", *obj); - - REQUIRE(str == -"int: [\n" -" 1,\n" -" 42,\n" -" 666\n" -"]"); -} diff --git a/nihil.ucl/tests/integer.cc b/nihil.ucl/tests/integer.cc deleted file mode 100644 index 6584764..0000000 --- a/nihil.ucl/tests/integer.cc +++ /dev/null @@ -1,247 +0,0 @@ -/* - * 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: invariants", "[ucl]") -{ - 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: constructor", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("default") { - auto i = integer(); - REQUIRE(i == 0); - } - - SECTION("with value") { - auto i = integer(42); - REQUIRE(i == 42); - } -} - -TEST_CASE("ucl: integer: literal", "[ucl]") -{ - SECTION("with namespace nihil::ucl::literals") { - using namespace nihil::ucl::literals; - - auto i = 42_ucl; - REQUIRE(i.type() == nihil::ucl::object_type::integer); - REQUIRE(i == 42); - } - - SECTION("with namespace nihil::literals") { - using namespace nihil::literals; - - auto i = 42_ucl; - REQUIRE(i.type() == nihil::ucl::object_type::integer); - REQUIRE(i == 42); - } -} - -TEST_CASE("ucl: integer: construct from UCL object", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("ref, correct type") { - auto uobj = ::ucl_object_fromint(42); - - auto i = integer(ref, uobj); - REQUIRE(i == 42); - - ::ucl_object_unref(uobj); - } - - SECTION("noref, correct type") { - auto uobj = ::ucl_object_fromint(42); - - auto i = integer(noref, uobj); - REQUIRE(i == 42); - } - - SECTION("ref, wrong type") { - auto uobj = ::ucl_object_frombool(true); - - REQUIRE_THROWS_AS(integer(ref, uobj), type_mismatch); - - ::ucl_object_unref(uobj); - } - - SECTION("noref, wrong type") { - auto uobj = ::ucl_object_frombool(true); - - REQUIRE_THROWS_AS(integer(noref, uobj), type_mismatch); - - ::ucl_object_unref(uobj); - } -} - -TEST_CASE("ucl: integer: make_integer", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("default value") { - auto i = make_integer().value(); - REQUIRE(i == 0); - } - - SECTION("explicit value") { - auto i = make_integer(42).value(); - 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]") -{ - using namespace nihil::ucl; - - auto i = 42_ucl; - REQUIRE(i.value() == 42); -} - -TEST_CASE("ucl: integer: key()", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("parsed with key") { - auto obj = parse("an_int = 42").value(); - auto i = object_cast<integer>(obj["an_int"]).value(); - REQUIRE(i.key() == "an_int"); - } - - SECTION("bare integer, no key") { - auto i = 42_ucl; - REQUIRE(i.key() == ""); - } -} - -TEST_CASE("ucl: integer: comparison", "[ucl]") -{ - using namespace nihil::ucl; - - auto i = 42_ucl; - - SECTION("operator==") { - REQUIRE(i == 42); - REQUIRE(i == 42_ucl); - } - - SECTION("operator!=") { - REQUIRE(i != 1); - REQUIRE(i != 1_ucl); - } - - SECTION("operator<") { - REQUIRE(i < 43); - REQUIRE(i < 43_ucl); - } - - SECTION("operator>") { - REQUIRE(i > 1); - REQUIRE(i > 1_ucl); - } -} - -TEST_CASE("ucl: integer: parse", "[ucl]") -{ - using namespace nihil::ucl; - - auto obj = parse("value = 42").value(); - - auto v = obj["value"]; - REQUIRE(v.key() == "value"); - REQUIRE(object_cast<integer>(v) == 42); -} - -TEST_CASE("ucl: integer: parse and emit", "[ucl]") -{ - using namespace nihil::ucl; - - auto ucl = parse("int = 42;").value(); - - auto output = std::string(); - emit(ucl, emitter::configuration, std::back_inserter(output)); - - REQUIRE(output == "int = 42;\n"); -} - -TEST_CASE("ucl: integer: format", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("bare integer") { - auto str = std::format("{}", 42_ucl); - REQUIRE(str == "42"); - } - - SECTION("parsed integer") { - auto obj = parse("int = 42;").value(); - auto i = object_cast<integer>(obj["int"]).value(); - - auto str = std::format("{}", i); - REQUIRE(str == "42"); - } - - SECTION("with format string") { - auto str = std::format("{:-05}", 42_ucl); - REQUIRE(str == "00042"); - } -} - -TEST_CASE("ucl: integer: print to ostream", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("bare integer") { - auto strm = std::ostringstream(); - strm << 42_ucl; - - REQUIRE(strm.str() == "42"); - } - - SECTION("parsed integer") { - auto obj = parse("int = 42;").value(); - auto i = object_cast<integer>(obj["int"]).value(); - - auto strm = std::ostringstream(); - strm << i; - - REQUIRE(strm.str() == "42"); - } -} diff --git a/nihil.ucl/tests/map.cc b/nihil.ucl/tests/map.cc deleted file mode 100644 index 7240cb3..0000000 --- a/nihil.ucl/tests/map.cc +++ /dev/null @@ -1,192 +0,0 @@ -/* - * This source code is released into the public domain. - */ - -#include <concepts> - -#include <catch2/catch_test_macros.hpp> -#include <ucl.h> - -import nihil.ucl; - -//NOLINTBEGIN(bugprone-unchecked-optional-access) - -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<>(); - REQUIRE(str(map.type()) == "object"); -} - -TEST_CASE("ucl: map: construct from initializer_list", "[ucl]") -{ - using namespace nihil::ucl; - using namespace std::literals; - - auto map = nihil::ucl::map<integer>{ - {"1"sv, integer(1)}, - {"42"sv, integer(42)}, - }; - - REQUIRE(str(map.type()) == "object"); - REQUIRE(map["1"] == 1); - 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; - using namespace std::literals; - - auto m = map<integer>(); - - m.insert({"test1"sv, integer(42)}); - m.insert({"test2"sv, integer(666)}); - - REQUIRE(m["test1"] == 42); - REQUIRE(m["test2"] == 666); -} - -TEST_CASE("ucl: map: find", "[ucl]") -{ - using namespace nihil::ucl; - using namespace std::literals; - - auto map = nihil::ucl::map<integer>{ - {"1"sv, integer(1)}, - {"42"sv, integer(42)}, - }; - - auto obj = map.find("42"); - REQUIRE(obj.value() == 42); - - obj = map.find("43"); - REQUIRE(!obj.has_value()); -} - -TEST_CASE("ucl: map: iterate", "[ucl]") -{ - using namespace nihil::ucl; - using namespace std::literals; - - auto map = nihil::ucl::map<integer>{ - {"1"sv, integer(1)}, - {"42"sv, integer(42)}, - }; - - auto i = 0u; - - for (auto [key, value] : map) { - if (key == "1") - REQUIRE(value == 1); - else if (key == "42") - REQUIRE(value == 42); - else - REQUIRE(false); - ++i; - } - - REQUIRE(i == 2); -} - -TEST_CASE("ucl: map: operator[] throws key_not_found", "[ucl]") -{ - auto map = nihil::ucl::map<nihil::ucl::integer>(); - REQUIRE_THROWS_AS(map["nonesuch"], nihil::ucl::key_not_found); -} - -TEST_CASE("ucl: map: remove", "[uc]") -{ - using namespace std::literals; - using namespace nihil::ucl; - - auto map = nihil::ucl::map<integer>{ - {"1"sv, integer(1)}, - {"42"sv, integer(42)}, - }; - - REQUIRE(map.find("42") != std::nullopt); - REQUIRE(map.remove("42") == true); - REQUIRE(map.find("42") == std::nullopt); - REQUIRE(map["1"] == 1); - - REQUIRE(map.remove("42") == false); -} - -TEST_CASE("ucl: map: pop", "[uc]") -{ - using namespace std::literals; - using namespace nihil::ucl; - - auto map = nihil::ucl::map<integer>{ - {"1"sv, integer(1)}, - {"42"sv, integer(42)}, - }; - - REQUIRE(map.find("42") != std::nullopt); - - auto obj = map.pop("42"); - REQUIRE(obj.value() == 42); - - REQUIRE(!map.find("42")); - REQUIRE(map["1"] == 1); - - obj = map.pop("42"); - REQUIRE(!obj); -} - -//NOLINTEND(bugprone-unchecked-optional-access) diff --git a/nihil.ucl/tests/object.cc b/nihil.ucl/tests/object.cc deleted file mode 100644 index 3ad180e..0000000 --- a/nihil.ucl/tests/object.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This source code is released into the public domain. - */ - -#include <catch2/catch_test_macros.hpp> - -#include <ucl.h> - -import nihil.ucl; - -TEST_CASE("ucl object: get_ucl_object", "[ucl]") -{ - auto obj = nihil::ucl::integer(42); - - REQUIRE(obj.get_ucl_object() != nullptr); - static_assert(std::same_as<::ucl_object_t *, - decltype(obj.get_ucl_object())>); - - auto const cobj = obj; - static_assert(std::same_as<::ucl_object_t const *, - decltype(cobj.get_ucl_object())>); -} - -TEST_CASE("ucl object: compare", "[ucl]") -{ - using namespace std::literals; - - auto obj_41 = nihil::ucl::parse("int = 41;"sv); - REQUIRE(obj_41); - - auto obj_42 = nihil::ucl::parse("int = 42;"sv); - REQUIRE(obj_42); - - auto obj_42_2 = nihil::ucl::parse("int = 42;"sv); - REQUIRE(obj_42_2); - - auto obj_43 = nihil::ucl::parse("int = 43;"sv); - REQUIRE(obj_43); - - REQUIRE(*obj_42 == *obj_42_2); - REQUIRE(*obj_42 != *obj_43); - REQUIRE(*obj_42 < *obj_43); - REQUIRE(*obj_42 > *obj_41); -} diff --git a/nihil.ucl/tests/parse.cc b/nihil.ucl/tests/parse.cc deleted file mode 100644 index 43ce219..0000000 --- a/nihil.ucl/tests/parse.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This source code is released into the public domain. - */ - -#include <string> - -#include <catch2/catch_test_macros.hpp> -#include <catch2/matchers/catch_matchers_floating_point.hpp> - -import nihil.ucl; - -TEST_CASE("ucl parse: iterate array", "[ucl]") -{ - using namespace std::literals; - using namespace nihil::ucl; - - auto err = parse("value = [1, 42, 666];"sv); - REQUIRE(err); - - auto obj = *err; - - auto arr = obj["value"]; - REQUIRE(arr.key() == "value"); - - auto ints = object_cast<array<integer>>(arr); - REQUIRE(ints); - - auto vec = std::vector(std::from_range, *ints); - - REQUIRE(vec.size() == 3); - REQUIRE(vec[0] == 1); - REQUIRE(vec[1] == 42); - REQUIRE(vec[2] == 666); -} - -TEST_CASE("ucl parse: iterate hash", "[ucl]") -{ - using namespace std::literals; - using namespace nihil::ucl; - - auto input = "int = 42; bool = true; str = \"test\";"sv; - auto obj = parse(input); - REQUIRE(obj); - - for (auto &&[key, value] : *obj) { - REQUIRE(key == value.key()); - - if (key == "int") - REQUIRE(object_cast<integer>(value) == 42); - else if (key == "bool") - REQUIRE(object_cast<boolean>(value) == true); - else if (key == "str") - REQUIRE(object_cast<string>(value) == "test"); - } -} diff --git a/nihil.ucl/tests/real.cc b/nihil.ucl/tests/real.cc deleted file mode 100644 index 421917e..0000000 --- a/nihil.ucl/tests/real.cc +++ /dev/null @@ -1,248 +0,0 @@ -/* - * 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: constructor", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("default") { - auto r = real(); - REQUIRE(r == 0); - } - - SECTION("with value") { - auto r = real(42.1); - REQUIRE_THAT(r.value(), Catch::Matchers::WithinRel(42.1)); - } -} - -TEST_CASE("ucl: real: literal", "[ucl]") -{ - SECTION("with namespace nihil::ucl::literals") { - using namespace nihil::ucl::literals; - - auto r = 42.5_ucl; - REQUIRE(r.type() == nihil::ucl::object_type::real); - REQUIRE_THAT(r.value(), Catch::Matchers::WithinRel(42.5)); - } - - SECTION("with namespace nihil::literals") { - using namespace nihil::literals; - - auto r = 42.5_ucl; - REQUIRE(r.type() == nihil::ucl::object_type::real); - REQUIRE_THAT(r.value(), Catch::Matchers::WithinRel(42.5)); - } -} - -TEST_CASE("ucl: real: construct from UCL object", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("ref, correct type") { - auto uobj = ::ucl_object_fromdouble(42); - - auto r = real(ref, uobj); - REQUIRE(r == 42); - - ::ucl_object_unref(uobj); - } - - SECTION("noref, correct type") { - auto uobj = ::ucl_object_fromdouble(42); - - auto r = real(noref, uobj); - REQUIRE(r == 42); - } - - SECTION("ref, wrong type") { - auto uobj = ::ucl_object_fromint(42); - - REQUIRE_THROWS_AS(real(ref, uobj), type_mismatch); - - ::ucl_object_unref(uobj); - } - - SECTION("noref, wrong type") { - auto uobj = ::ucl_object_fromint(42); - - REQUIRE_THROWS_AS(real(noref, uobj), type_mismatch); - - ::ucl_object_unref(uobj); - } -} - -TEST_CASE("ucl: real: make_real", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("default value") { - auto i = make_real().value(); - REQUIRE(i == 0); - } - - SECTION("explicit value") { - auto i = make_real(42).value(); - REQUIRE(i == 42); - } -} - -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: value()", "[ucl]") -{ - using namespace nihil::ucl; - - auto r = 42.5_ucl; - REQUIRE_THAT(r.value(), Catch::Matchers::WithinRel(42.5)); -} - -TEST_CASE("ucl: real: key()", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("parsed with key") { - auto obj = parse("a_real = 42.5").value(); - auto r = object_cast<real>(obj["a_real"]).value(); - REQUIRE(r.key() == "a_real"); - } - - SECTION("bare real, no key") { - auto i = 42.5_ucl; - REQUIRE(i.key() == ""); - } -} - -TEST_CASE("ucl: real: comparison", "[ucl]") -{ - using namespace nihil::ucl; - - auto i = nihil::ucl::real(42.5); - - SECTION("operator==") { - REQUIRE(i == 42.5); - REQUIRE(i == 42.5_ucl); - } - - SECTION("operator!=") { - REQUIRE(i != 1); - REQUIRE(i != 1._ucl); - } - - SECTION("operator<") { - REQUIRE(i < 43); - REQUIRE(i < 43._ucl); - } - - SECTION("operator>") { - REQUIRE(i > 1); - REQUIRE(i > 1._ucl); - } -} - -TEST_CASE("ucl: real: parse", "[ucl]") -{ - using namespace nihil::ucl; - - auto obj = parse("value = 42.1").value(); - - auto v = obj["value"]; - REQUIRE(v.key() == "value"); - REQUIRE_THAT(object_cast<real>(v).value().value(), - Catch::Matchers::WithinRel(42.1)); -} - -TEST_CASE("ucl: real: parse and emit", "[ucl]") -{ - using namespace nihil::ucl; - - auto ucl = parse("real = 42.2").value(); - - auto output = std::string(); - emit(ucl, emitter::configuration, std::back_inserter(output)); - - REQUIRE(output == "real = 42.2;\n"); -} - -TEST_CASE("ucl: real: format", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("bare real") { - auto str = std::format("{}", 42.5_ucl); - REQUIRE(str == "42.5"); - } - - SECTION("parsed real") { - auto obj = parse("real = 42.5;").value(); - auto r = object_cast<real>(obj["real"]).value(); - - auto str = std::format("{}", r); - REQUIRE(str == "42.5"); - } - - SECTION("with format string") { - auto str = std::format("{:10.5f}", 42.5_ucl); - REQUIRE(str == " 42.50000"); - } -} - -TEST_CASE("ucl: real: print to ostream", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("bare real") { - auto strm = std::ostringstream(); - strm << 42.5_ucl; - - REQUIRE(strm.str() == "42.5"); - } - - SECTION("parsed real") { - auto obj = parse("real = 42.5;").value(); - auto i = object_cast<real>(obj["real"]).value(); - - auto strm = std::ostringstream(); - strm << i; - - REQUIRE(strm.str() == "42.5"); - } -} diff --git a/nihil.ucl/tests/string.cc b/nihil.ucl/tests/string.cc deleted file mode 100644 index 6409b8d..0000000 --- a/nihil.ucl/tests/string.cc +++ /dev/null @@ -1,415 +0,0 @@ -/* - * This source code is released into the public domain. - */ - -#include <concepts> -#include <list> -#include <sstream> -#include <string> -#include <vector> - -#include <catch2/catch_test_macros.hpp> -#include <ucl.h> - -import nihil.ucl; - -TEST_CASE("ucl: string: invariants", "[ucl]") -{ - using namespace nihil::ucl; - - 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: literal", "[ucl]") -{ - SECTION("with namespace nihil::ucl::literals") { - using namespace nihil::ucl::literals; - - auto s = "testing"_ucl; - REQUIRE(s.type() == nihil::ucl::object_type::string); - REQUIRE(s == "testing"); - } - - SECTION("with namespace nihil::literals") { - using namespace nihil::literals; - - auto s = "testing"_ucl; - REQUIRE(s.type() == nihil::ucl::object_type::string); - REQUIRE(s == "testing"); - } -} - -TEST_CASE("ucl: string: construct", "[ucl]") -{ - using namespace nihil::ucl; - using namespace std::literals; - - SECTION("empty string") { - auto str = string(); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == ""); - } - - SECTION("with integer-like value") { - auto str = "42"_ucl; - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "42"); - } - - SECTION("with boolean-like value") { - auto str = "true"_ucl; - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "true"); - } - - SECTION("from string literal") { - auto str = string("testing"); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from std::string") { - auto str = string("testing"s); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from std::string_view") { - auto str = string("testing"sv); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from contiguous range") { - auto s = std::vector{'t', 'e', 's', 't', 'i', 'n', 'g'}; - auto str = string(s); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from non-contiguous range") { - auto s = std::list{'t', 'e', 's', 't', 'i', 'n', 'g'}; - auto str = string(s); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from contiguous iterator pair") { - auto s = std::vector{'t', 'e', 's', 't', 'i', 'n', 'g'}; - auto str = string(s.begin(), s.end()); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from non-contiguous iterator pair") { - auto s = std::list{'t', 'e', 's', 't', 'i', 'n', 'g'}; - auto str = string(s.begin(), s.end()); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } -} - -TEST_CASE("ucl: string: construct from UCL object", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("ref, correct type") { - auto uobj = ::ucl_object_fromstring("testing"); - - auto s = string(ref, uobj); - REQUIRE(s == "testing"); - - ::ucl_object_unref(uobj); - } - - SECTION("noref, correct type") { - auto uobj = ::ucl_object_fromstring("testing"); - - auto s = string(noref, uobj); - REQUIRE(s == "testing"); - } - - SECTION("ref, wrong type") { - auto uobj = ::ucl_object_frombool(true); - - REQUIRE_THROWS_AS(string(ref, uobj), type_mismatch); - - ::ucl_object_unref(uobj); - } - - SECTION("noref, wrong type") { - auto uobj = ::ucl_object_frombool(true); - - REQUIRE_THROWS_AS(string(noref, uobj), type_mismatch); - - ::ucl_object_unref(uobj); - } -} - -TEST_CASE("ucl: string: make_string", "[ucl]") -{ - using namespace nihil::ucl; - using namespace std::literals; - - SECTION("empty string") { - auto str = make_string().value(); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == ""); - } - - SECTION("from string literal") { - auto str = make_string("testing").value(); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from std::string") { - auto str = make_string("testing"s).value(); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from std::string_view") { - auto str = make_string("testing"sv).value(); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from contiguous range") { - auto s = std::vector{'t', 'e', 's', 't', 'i', 'n', 'g'}; - auto str = make_string(s).value(); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from non-contiguous range") { - auto s = std::list{'t', 'e', 's', 't', 'i', 'n', 'g'}; - auto str = make_string(s).value(); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from contiguous iterator pair") { - auto s = std::vector{'t', 'e', 's', 't', 'i', 'n', 'g'}; - auto str = make_string(s.begin(), s.end()).value(); - REQUIRE(str.type() == object_type::string); - REQUIRE(str == "testing"); - } - - SECTION("from non-contiguous iterator pair") { - auto s = std::list{'t', 'e', 's', 't', 'i', 'n', 'g'}; - auto str = make_string(s.begin(), s.end()).value(); - REQUIRE(str.type() == object_type::string); - 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]") -{ - using namespace nihil::ucl; - - auto s = string("te\"st"); - REQUIRE(s.value() == "te\"st"); -} - -TEST_CASE("ucl: string: key()", "[ucl]") -{ - using namespace nihil::ucl; - - auto err = parse("a_string = \"test\""); - REQUIRE(err); - - auto obj = *err; - REQUIRE(object_cast<string>(obj["a_string"])->key() == "a_string"); - - auto s = 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: iterate", "[ucl]") -{ - using namespace nihil::ucl; - - auto str = "test"_ucl; - - SECTION("as iterator pair") { - auto begin = str.begin(); - static_assert(std::contiguous_iterator<decltype(begin)>); - - auto end = str.end(); - 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); - } - - SECTION("as range") { - auto s = std::string(std::from_range, str); - REQUIRE(s == "test"); - } -} - -TEST_CASE("ucl: string: comparison", "[ucl]") -{ - using namespace nihil::ucl; - - auto str = "testing"_ucl; - - SECTION("operator==") { - REQUIRE(str == "testing"_ucl); - REQUIRE(str == std::string_view("testing")); - REQUIRE(str == std::string("testing")); - REQUIRE(str == "testing"); - } - - SECTION("operator!=") { - REQUIRE(str != "test"_ucl); - REQUIRE(str != std::string_view("test")); - REQUIRE(str != std::string("test")); - REQUIRE(str != "test"); - } - - SECTION("operator<") { - REQUIRE(str < "zzz"_ucl); - REQUIRE(str < std::string_view("zzz")); - REQUIRE(str < std::string("zzz")); - REQUIRE(str < "zzz"); - } - - SECTION("operator>") { - REQUIRE(str > "aaa"_ucl); - REQUIRE(str > std::string_view("aaa")); - REQUIRE(str > std::string("aaa")); - REQUIRE(str > "aaa"); - } -} - -TEST_CASE("ucl: string: parse", "[ucl]") -{ - using namespace nihil::ucl; - - auto obj = parse("value = \"te\\\"st\"").value(); - - auto v = obj["value"]; - REQUIRE(v.key() == "value"); - REQUIRE(object_cast<nihil::ucl::string>(v).value() == "te\"st"); -} - -TEST_CASE("ucl: string: emit", "[ucl]") -{ - using namespace nihil::ucl; - - auto ucl = parse("str = \"te\\\"st\";").value(); - - auto output = std::string(); - emit(ucl, emitter::configuration, std::back_inserter(output)); - - REQUIRE(output == "str = \"te\\\"st\";\n"); -} - -TEST_CASE("ucl: string: format", "[ucl]") -{ - using namespace nihil::ucl; - using namespace std::literals; - - auto constexpr test_string = "te\"st"sv; - - SECTION("bare string") { - auto str = std::format("{}", string(test_string)); - REQUIRE(str == test_string); - } - - SECTION("parsed string") { - auto obj = parse("string = \"te\\\"st\";").value(); - auto s = object_cast<string>(obj["string"]).value(); - - auto str = std::format("{}", s); - REQUIRE(str == test_string); - } - - SECTION("with format string") { - auto str = std::format("{: >10}", string(test_string)); - REQUIRE(str == " te\"st"); - } -} - -TEST_CASE("ucl: string: print to ostream", "[ucl]") -{ - using namespace nihil::ucl; - using namespace std::literals; - - auto constexpr test_string = "te\"st"sv; - - SECTION("bare string") { - auto strm = std::ostringstream(); - strm << string(test_string); - - REQUIRE(strm.str() == test_string); - } - - SECTION("parsed string") { - auto obj = parse("string = \"te\\\"st\";").value(); - auto s = object_cast<string>(obj["string"]).value(); - - auto strm = std::ostringstream(); - strm << s; - - REQUIRE(strm.str() == test_string); - } - - SECTION("with format string") { - auto str = std::format("{: >10}", string(test_string)); - REQUIRE(str == " te\"st"); - } -} |
