From 08d9cfe82c1ba1c5486401f8edac932a5eb6fe5d Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 10 Jun 2020 17:37:21 +0200 Subject: [PATCH] test: added meta_func --- test/CMakeLists.txt | 1 + test/entt/meta/meta.cpp | 232 -------------------------- test/entt/meta/meta_func.cpp | 312 +++++++++++++++++++++++++++++++++++ 3 files changed, 313 insertions(+), 232 deletions(-) create mode 100644 test/entt/meta/meta_func.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ee7da9cb3..3021949b8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -183,6 +183,7 @@ SETUP_BASIC_TEST(meta_basic entt/meta/meta_basic.cpp) SETUP_BASIC_TEST(meta_conv entt/meta/meta_conv.cpp) SETUP_BASIC_TEST(meta_ctor entt/meta/meta_ctor.cpp) SETUP_BASIC_TEST(meta_data entt/meta/meta_data.cpp) +SETUP_BASIC_TEST(meta_func entt/meta/meta_func.cpp) SETUP_BASIC_TEST(meta_prop entt/meta/meta_prop.cpp) list(APPEND TEST_META_SOURCES entt/meta/meta.cpp entt/meta/fixture.cpp) diff --git a/test/entt/meta/meta.cpp b/test/entt/meta/meta.cpp index 8257b0072..03f7ab41c 100644 --- a/test/entt/meta/meta.cpp +++ b/test/entt/meta/meta.cpp @@ -9,238 +9,6 @@ #include #include "fixture.h" -TEST_F(Meta, MetaFunc) { - auto func = entt::resolve().func("f2"_hs); - func_type instance{}; - - ASSERT_TRUE(func); - ASSERT_EQ(func.parent(), entt::resolve_id("func"_hs)); - ASSERT_EQ(func.id(), "f2"_hs); - ASSERT_EQ(func.size(), 2u); - ASSERT_FALSE(func.is_const()); - ASSERT_FALSE(func.is_static()); - ASSERT_EQ(func.ret(), entt::resolve()); - ASSERT_EQ(func.arg(0u), entt::resolve()); - ASSERT_EQ(func.arg(1u), entt::resolve()); - ASSERT_FALSE(func.arg(2u)); - - auto any = func.invoke(instance, 3, 2); - auto empty = func.invoke(instance); - - ASSERT_FALSE(empty); - ASSERT_TRUE(any); - ASSERT_EQ(any.type(), entt::resolve()); - ASSERT_EQ(any.cast(), 4); - ASSERT_EQ(func_type::value, 3); - - func.prop([](auto prop) { - ASSERT_EQ(prop.key(), props::prop_bool); - ASSERT_FALSE(prop.value().template cast()); - }); - - ASSERT_FALSE(func.prop(props::prop_int)); - - auto prop = func.prop(props::prop_bool); - - ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), props::prop_bool); - ASSERT_FALSE(prop.value().cast()); -} - -TEST_F(Meta, MetaFuncConst) { - auto func = entt::resolve().func("f1"_hs); - func_type instance{}; - - ASSERT_TRUE(func); - ASSERT_EQ(func.parent(), entt::resolve_id("func"_hs)); - ASSERT_EQ(func.id(), "f1"_hs); - ASSERT_EQ(func.size(), 1u); - ASSERT_TRUE(func.is_const()); - ASSERT_FALSE(func.is_static()); - ASSERT_EQ(func.ret(), entt::resolve()); - ASSERT_EQ(func.arg(0u), entt::resolve()); - ASSERT_FALSE(func.arg(1u)); - - auto any = func.invoke(instance, 4); - auto empty = func.invoke(instance, 'c'); - - ASSERT_FALSE(empty); - ASSERT_TRUE(any); - ASSERT_EQ(any.type(), entt::resolve()); - ASSERT_EQ(any.cast(), 16); - - func.prop([](auto prop) { - ASSERT_EQ(prop.key(), props::prop_bool); - ASSERT_FALSE(prop.value().template cast()); - }); - - ASSERT_FALSE(func.prop(props::prop_int)); - - auto prop = func.prop(props::prop_bool); - - ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), props::prop_bool); - ASSERT_FALSE(prop.value().cast()); -} - -TEST_F(Meta, MetaFuncRetVoid) { - auto func = entt::resolve().func("g"_hs); - func_type instance{}; - - ASSERT_TRUE(func); - ASSERT_EQ(func.parent(), entt::resolve_id("func"_hs)); - ASSERT_EQ(func.id(), "g"_hs); - ASSERT_EQ(func.size(), 1u); - ASSERT_FALSE(func.is_const()); - ASSERT_FALSE(func.is_static()); - ASSERT_EQ(func.ret(), entt::resolve()); - ASSERT_EQ(func.arg(0u), entt::resolve()); - ASSERT_FALSE(func.arg(1u)); - - auto any = func.invoke(instance, 5); - - ASSERT_TRUE(any); - ASSERT_EQ(any.type(), entt::resolve()); - ASSERT_EQ(func_type::value, 25); - - func.prop([](auto prop) { - ASSERT_EQ(prop.key(), props::prop_bool); - ASSERT_FALSE(prop.value().template cast()); - }); - - ASSERT_FALSE(func.prop(props::prop_int)); - - auto prop = func.prop(props::prop_bool); - - ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), props::prop_bool); - ASSERT_FALSE(prop.value().cast()); -} - -TEST_F(Meta, MetaFuncStatic) { - auto func = entt::resolve().func("h"_hs); - func_type::value = 2; - - ASSERT_TRUE(func); - ASSERT_EQ(func.parent(), entt::resolve_id("func"_hs)); - ASSERT_EQ(func.id(), "h"_hs); - ASSERT_EQ(func.size(), 1u); - ASSERT_FALSE(func.is_const()); - ASSERT_TRUE(func.is_static()); - ASSERT_EQ(func.ret(), entt::resolve()); - ASSERT_EQ(func.arg(0u), entt::resolve()); - ASSERT_FALSE(func.arg(1u)); - - auto any = func.invoke({}, 3); - auto empty = func.invoke({}, 'c'); - - ASSERT_FALSE(empty); - ASSERT_TRUE(any); - ASSERT_EQ(any.type(), entt::resolve()); - ASSERT_EQ(any.cast(), 6); - - func.prop([](auto prop) { - ASSERT_EQ(prop.key(), props::prop_bool); - ASSERT_FALSE(prop.value().template cast()); - }); - - ASSERT_FALSE(func.prop(props::prop_int)); - - auto prop = func.prop(props::prop_bool); - - ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), props::prop_bool); - ASSERT_FALSE(prop.value().cast()); -} - -TEST_F(Meta, MetaFuncStaticRetVoid) { - auto func = entt::resolve().func("k"_hs); - - ASSERT_TRUE(func); - ASSERT_EQ(func.parent(), entt::resolve_id("func"_hs)); - ASSERT_EQ(func.id(), "k"_hs); - ASSERT_EQ(func.size(), 1u); - ASSERT_FALSE(func.is_const()); - ASSERT_TRUE(func.is_static()); - ASSERT_EQ(func.ret(), entt::resolve()); - ASSERT_EQ(func.arg(0u), entt::resolve()); - ASSERT_FALSE(func.arg(1u)); - - auto any = func.invoke({}, 42); - - ASSERT_TRUE(any); - ASSERT_EQ(any.type(), entt::resolve()); - ASSERT_EQ(func_type::value, 42); - - func.prop([](auto prop) { - ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), props::prop_bool); - ASSERT_FALSE(prop.value().template cast()); - }); - - ASSERT_FALSE(func.prop(props::prop_int)); - - auto prop = func.prop(props::prop_bool); - - ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), props::prop_bool); - ASSERT_FALSE(prop.value().cast()); -} - -TEST_F(Meta, MetaFuncMetaAnyArgs) { - func_type instance; - auto any = entt::resolve().func("f1"_hs).invoke(instance, 3); - - ASSERT_TRUE(any); - ASSERT_EQ(any.type(), entt::resolve()); - ASSERT_EQ(any.cast(), 9); -} - -TEST_F(Meta, MetaFuncInvalidArgs) { - empty_type instance; - - ASSERT_FALSE(entt::resolve().func("f1"_hs).invoke(instance, 'c')); -} - -TEST_F(Meta, MetaFuncCastAndConvert) { - func_type instance; - auto any = entt::resolve().func("f3"_hs).invoke(instance, derived_type{}, 0, 3.); - - ASSERT_TRUE(any); - ASSERT_EQ(any.type(), entt::resolve()); - ASSERT_EQ(any.cast(), 9); -} - -TEST_F(Meta, MetaFuncAsVoid) { - auto func = entt::resolve().func("v"_hs); - func_type instance{}; - - ASSERT_EQ(func.invoke(instance, 42), entt::meta_any{std::in_place_type}); - ASSERT_EQ(func.ret(), entt::resolve()); - ASSERT_EQ(instance.value, 42); -} - -TEST_F(Meta, MetaFuncAsAlias) { - func_type instance{}; - auto func = entt::resolve().func("a"_hs); - func.invoke(instance).cast() = 3; - - ASSERT_EQ(func.ret(), entt::resolve()); - ASSERT_EQ(instance.value, 3); -} - -TEST_F(Meta, MetaFuncByReference) { - auto func = entt::resolve().func("h"_hs); - func_type::value = 2; - entt::meta_any any{3}; - int value = 4; - - ASSERT_EQ(func.invoke({}, std::ref(value)).cast(), 8); - ASSERT_EQ(func.invoke({}, *any).cast(), 6); - ASSERT_EQ(any.cast(), 6); - ASSERT_EQ(value, 8); -} - TEST_F(Meta, MetaType) { auto type = entt::resolve(); diff --git a/test/entt/meta/meta_func.cpp b/test/entt/meta/meta_func.cpp new file mode 100644 index 000000000..7e40a628e --- /dev/null +++ b/test/entt/meta/meta_func.cpp @@ -0,0 +1,312 @@ +#include +#include +#include +#include +#include +#include + +struct base_t { + virtual ~base_t() = default; + static void destroy(base_t &) { + ++counter; + } + + inline static int counter = 0; +}; + +struct derived_t: base_t {}; + +struct func_t { + int f(const base_t &, int a, int b) { + return f(a, b); + } + + int f(int a, int b) { + value = a; + return b*b; + } + + int f(int v) const { + return v*v; + } + + void g(int v) { + value = v*v; + } + + static int h(int &v) { + return (v *= value); + } + + static void k(int v) { + value = v; + } + + int v(int v) const { + return (value = v); + } + + int & a() const { + return value; + } + + inline static int value = 0; +}; + +struct Meta: ::testing::Test { + static void SetUpTestCase() { + entt::meta().conv(); + entt::meta().dtor<&base_t::destroy>(); + entt::meta().base().dtor<&derived_t::destroy>(); + + entt::meta().type("func"_hs) + .func(&func_t::f)>("f3"_hs) + .func(&func_t::f)>("f2"_hs).prop(true, false) + .func(&func_t::f)>("f1"_hs).prop(true, false) + .func<&func_t::g>("g"_hs).prop(true, false) + .func<&func_t::h>("h"_hs).prop(true, false) + .func<&func_t::k>("k"_hs).prop(true, false) + .func<&func_t::v, entt::as_void_t>("v"_hs) + .func<&func_t::a, entt::as_ref_t>("a"_hs); + } + + void SetUp() override { + base_t::counter = 0; + } +}; + +TEST_F(Meta, MetaFunc) { + auto func = entt::resolve().func("f2"_hs); + func_t instance{}; + + ASSERT_TRUE(func); + ASSERT_EQ(func.parent(), entt::resolve_id("func"_hs)); + ASSERT_EQ(func.id(), "f2"_hs); + ASSERT_EQ(func.size(), 2u); + ASSERT_FALSE(func.is_const()); + ASSERT_FALSE(func.is_static()); + ASSERT_EQ(func.ret(), entt::resolve()); + ASSERT_EQ(func.arg(0u), entt::resolve()); + ASSERT_EQ(func.arg(1u), entt::resolve()); + ASSERT_FALSE(func.arg(2u)); + + auto any = func.invoke(instance, 3, 2); + auto empty = func.invoke(instance); + + ASSERT_FALSE(empty); + ASSERT_TRUE(any); + ASSERT_EQ(any.type(), entt::resolve()); + ASSERT_EQ(any.cast(), 4); + ASSERT_EQ(func_t::value, 3); + + func.prop([](auto prop) { + ASSERT_EQ(prop.key(), true); + ASSERT_FALSE(prop.value().template cast()); + }); + + ASSERT_FALSE(func.prop(false)); + ASSERT_FALSE(func.prop('c')); + + auto prop = func.prop(true); + + ASSERT_TRUE(prop); + ASSERT_EQ(prop.key(), true); + ASSERT_FALSE(prop.value().cast()); +} + +TEST_F(Meta, MetaFuncConst) { + auto func = entt::resolve().func("f1"_hs); + func_t instance{}; + + ASSERT_TRUE(func); + ASSERT_EQ(func.parent(), entt::resolve_id("func"_hs)); + ASSERT_EQ(func.id(), "f1"_hs); + ASSERT_EQ(func.size(), 1u); + ASSERT_TRUE(func.is_const()); + ASSERT_FALSE(func.is_static()); + ASSERT_EQ(func.ret(), entt::resolve()); + ASSERT_EQ(func.arg(0u), entt::resolve()); + ASSERT_FALSE(func.arg(1u)); + + auto any = func.invoke(instance, 4); + auto empty = func.invoke(instance, 'c'); + + ASSERT_FALSE(empty); + ASSERT_TRUE(any); + ASSERT_EQ(any.type(), entt::resolve()); + ASSERT_EQ(any.cast(), 16); + + func.prop([](auto prop) { + ASSERT_EQ(prop.key(), true); + ASSERT_FALSE(prop.value().template cast()); + }); + + ASSERT_FALSE(func.prop(false)); + ASSERT_FALSE(func.prop('c')); + + auto prop = func.prop(true); + + ASSERT_TRUE(prop); + ASSERT_EQ(prop.key(), true); + ASSERT_FALSE(prop.value().cast()); +} + +TEST_F(Meta, MetaFuncRetVoid) { + auto func = entt::resolve().func("g"_hs); + func_t instance{}; + + ASSERT_TRUE(func); + ASSERT_EQ(func.parent(), entt::resolve_id("func"_hs)); + ASSERT_EQ(func.id(), "g"_hs); + ASSERT_EQ(func.size(), 1u); + ASSERT_FALSE(func.is_const()); + ASSERT_FALSE(func.is_static()); + ASSERT_EQ(func.ret(), entt::resolve()); + ASSERT_EQ(func.arg(0u), entt::resolve()); + ASSERT_FALSE(func.arg(1u)); + + auto any = func.invoke(instance, 5); + + ASSERT_TRUE(any); + ASSERT_EQ(any.type(), entt::resolve()); + ASSERT_EQ(func_t::value, 25); + + func.prop([](auto prop) { + ASSERT_EQ(prop.key(), true); + ASSERT_FALSE(prop.value().template cast()); + }); + + ASSERT_FALSE(func.prop(false)); + ASSERT_FALSE(func.prop('c')); + + auto prop = func.prop(true); + + ASSERT_TRUE(prop); + ASSERT_EQ(prop.key(), true); + ASSERT_FALSE(prop.value().cast()); +} + +TEST_F(Meta, MetaFuncStatic) { + auto func = entt::resolve().func("h"_hs); + func_t::value = 2; + + ASSERT_TRUE(func); + ASSERT_EQ(func.parent(), entt::resolve_id("func"_hs)); + ASSERT_EQ(func.id(), "h"_hs); + ASSERT_EQ(func.size(), 1u); + ASSERT_FALSE(func.is_const()); + ASSERT_TRUE(func.is_static()); + ASSERT_EQ(func.ret(), entt::resolve()); + ASSERT_EQ(func.arg(0u), entt::resolve()); + ASSERT_FALSE(func.arg(1u)); + + auto any = func.invoke({}, 3); + auto empty = func.invoke({}, 'c'); + + ASSERT_FALSE(empty); + ASSERT_TRUE(any); + ASSERT_EQ(any.type(), entt::resolve()); + ASSERT_EQ(any.cast(), 6); + + func.prop([](auto prop) { + ASSERT_EQ(prop.key(), true); + ASSERT_FALSE(prop.value().template cast()); + }); + + ASSERT_FALSE(func.prop(false)); + ASSERT_FALSE(func.prop('c')); + + auto prop = func.prop(true); + + ASSERT_TRUE(prop); + ASSERT_EQ(prop.key(), true); + ASSERT_FALSE(prop.value().cast()); +} + +TEST_F(Meta, MetaFuncStaticRetVoid) { + auto func = entt::resolve().func("k"_hs); + + ASSERT_TRUE(func); + ASSERT_EQ(func.parent(), entt::resolve_id("func"_hs)); + ASSERT_EQ(func.id(), "k"_hs); + ASSERT_EQ(func.size(), 1u); + ASSERT_FALSE(func.is_const()); + ASSERT_TRUE(func.is_static()); + ASSERT_EQ(func.ret(), entt::resolve()); + ASSERT_EQ(func.arg(0u), entt::resolve()); + ASSERT_FALSE(func.arg(1u)); + + auto any = func.invoke({}, 42); + + ASSERT_TRUE(any); + ASSERT_EQ(any.type(), entt::resolve()); + ASSERT_EQ(func_t::value, 42); + + func.prop([](auto prop) { + ASSERT_TRUE(prop); + ASSERT_EQ(prop.key(), true); + ASSERT_FALSE(prop.value().template cast()); + }); + + ASSERT_FALSE(func.prop(false)); + ASSERT_FALSE(func.prop('c')); + + auto prop = func.prop(true); + + ASSERT_TRUE(prop); + ASSERT_EQ(prop.key(), true); + ASSERT_FALSE(prop.value().cast()); +} + +TEST_F(Meta, MetaFuncMetaAnyArgs) { + func_t instance; + auto any = entt::resolve().func("f1"_hs).invoke(instance, 3); + + ASSERT_TRUE(any); + ASSERT_EQ(any.type(), entt::resolve()); + ASSERT_EQ(any.cast(), 9); +} + +TEST_F(Meta, MetaFuncInvalidArgs) { + int value = 3; + ASSERT_FALSE(entt::resolve().func("f1"_hs).invoke(value, 'c')); +} + +TEST_F(Meta, MetaFuncCastAndConvert) { + func_t instance; + auto any = entt::resolve().func("f3"_hs).invoke(instance, derived_t{}, 0, 3.); + + ASSERT_TRUE(any); + ASSERT_EQ(any.type(), entt::resolve()); + ASSERT_EQ(any.cast(), 9); +} + +TEST_F(Meta, MetaFuncAsVoid) { + auto func = entt::resolve().func("v"_hs); + func_t instance{}; + + ASSERT_EQ(func.invoke(instance, 42), entt::meta_any{std::in_place_type}); + ASSERT_EQ(func.ret(), entt::resolve()); + ASSERT_EQ(instance.value, 42); +} + +TEST_F(Meta, MetaFuncAsAlias) { + func_t instance{}; + auto func = entt::resolve().func("a"_hs); + func.invoke(instance).cast() = 3; + + ASSERT_EQ(func.ret(), entt::resolve()); + ASSERT_EQ(instance.value, 3); +} + +TEST_F(Meta, MetaFuncByReference) { + auto func = entt::resolve().func("h"_hs); + func_t::value = 2; + entt::meta_any any{3}; + int value = 4; + + ASSERT_EQ(func.invoke({}, std::ref(value)).cast(), 8); + ASSERT_EQ(func.invoke({}, *any).cast(), 6); + ASSERT_EQ(any.cast(), 6); + ASSERT_EQ(value, 8); +}