From 2e2d1bd3b6c7776b77c33b94f30ead89367a71e6 Mon Sep 17 00:00:00 2001 From: Lexi Winter Date: Tue, 1 Jul 2025 17:07:04 +0100 Subject: add nihil.std --- nihil.ucl/tests/array.cc | 478 ----------------------------------------------- 1 file changed, 478 deletions(-) delete mode 100644 nihil.ucl/tests/array.cc (limited to 'nihil.ucl/tests/array.cc') 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 -#include -#include -#include -#include - -#include -#include - -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>); - static_assert(std::default_initializable>); - static_assert(std::move_constructible>); - static_assert(std::copy_constructible>); - static_assert(std::equality_comparable>); - static_assert(std::totally_ordered>); - static_assert(std::swappable>); - - static_assert(std::ranges::sized_range>); - static_assert(std::same_as>, - integer>); -} - -TEST_CASE("ucl: array: constructor", "[ucl]") -{ - using namespace nihil::ucl; - - SECTION("default") { - auto arr = array(); - REQUIRE(arr.size() == 0); - REQUIRE(str(arr.type()) == "array"); - } - - SECTION("from range") { - auto vec = std::vector{integer(1), integer(42)}; - auto arr = array(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(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(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(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(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(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(1), - nihil::ucl::integer(2) - }; - - auto arr2 = nihil::ucl::array{ - 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(); - 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(1), integer(42), integer(666) - }; - - auto arr2 = array(); - 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(1), integer(1), integer(1) - }; - - REQUIRE(arr != arr3); -} - -TEST_CASE("ucl: array: iterator", "[ucl]") -{ - using namespace nihil::ucl; - - auto arr = array{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>(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(); - REQUIRE(std::format("{}", arr) == "[]"); - } - - SECTION("bare array") { - auto arr = array{ - 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>(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(); - auto strm = std::ostringstream(); - strm << arr; - - REQUIRE(strm.str() == "[]"); - } - - SECTION("bare array") { - auto arr = array{ - 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>(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(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); - - auto end = std::ranges::end(arr); - static_assert(std::sentinel_for); - - REQUIRE(std::distance(begin, end) == 3); - - auto vec = std::vector(); - 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(); - std::ranges::copy(arr_as_ints, std::back_inserter(int_vec)); - REQUIRE(int_vec == std::vector{1, 42, 666}); - -} - -TEST_CASE("ucl: array: bad object_cast", "[ucl]") -{ - using namespace nihil::ucl; - - auto arr = array(); - - auto cast_ok = object_cast(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>(obj["array"]); - REQUIRE(err); - - auto arr = *err; - REQUIRE(arr.size() == 3); - - auto int_obj = object_cast(arr[0]); - REQUIRE(int_obj); - REQUIRE(*int_obj == 42); - - auto bool_obj = object_cast(arr[1]); - REQUIRE(bool_obj); - REQUIRE(*bool_obj == true); - - auto string_obj = object_cast(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 should fail. - auto cast_ok = object_cast>(arr); - REQUIRE(!cast_ok); - - // Converting to array should succeed. - auto err = object_cast>(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 should fail. - auto cast_ok = object_cast>(obj); - REQUIRE(!cast_ok); - - // Converting to an array should succeed. - auto err = object_cast>(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(); - - 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(); - 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(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(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(); - REQUIRE_THROWS_AS(it == it2, std::logic_error); - REQUIRE_THROWS_AS(it > it2, std::logic_error); - REQUIRE_THROWS_AS(it - it2, std::logic_error); - } -} -- cgit v1.2.3