xref: /netbsd-src/external/bsd/kyua-cli/dist/utils/config/nodes_test.cpp (revision 6b3a42af15b5e090c339512c790dd68f3d11a9d8)
1 // Copyright 2012 Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 //   notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 //   notice, this list of conditions and the following disclaimer in the
12 //   documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 //   may be used to endorse or promote products derived from this software
15 //   without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #include "utils/config/nodes.ipp"
30 
31 #include <atf-c++.hpp>
32 
33 #include <lutok/state.ipp>
34 
35 #include "utils/config/exceptions.hpp"
36 #include "utils/config/keys.hpp"
37 #include "utils/defs.hpp"
38 
39 namespace config = utils::config;
40 
41 
42 namespace {
43 
44 
45 /// Typed leaf node that specializes the validate() method.
46 class validation_node : public config::int_node {
47     /// Checks a given value for validity against a fake value.
48     ///
49     /// \param new_value The value to validate.
50     ///
51     /// \throw value_error If the value is not valid.
52     void
validate(const value_type & new_value) const53     validate(const value_type& new_value) const
54     {
55         if (new_value == 12345)
56             throw config::value_error("Custom validate method");
57     }
58 };
59 
60 
61 /// Set node that specializes the validate() method.
62 class set_validation_node : public config::strings_set_node {
63     /// Checks a given value for validity against a fake value.
64     ///
65     /// \param new_value The value to validate.
66     ///
67     /// \throw value_error If the value is not valid.
68     void
validate(const value_type & new_value) const69     validate(const value_type& new_value) const
70     {
71         for (value_type::const_iterator iter = new_value.begin();
72              iter != new_value.end(); ++iter)
73             if (*iter == "throw")
74                 throw config::value_error("Custom validate method");
75     }
76 };
77 
78 
79 }  // anonymous namespace
80 
81 
82 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__deep_copy);
ATF_TEST_CASE_BODY(bool_node__deep_copy)83 ATF_TEST_CASE_BODY(bool_node__deep_copy)
84 {
85     config::bool_node node;
86     node.set(true);
87     config::detail::base_node* raw_copy = node.deep_copy();
88     config::bool_node* copy = static_cast< config::bool_node* >(raw_copy);
89     ATF_REQUIRE(copy->value());
90     copy->set(false);
91     ATF_REQUIRE(node.value());
92     ATF_REQUIRE(!copy->value());
93     delete copy;
94 }
95 
96 
97 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__is_set_and_set);
ATF_TEST_CASE_BODY(bool_node__is_set_and_set)98 ATF_TEST_CASE_BODY(bool_node__is_set_and_set)
99 {
100     config::bool_node node;
101     ATF_REQUIRE(!node.is_set());
102     node.set(false);
103     ATF_REQUIRE( node.is_set());
104 }
105 
106 
107 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__value_and_set);
ATF_TEST_CASE_BODY(bool_node__value_and_set)108 ATF_TEST_CASE_BODY(bool_node__value_and_set)
109 {
110     config::bool_node node;
111     node.set(false);
112     ATF_REQUIRE(!node.value());
113     node.set(true);
114     ATF_REQUIRE( node.value());
115 }
116 
117 
118 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__push_lua);
ATF_TEST_CASE_BODY(bool_node__push_lua)119 ATF_TEST_CASE_BODY(bool_node__push_lua)
120 {
121     lutok::state state;
122 
123     config::bool_node node;
124     node.set(true);
125     node.push_lua(state);
126     ATF_REQUIRE(state.is_boolean(-1));
127     ATF_REQUIRE(state.to_boolean(-1));
128     state.pop(1);
129 }
130 
131 
132 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_lua__ok);
ATF_TEST_CASE_BODY(bool_node__set_lua__ok)133 ATF_TEST_CASE_BODY(bool_node__set_lua__ok)
134 {
135     lutok::state state;
136 
137     config::bool_node node;
138     state.push_boolean(false);
139     node.set_lua(state, -1);
140     state.pop(1);
141     ATF_REQUIRE(!node.value());
142 }
143 
144 
145 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_lua__invalid_value);
ATF_TEST_CASE_BODY(bool_node__set_lua__invalid_value)146 ATF_TEST_CASE_BODY(bool_node__set_lua__invalid_value)
147 {
148     lutok::state state;
149 
150     config::bool_node node;
151     state.push_string("foo bar");
152     ATF_REQUIRE_THROW(config::value_error, node.set_lua(state, -1));
153     state.pop(1);
154     ATF_REQUIRE(!node.is_set());
155 }
156 
157 
158 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_string__ok);
ATF_TEST_CASE_BODY(bool_node__set_string__ok)159 ATF_TEST_CASE_BODY(bool_node__set_string__ok)
160 {
161     config::bool_node node;
162     node.set_string("false");
163     ATF_REQUIRE(!node.value());
164     node.set_string("true");
165     ATF_REQUIRE( node.value());
166 }
167 
168 
169 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_string__invalid_value);
ATF_TEST_CASE_BODY(bool_node__set_string__invalid_value)170 ATF_TEST_CASE_BODY(bool_node__set_string__invalid_value)
171 {
172     config::bool_node node;
173     ATF_REQUIRE_THROW(config::value_error, node.set_string("12345"));
174     ATF_REQUIRE(!node.is_set());
175 }
176 
177 
178 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__to_string);
ATF_TEST_CASE_BODY(bool_node__to_string)179 ATF_TEST_CASE_BODY(bool_node__to_string)
180 {
181     config::bool_node node;
182     node.set(false);
183     ATF_REQUIRE_EQ("false", node.to_string());
184     node.set(true);
185     ATF_REQUIRE_EQ("true", node.to_string());
186 }
187 
188 
189 ATF_TEST_CASE_WITHOUT_HEAD(int_node__deep_copy);
ATF_TEST_CASE_BODY(int_node__deep_copy)190 ATF_TEST_CASE_BODY(int_node__deep_copy)
191 {
192     config::int_node node;
193     node.set(5);
194     config::detail::base_node* raw_copy = node.deep_copy();
195     config::int_node* copy = static_cast< config::int_node* >(raw_copy);
196     ATF_REQUIRE_EQ(5, copy->value());
197     copy->set(10);
198     ATF_REQUIRE_EQ(5, node.value());
199     ATF_REQUIRE_EQ(10, copy->value());
200     delete copy;
201 }
202 
203 
204 ATF_TEST_CASE_WITHOUT_HEAD(int_node__is_set_and_set);
ATF_TEST_CASE_BODY(int_node__is_set_and_set)205 ATF_TEST_CASE_BODY(int_node__is_set_and_set)
206 {
207     config::int_node node;
208     ATF_REQUIRE(!node.is_set());
209     node.set(20);
210     ATF_REQUIRE( node.is_set());
211 }
212 
213 
214 ATF_TEST_CASE_WITHOUT_HEAD(int_node__value_and_set);
ATF_TEST_CASE_BODY(int_node__value_and_set)215 ATF_TEST_CASE_BODY(int_node__value_and_set)
216 {
217     config::int_node node;
218     node.set(20);
219     ATF_REQUIRE_EQ(20, node.value());
220     node.set(0);
221     ATF_REQUIRE_EQ(0, node.value());
222 }
223 
224 
225 ATF_TEST_CASE_WITHOUT_HEAD(int_node__push_lua);
ATF_TEST_CASE_BODY(int_node__push_lua)226 ATF_TEST_CASE_BODY(int_node__push_lua)
227 {
228     lutok::state state;
229 
230     config::int_node node;
231     node.set(754);
232     node.push_lua(state);
233     ATF_REQUIRE(state.is_number(-1));
234     ATF_REQUIRE_EQ(754, state.to_integer(-1));
235     state.pop(1);
236 }
237 
238 
239 ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_lua__ok);
ATF_TEST_CASE_BODY(int_node__set_lua__ok)240 ATF_TEST_CASE_BODY(int_node__set_lua__ok)
241 {
242     lutok::state state;
243 
244     config::int_node node;
245     state.push_integer(123);
246     state.push_string("456");
247     node.set_lua(state, -2);
248     ATF_REQUIRE_EQ(123, node.value());
249     node.set_lua(state, -1);
250     ATF_REQUIRE_EQ(456, node.value());
251     state.pop(2);
252 }
253 
254 
255 ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_lua__invalid_value);
ATF_TEST_CASE_BODY(int_node__set_lua__invalid_value)256 ATF_TEST_CASE_BODY(int_node__set_lua__invalid_value)
257 {
258     lutok::state state;
259 
260     config::int_node node;
261     state.push_boolean(true);
262     ATF_REQUIRE_THROW(config::value_error, node.set_lua(state, -1));
263     state.pop(1);
264     ATF_REQUIRE(!node.is_set());
265 }
266 
267 
268 ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_string__ok);
ATF_TEST_CASE_BODY(int_node__set_string__ok)269 ATF_TEST_CASE_BODY(int_node__set_string__ok)
270 {
271     config::int_node node;
272     node.set_string("178");
273     ATF_REQUIRE_EQ(178, node.value());
274     node.set_string("-123");
275     ATF_REQUIRE_EQ(-123, node.value());
276 }
277 
278 
279 ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_string__invalid_value);
ATF_TEST_CASE_BODY(int_node__set_string__invalid_value)280 ATF_TEST_CASE_BODY(int_node__set_string__invalid_value)
281 {
282     config::int_node node;
283     ATF_REQUIRE_THROW(config::value_error, node.set_string(" 23"));
284     ATF_REQUIRE(!node.is_set());
285 }
286 
287 
288 ATF_TEST_CASE_WITHOUT_HEAD(int_node__to_string);
ATF_TEST_CASE_BODY(int_node__to_string)289 ATF_TEST_CASE_BODY(int_node__to_string)
290 {
291     config::int_node node;
292     node.set(89);
293     ATF_REQUIRE_EQ("89", node.to_string());
294     node.set(-57);
295     ATF_REQUIRE_EQ("-57", node.to_string());
296 }
297 
298 
299 ATF_TEST_CASE_WITHOUT_HEAD(string_node__deep_copy);
ATF_TEST_CASE_BODY(string_node__deep_copy)300 ATF_TEST_CASE_BODY(string_node__deep_copy)
301 {
302     config::string_node node;
303     node.set("first");
304     config::detail::base_node* raw_copy = node.deep_copy();
305     config::string_node* copy = static_cast< config::string_node* >(raw_copy);
306     ATF_REQUIRE_EQ("first", copy->value());
307     copy->set("second");
308     ATF_REQUIRE_EQ("first", node.value());
309     ATF_REQUIRE_EQ("second", copy->value());
310     delete copy;
311 }
312 
313 
314 ATF_TEST_CASE_WITHOUT_HEAD(string_node__is_set_and_set);
ATF_TEST_CASE_BODY(string_node__is_set_and_set)315 ATF_TEST_CASE_BODY(string_node__is_set_and_set)
316 {
317     config::string_node node;
318     ATF_REQUIRE(!node.is_set());
319     node.set("foo");
320     ATF_REQUIRE( node.is_set());
321 }
322 
323 
324 ATF_TEST_CASE_WITHOUT_HEAD(string_node__value_and_set);
ATF_TEST_CASE_BODY(string_node__value_and_set)325 ATF_TEST_CASE_BODY(string_node__value_and_set)
326 {
327     config::string_node node;
328     node.set("foo");
329     ATF_REQUIRE_EQ("foo", node.value());
330     node.set("");
331     ATF_REQUIRE_EQ("", node.value());
332 }
333 
334 
335 ATF_TEST_CASE_WITHOUT_HEAD(string_node__push_lua);
ATF_TEST_CASE_BODY(string_node__push_lua)336 ATF_TEST_CASE_BODY(string_node__push_lua)
337 {
338     lutok::state state;
339 
340     config::string_node node;
341     node.set("some message");
342     node.push_lua(state);
343     ATF_REQUIRE(state.is_string(-1));
344     ATF_REQUIRE_EQ("some message", state.to_string(-1));
345     state.pop(1);
346 }
347 
348 
349 ATF_TEST_CASE_WITHOUT_HEAD(string_node__set_lua__ok);
ATF_TEST_CASE_BODY(string_node__set_lua__ok)350 ATF_TEST_CASE_BODY(string_node__set_lua__ok)
351 {
352     lutok::state state;
353 
354     config::string_node node;
355     state.push_string("text 1");
356     state.push_integer(231);
357     node.set_lua(state, -2);
358     ATF_REQUIRE_EQ("text 1", node.value());
359     node.set_lua(state, -1);
360     ATF_REQUIRE_EQ("231", node.value());
361     state.pop(2);
362 }
363 
364 
365 ATF_TEST_CASE_WITHOUT_HEAD(string_node__set_lua__invalid_value);
ATF_TEST_CASE_BODY(string_node__set_lua__invalid_value)366 ATF_TEST_CASE_BODY(string_node__set_lua__invalid_value)
367 {
368     lutok::state state;
369 
370     config::bool_node node;
371     state.new_table();
372     ATF_REQUIRE_THROW(config::value_error, node.set_lua(state, -1));
373     state.pop(1);
374     ATF_REQUIRE(!node.is_set());
375 }
376 
377 
378 ATF_TEST_CASE_WITHOUT_HEAD(string_node__set_string);
ATF_TEST_CASE_BODY(string_node__set_string)379 ATF_TEST_CASE_BODY(string_node__set_string)
380 {
381     config::string_node node;
382     node.set_string("abcd efgh");
383     ATF_REQUIRE_EQ("abcd efgh", node.value());
384     node.set_string("  1234  ");
385     ATF_REQUIRE_EQ("  1234  ", node.value());
386 }
387 
388 
389 ATF_TEST_CASE_WITHOUT_HEAD(string_node__to_string);
ATF_TEST_CASE_BODY(string_node__to_string)390 ATF_TEST_CASE_BODY(string_node__to_string)
391 {
392     config::string_node node;
393     node.set("");
394     ATF_REQUIRE_EQ("", node.to_string());
395     node.set("aaa");
396     ATF_REQUIRE_EQ("aaa", node.to_string());
397 }
398 
399 
400 ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__deep_copy);
ATF_TEST_CASE_BODY(strings_set_node__deep_copy)401 ATF_TEST_CASE_BODY(strings_set_node__deep_copy)
402 {
403     std::set< std::string > value;
404     config::strings_set_node node;
405     value.insert("foo");
406     node.set(value);
407     config::detail::base_node* raw_copy = node.deep_copy();
408     config::strings_set_node* copy =
409         static_cast< config::strings_set_node* >(raw_copy);
410     value.insert("bar");
411     ATF_REQUIRE_EQ(1, copy->value().size());
412     copy->set(value);
413     ATF_REQUIRE_EQ(1, node.value().size());
414     ATF_REQUIRE_EQ(2, copy->value().size());
415     delete copy;
416 }
417 
418 
419 ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__is_set_and_set);
ATF_TEST_CASE_BODY(strings_set_node__is_set_and_set)420 ATF_TEST_CASE_BODY(strings_set_node__is_set_and_set)
421 {
422     std::set< std::string > value;
423     value.insert("foo");
424 
425     config::strings_set_node node;
426     ATF_REQUIRE(!node.is_set());
427     node.set(value);
428     ATF_REQUIRE( node.is_set());
429 }
430 
431 
432 ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__value_and_set);
ATF_TEST_CASE_BODY(strings_set_node__value_and_set)433 ATF_TEST_CASE_BODY(strings_set_node__value_and_set)
434 {
435     std::set< std::string > value;
436     value.insert("first");
437 
438     config::strings_set_node node;
439     node.set(value);
440     ATF_REQUIRE(value == node.value());
441     value.clear();
442     node.set(value);
443     value.insert("second");
444     ATF_REQUIRE(node.value().empty());
445 }
446 
447 
448 ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__set_string);
ATF_TEST_CASE_BODY(strings_set_node__set_string)449 ATF_TEST_CASE_BODY(strings_set_node__set_string)
450 {
451     config::strings_set_node node;
452     {
453         std::set< std::string > expected;
454         expected.insert("abcd");
455         expected.insert("efgh");
456 
457         node.set_string("abcd efgh");
458         ATF_REQUIRE(expected == node.value());
459     }
460     {
461         std::set< std::string > expected;
462         expected.insert("1234");
463 
464         node.set_string("  1234  ");
465         ATF_REQUIRE(expected == node.value());
466     }
467 }
468 
469 
470 ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__to_string);
ATF_TEST_CASE_BODY(strings_set_node__to_string)471 ATF_TEST_CASE_BODY(strings_set_node__to_string)
472 {
473     std::set< std::string > value;
474     config::strings_set_node node;
475     value.insert("second");
476     value.insert("first");
477     node.set(value);
478     ATF_REQUIRE_EQ("first second", node.to_string());
479 }
480 
481 
482 ATF_TEST_CASE_WITHOUT_HEAD(typed_leaf_node__validate_set);
ATF_TEST_CASE_BODY(typed_leaf_node__validate_set)483 ATF_TEST_CASE_BODY(typed_leaf_node__validate_set)
484 {
485     validation_node node;
486     node.set(1234);
487     ATF_REQUIRE_THROW_RE(config::value_error, "Custom validate method",
488                          node.set(12345));
489 }
490 
491 
492 ATF_TEST_CASE_WITHOUT_HEAD(typed_leaf_node__validate_set_string);
ATF_TEST_CASE_BODY(typed_leaf_node__validate_set_string)493 ATF_TEST_CASE_BODY(typed_leaf_node__validate_set_string)
494 {
495     validation_node node;
496     node.set_string("1234");
497     ATF_REQUIRE_THROW_RE(config::value_error, "Custom validate method",
498                          node.set_string("12345"));
499 }
500 
501 
502 ATF_TEST_CASE_WITHOUT_HEAD(base_set_node__validate_set);
ATF_TEST_CASE_BODY(base_set_node__validate_set)503 ATF_TEST_CASE_BODY(base_set_node__validate_set)
504 {
505     set_validation_node node;
506     set_validation_node::value_type values;
507     values.insert("foo");
508     values.insert("bar");
509     node.set(values);
510     values.insert("throw");
511     values.insert("baz");
512     ATF_REQUIRE_THROW_RE(config::value_error, "Custom validate method",
513                          node.set(values));
514 }
515 
516 
517 ATF_TEST_CASE_WITHOUT_HEAD(base_set_node__validate_set_string);
ATF_TEST_CASE_BODY(base_set_node__validate_set_string)518 ATF_TEST_CASE_BODY(base_set_node__validate_set_string)
519 {
520     set_validation_node node;
521     node.set_string("foo bar");
522     ATF_REQUIRE_THROW_RE(config::value_error, "Custom validate method",
523                          node.set_string("foo bar throw baz"));
524 }
525 
526 
ATF_INIT_TEST_CASES(tcs)527 ATF_INIT_TEST_CASES(tcs)
528 {
529     ATF_ADD_TEST_CASE(tcs, bool_node__deep_copy);
530     ATF_ADD_TEST_CASE(tcs, bool_node__is_set_and_set);
531     ATF_ADD_TEST_CASE(tcs, bool_node__value_and_set);
532     ATF_ADD_TEST_CASE(tcs, bool_node__push_lua);
533     ATF_ADD_TEST_CASE(tcs, bool_node__set_lua__ok);
534     ATF_ADD_TEST_CASE(tcs, bool_node__set_lua__invalid_value);
535     ATF_ADD_TEST_CASE(tcs, bool_node__set_string__ok);
536     ATF_ADD_TEST_CASE(tcs, bool_node__set_string__invalid_value);
537     ATF_ADD_TEST_CASE(tcs, bool_node__to_string);
538 
539     ATF_ADD_TEST_CASE(tcs, int_node__deep_copy);
540     ATF_ADD_TEST_CASE(tcs, int_node__is_set_and_set);
541     ATF_ADD_TEST_CASE(tcs, int_node__value_and_set);
542     ATF_ADD_TEST_CASE(tcs, int_node__push_lua);
543     ATF_ADD_TEST_CASE(tcs, int_node__set_lua__ok);
544     ATF_ADD_TEST_CASE(tcs, int_node__set_lua__invalid_value);
545     ATF_ADD_TEST_CASE(tcs, int_node__set_string__ok);
546     ATF_ADD_TEST_CASE(tcs, int_node__set_string__invalid_value);
547     ATF_ADD_TEST_CASE(tcs, int_node__to_string);
548 
549     ATF_ADD_TEST_CASE(tcs, string_node__deep_copy);
550     ATF_ADD_TEST_CASE(tcs, string_node__is_set_and_set);
551     ATF_ADD_TEST_CASE(tcs, string_node__value_and_set);
552     ATF_ADD_TEST_CASE(tcs, string_node__push_lua);
553     ATF_ADD_TEST_CASE(tcs, string_node__set_lua__ok);
554     ATF_ADD_TEST_CASE(tcs, string_node__set_lua__invalid_value);
555     ATF_ADD_TEST_CASE(tcs, string_node__set_string);
556     ATF_ADD_TEST_CASE(tcs, string_node__to_string);
557 
558     ATF_ADD_TEST_CASE(tcs, strings_set_node__deep_copy);
559     ATF_ADD_TEST_CASE(tcs, strings_set_node__is_set_and_set);
560     ATF_ADD_TEST_CASE(tcs, strings_set_node__value_and_set);
561     ATF_ADD_TEST_CASE(tcs, strings_set_node__set_string);
562     ATF_ADD_TEST_CASE(tcs, strings_set_node__to_string);
563 
564     ATF_ADD_TEST_CASE(tcs, typed_leaf_node__validate_set);
565     ATF_ADD_TEST_CASE(tcs, typed_leaf_node__validate_set_string);
566     ATF_ADD_TEST_CASE(tcs, base_set_node__validate_set);
567     ATF_ADD_TEST_CASE(tcs, base_set_node__validate_set_string);
568 }
569