1 #include <msp/game/reflection.h>
2 #include <msp/test/test.h>
7 class ReflectionTests: public Test::RegisteredTest<ReflectionTests>
12 static const char *get_name() { return "Reflection"; }
16 void basic_polymorphism();
17 void polymorphism_conflict();
18 void deep_polymorphism();
19 void branching_polymorphism();
22 struct A { virtual ~A() = default; };
29 ReflectionTests::ReflectionTests()
31 add(&ReflectionTests::find_class, "find_class");
32 add(&ReflectionTests::basic_polymorphism, "Basic polymorphism");
33 add(&ReflectionTests::polymorphism_conflict, "Polymorphism conflict").expect_throw<std::logic_error>();
34 add(&ReflectionTests::deep_polymorphism, "Deep polymorphism");
35 add(&ReflectionTests::branching_polymorphism, "Branching polymorphism");
39 void ReflectionTests::find_class()
41 Game::Reflection::Reflector reflector;
42 Game::Reflection::Class<A> *a_class = reflector.find_class<A>();
43 EXPECT_EQUAL(a_class, nullptr);
44 Game::Reflection::Class<A> &a_reg = reflector.get_or_create_class<A>();
45 a_class = reflector.find_class<A>();
46 EXPECT(a_class!=nullptr);
47 EXPECT_EQUAL(a_class, &a_reg);
50 void ReflectionTests::basic_polymorphism()
52 Game::Reflection::Reflector reflector;
54 Game::Reflection::Class<A> &a_class = reflector.get_or_create_class<A>();
55 a_class.set_polymorphic_base<A>();
56 Game::Reflection::Class<B> &b_class = reflector.get_or_create_class<B>();
57 b_class.set_polymorphic_base<A>(B());
59 EXPECT(a_class.is_direct_base_of(b_class));
60 EXPECT(!b_class.is_direct_base_of(a_class));
63 EXPECT(a_class.is_instance(a_obj));
64 EXPECT(!b_class.is_instance(a_obj));
67 EXPECT(a_class.is_instance(b_obj));
68 EXPECT(b_class.is_instance(b_obj));
70 A &a_ref_to_b = b_obj;
71 EXPECT(a_class.is_instance(a_ref_to_b));
72 EXPECT(b_class.is_instance(a_ref_to_b));
75 void ReflectionTests::polymorphism_conflict()
77 Game::Reflection::Reflector reflector;
78 Game::Reflection::Class<B> &b_class = reflector.get_or_create_class<B>();
79 b_class.set_polymorphic_base<A>();
80 b_class.set_polymorphic_base<B>();
83 void ReflectionTests::deep_polymorphism()
85 Game::Reflection::Reflector reflector;
87 Game::Reflection::Class<A> &a_class = reflector.get_or_create_class<A>();
88 a_class.set_polymorphic_base<A>();
89 Game::Reflection::Class<B> &b_class = reflector.get_or_create_class<B>();
90 b_class.set_polymorphic_base<A>(B());
91 Game::Reflection::Class<C> &c_class = reflector.get_or_create_class<C>();
92 c_class.set_polymorphic_base<A>(C());
93 Game::Reflection::Class<D> &d_class = reflector.get_or_create_class<D>();
94 d_class.set_polymorphic_base<A>(D());
96 EXPECT(a_class.is_direct_base_of(b_class));
97 EXPECT(!a_class.is_direct_base_of(c_class));
98 EXPECT(!a_class.is_direct_base_of(d_class));
99 EXPECT(a_class.is_base_of(c_class));
100 EXPECT(a_class.is_base_of(d_class));
101 EXPECT(b_class.is_direct_base_of(c_class));
102 EXPECT(!b_class.is_direct_base_of(d_class));
103 EXPECT(b_class.is_base_of(d_class));
104 EXPECT(c_class.is_direct_base_of(d_class));
107 EXPECT(a_class.is_instance(d_obj));
108 EXPECT(b_class.is_instance(d_obj));
109 EXPECT(c_class.is_instance(d_obj));
110 EXPECT(d_class.is_instance(d_obj));
112 B &b_ref_to_d = d_obj;
113 EXPECT(a_class.is_instance(b_ref_to_d));
114 EXPECT(b_class.is_instance(b_ref_to_d));
115 EXPECT(c_class.is_instance(b_ref_to_d));
116 EXPECT(d_class.is_instance(b_ref_to_d));
118 C &c_ref_to_d = d_obj;
119 EXPECT(a_class.is_instance(c_ref_to_d));
120 EXPECT(b_class.is_instance(c_ref_to_d));
121 EXPECT(c_class.is_instance(c_ref_to_d));
122 EXPECT(d_class.is_instance(c_ref_to_d));
125 void ReflectionTests::branching_polymorphism()
127 Game::Reflection::Reflector reflector;
129 Game::Reflection::Class<A> &a_class = reflector.get_or_create_class<A>();
130 a_class.set_polymorphic_base<A>();
131 Game::Reflection::Class<B> &b_class = reflector.get_or_create_class<B>();
132 b_class.set_polymorphic_base<A>(B());
133 Game::Reflection::Class<C> &c_class = reflector.get_or_create_class<C>();
134 c_class.set_polymorphic_base<A>(C());
135 Game::Reflection::Class<C2> &c2_class = reflector.get_or_create_class<C2>();
136 c2_class.set_polymorphic_base<A>(C2());
138 EXPECT(a_class.is_direct_base_of(b_class));
139 EXPECT(a_class.is_base_of(c_class));
140 EXPECT(a_class.is_base_of(c2_class));
141 EXPECT(b_class.is_direct_base_of(c_class));
142 EXPECT(b_class.is_direct_base_of(c2_class));
143 EXPECT(!c_class.is_base_of(c2_class));
144 EXPECT(!c2_class.is_base_of(c_class));
148 EXPECT(a_class.is_instance(c_obj));
149 EXPECT(a_class.is_instance(c2_obj));
150 EXPECT(b_class.is_instance(c_obj));
151 EXPECT(b_class.is_instance(c2_obj));
152 EXPECT(c_class.is_instance(c_obj));
153 EXPECT(!c_class.is_instance(c2_obj));
154 EXPECT(c2_class.is_instance(c2_obj));
155 EXPECT(!c2_class.is_instance(c_obj));