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