From 7d1b3c5df2eab1d42179332d467d5756aefed587 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Wed, 14 Jan 2015 02:44:09 +0100 Subject: Implemented attaching Methods and Property information to Types (this will later allow script engines to access these methods). --- test/core/common/PropertyTest.cpp | 10 ++- test/core/common/RttiTest.cpp | 164 +++++++++++++++++++++++++++++++++++--- test/core/managed/ManagedTest.cpp | 9 ++- 3 files changed, 163 insertions(+), 20 deletions(-) (limited to 'test/core') diff --git a/test/core/common/PropertyTest.cpp b/test/core/common/PropertyTest.cpp index c28feeb..0f3d74e 100644 --- a/test/core/common/PropertyTest.cpp +++ b/test/core/common/PropertyTest.cpp @@ -61,7 +61,8 @@ TEST(Getter, construction) TEST(Getter, validation) { - const PropertyType type{RttiTypes::Int}; + std::shared_ptr type = + std::make_shared(RttiTypes::Int); TestObject obj{123}; { @@ -73,7 +74,7 @@ TEST(Getter, validation) { // Int type set, returning strings is an exception Getter getter{getString}; - getter.propertyType = &type; + getter.propertyType = type; ASSERT_THROW(getter.get(&obj), LoggableException); } @@ -109,7 +110,8 @@ TEST(Setter, construction) TEST(Setter, validation) { - const PropertyType type{RttiTypes::Int}; + std::shared_ptr type = + std::make_shared(RttiTypes::Int); TestObject obj{123}; Setter setter{TestObject::setA}; @@ -128,7 +130,7 @@ TEST(Setter, validation) setter.set("foo", &obj); ASSERT_EQ(42, obj.a); - setter.propertyType = &type; + setter.propertyType = type; ASSERT_THROW(setter.set("foo", &obj), LoggableException); setter.set(123, &obj); diff --git a/test/core/common/RttiTest.cpp b/test/core/common/RttiTest.cpp index 36bf48f..5d02553 100644 --- a/test/core/common/RttiTest.cpp +++ b/test/core/common/RttiTest.cpp @@ -22,7 +22,10 @@ #include +#include #include +#include +#include namespace ousia { namespace { @@ -45,18 +48,15 @@ class RttiTestClass7 { extern const Rtti Type6; extern const Rtti Type7; -const Rtti Type1("Type1"); -const Rtti Type2("Type2"); -const Rtti Type3("Type3", {&Type1}); -const Rtti Type4("Type4", {&Type3, &Type2}); -const Rtti Type5("Type5", - std::unordered_set{}, - {&Type6, &Type7}); -const Rtti Type6("Type6", - std::unordered_set{}, - {&Type1}); -const Rtti Type7("Type7", {&Type6}, - std::unordered_set{}); +const Rtti Type1 = RttiBuilder{"Type1"}; +const Rtti Type2 = RttiBuilder{"Type2"}; +const Rtti Type3 = RttiBuilder{"Type3"}.parent(&Type1); +const Rtti Type4 = + RttiBuilder{"Type4"}.parent({&Type3, &Type2}); +const Rtti Type5 = + RttiBuilder{"Type5"}.composedOf({&Type6, &Type7}); +const Rtti Type6 = RttiBuilder{"Type6"}.composedOf(&Type1); +const Rtti Type7 = RttiBuilder{"Type7"}.parent(&Type6); TEST(Rtti, isa) { @@ -118,6 +118,146 @@ TEST(Rtti, composedOf) ASSERT_FALSE(Type7.composedOf(Type6)); ASSERT_FALSE(Type7.composedOf(Type7)); } + +class RttiMethodTestClass1 { +}; +class RttiMethodTestClass2 { +}; + +static const Rtti MType1 = + RttiBuilder{"MType1"} + .genericMethod( + "a", std::make_shared>([]( + Variant::arrayType &args, + RttiMethodTestClass1 *thisPtr) { return Variant{"a"}; })) + .genericMethod( + "b", std::make_shared>([]( + Variant::arrayType &args, + RttiMethodTestClass1 *thisPtr) { return Variant{"b"}; })) + .genericMethod( + "c", std::make_shared>([]( + Variant::arrayType &args, + RttiMethodTestClass1 *thisPtr) { return Variant{"c"}; })); + +static const Rtti MType2 = + TypedRttiBuilder{"MType2"} + .parent(&MType1) + .method("c", + [](Variant::arrayType &args, + RttiMethodTestClass2 *thisPtr) { return Variant{"c2"}; }) + .method("d", [](Variant::arrayType &args, + RttiMethodTestClass2 *thisPtr) { return Variant{"d"}; }) + .method("e", + {{Argument::Int("a"), Argument::Int("b")}, + [](Variant::arrayType &args, RttiMethodTestClass2 *thisPtr) { + return Variant{args[0].asInt() * args[1].asInt()}; + }}); + +TEST(Rtti, methods) +{ + auto methods = MType1.getMethods(); + ASSERT_TRUE(methods.count("a") > 0); + ASSERT_TRUE(methods.count("b") > 0); + ASSERT_TRUE(methods.count("c") > 0); + + ASSERT_FALSE(MType1.getMethod("a") == nullptr); + ASSERT_FALSE(MType1.getMethod("b") == nullptr); + ASSERT_FALSE(MType1.getMethod("c") == nullptr); + ASSERT_TRUE(MType1.getMethod("d") == nullptr); + + ASSERT_EQ("a", MType1.getMethod("a")->call().asString()); + ASSERT_EQ("b", MType1.getMethod("b")->call().asString()); + ASSERT_EQ("c", MType1.getMethod("c")->call().asString()); + + methods = MType2.getMethods(); + ASSERT_TRUE(methods.count("a") > 0); + ASSERT_TRUE(methods.count("b") > 0); + ASSERT_TRUE(methods.count("c") > 0); + ASSERT_TRUE(methods.count("d") > 0); + + ASSERT_FALSE(MType2.getMethod("a") == nullptr); + ASSERT_FALSE(MType2.getMethod("b") == nullptr); + ASSERT_FALSE(MType2.getMethod("c") == nullptr); + ASSERT_FALSE(MType2.getMethod("d") == nullptr); + + ASSERT_EQ("a", MType2.getMethod("a")->call().asString()); + ASSERT_EQ("b", MType2.getMethod("b")->call().asString()); + ASSERT_EQ("c2", MType2.getMethod("c")->call().asString()); + ASSERT_EQ("d", MType2.getMethod("d")->call().asString()); + ASSERT_EQ(42, + MType2.getMethod("e")->call(Variant::arrayType{6, 7}).asInt()); + ASSERT_THROW(MType2.getMethod("e")->call(Variant::arrayType{6, "7"}), + LoggableException); +} + +class RttiPropertyTestClass1 { +public: + int a; + + RttiPropertyTestClass1() : a(0) {} + + static Variant getA(const RttiPropertyTestClass1 *obj) { return obj->a; } + + static void setA(const Variant &value, RttiPropertyTestClass1 *obj) + { + obj->a = value.asInt(); + } +}; + +class RttiPropertyTestClass2 : public RttiPropertyTestClass1 { +public: + int b; + + RttiPropertyTestClass2() : b(0) {} + + static Variant getB(const RttiPropertyTestClass2 *obj) { return obj->b; } + + static void setB(const Variant &value, RttiPropertyTestClass2 *obj) + { + obj->b = value.asInt(); + } +}; + +static const Rtti PType1 = + TypedRttiBuilder{"PType1"}.property( + "a", {RttiTypes::Int, RttiPropertyTestClass1::getA, + RttiPropertyTestClass1::setA}); + +static const Rtti PType2 = + TypedRttiBuilder{"PType2"}.parent(&PType1).property( + "b", {RttiTypes::Int, RttiPropertyTestClass2::getB, + RttiPropertyTestClass2::setB}); + +TEST(Rtti, properties) +{ + RttiPropertyTestClass2 obj; + + auto properties = PType1.getProperties(); + ASSERT_TRUE(properties.count("a") > 0); + ASSERT_FALSE(properties.count("b") > 0); + + ASSERT_FALSE(PType1.getProperty("a") == nullptr); + ASSERT_TRUE(PType1.getProperty("b") == nullptr); + + ASSERT_EQ(0, PType1.getProperty("a")->get(&obj).asInt()); + PType1.getProperty("a")->set(4, &obj); + ASSERT_EQ(4, PType1.getProperty("a")->get(&obj).asInt()); + + properties = PType2.getProperties(); + ASSERT_TRUE(properties.count("a") > 0); + ASSERT_TRUE(properties.count("b") > 0); + + ASSERT_FALSE(PType2.getProperty("a") == nullptr); + ASSERT_FALSE(PType2.getProperty("b") == nullptr); + + ASSERT_EQ(4, PType2.getProperty("a")->get(&obj).asInt()); + PType2.getProperty("a")->set(8, &obj); + ASSERT_EQ(8, PType2.getProperty("a")->get(&obj).asInt()); + + ASSERT_EQ(0, PType2.getProperty("b")->get(&obj).asInt()); + PType2.getProperty("b")->set(5, &obj); + ASSERT_EQ(5, PType2.getProperty("b")->get(&obj).asInt()); +} } } diff --git a/test/core/managed/ManagedTest.cpp b/test/core/managed/ManagedTest.cpp index a943f5d..0391738 100644 --- a/test/core/managed/ManagedTest.cpp +++ b/test/core/managed/ManagedTest.cpp @@ -76,10 +76,11 @@ class TypeTestManaged5 : public Managed { using Managed::Managed; }; -static const Rtti Type1("Type1"); -static const Rtti Type2("Type2"); -static const Rtti Type3("Type3", {&Type1}); -static const Rtti Type4("Type4", {&Type3, &Type2}); +static const Rtti Type1 = RttiBuilder{"Type1"}; +static const Rtti Type2 = RttiBuilder{"Type2"}; +static const Rtti Type3 = RttiBuilder{"Type3"}.parent(&Type1); +static const Rtti Type4 = + RttiBuilder{"Type4"}.parent({&Type3, &Type2}); TEST(Managed, type) { -- cgit v1.2.3