Skip to content

Commit 0c2ddb0

Browse files
committed
Merge branch 'main' into add-project-level-readme
2 parents b574c7a + f25064b commit 0c2ddb0

File tree

2 files changed

+202
-2
lines changed

2 files changed

+202
-2
lines changed

tests/expression_tree.cpp

Lines changed: 186 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <attwoodn/expression_tree.hpp>
22
#include "test_utils.hpp"
3+
#include <functional>
34
#include <cassert>
45

56
using namespace attwoodn::expression_tree;
@@ -9,13 +10,15 @@ void test_simple_expression_tree();
910
void test_complex_expression_tree();
1011
void test_moved_expression_tree();
1112
void test_copied_expression_tree();
13+
void test_user_defined_operator();
1214

1315
int main(int argc, char** argv) {
1416
test_expression_tree_std_string_template();
1517
test_simple_expression_tree();
1618
test_complex_expression_tree();
1719
test_moved_expression_tree();
1820
test_copied_expression_tree();
21+
test_user_defined_operator();
1922

2023
return EXIT_SUCCESS;
2124
}
@@ -70,6 +73,140 @@ void test_simple_expression_tree() {
7073

7174
void test_complex_expression_tree() {
7275

76+
// expression: (uint > 0 AND (some_string > "a" AND some_string < "z")) OR (some_string > "0" AND some_string < "9")
77+
expression_tree<test_fixture> expr {
78+
(make_expr(&test_fixture::is_some_uint_greater_than_zero, op::equals, true)
79+
->AND((make_expr(&test_fixture::some_string, op::greater_than, std::string("a"))
80+
->AND(make_expr(&test_fixture::some_string, op::less_than, std::string("z")))
81+
))
82+
)
83+
->OR((make_expr(&test_fixture::some_string, op::greater_than, std::string("0"))
84+
->AND(make_expr(&test_fixture::some_string, op::less_than, std::string("9")))
85+
)
86+
)
87+
};
88+
89+
test_fixture fixture;
90+
91+
fixture.some_uint = 0;
92+
93+
// test left-hand side of the expression tree when some_uint is 0
94+
{
95+
fixture.some_string = "a";
96+
assert(!expr.evaluate(fixture));
97+
98+
fixture.some_string = "aaa";
99+
assert(!expr.evaluate(fixture));
100+
101+
fixture.some_string = "c";
102+
assert(!expr.evaluate(fixture));
103+
104+
fixture.some_string = "yyyyy";
105+
assert(!expr.evaluate(fixture));
106+
107+
fixture.some_string = "B";
108+
assert(!expr.evaluate(fixture));
109+
110+
fixture.some_string = "ZZZ";
111+
assert(!expr.evaluate(fixture));
112+
113+
fixture.some_string = "/";
114+
assert(!expr.evaluate(fixture));
115+
116+
fixture.some_string = "red";
117+
assert(!expr.evaluate(fixture));
118+
119+
fixture.some_string = " ";
120+
assert(!expr.evaluate(fixture));
121+
122+
fixture.some_string = "tree fiddy";
123+
assert(!expr.evaluate(fixture));
124+
}
125+
126+
// test right-hand side of the expression tree when some_uint is 0
127+
{
128+
fixture.some_string = "000";
129+
assert(expr.evaluate(fixture));
130+
131+
fixture.some_string = "00";
132+
assert(expr.evaluate(fixture));
133+
134+
fixture.some_string = "0";
135+
assert(!expr.evaluate(fixture));
136+
137+
fixture.some_string = "12345";
138+
assert(expr.evaluate(fixture));
139+
140+
fixture.some_string = "7";
141+
assert(expr.evaluate(fixture));
142+
143+
fixture.some_string = "89999";
144+
assert(expr.evaluate(fixture));
145+
146+
fixture.some_string = "9";
147+
assert(!expr.evaluate(fixture));
148+
}
149+
150+
fixture.some_uint = 1;
151+
152+
// test left-hand side of the expression tree when some_uint is 0
153+
{
154+
fixture.some_string = "a";
155+
assert(!expr.evaluate(fixture));
156+
157+
fixture.some_string = "aaa";
158+
assert(expr.evaluate(fixture));
159+
160+
fixture.some_string = "c";
161+
assert(expr.evaluate(fixture));
162+
163+
fixture.some_string = "yyyyy";
164+
assert(expr.evaluate(fixture));
165+
166+
fixture.some_string = "B";
167+
assert(!expr.evaluate(fixture));
168+
169+
fixture.some_string = "ZZZ";
170+
assert(!expr.evaluate(fixture));
171+
172+
fixture.some_string = "/";
173+
assert(!expr.evaluate(fixture));
174+
175+
fixture.some_string = "red";
176+
assert(expr.evaluate(fixture));
177+
178+
fixture.some_string = " ";
179+
assert(!expr.evaluate(fixture));
180+
181+
fixture.some_string = "tree fiddy";
182+
assert(expr.evaluate(fixture));
183+
}
184+
185+
// test right-hand side of the expression tree when some_uint is 1
186+
{
187+
fixture.some_string = "000";
188+
assert(expr.evaluate(fixture));
189+
190+
fixture.some_string = "00";
191+
assert(expr.evaluate(fixture));
192+
193+
fixture.some_string = "0";
194+
assert(!expr.evaluate(fixture));
195+
196+
fixture.some_string = "12345";
197+
assert(expr.evaluate(fixture));
198+
199+
fixture.some_string = "7";
200+
assert(expr.evaluate(fixture));
201+
202+
fixture.some_string = "89999";
203+
assert(expr.evaluate(fixture));
204+
205+
fixture.some_string = "9";
206+
assert(!expr.evaluate(fixture));
207+
}
208+
209+
73210
}
74211

75212
void test_moved_expression_tree() {
@@ -103,7 +240,7 @@ void test_moved_expression_tree() {
103240
};
104241
test_procedure(expr);
105242

106-
expression_tree<test_fixture> move_constructed_expr( std::move(expr) );
243+
expression_tree<test_fixture> move_constructed_expr(std::move(expr));
107244
test_procedure(move_constructed_expr);
108245

109246
expression_tree<test_fixture> move_assigned_expr = std::move(move_constructed_expr);
@@ -141,7 +278,7 @@ void test_copied_expression_tree() {
141278
};
142279
test_procedure(expr);
143280

144-
expression_tree<test_fixture> copy_constructed_expr( expr );
281+
expression_tree<test_fixture> copy_constructed_expr(expr);
145282
test_procedure(copy_constructed_expr);
146283

147284
expression_tree<test_fixture> copy_assigned_expr = copy_constructed_expr;
@@ -150,4 +287,51 @@ void test_copied_expression_tree() {
150287
// ensure both of the old copied versions still work after copying
151288
test_procedure(expr);
152289
test_procedure(copy_constructed_expr);
290+
}
291+
292+
void test_user_defined_operator() {
293+
auto is_small_packet_payload = [](const packet_payload& incoming, const packet_payload&) -> bool {
294+
if(incoming.error_code == 0 && incoming.checksum_ok && incoming.payload_size() <= 10) {
295+
return true;
296+
}
297+
return false;
298+
};
299+
300+
// only accept small, non-errored data packets from Jim.
301+
// evaluate packet contents using the user-defined lambda operator defined above
302+
expression_tree<data_packet> expr {
303+
make_expr(&data_packet::sender_name, op::equals, std::string("Jim"))
304+
->AND(make_expr(&data_packet::payload, is_small_packet_payload, packet_payload()))
305+
};
306+
307+
data_packet incoming_packet;
308+
309+
// Jim sends a small, non-errored data packet
310+
incoming_packet.sender_name = "Jim";
311+
incoming_packet.payload.checksum_ok = true;
312+
incoming_packet.payload.data = "hello!";
313+
incoming_packet.payload.error_code = 0;
314+
assert(expr.evaluate(incoming_packet)); // passes evaluation
315+
316+
// Pam sends the same packet payload
317+
incoming_packet.sender_name = "Pam";
318+
assert(!expr.evaluate(incoming_packet)); // fails evaluation. No messages from Pam are accepted (sorry Pam)
319+
320+
// Jim sends a packet with a bad checksum
321+
incoming_packet.sender_name = "Jim";
322+
incoming_packet.payload.checksum_ok = false;
323+
assert(!expr.evaluate(incoming_packet)); // fails evaluation. The packet was from Jim, but the checksum was bad
324+
325+
// Jim sends a packet whose payload is too big
326+
incoming_packet.payload.checksum_ok = true;
327+
incoming_packet.payload.data = "Boy do I have a long story for you - so I was talking to Pam ...";
328+
assert(!expr.evaluate(incoming_packet)); // fails evaluation. The packet's payload was too big. Give me the TLDR next time, Jim
329+
330+
// Jim sends a small, rude packet
331+
incoming_packet.payload.data = "Dwight sux";
332+
assert(expr.evaluate(incoming_packet)); // passes evaluation. The packet's payload was the right size this time
333+
334+
// Jim sends a packet has an error code
335+
incoming_packet.payload.error_code = 404;
336+
assert(!expr.evaluate(incoming_packet)); // fails evaluation. The packet's payload had an error code
153337
}

tests/test_utils.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,20 @@ struct test_fixture {
1515
bool is_some_uint_greater_than_zero() const {
1616
return some_uint;
1717
}
18+
};
19+
20+
struct packet_payload {
21+
uint16_t error_code;
22+
std::string data;
23+
bool checksum_ok;
24+
25+
uint64_t payload_size() const {
26+
return data.size();
27+
}
28+
};
29+
30+
class data_packet {
31+
public:
32+
std::string sender_name;
33+
packet_payload payload;
1834
};

0 commit comments

Comments
 (0)