refactored identifier, added tests and added primary_key_accessor and tests

This commit is contained in:
2026-04-03 19:14:14 +02:00
parent f751541bdd
commit 920fdc68ed
9 changed files with 696 additions and 275 deletions
+177 -14
View File
@@ -10,12 +10,7 @@ TEST_CASE("Test create identifier", "[identifier][create]") {
REQUIRE(id.is_null());
REQUIRE(!id.is_integer());
REQUIRE(!id.is_floating_point());
REQUIRE(!id.is_bool());
REQUIRE(!id.is_varchar());
REQUIRE(!id.is_date());
REQUIRE(!id.is_time());
REQUIRE(!id.is_blob());
REQUIRE(!id.is_valid());
REQUIRE(id.str() == "null");
}
@@ -88,7 +83,7 @@ TEST_CASE("Test copy identifier" "[identifier][copy]") {
identifier id3 = id1;
REQUIRE(id1 == id3);
REQUIRE(id1 < id3);
REQUIRE(!(id1 < id3));
REQUIRE(id3.is_null());
REQUIRE(id1.hash() == id3.hash());
@@ -103,16 +98,184 @@ TEST_CASE("Test move identifier", "[identifier][move]") {
REQUIRE(!id1.is_null());
const auto id2 = std::move(id1);
REQUIRE(id1.is_null());
REQUIRE(!id1.is_null());
REQUIRE(id2.is_integer());
}
TEST_CASE("Test share identifier", "[identifier][share]") {
const identifier id1{6};
TEST_CASE("identifier assignment from integer types", "[utils][identifier][assign]") {
identifier id;
REQUIRE(id1.use_count() == 1);
id = int8_t{-5};
REQUIRE(id.type() == basic_type::Int8);
REQUIRE(id.str() == "-5");
REQUIRE(id.is_integer());
REQUIRE(id.is_valid());
auto id2 = id1.share();
REQUIRE(id1 == id2);
REQUIRE(id1.use_count() == 2);
}
id = int16_t{42};
REQUIRE(id.type() == basic_type::Int16);
REQUIRE(id.str() == "42");
REQUIRE(id.is_integer());
REQUIRE(id.is_valid());
id = uint32_t{123456u};
REQUIRE(id.type() == basic_type::UInt32);
REQUIRE(id.str() == "123456");
REQUIRE(id.is_integer());
REQUIRE(id.is_valid());
}
TEST_CASE("identifier assignment from string type", "[utils][identifier][assign]") {
identifier id;
id = std::string{"hello"};
REQUIRE(id.type() == basic_type::Varchar);
REQUIRE(id.str() == "hello");
REQUIRE(id.is_varchar());
REQUIRE(id.is_valid());
id = std::string{};
REQUIRE(id.type() == basic_type::Varchar);
REQUIRE(id.str().empty());
REQUIRE_FALSE(id.is_valid());
}
TEST_CASE("identifier assignment from const char*", "[utils][identifier][assign]") {
identifier id;
id = "world";
REQUIRE(id.type() == basic_type::Varchar);
REQUIRE(id.str() == "world");
REQUIRE(id.is_varchar());
REQUIRE(id.is_valid());
id = static_cast<const char*>(nullptr);
REQUIRE(id.type() == basic_type::Varchar);
REQUIRE(id.str().empty());
REQUIRE_FALSE(id.is_valid());
}
TEST_CASE("identifier assignment from nullptr", "[utils][identifier][assign]") {
identifier id{42};
REQUIRE(id.is_valid());
REQUIRE_FALSE(id.is_null());
id = nullptr;
REQUIRE(id.is_null());
REQUIRE(id.type() == basic_type::Null);
REQUIRE(id.str() == "null");
REQUIRE_FALSE(id.is_valid());
}
TEST_CASE("identifier reassignment between types", "[utils][identifier][assign]") {
identifier id{uint64_t{7}};
REQUIRE(id.is_integer());
REQUIRE(id.str() == "7");
id = std::string{"abc"};
REQUIRE(id.is_varchar());
REQUIRE(id.str() == "abc");
REQUIRE(id.is_valid());
id = int64_t{99};
REQUIRE(id.is_integer());
REQUIRE(id.str() == "99");
REQUIRE(id.is_valid());
id = nullptr;
REQUIRE(id.is_null());
REQUIRE(id.str() == "null");
}
TEST_CASE("identifier as() returns exact integer type", "[utils][identifier][as]") {
identifier id{int32_t{42}};
const auto as_i32 = id.as<int32_t>();
REQUIRE(as_i32.is_ok());
REQUIRE(*as_i32 == 42);
const auto as_i64 = id.as<int64_t>();
REQUIRE(as_i64.is_error());
}
TEST_CASE("identifier as() returns exact string type", "[utils][identifier][as]") {
identifier id{std::string{"hello"}};
const auto as_string = id.as<std::string>();
REQUIRE(as_string.is_ok());
REQUIRE(*as_string == "hello");
const auto as_i32 = id.as<int32_t>();
REQUIRE(as_i32.is_error());
}
TEST_CASE("identifier as() returns null type failure for null identifier", "[utils][identifier][as]") {
identifier id{nullptr};
const auto as_i32 = id.as<int32_t>();
REQUIRE(as_i32.is_error());
const auto as_string = id.as<std::string>();
REQUIRE(as_string.is_error());
}
TEST_CASE("identifier convert() converts between integer types", "[utils][identifier][convert]") {
identifier id{int32_t{123}};
const auto as_i64 = id.convert<int64_t>();
REQUIRE(as_i64.is_ok());
REQUIRE(*as_i64 == 123);
const auto as_u8 = id.convert<uint8_t>();
REQUIRE(as_u8.is_ok());
REQUIRE(*as_u8 == 123);
}
TEST_CASE("identifier convert() rejects out of range integer conversion", "[utils][identifier][convert]") {
identifier id{int32_t{300}};
const auto as_u8 = id.convert<uint8_t>();
REQUIRE(as_u8.is_error());
}
TEST_CASE("identifier convert() rejects negative to unsigned conversion", "[utils][identifier][convert]") {
identifier id{int32_t{-1}};
const auto as_u32 = id.convert<uint32_t>();
REQUIRE(as_u32.is_error());
}
TEST_CASE("identifier convert() rejects non-integer source types", "[utils][identifier][convert]") {
identifier id{std::string{"123"}};
const auto as_i32 = id.convert<int32_t>();
REQUIRE(as_i32.is_error());
identifier null_id{nullptr};
const auto null_to_i64 = null_id.convert<int64_t>();
REQUIRE(null_to_i64.is_error());
}
TEST_CASE("identifier convert() works with unsigned integer sources", "[utils][identifier][convert]") {
identifier id{uint16_t{500}};
const auto as_i32 = id.convert<int32_t>();
REQUIRE(as_i32.is_ok());
REQUIRE(*as_i32 == 500);
const auto as_u8 = id.convert<uint8_t>();
REQUIRE(as_u8.is_error());
}
TEST_CASE("identifier as() and convert() behave consistently for same integer type", "[utils][identifier][as][convert]") {
identifier id{uint64_t{77}};
const auto as_u64 = id.as<uint64_t>();
REQUIRE(as_u64.is_ok());
REQUIRE(*as_u64 == 77);
const auto conv_u64 = id.convert<uint64_t>();
REQUIRE(conv_u64.is_ok());
REQUIRE(*conv_u64 == 77);
}
@@ -0,0 +1,68 @@
#include <catch2/catch_test_macros.hpp>
#include "matador/utils/identifier.hpp"
#include "matador/utils/primary_key_accessor.hpp"
#include "../test/models/person.hpp"
TEST_CASE("primary_key_accessor detects unset primary key", "[utils][primary_key_accessor]") {
using namespace matador;
utils::primary_key_accessor accessor;
test::person p{};
REQUIRE_FALSE(accessor.is_set(p));
}
TEST_CASE("primary_key_accessor detects set primary key", "[utils][primary_key_accessor]") {
using namespace matador;
utils::primary_key_accessor accessor;
test::person p{};
p.id = 42;
REQUIRE(accessor.is_set(p));
}
TEST_CASE("primary_key_accessor gets integer primary key", "[utils][primary_key_accessor]") {
using namespace matador;
utils::primary_key_accessor accessor;
test::person p{};
p.id = 17;
const auto pk = accessor.get(p);
REQUIRE(pk.is_integer());
REQUIRE(pk.is_valid());
REQUIRE(pk.as<unsigned int>().is_ok());
REQUIRE(*pk.as<unsigned int>() == 17u);
}
TEST_CASE("primary_key_accessor sets integer primary key", "[utils][primary_key_accessor]") {
using namespace matador;
utils::primary_key_accessor accessor;
test::person p{};
accessor.set(p, utils::identifier{123u});
REQUIRE(p.id == 123u);
REQUIRE(accessor.is_set(p));
}
TEST_CASE("primary_key_accessor can round-trip primary key value", "[utils][primary_key_accessor]") {
using namespace matador;
utils::primary_key_accessor accessor;
test::person original{};
original.id = 88u;
const auto pk = accessor.get(original);
test::person copy{};
accessor.set(copy, pk);
REQUIRE(copy.id == 88u);
REQUIRE(accessor.is_set(copy));
}