From 808ca1de7f68ef0bc259439f30a97bd3b09c2461 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Sat, 1 Jun 2024 10:52:31 +0200 Subject: [PATCH] Add unit tests for Blackboard --- tests/test_blackboard.h | 186 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 tests/test_blackboard.h diff --git a/tests/test_blackboard.h b/tests/test_blackboard.h new file mode 100644 index 0000000..5605129 --- /dev/null +++ b/tests/test_blackboard.h @@ -0,0 +1,186 @@ +#ifndef TEST_BLACKBOARD_H +#define TEST_BLACKBOARD_H + +#include "core/variant/variant.h" +#include "limbo_test.h" + +#include "modules/limboai/blackboard/blackboard.h" + +namespace TestBlackboard { + +class TestPropertyHolder : public RefCounted { + GDCLASS(TestPropertyHolder, RefCounted); + +public: + int property = 0; + + void set_property(int p_property) { property = p_property; } + int get_property() { return property; } + + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_property", "property"), &TestPropertyHolder::set_property); + ClassDB::bind_method(D_METHOD("get_property"), &TestPropertyHolder::get_property); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "property"), "set_property", "get_property"); + } +}; + +TEST_CASE("[Modules][LimboAI] Test Blackboard") { + Ref blackboard = memnew(Blackboard); + + blackboard->set_var("a", 1); + blackboard->set_var("b", Vector2(2, 2)); + blackboard->set_var("c", String("3")); + + Variant not_found("not_found"); + + SUBCASE("Test getter") { + CHECK_EQ(blackboard->get_var("a", not_found), Variant(1)); + CHECK_EQ(blackboard->get_var("b", not_found), Variant(Vector2(2, 2))); + CHECK_EQ(blackboard->get_var("c", not_found), Variant("3")); + } + + SUBCASE("Test has_var()") { + CHECK(blackboard->has_var("a")); + CHECK(blackboard->has_var("b")); + CHECK(blackboard->has_var("c")); + CHECK_FALSE(blackboard->has_var("d")); + } + + SUBCASE("Test erase_var()") { + blackboard->erase_var("b"); + CHECK_FALSE(blackboard->has_var("b")); + CHECK(blackboard->has_var("a")); + CHECK(blackboard->has_var("c")); + } + + SUBCASE("Test clear()") { + blackboard->clear(); + CHECK_FALSE(blackboard->has_var("a")); + CHECK_FALSE(blackboard->has_var("b")); + CHECK_FALSE(blackboard->has_var("c")); + } + + SUBCASE("Test list_vars()") { + TypedArray vars = blackboard->list_vars(); + CHECK_EQ(vars.size(), 3); + CHECK(vars.has("a")); + CHECK(vars.has("b")); + CHECK(vars.has("c")); + } + + SUBCASE("Test get_vars_as_dict()") { + Dictionary dict = blackboard->get_vars_as_dict(); + CHECK_EQ(dict.size(), 3); + CHECK(dict.has("a")); + CHECK(dict.has("b")); + CHECK(dict.has("c")); + CHECK_EQ(dict["a"], Variant(1)); + CHECK_EQ(dict["b"], Variant(Vector2(2, 2))); + CHECK_EQ(dict["c"], Variant("3")); + + // * Should not include parent scope values + Ref parent_scope = memnew(Blackboard); + blackboard->set_parent(parent_scope); + parent_scope->set_var("d", 1); + dict = blackboard->get_vars_as_dict(); + CHECK_EQ(dict.size(), 3); + CHECK_FALSE(dict.has("d")); + } + + SUBCASE("Test populate_from_dict() overriding values") { + Dictionary dict; + dict["a"] = "value_a"; + dict["b"] = "value_b"; + dict["c"] = "value_c"; + blackboard->populate_from_dict(dict); + + CHECK_EQ(blackboard->list_vars().size(), 3); + CHECK_EQ(blackboard->get_var("a", not_found), Variant("value_a")); + CHECK_EQ(blackboard->get_var("b", not_found), Variant("value_b")); + CHECK_EQ(blackboard->get_var("c", not_found), Variant("value_c")); + } + + SUBCASE("Test populate_from_dict() creating new values") { + Dictionary dict; + dict["d"] = "value_d"; + dict["e"] = "value_e"; + blackboard->populate_from_dict(dict); + + CHECK_EQ(blackboard->list_vars().size(), 5); + CHECK_EQ(blackboard->get_var("d", not_found), Variant("value_d")); + CHECK_EQ(blackboard->get_var("e", not_found), Variant("value_e")); + } + + SUBCASE("Test scoping") { + CHECK_EQ(blackboard->top(), blackboard); + + Ref parent_scope = memnew(Blackboard); + blackboard->set_parent(parent_scope); + CHECK_EQ(blackboard->get_parent(), parent_scope); + CHECK_EQ(blackboard->top(), parent_scope); + + parent_scope->set_var("a", 5); + CHECK_EQ(blackboard->get_var("a", not_found), Variant(1)); // * should return current scope value + CHECK_EQ(parent_scope->get_var("a", not_found), Variant(5)); // * should return parent scope value + CHECK_EQ(parent_scope->get_var("b", not_found, false), not_found); // * should not return current scope value + + parent_scope->set_var("d", 123); + CHECK_EQ(blackboard->get_var("d", not_found), Variant(123)); // * should return parent scope value + + blackboard->set_var("d", 456); + CHECK_EQ(blackboard->get_var("d", not_found), Variant(456)); // * should return new value + CHECK_EQ(parent_scope->get_var("d", not_found), Variant(123)); // * should return parent scope value + + Ref grand_parent_scope = memnew(Blackboard); + parent_scope->set_parent(grand_parent_scope); + CHECK_EQ(blackboard->top(), grand_parent_scope); + + grand_parent_scope->set_var("a", "value_found"); + CHECK_EQ(grand_parent_scope->get_var("a", not_found), Variant("value_found")); + CHECK_EQ(grand_parent_scope->get_var("b", not_found, false), not_found); + CHECK_EQ(grand_parent_scope->get_var("c", not_found, false), not_found); + CHECK_EQ(grand_parent_scope->get_var("d", not_found, false), not_found); + CHECK_EQ(parent_scope->get_var("a", not_found), Variant(5)); + CHECK_EQ(blackboard->get_var("a", not_found), Variant(1)); + } + + SUBCASE("Test binding") { + Ref holder = memnew(TestPropertyHolder); + blackboard->bind_var_to_property("a", holder.ptr(), "property"); + + holder->set_property(5); + CHECK_EQ(blackboard->get_var("a", not_found), Variant(5)); + blackboard->set_var("a", Variant(6)); + CHECK_EQ(holder->get_property(), 6); + + blackboard->unbind_var("a"); + blackboard->set_var("a", Variant(7)); + CHECK_EQ(holder->get_property(), 6); + CHECK_EQ(blackboard->get_var("a", not_found), Variant(7)); + } + + SUBCASE("Test linking") { + Ref target_blackboard = memnew(Blackboard); + + target_blackboard->set_var("aa", Variant(111)); + blackboard->link_var("a", target_blackboard, "aa"); + CHECK(target_blackboard->has_var("aa")); + CHECK_FALSE(target_blackboard->has_var("a")); + + CHECK_EQ(blackboard->get_var("a", not_found), Variant(111)); + CHECK_EQ(target_blackboard->get_var("aa", not_found), Variant(111)); + + blackboard->set_var("a", Variant(222)); + CHECK_EQ(blackboard->get_var("a", not_found), Variant(222)); + CHECK_EQ(target_blackboard->get_var("aa", not_found), Variant(222)); + + target_blackboard->set_var("aa", Variant(333)); + CHECK_EQ(blackboard->get_var("a", not_found), Variant(333)); + CHECK_EQ(target_blackboard->get_var("aa", not_found), Variant(333)); + } +} + +} //namespace TestBlackboard + +#endif // TEST_BLACKBOARD_H