#include #include "matador/object/repository.hpp" #include "../../models/department.hpp" #include "../../models/recipe.hpp" #include "../../models/person.hpp" struct node { }; using namespace matador; struct person { virtual ~person() = default; template void process(Operator &/*op*/) { } }; struct student final : person { }; struct teacher final : person { }; struct names { unsigned int id{}; std::vector names_list; template void process(Operator &op) { namespace field = matador::access; field::primary_key(op, "id", id); field::has_many(op, "name_list", names_list, "names_id", utils::fetch_type::Eager); } }; TEST_CASE("Test empty prototype tree", "[schema_node][empty]") { const object::repository repo; REQUIRE(repo.empty()); } TEST_CASE("Test add type to prototype tree", "[schema_node][add]") { object::repository repo; REQUIRE(repo.empty()); auto res = repo.attach("person"); REQUIRE(res.is_ok()); res = repo.attach("student"); REQUIRE(res.is_ok()); res = repo.attach("teacher"); REQUIRE(res.is_ok()); REQUIRE(!repo.empty()); REQUIRE(repo.size() == 3); } TEST_CASE("Test next and previous of schema node", "[schema_node][next][previous]") { object::repository repo; REQUIRE(repo.empty()); auto res = repo.attach("person"); REQUIRE(res.is_ok()); REQUIRE(repo.size() == 1); auto it = repo.begin(); REQUIRE(it->name() == "person"); REQUIRE((--it)->name() == "person"); REQUIRE(++it == repo.end()); } TEST_CASE("Test automatic creating of a relation table with foreign key", "[schema][relation_table][foreign_key]") { object::repository repo; REQUIRE(repo.empty()); auto res = repo.attach("department"); REQUIRE(res.is_ok()); REQUIRE(repo.size() == 2); } TEST_CASE("Test automatic creating of a relation table with values", "[schema][relation_table][values]") { object::repository repo; REQUIRE(repo.empty()); auto res = repo.attach("names"); REQUIRE(res.is_ok()); } TEST_CASE("Test one to many", "[relation][one-to-many]") { object::repository repo; REQUIRE(repo.empty()); auto res = repo.attach("departments") .and_then([&repo] { return repo.attach("employees"); }); REQUIRE(res.is_ok()); REQUIRE(repo.size() == 2); REQUIRE(repo.contains("departments")); REQUIRE(repo.contains("employees")); auto result = repo.basic_info("departments"); REQUIRE(!result->get().endpoints_empty()); REQUIRE(result->get().endpoints_size() == 1); std::cout << *result->get().object(); result = repo.basic_info("employees"); REQUIRE(!result->get().endpoints_empty()); REQUIRE(result->get().endpoints_size() == 1); std::cout << *result->get().object(); } TEST_CASE("Test one to many reverse", "[relation][one-to-many][reverse]") { object::repository repo; REQUIRE(repo.empty()); auto res = repo.attach("employees") .and_then([&repo] { return repo.attach("departments"); }); REQUIRE(res.is_ok()); REQUIRE(repo.size() == 2); REQUIRE(repo.contains("departments")); REQUIRE(repo.contains("employees")); auto result = repo.basic_info("departments"); REQUIRE(result.is_ok()); REQUIRE(!result->get().endpoints_empty()); REQUIRE(result->get().endpoints_size() == 1); std::cout << *result->get().object(); result = repo.basic_info("employees"); REQUIRE(!result->get().endpoints_empty()); REQUIRE(result->get().endpoints_size() == 1); std::cout << *result->get().object(); } TEST_CASE("Test many to many relation", "[relation][many-to-many]") { object::repository repo; REQUIRE(repo.empty()); auto res = repo.attach("recipes") .and_then([&repo] { return repo.attach("ingredients"); }); REQUIRE(res); REQUIRE(repo.size() == 3); REQUIRE(repo.contains("ingredients")); REQUIRE(repo.contains("recipes")); REQUIRE(repo.contains("recipe_ingredients")); std::cout << *repo.basic_info("ingredients")->get().object(); std::cout << *repo.basic_info("recipes")->get().object(); std::cout << *repo.basic_info("recipe_ingredients")->get().object(); auto result = repo.basic_info("ingredients"); REQUIRE(!result->get().endpoints_empty()); REQUIRE(result->get().endpoints_size() == 1); std::cout << *result->get().object(); result = repo.basic_info("recipes"); REQUIRE(!result->get().endpoints_empty()); REQUIRE(result->get().endpoints_size() == 1); std::cout << *result->get().object(); result = repo.basic_info("recipe_ingredients"); REQUIRE(!result->get().endpoints_empty()); REQUIRE(result->get().endpoints_size() == 2); std::cout << *result->get().object(); } template class test_observer : public matador::object::observer { public: void on_attach(object::repository_node& node, const Type& prototype) override { int i = 0; } void on_detach(object::repository_node& node, const Type& prototype) override { } void on_insert(Type& obj) override { } void on_update(Type& obj) override { } void on_delete(Type& obj) override { } }; TEST_CASE("Test repository observer", "[repository][observer]") { object::repository repo; REQUIRE(repo.empty()); const auto result = repo.attach("person", test_observer()); REQUIRE(result.is_ok()); }