]> git.tdb.fi Git - libs/game.git/blob - tests/reflection.cpp
Add unit tests for reflection
[libs/game.git] / tests / reflection.cpp
1 #include <msp/game/reflection.h>
2 #include <msp/test/test.h>
3
4 using namespace std;
5 using namespace Msp;
6
7 class ReflectionTests: public Test::RegisteredTest<ReflectionTests>
8 {
9 public:
10         ReflectionTests();
11
12         static const char *get_name() { return "Reflection"; }
13
14 private:
15         void find_class();
16         void basic_polymorphism();
17         void polymorphism_conflict();
18         void deep_polymorphism();
19         void branching_polymorphism();
20 };
21
22 struct A { virtual ~A() = default; };
23 struct B: A { };
24 struct C: B { };
25 struct D: C { };
26 struct C2: B { };
27
28
29 ReflectionTests::ReflectionTests()
30 {
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");
36 }
37
38
39 void ReflectionTests::find_class()
40 {
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);
48 }
49
50 void ReflectionTests::basic_polymorphism()
51 {
52         Game::Reflection::Reflector reflector;
53
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());
58
59         EXPECT(a_class.is_direct_base_of(b_class));
60         EXPECT(!b_class.is_direct_base_of(a_class));
61
62         A a_obj;
63         EXPECT(a_class.is_instance(a_obj));
64         EXPECT(!b_class.is_instance(a_obj));
65
66         B b_obj;
67         EXPECT(a_class.is_instance(b_obj));
68         EXPECT(b_class.is_instance(b_obj));
69
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));
73 }
74
75 void ReflectionTests::polymorphism_conflict()
76 {
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>();
81 }
82
83 void ReflectionTests::deep_polymorphism()
84 {
85         Game::Reflection::Reflector reflector;
86
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());
95
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));
105
106         D d_obj;
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));
111
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));
117
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));
123 }
124
125 void ReflectionTests::branching_polymorphism()
126 {
127         Game::Reflection::Reflector reflector;
128
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());
137
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));
145
146         C c_obj;
147         C2 c2_obj;
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));
156 }