Skip to content

Commit 26bac42

Browse files
committed
gamestate: Add unit tests for activity node types.
1 parent 70c6229 commit 26bac42

File tree

4 files changed

+256
-0
lines changed

4 files changed

+256
-0
lines changed

libopenage/gamestate/activity/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ add_sources(libopenage
1414

1515
add_subdirectory("event")
1616
add_subdirectory("condition")
17+
add_subdirectory("tests")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
add_sources(libopenage
2+
node_types.cpp
3+
)
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
// Copyright 2024-2024 the openage authors. See copying.md for legal info.
2+
3+
#include <memory>
4+
5+
#include "gamestate/activity/end_node.h"
6+
#include "gamestate/activity/start_node.h"
7+
#include "gamestate/activity/task_node.h"
8+
#include "gamestate/activity/task_system_node.h"
9+
#include "gamestate/activity/types.h"
10+
#include "gamestate/activity/xor_event_gate.h"
11+
#include "gamestate/activity/xor_gate.h"
12+
#include "gamestate/activity/xor_switch_gate.h"
13+
#include "gamestate/system/types.h"
14+
#include "testing/testing.h"
15+
16+
17+
namespace openage::gamestate::activity::tests {
18+
19+
/**
20+
* Unit tests for the activity node types.
21+
*/
22+
void node_types() {
23+
// Start node type
24+
{
25+
auto start_node = std::make_shared<StartNode>(0);
26+
27+
// Check basic properties inherited from Node interface
28+
TESTEQUALS(start_node->get_id(), 0);
29+
TESTEQUALS(static_cast<int>(start_node->get_type()), static_cast<int>(node_t::START));
30+
TESTEQUALS(start_node->get_label(), "Start");
31+
TESTEQUALS(start_node->str(), "Start (id=0)");
32+
33+
auto next_node = std::make_shared<EndNode>(1);
34+
start_node->add_output(next_node);
35+
36+
// Check the next node
37+
TESTEQUALS(start_node->get_next(), 1);
38+
TESTEQUALS(start_node->next(1), next_node);
39+
40+
// Check that the node throws errors for invalid output IDs
41+
TESTTHROWS(start_node->next(999));
42+
}
43+
44+
// End node type
45+
{
46+
auto end_node = std::make_shared<EndNode>(0);
47+
48+
// Check basic properties inherited from Node interface
49+
TESTEQUALS(end_node->get_id(), 0);
50+
// TESTEQUALS(end_node->get_type(), node_t::END);
51+
TESTEQUALS(end_node->get_label(), "End");
52+
TESTEQUALS(end_node->str(), "End (id=0)");
53+
54+
// End nodes have no outputs
55+
TESTTHROWS(end_node->next(999));
56+
}
57+
58+
// Task system node type
59+
{
60+
auto task_system_node = std::make_shared<TaskSystemNode>(0);
61+
62+
// Check basic properties inherited from Node interface
63+
TESTEQUALS(task_system_node->get_id(), 0);
64+
// TESTEQUALS(task_system_node->get_type(), node_t::TASK_SYSTEM);
65+
TESTEQUALS(task_system_node->get_label(), "TaskSystem");
66+
TESTEQUALS(task_system_node->str(), "TaskSystem (id=0)");
67+
68+
auto next_node = std::make_shared<EndNode>(1);
69+
task_system_node->add_output(next_node);
70+
71+
// Check the next node
72+
TESTEQUALS(task_system_node->get_next(), 1);
73+
TESTEQUALS(task_system_node->next(1), next_node);
74+
75+
// Check that the node throws errors for invalid output IDs
76+
TESTTHROWS(task_system_node->next(999));
77+
78+
auto sytem_id = system::system_id_t::MOVE_DEFAULT;
79+
task_system_node->set_system_id(sytem_id);
80+
81+
// Check the system ID
82+
TESTEQUALS(static_cast<int>(task_system_node->get_system_id()), static_cast<int>(sytem_id));
83+
}
84+
85+
// Task custom node type
86+
{
87+
auto task_custom_node = std::make_shared<TaskCustom>(0);
88+
89+
// Check basic properties inherited from Node interface
90+
TESTEQUALS(task_custom_node->get_id(), 0);
91+
// TESTEQUALS(task_custom_node->get_type(), node_t::TASK_CUSTOM);
92+
TESTEQUALS(task_custom_node->get_label(), "TaskCustom");
93+
TESTEQUALS(task_custom_node->str(), "TaskCustom (id=0)");
94+
95+
auto next_node = std::make_shared<EndNode>(1);
96+
task_custom_node->add_output(next_node);
97+
98+
// Check the next node
99+
TESTEQUALS(task_custom_node->get_next(), 1);
100+
TESTEQUALS(task_custom_node->next(1), next_node);
101+
102+
// Check that the node throws errors for invalid output IDs
103+
TESTTHROWS(task_custom_node->next(999));
104+
105+
auto task_func = [](const time::time_t & /* time */, const std::shared_ptr<GameEntity> & /* entity */) {
106+
// Do nothing
107+
};
108+
task_custom_node->set_task_func(task_func);
109+
110+
// Check the task function
111+
auto get_func = task_custom_node->get_task_func();
112+
get_func(time::time_t{0}, nullptr);
113+
}
114+
115+
// Xor gate node type
116+
{
117+
auto xor_gate_node = std::make_shared<XorGate>(0);
118+
119+
// Check basic properties inherited from Node interface
120+
TESTEQUALS(xor_gate_node->get_id(), 0);
121+
// TESTEQUALS(xor_gate_node->get_type(), node_t::XOR_GATE);
122+
TESTEQUALS(xor_gate_node->get_label(), "ExclusiveGateway");
123+
TESTEQUALS(xor_gate_node->str(), "ExclusiveGateway (id=0)");
124+
125+
auto default_node = std::make_shared<EndNode>(1);
126+
xor_gate_node->set_default(default_node);
127+
128+
// Check the default node
129+
TESTEQUALS(xor_gate_node->get_default(), default_node);
130+
131+
auto option1_node = std::make_shared<EndNode>(2);
132+
xor_gate_node->add_output(option1_node, [](const time::time_t &time, const std::shared_ptr<GameEntity> & /* entity */) {
133+
return time == time::TIME_ZERO;
134+
});
135+
136+
auto option2_node = std::make_shared<EndNode>(3);
137+
xor_gate_node->add_output(option2_node, [](const time::time_t &time, const std::shared_ptr<GameEntity> & /* entity */) {
138+
return time == time::TIME_MAX;
139+
});
140+
141+
auto conditions = xor_gate_node->get_conditions();
142+
143+
// Check the conditions
144+
TESTEQUALS(conditions.size(), 2);
145+
146+
TESTEQUALS(conditions.at(2)(time::TIME_ZERO, nullptr), true);
147+
TESTEQUALS(conditions.at(3)(time::TIME_ZERO, nullptr), false);
148+
149+
TESTEQUALS(conditions.at(2)(time::TIME_MAX, nullptr), false);
150+
TESTEQUALS(conditions.at(3)(time::TIME_MAX, nullptr), true);
151+
152+
// Check if next nodes return correctly
153+
TESTEQUALS(xor_gate_node->next(1), default_node);
154+
TESTEQUALS(xor_gate_node->next(2), option1_node);
155+
TESTEQUALS(xor_gate_node->next(3), option2_node);
156+
157+
// Check that the node throws errors for invalid output IDs
158+
TESTTHROWS(xor_gate_node->next(999));
159+
}
160+
161+
// Xor switch gate node type
162+
{
163+
auto xor_switch_gate_node = std::make_shared<XorSwitchGate>(0);
164+
165+
// Check basic properties inherited from Node interface
166+
TESTEQUALS(xor_switch_gate_node->get_id(), 0);
167+
// TESTEQUALS(xor_switch_gate_node->get_type(), node_t::XOR_SWITCH_GATE);
168+
TESTEQUALS(xor_switch_gate_node->get_label(), "ExclusiveSwitchGateway");
169+
TESTEQUALS(xor_switch_gate_node->str(), "ExclusiveSwitchGateway (id=0)");
170+
171+
auto default_node = std::make_shared<EndNode>(1);
172+
xor_switch_gate_node->set_default(default_node);
173+
174+
// Check the default node
175+
TESTEQUALS(xor_switch_gate_node->get_default(), default_node);
176+
177+
auto option1_node = std::make_shared<EndNode>(2);
178+
xor_switch_gate_node->set_output(option1_node, 1);
179+
180+
auto option2_node = std::make_shared<EndNode>(3);
181+
xor_switch_gate_node->set_output(option2_node, 2);
182+
183+
auto lookup_func = [](const time::time_t &time, const std::shared_ptr<GameEntity> & /* entity */) {
184+
if (time == time::TIME_ZERO) {
185+
return 1;
186+
}
187+
if (time == time::TIME_MAX) {
188+
return 2;
189+
}
190+
191+
return 0;
192+
};
193+
xor_switch_gate_node->set_lookup_func(lookup_func);
194+
195+
// Check the lookup function
196+
TESTEQUALS(xor_switch_gate_node->get_lookup_func()(time::TIME_ZERO, nullptr), 1);
197+
TESTEQUALS(xor_switch_gate_node->get_lookup_func()(time::TIME_MAX, nullptr), 2);
198+
TESTEQUALS(xor_switch_gate_node->get_lookup_func()(time::TIME_MIN, nullptr), 0);
199+
200+
auto lookup_dict = xor_switch_gate_node->get_lookup_dict();
201+
202+
// Check the lookup dict
203+
TESTEQUALS(lookup_dict.size(), 2);
204+
205+
TESTEQUALS(lookup_dict.at(1), option1_node);
206+
TESTEQUALS(lookup_dict.at(2), option2_node);
207+
208+
// Check if next nodes return correctly
209+
TESTEQUALS(xor_switch_gate_node->next(1), default_node);
210+
TESTEQUALS(xor_switch_gate_node->next(2), option1_node);
211+
TESTEQUALS(xor_switch_gate_node->next(3), option2_node);
212+
213+
// Check that the node throws errors for invalid output IDs
214+
TESTTHROWS(xor_switch_gate_node->next(999));
215+
}
216+
217+
// Xor event gate node type
218+
{
219+
auto xor_event_gate_node = std::make_shared<XorEventGate>(0);
220+
221+
// Check basic properties inherited from Node interface
222+
TESTEQUALS(xor_event_gate_node->get_id(), 0);
223+
// TESTEQUALS(xor_event_gate_node->get_type(), node_t::XOR_EVENT_GATE);
224+
TESTEQUALS(xor_event_gate_node->get_label(), "ExclusiveEventGateway");
225+
TESTEQUALS(xor_event_gate_node->str(), "ExclusiveEventGateway (id=0)");
226+
227+
auto option1_node = std::make_shared<EndNode>(1);
228+
xor_event_gate_node->add_output(option1_node, [](const time::time_t & /* time */, const std::shared_ptr<GameEntity> & /* entity */, const std::shared_ptr<event::EventLoop> & /* loop */, const std::shared_ptr<GameState> & /* state */, size_t /* next_id */) {
229+
return nullptr;
230+
});
231+
232+
auto option2_node = std::make_shared<EndNode>(2);
233+
xor_event_gate_node->add_output(option2_node, [](const time::time_t & /* time */, const std::shared_ptr<GameEntity> & /* entity */, const std::shared_ptr<event::EventLoop> & /* loop */, const std::shared_ptr<GameState> & /* state */, size_t /* next_id */) {
234+
return nullptr;
235+
});
236+
237+
auto primers = xor_event_gate_node->get_primers();
238+
239+
// Check the primers
240+
TESTEQUALS(primers.size(), 2);
241+
242+
// Check if next nodes return correctly
243+
TESTEQUALS(xor_event_gate_node->next(1), option1_node);
244+
TESTEQUALS(xor_event_gate_node->next(2), option2_node);
245+
246+
// Check that the node throws errors for invalid output IDs
247+
TESTTHROWS(xor_event_gate_node->next(999));
248+
}
249+
}
250+
251+
} // namespace openage::gamestate::activity::tests

openage/testing/testlist.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def tests_cpp():
104104
yield "openage::curve::tests::container"
105105
yield "openage::curve::tests::curve_types"
106106
yield "openage::event::tests::eventtrigger"
107+
yield "openage::gamestate::activity::tests::node_types"
107108

108109

109110
def demos_cpp():

0 commit comments

Comments
 (0)