1 // Copyright 2012 Google Inc.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
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.
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.
29 #include "utils/config/tree.ipp"
31 #include <atf-c++.hpp>
33 #include "utils/config/nodes.ipp"
34 #include "utils/format/macros.hpp"
35 #include "utils/text/operations.ipp"
37 namespace config
= utils::config
;
38 namespace text
= utils::text
;
44 /// Simple wrapper around an integer value without default constructors.
46 /// The purpose of this type is to have a simple class without default
47 /// constructors to validate that we can use it as a leaf of a tree.
49 /// The wrapped integer value.
53 /// Constructs a new wrapped integer.
55 /// \param value_ The value to store in the object.
56 explicit int_wrapper(int value_
) :
61 /// Gets the integer value stored in the object.
70 /// Custom tree leaf type for an object without defualt constructors.
71 class wrapped_int_node
: public config::typed_leaf_node
< int_wrapper
> {
75 /// \return A dynamically-allocated node.
79 std::auto_ptr
< wrapped_int_node
> new_node(new wrapped_int_node());
80 new_node
->_value
= _value
;
81 return new_node
.release();
84 /// Pushes the node's value onto the Lua stack.
86 /// \param state The Lua state onto which to push the value.
88 push_lua(lutok::state
& state
) const
91 config::typed_leaf_node
< int_wrapper
>::value().value());
94 /// Sets the value of the node from an entry in the Lua stack.
96 /// \param state The Lua state from which to get the value.
97 /// \param value_index The stack index in which the value resides.
99 set_lua(lutok::state
& state
, const int value_index
)
101 ATF_REQUIRE(state
.is_number(value_index
));
102 int_wrapper
new_value(state
.to_integer(value_index
));
103 config::typed_leaf_node
< int_wrapper
>::set(new_value
);
106 /// Sets the value of the node from a raw string representation.
108 /// \param raw_value The value to set the node to.
110 set_string(const std::string
& raw_value
)
112 int_wrapper
new_value(text::to_type
< int >(raw_value
));
113 config::typed_leaf_node
< int_wrapper
>::set(new_value
);
116 /// Converts the contents of the node to a string.
118 /// \return A string representation of the value held by the node.
120 to_string(void) const
123 config::typed_leaf_node
< int_wrapper
>::value().value();
128 } // anonymous namespace
131 ATF_TEST_CASE_WITHOUT_HEAD(define_set_lookup__one_level
);
132 ATF_TEST_CASE_BODY(define_set_lookup__one_level
)
136 tree
.define
< config::int_node
>("var1");
137 tree
.define
< config::string_node
>("var2");
138 tree
.define
< config::bool_node
>("var3");
140 tree
.set
< config::int_node
>("var1", 42);
141 tree
.set
< config::string_node
>("var2", "hello");
142 tree
.set
< config::bool_node
>("var3", false);
144 ATF_REQUIRE_EQ(42, tree
.lookup
< config::int_node
>("var1"));
145 ATF_REQUIRE_EQ("hello", tree
.lookup
< config::string_node
>("var2"));
146 ATF_REQUIRE(!tree
.lookup
< config::bool_node
>("var3"));
150 ATF_TEST_CASE_WITHOUT_HEAD(define_set_lookup__multiple_levels
);
151 ATF_TEST_CASE_BODY(define_set_lookup__multiple_levels
)
155 tree
.define
< config::int_node
>("foo.bar.1");
156 tree
.define
< config::string_node
>("foo.bar.2");
157 tree
.define
< config::bool_node
>("foo.3");
158 tree
.define_dynamic("sub.tree");
160 tree
.set
< config::int_node
>("foo.bar.1", 42);
161 tree
.set
< config::string_node
>("foo.bar.2", "hello");
162 tree
.set
< config::bool_node
>("foo.3", true);
163 tree
.set
< config::string_node
>("sub.tree.1", "bye");
164 tree
.set
< config::int_node
>("sub.tree.2", 4);
165 tree
.set
< config::int_node
>("sub.tree.3.4", 123);
167 ATF_REQUIRE_EQ(42, tree
.lookup
< config::int_node
>("foo.bar.1"));
168 ATF_REQUIRE_EQ("hello", tree
.lookup
< config::string_node
>("foo.bar.2"));
169 ATF_REQUIRE(tree
.lookup
< config::bool_node
>("foo.3"));
170 ATF_REQUIRE_EQ(4, tree
.lookup
< config::int_node
>("sub.tree.2"));
171 ATF_REQUIRE_EQ(123, tree
.lookup
< config::int_node
>("sub.tree.3.4"));
175 ATF_TEST_CASE_WITHOUT_HEAD(deep_copy__empty
);
176 ATF_TEST_CASE_BODY(deep_copy__empty
)
179 config::tree tree2
= tree1
.deep_copy();
181 tree1
.define
< config::bool_node
>("var1");
182 // This would crash if the copy shared the internal data.
183 tree2
.define
< config::int_node
>("var1");
187 ATF_TEST_CASE_WITHOUT_HEAD(deep_copy__some
);
188 ATF_TEST_CASE_BODY(deep_copy__some
)
191 tree1
.define
< config::bool_node
>("this.is.a.var");
192 tree1
.set
< config::bool_node
>("this.is.a.var", true);
193 tree1
.define
< config::int_node
>("this.is.another.var");
194 tree1
.set
< config::int_node
>("this.is.another.var", 34);
195 tree1
.define
< config::int_node
>("and.another");
196 tree1
.set
< config::int_node
>("and.another", 123);
198 config::tree tree2
= tree1
.deep_copy();
199 tree2
.set
< config::bool_node
>("this.is.a.var", false);
200 tree2
.set
< config::int_node
>("this.is.another.var", 43);
202 ATF_REQUIRE( tree1
.lookup
< config::bool_node
>("this.is.a.var"));
203 ATF_REQUIRE(!tree2
.lookup
< config::bool_node
>("this.is.a.var"));
205 ATF_REQUIRE_EQ(34, tree1
.lookup
< config::int_node
>("this.is.another.var"));
206 ATF_REQUIRE_EQ(43, tree2
.lookup
< config::int_node
>("this.is.another.var"));
208 ATF_REQUIRE_EQ(123, tree1
.lookup
< config::int_node
>("and.another"));
209 ATF_REQUIRE_EQ(123, tree2
.lookup
< config::int_node
>("and.another"));
213 ATF_TEST_CASE_WITHOUT_HEAD(lookup__invalid_key
);
214 ATF_TEST_CASE_BODY(lookup__invalid_key
)
218 ATF_REQUIRE_THROW(config::invalid_key_error
,
219 tree
.lookup
< config::int_node
>("."));
223 ATF_TEST_CASE_WITHOUT_HEAD(lookup__unknown_key
);
224 ATF_TEST_CASE_BODY(lookup__unknown_key
)
228 tree
.define
< config::int_node
>("foo.bar");
229 tree
.define
< config::int_node
>("a.b.c");
230 tree
.define_dynamic("a.d");
231 tree
.set
< config::int_node
>("a.b.c", 123);
232 tree
.set
< config::int_node
>("a.d.100", 0);
234 ATF_REQUIRE_THROW(config::unknown_key_error
,
235 tree
.lookup
< config::int_node
>("abc"));
237 ATF_REQUIRE_THROW(config::unknown_key_error
,
238 tree
.lookup
< config::int_node
>("foo"));
239 ATF_REQUIRE_THROW(config::unknown_key_error
,
240 tree
.lookup
< config::int_node
>("foo.bar"));
241 ATF_REQUIRE_THROW(config::unknown_key_error
,
242 tree
.lookup
< config::int_node
>("foo.bar.baz"));
244 ATF_REQUIRE_THROW(config::unknown_key_error
,
245 tree
.lookup
< config::int_node
>("a"));
246 ATF_REQUIRE_THROW(config::unknown_key_error
,
247 tree
.lookup
< config::int_node
>("a.b"));
248 ATF_REQUIRE_THROW(config::unknown_key_error
,
249 tree
.lookup
< config::int_node
>("a.c"));
250 (void)tree
.lookup
< config::int_node
>("a.b.c");
251 ATF_REQUIRE_THROW(config::unknown_key_error
,
252 tree
.lookup
< config::int_node
>("a.b.c.d"));
253 ATF_REQUIRE_THROW(config::unknown_key_error
,
254 tree
.lookup
< config::int_node
>("a.d"));
255 (void)tree
.lookup
< config::int_node
>("a.d.100");
256 ATF_REQUIRE_THROW(config::unknown_key_error
,
257 tree
.lookup
< config::int_node
>("a.d.101"));
258 ATF_REQUIRE_THROW(config::unknown_key_error
,
259 tree
.lookup
< config::int_node
>("a.d.100.3"));
260 ATF_REQUIRE_THROW(config::unknown_key_error
,
261 tree
.lookup
< config::int_node
>("a.d.e"));
265 ATF_TEST_CASE_WITHOUT_HEAD(is_set__one_level
);
266 ATF_TEST_CASE_BODY(is_set__one_level
)
270 tree
.define
< config::int_node
>("var1");
271 tree
.define
< config::string_node
>("var2");
272 tree
.define
< config::bool_node
>("var3");
274 tree
.set
< config::int_node
>("var1", 42);
275 tree
.set
< config::bool_node
>("var3", false);
277 ATF_REQUIRE( tree
.is_set("var1"));
278 ATF_REQUIRE(!tree
.is_set("var2"));
279 ATF_REQUIRE( tree
.is_set("var3"));
283 ATF_TEST_CASE_WITHOUT_HEAD(is_set__multiple_levels
);
284 ATF_TEST_CASE_BODY(is_set__multiple_levels
)
288 tree
.define
< config::int_node
>("a.b.var1");
289 tree
.define
< config::string_node
>("a.b.var2");
290 tree
.define
< config::bool_node
>("e.var3");
292 tree
.set
< config::int_node
>("a.b.var1", 42);
293 tree
.set
< config::bool_node
>("e.var3", false);
295 ATF_REQUIRE(!tree
.is_set("a"));
296 ATF_REQUIRE(!tree
.is_set("a.b"));
297 ATF_REQUIRE( tree
.is_set("a.b.var1"));
298 ATF_REQUIRE(!tree
.is_set("a.b.var1.trailing"));
300 ATF_REQUIRE(!tree
.is_set("a"));
301 ATF_REQUIRE(!tree
.is_set("a.b"));
302 ATF_REQUIRE(!tree
.is_set("a.b.var2"));
303 ATF_REQUIRE(!tree
.is_set("a.b.var2.trailing"));
305 ATF_REQUIRE(!tree
.is_set("e"));
306 ATF_REQUIRE( tree
.is_set("e.var3"));
307 ATF_REQUIRE(!tree
.is_set("e.var3.trailing"));
311 ATF_TEST_CASE_WITHOUT_HEAD(is_set__invalid_key
);
312 ATF_TEST_CASE_BODY(is_set__invalid_key
)
316 ATF_REQUIRE_THROW(config::invalid_key_error
, tree
.is_set(".abc"));
320 ATF_TEST_CASE_WITHOUT_HEAD(set__invalid_key
);
321 ATF_TEST_CASE_BODY(set__invalid_key
)
325 ATF_REQUIRE_THROW(config::invalid_key_error
,
326 tree
.set
< config::int_node
>("foo.", 54));
330 ATF_TEST_CASE_WITHOUT_HEAD(set__unknown_key
);
331 ATF_TEST_CASE_BODY(set__unknown_key
)
335 tree
.define
< config::int_node
>("foo.bar");
336 tree
.define
< config::int_node
>("a.b.c");
337 tree
.define_dynamic("a.d");
338 tree
.set
< config::int_node
>("a.b.c", 123);
339 tree
.set
< config::string_node
>("a.d.3", "foo");
341 ATF_REQUIRE_THROW(config::unknown_key_error
,
342 tree
.set
< config::int_node
>("abc", 2));
344 tree
.set
< config::int_node
>("foo.bar", 15);
345 ATF_REQUIRE_THROW(config::unknown_key_error
,
346 tree
.set
< config::int_node
>("foo.bar.baz", 0));
348 ATF_REQUIRE_THROW(config::unknown_key_error
,
349 tree
.set
< config::int_node
>("a.c", 100));
350 tree
.set
< config::int_node
>("a.b.c", -3);
351 ATF_REQUIRE_THROW(config::unknown_key_error
,
352 tree
.set
< config::int_node
>("a.b.c.d", 82));
353 tree
.set
< config::string_node
>("a.d.3", "bar");
354 tree
.set
< config::string_node
>("a.d.4", "bar");
355 ATF_REQUIRE_THROW(config::unknown_key_error
,
356 tree
.set
< config::int_node
>("a.d.4.5", 82));
357 tree
.set
< config::int_node
>("a.d.5.6", 82);
361 ATF_TEST_CASE_WITHOUT_HEAD(set__value_error
);
362 ATF_TEST_CASE_BODY(set__value_error
)
366 tree
.define
< config::int_node
>("foo.bar");
367 tree
.define_dynamic("a.d");
369 ATF_REQUIRE_THROW(config::value_error
,
370 tree
.set
< config::int_node
>("foo", 3));
371 ATF_REQUIRE_THROW(config::value_error
,
372 tree
.set
< config::int_node
>("a", -10));
376 ATF_TEST_CASE_WITHOUT_HEAD(push_lua__ok
);
377 ATF_TEST_CASE_BODY(push_lua__ok
)
381 tree
.define
< config::int_node
>("top.integer");
382 tree
.define
< wrapped_int_node
>("top.custom");
383 tree
.define_dynamic("dynamic");
384 tree
.set
< config::int_node
>("top.integer", 5);
385 tree
.set
< wrapped_int_node
>("top.custom", int_wrapper(10));
386 tree
.set_string("dynamic.first", "foo");
389 tree
.push_lua("top.integer", state
);
390 tree
.push_lua("top.custom", state
);
391 tree
.push_lua("dynamic.first", state
);
392 ATF_REQUIRE(state
.is_number(-3));
393 ATF_REQUIRE_EQ(5, state
.to_integer(-3));
394 ATF_REQUIRE(state
.is_number(-2));
395 ATF_REQUIRE_EQ(10, state
.to_integer(-2));
396 ATF_REQUIRE(state
.is_string(-1));
397 ATF_REQUIRE_EQ("foo", state
.to_string(-1));
402 ATF_TEST_CASE_WITHOUT_HEAD(set_lua__ok
);
403 ATF_TEST_CASE_BODY(set_lua__ok
)
407 tree
.define
< config::int_node
>("top.integer");
408 tree
.define
< wrapped_int_node
>("top.custom");
409 tree
.define_dynamic("dynamic");
413 state
.push_integer(5);
414 state
.push_integer(10);
415 state
.push_string("foo");
416 tree
.set_lua("top.integer", state
, -3);
417 tree
.set_lua("top.custom", state
, -2);
418 tree
.set_lua("dynamic.first", state
, -1);
422 ATF_REQUIRE_EQ(5, tree
.lookup
< config::int_node
>("top.integer"));
423 ATF_REQUIRE_EQ(10, tree
.lookup
< wrapped_int_node
>("top.custom").value());
424 ATF_REQUIRE_EQ("foo", tree
.lookup
< config::string_node
>("dynamic.first"));
428 ATF_TEST_CASE_WITHOUT_HEAD(lookup_rw
);
429 ATF_TEST_CASE_BODY(lookup_rw
)
433 tree
.define
< config::int_node
>("var1");
434 tree
.define
< config::bool_node
>("var3");
436 tree
.set
< config::int_node
>("var1", 42);
437 tree
.set
< config::bool_node
>("var3", false);
439 tree
.lookup_rw
< config::int_node
>("var1") += 10;
440 ATF_REQUIRE_EQ(52, tree
.lookup
< config::int_node
>("var1"));
441 ATF_REQUIRE(!tree
.lookup
< config::bool_node
>("var3"));
445 ATF_TEST_CASE_WITHOUT_HEAD(lookup_string__ok
);
446 ATF_TEST_CASE_BODY(lookup_string__ok
)
450 tree
.define
< config::int_node
>("var1");
451 tree
.define
< config::string_node
>("b.var2");
452 tree
.define
< config::bool_node
>("c.d.var3");
454 tree
.set
< config::int_node
>("var1", 42);
455 tree
.set
< config::string_node
>("b.var2", "hello");
456 tree
.set
< config::bool_node
>("c.d.var3", false);
458 ATF_REQUIRE_EQ("42", tree
.lookup_string("var1"));
459 ATF_REQUIRE_EQ("hello", tree
.lookup_string("b.var2"));
460 ATF_REQUIRE_EQ("false", tree
.lookup_string("c.d.var3"));
464 ATF_TEST_CASE_WITHOUT_HEAD(lookup_string__invalid_key
);
465 ATF_TEST_CASE_BODY(lookup_string__invalid_key
)
469 ATF_REQUIRE_THROW(config::invalid_key_error
, tree
.lookup_string(""));
473 ATF_TEST_CASE_WITHOUT_HEAD(lookup_string__unknown_key
);
474 ATF_TEST_CASE_BODY(lookup_string__unknown_key
)
478 tree
.define
< config::int_node
>("a.b.c");
480 ATF_REQUIRE_THROW(config::unknown_key_error
, tree
.lookup_string("a.b"));
481 ATF_REQUIRE_THROW(config::unknown_key_error
, tree
.lookup_string("a.b.c.d"));
485 ATF_TEST_CASE_WITHOUT_HEAD(set_string__ok
);
486 ATF_TEST_CASE_BODY(set_string__ok
)
490 tree
.define
< config::int_node
>("foo.bar.1");
491 tree
.define
< config::string_node
>("foo.bar.2");
492 tree
.define_dynamic("sub.tree");
494 tree
.set_string("foo.bar.1", "42");
495 tree
.set_string("foo.bar.2", "hello");
496 tree
.set_string("sub.tree.2", "15");
497 tree
.set_string("sub.tree.3.4", "bye");
499 ATF_REQUIRE_EQ(42, tree
.lookup
< config::int_node
>("foo.bar.1"));
500 ATF_REQUIRE_EQ("hello", tree
.lookup
< config::string_node
>("foo.bar.2"));
501 ATF_REQUIRE_EQ("15", tree
.lookup
< config::string_node
>("sub.tree.2"));
502 ATF_REQUIRE_EQ("bye", tree
.lookup
< config::string_node
>("sub.tree.3.4"));
506 ATF_TEST_CASE_WITHOUT_HEAD(set_string__invalid_key
);
507 ATF_TEST_CASE_BODY(set_string__invalid_key
)
511 ATF_REQUIRE_THROW(config::invalid_key_error
, tree
.set_string(".", "foo"));
515 ATF_TEST_CASE_WITHOUT_HEAD(set_string__unknown_key
);
516 ATF_TEST_CASE_BODY(set_string__unknown_key
)
520 tree
.define
< config::int_node
>("foo.bar");
521 tree
.define
< config::int_node
>("a.b.c");
522 tree
.define_dynamic("a.d");
523 tree
.set_string("a.b.c", "123");
524 tree
.set_string("a.d.3", "foo");
526 ATF_REQUIRE_THROW(config::unknown_key_error
, tree
.set_string("abc", "2"));
528 tree
.set_string("foo.bar", "15");
529 ATF_REQUIRE_THROW(config::unknown_key_error
,
530 tree
.set_string("foo.bar.baz", "0"));
532 ATF_REQUIRE_THROW(config::unknown_key_error
,
533 tree
.set_string("a.c", "100"));
534 tree
.set_string("a.b.c", "-3");
535 ATF_REQUIRE_THROW(config::unknown_key_error
,
536 tree
.set_string("a.b.c.d", "82"));
537 tree
.set_string("a.d.3", "bar");
538 tree
.set_string("a.d.4", "bar");
539 ATF_REQUIRE_THROW(config::unknown_key_error
,
540 tree
.set_string("a.d.4.5", "82"));
541 tree
.set_string("a.d.5.6", "82");
545 ATF_TEST_CASE_WITHOUT_HEAD(set_string__value_error
);
546 ATF_TEST_CASE_BODY(set_string__value_error
)
550 tree
.define
< config::int_node
>("foo.bar");
552 ATF_REQUIRE_THROW(config::value_error
,
553 tree
.set_string("foo", "abc"));
554 ATF_REQUIRE_THROW(config::value_error
,
555 tree
.set_string("foo.bar", " -3"));
556 ATF_REQUIRE_THROW(config::value_error
,
557 tree
.set_string("foo.bar", "3 "));
561 ATF_TEST_CASE_WITHOUT_HEAD(all_properties__none
);
562 ATF_TEST_CASE_BODY(all_properties__none
)
564 const config::tree tree
;
565 ATF_REQUIRE(tree
.all_properties().empty());
569 ATF_TEST_CASE_WITHOUT_HEAD(all_properties__all_set
);
570 ATF_TEST_CASE_BODY(all_properties__all_set
)
574 tree
.define
< config::int_node
>("plain");
575 tree
.set
< config::int_node
>("plain", 1234);
577 tree
.define
< config::int_node
>("static.first");
578 tree
.set
< config::int_node
>("static.first", -3);
579 tree
.define
< config::string_node
>("static.second");
580 tree
.set
< config::string_node
>("static.second", "some text");
582 tree
.define_dynamic("dynamic");
583 tree
.set
< config::string_node
>("dynamic.first", "hello");
584 tree
.set
< config::string_node
>("dynamic.second", "bye");
586 config::properties_map exp_properties
;
587 exp_properties
["plain"] = "1234";
588 exp_properties
["static.first"] = "-3";
589 exp_properties
["static.second"] = "some text";
590 exp_properties
["dynamic.first"] = "hello";
591 exp_properties
["dynamic.second"] = "bye";
593 const config::properties_map properties
= tree
.all_properties();
594 ATF_REQUIRE(exp_properties
== properties
);
598 ATF_TEST_CASE_WITHOUT_HEAD(all_properties__some_unset
);
599 ATF_TEST_CASE_BODY(all_properties__some_unset
)
603 tree
.define
< config::int_node
>("static.first");
604 tree
.set
< config::int_node
>("static.first", -3);
605 tree
.define
< config::string_node
>("static.second");
607 tree
.define_dynamic("dynamic");
609 config::properties_map exp_properties
;
610 exp_properties
["static.first"] = "-3";
612 const config::properties_map properties
= tree
.all_properties();
613 ATF_REQUIRE(exp_properties
== properties
);
617 ATF_TEST_CASE_WITHOUT_HEAD(all_properties__subtree__inner
);
618 ATF_TEST_CASE_BODY(all_properties__subtree__inner
)
622 tree
.define
< config::int_node
>("root.a.b.c.first");
623 tree
.define
< config::int_node
>("root.a.b.c.second");
624 tree
.define
< config::int_node
>("root.a.d.first");
626 tree
.set
< config::int_node
>("root.a.b.c.first", 1);
627 tree
.set
< config::int_node
>("root.a.b.c.second", 2);
628 tree
.set
< config::int_node
>("root.a.d.first", 3);
631 config::properties_map exp_properties
;
632 exp_properties
["root.a.b.c.first"] = "1";
633 exp_properties
["root.a.b.c.second"] = "2";
634 exp_properties
["root.a.d.first"] = "3";
635 ATF_REQUIRE(exp_properties
== tree
.all_properties("root"));
636 ATF_REQUIRE(exp_properties
== tree
.all_properties("root.a"));
640 config::properties_map exp_properties
;
641 exp_properties
["root.a.b.c.first"] = "1";
642 exp_properties
["root.a.b.c.second"] = "2";
643 ATF_REQUIRE(exp_properties
== tree
.all_properties("root.a.b"));
644 ATF_REQUIRE(exp_properties
== tree
.all_properties("root.a.b.c"));
648 config::properties_map exp_properties
;
649 exp_properties
["root.a.d.first"] = "3";
650 ATF_REQUIRE(exp_properties
== tree
.all_properties("root.a.d"));
655 ATF_TEST_CASE_WITHOUT_HEAD(all_properties__subtree__leaf
);
656 ATF_TEST_CASE_BODY(all_properties__subtree__leaf
)
660 tree
.define
< config::int_node
>("root.a.b.c.first");
661 tree
.set
< config::int_node
>("root.a.b.c.first", 1);
662 ATF_REQUIRE_THROW_RE(config::value_error
, "Cannot export.*leaf",
663 tree
.all_properties("root.a.b.c.first"));
667 ATF_TEST_CASE_WITHOUT_HEAD(all_properties__subtree__strip_key
);
668 ATF_TEST_CASE_BODY(all_properties__subtree__strip_key
)
672 tree
.define
< config::int_node
>("root.a.b.c.first");
673 tree
.define
< config::int_node
>("root.a.b.c.second");
674 tree
.define
< config::int_node
>("root.a.d.first");
676 tree
.set
< config::int_node
>("root.a.b.c.first", 1);
677 tree
.set
< config::int_node
>("root.a.b.c.second", 2);
678 tree
.set
< config::int_node
>("root.a.d.first", 3);
680 config::properties_map exp_properties
;
681 exp_properties
["b.c.first"] = "1";
682 exp_properties
["b.c.second"] = "2";
683 exp_properties
["d.first"] = "3";
684 ATF_REQUIRE(exp_properties
== tree
.all_properties("root.a", true));
688 ATF_TEST_CASE_WITHOUT_HEAD(all_properties__subtree__invalid_key
);
689 ATF_TEST_CASE_BODY(all_properties__subtree__invalid_key
)
693 ATF_REQUIRE_THROW(config::invalid_key_error
, tree
.all_properties("."));
697 ATF_TEST_CASE_WITHOUT_HEAD(all_properties__subtree__unknown_key
);
698 ATF_TEST_CASE_BODY(all_properties__subtree__unknown_key
)
702 tree
.define
< config::int_node
>("root.a.b.c.first");
703 tree
.set
< config::int_node
>("root.a.b.c.first", 1);
704 tree
.define
< config::int_node
>("root.a.b.c.unset");
706 ATF_REQUIRE_THROW(config::unknown_key_error
,
707 tree
.all_properties("root.a.b.c.first.foo"));
708 ATF_REQUIRE_THROW_RE(config::value_error
, "Cannot export.*leaf",
709 tree
.all_properties("root.a.b.c.unset"));
713 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__empty
);
714 ATF_TEST_CASE_BODY(operators_eq_and_ne__empty
)
718 ATF_REQUIRE( t1
== t2
);
719 ATF_REQUIRE(!(t1
!= t2
));
723 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__shallow_copy
);
724 ATF_TEST_CASE_BODY(operators_eq_and_ne__shallow_copy
)
727 t1
.define
< config::int_node
>("root.a.b.c.first");
728 t1
.set
< config::int_node
>("root.a.b.c.first", 1);
729 config::tree t2
= t1
;
730 ATF_REQUIRE( t1
== t2
);
731 ATF_REQUIRE(!(t1
!= t2
));
735 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__deep_copy
);
736 ATF_TEST_CASE_BODY(operators_eq_and_ne__deep_copy
)
739 t1
.define
< config::int_node
>("root.a.b.c.first");
740 t1
.set
< config::int_node
>("root.a.b.c.first", 1);
741 config::tree t2
= t1
.deep_copy();
742 ATF_REQUIRE( t1
== t2
);
743 ATF_REQUIRE(!(t1
!= t2
));
747 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__some_contents
);
748 ATF_TEST_CASE_BODY(operators_eq_and_ne__some_contents
)
752 t1
.define
< config::int_node
>("root.a.b.c.first");
753 t1
.set
< config::int_node
>("root.a.b.c.first", 1);
754 ATF_REQUIRE(!(t1
== t2
));
755 ATF_REQUIRE( t1
!= t2
);
757 t2
.define
< config::int_node
>("root.a.b.c.first");
758 t2
.set
< config::int_node
>("root.a.b.c.first", 1);
759 ATF_REQUIRE( t1
== t2
);
760 ATF_REQUIRE(!(t1
!= t2
));
762 t1
.set
< config::int_node
>("root.a.b.c.first", 2);
763 ATF_REQUIRE(!(t1
== t2
));
764 ATF_REQUIRE( t1
!= t2
);
766 t2
.set
< config::int_node
>("root.a.b.c.first", 2);
767 ATF_REQUIRE( t1
== t2
);
768 ATF_REQUIRE(!(t1
!= t2
));
770 t1
.define
< config::string_node
>("another.key");
771 t1
.set
< config::string_node
>("another.key", "some text");
772 ATF_REQUIRE(!(t1
== t2
));
773 ATF_REQUIRE( t1
!= t2
);
775 t2
.define
< config::string_node
>("another.key");
776 t2
.set
< config::string_node
>("another.key", "some text");
777 ATF_REQUIRE( t1
== t2
);
778 ATF_REQUIRE(!(t1
!= t2
));
782 ATF_TEST_CASE_WITHOUT_HEAD(custom_leaf__no_default_ctor
);
783 ATF_TEST_CASE_BODY(custom_leaf__no_default_ctor
)
787 tree
.define
< wrapped_int_node
>("test1");
788 tree
.define
< wrapped_int_node
>("test2");
789 tree
.set
< wrapped_int_node
>("test1", int_wrapper(5));
790 tree
.set
< wrapped_int_node
>("test2", int_wrapper(10));
791 const int_wrapper
& test1
= tree
.lookup
< wrapped_int_node
>("test1");
792 ATF_REQUIRE_EQ(5, test1
.value());
793 const int_wrapper
& test2
= tree
.lookup
< wrapped_int_node
>("test2");
794 ATF_REQUIRE_EQ(10, test2
.value());
798 ATF_INIT_TEST_CASES(tcs
)
800 ATF_ADD_TEST_CASE(tcs
, define_set_lookup__one_level
);
801 ATF_ADD_TEST_CASE(tcs
, define_set_lookup__multiple_levels
);
803 ATF_ADD_TEST_CASE(tcs
, deep_copy__empty
);
804 ATF_ADD_TEST_CASE(tcs
, deep_copy__some
);
806 ATF_ADD_TEST_CASE(tcs
, lookup__invalid_key
);
807 ATF_ADD_TEST_CASE(tcs
, lookup__unknown_key
);
809 ATF_ADD_TEST_CASE(tcs
, is_set__one_level
);
810 ATF_ADD_TEST_CASE(tcs
, is_set__multiple_levels
);
811 ATF_ADD_TEST_CASE(tcs
, is_set__invalid_key
);
813 ATF_ADD_TEST_CASE(tcs
, set__invalid_key
);
814 ATF_ADD_TEST_CASE(tcs
, set__unknown_key
);
815 ATF_ADD_TEST_CASE(tcs
, set__value_error
);
817 ATF_ADD_TEST_CASE(tcs
, push_lua__ok
);
818 ATF_ADD_TEST_CASE(tcs
, set_lua__ok
);
820 ATF_ADD_TEST_CASE(tcs
, lookup_rw
);
822 ATF_ADD_TEST_CASE(tcs
, lookup_string__ok
);
823 ATF_ADD_TEST_CASE(tcs
, lookup_string__invalid_key
);
824 ATF_ADD_TEST_CASE(tcs
, lookup_string__unknown_key
);
826 ATF_ADD_TEST_CASE(tcs
, set_string__ok
);
827 ATF_ADD_TEST_CASE(tcs
, set_string__invalid_key
);
828 ATF_ADD_TEST_CASE(tcs
, set_string__unknown_key
);
829 ATF_ADD_TEST_CASE(tcs
, set_string__value_error
);
831 ATF_ADD_TEST_CASE(tcs
, all_properties__none
);
832 ATF_ADD_TEST_CASE(tcs
, all_properties__all_set
);
833 ATF_ADD_TEST_CASE(tcs
, all_properties__some_unset
);
834 ATF_ADD_TEST_CASE(tcs
, all_properties__subtree__inner
);
835 ATF_ADD_TEST_CASE(tcs
, all_properties__subtree__leaf
);
836 ATF_ADD_TEST_CASE(tcs
, all_properties__subtree__strip_key
);
837 ATF_ADD_TEST_CASE(tcs
, all_properties__subtree__invalid_key
);
838 ATF_ADD_TEST_CASE(tcs
, all_properties__subtree__unknown_key
);
840 ATF_ADD_TEST_CASE(tcs
, operators_eq_and_ne__empty
);
841 ATF_ADD_TEST_CASE(tcs
, operators_eq_and_ne__shallow_copy
);
842 ATF_ADD_TEST_CASE(tcs
, operators_eq_and_ne__deep_copy
);
843 ATF_ADD_TEST_CASE(tcs
, operators_eq_and_ne__some_contents
);
845 ATF_ADD_TEST_CASE(tcs
, custom_leaf__no_default_ctor
);