1*b0d29bc4SBrooks Davis // Copyright 2012 The Kyua Authors.
2*b0d29bc4SBrooks Davis // All rights reserved.
3*b0d29bc4SBrooks Davis //
4*b0d29bc4SBrooks Davis // Redistribution and use in source and binary forms, with or without
5*b0d29bc4SBrooks Davis // modification, are permitted provided that the following conditions are
6*b0d29bc4SBrooks Davis // met:
7*b0d29bc4SBrooks Davis //
8*b0d29bc4SBrooks Davis // * Redistributions of source code must retain the above copyright
9*b0d29bc4SBrooks Davis //   notice, this list of conditions and the following disclaimer.
10*b0d29bc4SBrooks Davis // * Redistributions in binary form must reproduce the above copyright
11*b0d29bc4SBrooks Davis //   notice, this list of conditions and the following disclaimer in the
12*b0d29bc4SBrooks Davis //   documentation and/or other materials provided with the distribution.
13*b0d29bc4SBrooks Davis // * Neither the name of Google Inc. nor the names of its contributors
14*b0d29bc4SBrooks Davis //   may be used to endorse or promote products derived from this software
15*b0d29bc4SBrooks Davis //   without specific prior written permission.
16*b0d29bc4SBrooks Davis //
17*b0d29bc4SBrooks Davis // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*b0d29bc4SBrooks Davis // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*b0d29bc4SBrooks Davis // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*b0d29bc4SBrooks Davis // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*b0d29bc4SBrooks Davis // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*b0d29bc4SBrooks Davis // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*b0d29bc4SBrooks Davis // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*b0d29bc4SBrooks Davis // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*b0d29bc4SBrooks Davis // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*b0d29bc4SBrooks Davis // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*b0d29bc4SBrooks Davis // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*b0d29bc4SBrooks Davis 
29*b0d29bc4SBrooks Davis #include "utils/config/tree.ipp"
30*b0d29bc4SBrooks Davis 
31*b0d29bc4SBrooks Davis #include <atf-c++.hpp>
32*b0d29bc4SBrooks Davis 
33*b0d29bc4SBrooks Davis #include "utils/config/nodes.ipp"
34*b0d29bc4SBrooks Davis #include "utils/format/macros.hpp"
35*b0d29bc4SBrooks Davis #include "utils/text/operations.ipp"
36*b0d29bc4SBrooks Davis 
37*b0d29bc4SBrooks Davis namespace config = utils::config;
38*b0d29bc4SBrooks Davis namespace text = utils::text;
39*b0d29bc4SBrooks Davis 
40*b0d29bc4SBrooks Davis 
41*b0d29bc4SBrooks Davis namespace {
42*b0d29bc4SBrooks Davis 
43*b0d29bc4SBrooks Davis 
44*b0d29bc4SBrooks Davis /// Simple wrapper around an integer value without default constructors.
45*b0d29bc4SBrooks Davis ///
46*b0d29bc4SBrooks Davis /// The purpose of this type is to have a simple class without default
47*b0d29bc4SBrooks Davis /// constructors to validate that we can use it as a leaf of a tree.
48*b0d29bc4SBrooks Davis class int_wrapper {
49*b0d29bc4SBrooks Davis     /// The wrapped integer value.
50*b0d29bc4SBrooks Davis     int _value;
51*b0d29bc4SBrooks Davis 
52*b0d29bc4SBrooks Davis public:
53*b0d29bc4SBrooks Davis     /// Constructs a new wrapped integer.
54*b0d29bc4SBrooks Davis     ///
55*b0d29bc4SBrooks Davis     /// \param value_ The value to store in the object.
int_wrapper(int value_)56*b0d29bc4SBrooks Davis     explicit int_wrapper(int value_) :
57*b0d29bc4SBrooks Davis         _value(value_)
58*b0d29bc4SBrooks Davis     {
59*b0d29bc4SBrooks Davis     }
60*b0d29bc4SBrooks Davis 
61*b0d29bc4SBrooks Davis     /// \return The integer value stored by the object.
62*b0d29bc4SBrooks Davis     int
value(void) const63*b0d29bc4SBrooks Davis     value(void) const
64*b0d29bc4SBrooks Davis     {
65*b0d29bc4SBrooks Davis         return _value;
66*b0d29bc4SBrooks Davis     }
67*b0d29bc4SBrooks Davis };
68*b0d29bc4SBrooks Davis 
69*b0d29bc4SBrooks Davis 
70*b0d29bc4SBrooks Davis /// Custom tree leaf type for an object without defualt constructors.
71*b0d29bc4SBrooks Davis class wrapped_int_node : public config::typed_leaf_node< int_wrapper > {
72*b0d29bc4SBrooks Davis public:
73*b0d29bc4SBrooks Davis     /// Copies the node.
74*b0d29bc4SBrooks Davis     ///
75*b0d29bc4SBrooks Davis     /// \return A dynamically-allocated node.
76*b0d29bc4SBrooks Davis     virtual base_node*
deep_copy(void) const77*b0d29bc4SBrooks Davis     deep_copy(void) const
78*b0d29bc4SBrooks Davis     {
79*b0d29bc4SBrooks Davis         std::auto_ptr< wrapped_int_node > new_node(new wrapped_int_node());
80*b0d29bc4SBrooks Davis         new_node->_value = _value;
81*b0d29bc4SBrooks Davis         return new_node.release();
82*b0d29bc4SBrooks Davis     }
83*b0d29bc4SBrooks Davis 
84*b0d29bc4SBrooks Davis     /// Pushes the node's value onto the Lua stack.
85*b0d29bc4SBrooks Davis     ///
86*b0d29bc4SBrooks Davis     /// \param state The Lua state onto which to push the value.
87*b0d29bc4SBrooks Davis     void
push_lua(lutok::state & state) const88*b0d29bc4SBrooks Davis     push_lua(lutok::state& state) const
89*b0d29bc4SBrooks Davis     {
90*b0d29bc4SBrooks Davis         state.push_integer(
91*b0d29bc4SBrooks Davis             config::typed_leaf_node< int_wrapper >::value().value());
92*b0d29bc4SBrooks Davis     }
93*b0d29bc4SBrooks Davis 
94*b0d29bc4SBrooks Davis     /// Sets the value of the node from an entry in the Lua stack.
95*b0d29bc4SBrooks Davis     ///
96*b0d29bc4SBrooks Davis     /// \param state The Lua state from which to get the value.
97*b0d29bc4SBrooks Davis     /// \param value_index The stack index in which the value resides.
98*b0d29bc4SBrooks Davis     void
set_lua(lutok::state & state,const int value_index)99*b0d29bc4SBrooks Davis     set_lua(lutok::state& state, const int value_index)
100*b0d29bc4SBrooks Davis     {
101*b0d29bc4SBrooks Davis         ATF_REQUIRE(state.is_number(value_index));
102*b0d29bc4SBrooks Davis         int_wrapper new_value(state.to_integer(value_index));
103*b0d29bc4SBrooks Davis         config::typed_leaf_node< int_wrapper >::set(new_value);
104*b0d29bc4SBrooks Davis     }
105*b0d29bc4SBrooks Davis 
106*b0d29bc4SBrooks Davis     /// Sets the value of the node from a raw string representation.
107*b0d29bc4SBrooks Davis     ///
108*b0d29bc4SBrooks Davis     /// \param raw_value The value to set the node to.
109*b0d29bc4SBrooks Davis     void
set_string(const std::string & raw_value)110*b0d29bc4SBrooks Davis     set_string(const std::string& raw_value)
111*b0d29bc4SBrooks Davis     {
112*b0d29bc4SBrooks Davis         int_wrapper new_value(text::to_type< int >(raw_value));
113*b0d29bc4SBrooks Davis         config::typed_leaf_node< int_wrapper >::set(new_value);
114*b0d29bc4SBrooks Davis     }
115*b0d29bc4SBrooks Davis 
116*b0d29bc4SBrooks Davis     /// Converts the contents of the node to a string.
117*b0d29bc4SBrooks Davis     ///
118*b0d29bc4SBrooks Davis     /// \return A string representation of the value held by the node.
119*b0d29bc4SBrooks Davis     std::string
to_string(void) const120*b0d29bc4SBrooks Davis     to_string(void) const
121*b0d29bc4SBrooks Davis     {
122*b0d29bc4SBrooks Davis         return F("%s") %
123*b0d29bc4SBrooks Davis             config::typed_leaf_node< int_wrapper >::value().value();
124*b0d29bc4SBrooks Davis     }
125*b0d29bc4SBrooks Davis };
126*b0d29bc4SBrooks Davis 
127*b0d29bc4SBrooks Davis 
128*b0d29bc4SBrooks Davis }  // anonymous namespace
129*b0d29bc4SBrooks Davis 
130*b0d29bc4SBrooks Davis 
131*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(define_set_lookup__one_level);
ATF_TEST_CASE_BODY(define_set_lookup__one_level)132*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(define_set_lookup__one_level)
133*b0d29bc4SBrooks Davis {
134*b0d29bc4SBrooks Davis     config::tree tree;
135*b0d29bc4SBrooks Davis 
136*b0d29bc4SBrooks Davis     tree.define< config::int_node >("var1");
137*b0d29bc4SBrooks Davis     tree.define< config::string_node >("var2");
138*b0d29bc4SBrooks Davis     tree.define< config::bool_node >("var3");
139*b0d29bc4SBrooks Davis 
140*b0d29bc4SBrooks Davis     tree.set< config::int_node >("var1", 42);
141*b0d29bc4SBrooks Davis     tree.set< config::string_node >("var2", "hello");
142*b0d29bc4SBrooks Davis     tree.set< config::bool_node >("var3", false);
143*b0d29bc4SBrooks Davis 
144*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(42, tree.lookup< config::int_node >("var1"));
145*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("hello", tree.lookup< config::string_node >("var2"));
146*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.lookup< config::bool_node >("var3"));
147*b0d29bc4SBrooks Davis }
148*b0d29bc4SBrooks Davis 
149*b0d29bc4SBrooks Davis 
150*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(define_set_lookup__multiple_levels);
ATF_TEST_CASE_BODY(define_set_lookup__multiple_levels)151*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(define_set_lookup__multiple_levels)
152*b0d29bc4SBrooks Davis {
153*b0d29bc4SBrooks Davis     config::tree tree;
154*b0d29bc4SBrooks Davis 
155*b0d29bc4SBrooks Davis     tree.define< config::int_node >("foo.bar.1");
156*b0d29bc4SBrooks Davis     tree.define< config::string_node >("foo.bar.2");
157*b0d29bc4SBrooks Davis     tree.define< config::bool_node >("foo.3");
158*b0d29bc4SBrooks Davis     tree.define_dynamic("sub.tree");
159*b0d29bc4SBrooks Davis 
160*b0d29bc4SBrooks Davis     tree.set< config::int_node >("foo.bar.1", 42);
161*b0d29bc4SBrooks Davis     tree.set< config::string_node >("foo.bar.2", "hello");
162*b0d29bc4SBrooks Davis     tree.set< config::bool_node >("foo.3", true);
163*b0d29bc4SBrooks Davis     tree.set< config::string_node >("sub.tree.1", "bye");
164*b0d29bc4SBrooks Davis     tree.set< config::int_node >("sub.tree.2", 4);
165*b0d29bc4SBrooks Davis     tree.set< config::int_node >("sub.tree.3.4", 123);
166*b0d29bc4SBrooks Davis 
167*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(42, tree.lookup< config::int_node >("foo.bar.1"));
168*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("hello", tree.lookup< config::string_node >("foo.bar.2"));
169*b0d29bc4SBrooks Davis     ATF_REQUIRE(tree.lookup< config::bool_node >("foo.3"));
170*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(4, tree.lookup< config::int_node >("sub.tree.2"));
171*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(123, tree.lookup< config::int_node >("sub.tree.3.4"));
172*b0d29bc4SBrooks Davis }
173*b0d29bc4SBrooks Davis 
174*b0d29bc4SBrooks Davis 
175*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(deep_copy__empty);
ATF_TEST_CASE_BODY(deep_copy__empty)176*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(deep_copy__empty)
177*b0d29bc4SBrooks Davis {
178*b0d29bc4SBrooks Davis     config::tree tree1;
179*b0d29bc4SBrooks Davis     config::tree tree2 = tree1.deep_copy();
180*b0d29bc4SBrooks Davis 
181*b0d29bc4SBrooks Davis     tree1.define< config::bool_node >("var1");
182*b0d29bc4SBrooks Davis     // This would crash if the copy shared the internal data.
183*b0d29bc4SBrooks Davis     tree2.define< config::int_node >("var1");
184*b0d29bc4SBrooks Davis }
185*b0d29bc4SBrooks Davis 
186*b0d29bc4SBrooks Davis 
187*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(deep_copy__some);
ATF_TEST_CASE_BODY(deep_copy__some)188*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(deep_copy__some)
189*b0d29bc4SBrooks Davis {
190*b0d29bc4SBrooks Davis     config::tree tree1;
191*b0d29bc4SBrooks Davis     tree1.define< config::bool_node >("this.is.a.var");
192*b0d29bc4SBrooks Davis     tree1.set< config::bool_node >("this.is.a.var", true);
193*b0d29bc4SBrooks Davis     tree1.define< config::int_node >("this.is.another.var");
194*b0d29bc4SBrooks Davis     tree1.set< config::int_node >("this.is.another.var", 34);
195*b0d29bc4SBrooks Davis     tree1.define< config::int_node >("and.another");
196*b0d29bc4SBrooks Davis     tree1.set< config::int_node >("and.another", 123);
197*b0d29bc4SBrooks Davis 
198*b0d29bc4SBrooks Davis     config::tree tree2 = tree1.deep_copy();
199*b0d29bc4SBrooks Davis     tree2.set< config::bool_node >("this.is.a.var", false);
200*b0d29bc4SBrooks Davis     tree2.set< config::int_node >("this.is.another.var", 43);
201*b0d29bc4SBrooks Davis 
202*b0d29bc4SBrooks Davis     ATF_REQUIRE( tree1.lookup< config::bool_node >("this.is.a.var"));
203*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree2.lookup< config::bool_node >("this.is.a.var"));
204*b0d29bc4SBrooks Davis 
205*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(34, tree1.lookup< config::int_node >("this.is.another.var"));
206*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(43, tree2.lookup< config::int_node >("this.is.another.var"));
207*b0d29bc4SBrooks Davis 
208*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(123, tree1.lookup< config::int_node >("and.another"));
209*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(123, tree2.lookup< config::int_node >("and.another"));
210*b0d29bc4SBrooks Davis }
211*b0d29bc4SBrooks Davis 
212*b0d29bc4SBrooks Davis 
213*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(combine__empty);
ATF_TEST_CASE_BODY(combine__empty)214*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(combine__empty)
215*b0d29bc4SBrooks Davis {
216*b0d29bc4SBrooks Davis     const config::tree t1, t2;
217*b0d29bc4SBrooks Davis     const config::tree combined = t1.combine(t2);
218*b0d29bc4SBrooks Davis 
219*b0d29bc4SBrooks Davis     const config::tree expected;
220*b0d29bc4SBrooks Davis     ATF_REQUIRE(expected == combined);
221*b0d29bc4SBrooks Davis }
222*b0d29bc4SBrooks Davis 
223*b0d29bc4SBrooks Davis 
224*b0d29bc4SBrooks Davis static void
init_tree_for_combine_test(config::tree & tree)225*b0d29bc4SBrooks Davis init_tree_for_combine_test(config::tree& tree)
226*b0d29bc4SBrooks Davis {
227*b0d29bc4SBrooks Davis     tree.define< config::int_node >("int-node");
228*b0d29bc4SBrooks Davis     tree.define< config::string_node >("string-node");
229*b0d29bc4SBrooks Davis     tree.define< config::int_node >("unused.node");
230*b0d29bc4SBrooks Davis     tree.define< config::int_node >("deeper.int.node");
231*b0d29bc4SBrooks Davis     tree.define_dynamic("deeper.dynamic");
232*b0d29bc4SBrooks Davis }
233*b0d29bc4SBrooks Davis 
234*b0d29bc4SBrooks Davis 
235*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(combine__same_layout__no_overrides);
ATF_TEST_CASE_BODY(combine__same_layout__no_overrides)236*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(combine__same_layout__no_overrides)
237*b0d29bc4SBrooks Davis {
238*b0d29bc4SBrooks Davis     config::tree t1, t2;
239*b0d29bc4SBrooks Davis     init_tree_for_combine_test(t1);
240*b0d29bc4SBrooks Davis     init_tree_for_combine_test(t2);
241*b0d29bc4SBrooks Davis     t1.set< config::int_node >("int-node", 3);
242*b0d29bc4SBrooks Davis     t1.set< config::string_node >("string-node", "foo");
243*b0d29bc4SBrooks Davis     t1.set< config::int_node >("deeper.int.node", 15);
244*b0d29bc4SBrooks Davis     t1.set_string("deeper.dynamic.first", "value1");
245*b0d29bc4SBrooks Davis     t1.set_string("deeper.dynamic.second", "value2");
246*b0d29bc4SBrooks Davis     const config::tree combined = t1.combine(t2);
247*b0d29bc4SBrooks Davis 
248*b0d29bc4SBrooks Davis     ATF_REQUIRE(t1 == combined);
249*b0d29bc4SBrooks Davis }
250*b0d29bc4SBrooks Davis 
251*b0d29bc4SBrooks Davis 
252*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(combine__same_layout__no_base);
ATF_TEST_CASE_BODY(combine__same_layout__no_base)253*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(combine__same_layout__no_base)
254*b0d29bc4SBrooks Davis {
255*b0d29bc4SBrooks Davis     config::tree t1, t2;
256*b0d29bc4SBrooks Davis     init_tree_for_combine_test(t1);
257*b0d29bc4SBrooks Davis     init_tree_for_combine_test(t2);
258*b0d29bc4SBrooks Davis     t2.set< config::int_node >("int-node", 3);
259*b0d29bc4SBrooks Davis     t2.set< config::string_node >("string-node", "foo");
260*b0d29bc4SBrooks Davis     t2.set< config::int_node >("deeper.int.node", 15);
261*b0d29bc4SBrooks Davis     t2.set_string("deeper.dynamic.first", "value1");
262*b0d29bc4SBrooks Davis     t2.set_string("deeper.dynamic.second", "value2");
263*b0d29bc4SBrooks Davis     const config::tree combined = t1.combine(t2);
264*b0d29bc4SBrooks Davis 
265*b0d29bc4SBrooks Davis     ATF_REQUIRE(t2 == combined);
266*b0d29bc4SBrooks Davis }
267*b0d29bc4SBrooks Davis 
268*b0d29bc4SBrooks Davis 
269*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(combine__same_layout__mix);
ATF_TEST_CASE_BODY(combine__same_layout__mix)270*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(combine__same_layout__mix)
271*b0d29bc4SBrooks Davis {
272*b0d29bc4SBrooks Davis     config::tree t1, t2;
273*b0d29bc4SBrooks Davis     init_tree_for_combine_test(t1);
274*b0d29bc4SBrooks Davis     init_tree_for_combine_test(t2);
275*b0d29bc4SBrooks Davis     t1.set< config::int_node >("int-node", 3);
276*b0d29bc4SBrooks Davis     t2.set< config::int_node >("int-node", 5);
277*b0d29bc4SBrooks Davis     t1.set< config::string_node >("string-node", "foo");
278*b0d29bc4SBrooks Davis     t2.set< config::int_node >("deeper.int.node", 15);
279*b0d29bc4SBrooks Davis     t1.set_string("deeper.dynamic.first", "value1");
280*b0d29bc4SBrooks Davis     t1.set_string("deeper.dynamic.second", "value2.1");
281*b0d29bc4SBrooks Davis     t2.set_string("deeper.dynamic.second", "value2.2");
282*b0d29bc4SBrooks Davis     t2.set_string("deeper.dynamic.third", "value3");
283*b0d29bc4SBrooks Davis     const config::tree combined = t1.combine(t2);
284*b0d29bc4SBrooks Davis 
285*b0d29bc4SBrooks Davis     config::tree expected;
286*b0d29bc4SBrooks Davis     init_tree_for_combine_test(expected);
287*b0d29bc4SBrooks Davis     expected.set< config::int_node >("int-node", 5);
288*b0d29bc4SBrooks Davis     expected.set< config::string_node >("string-node", "foo");
289*b0d29bc4SBrooks Davis     expected.set< config::int_node >("deeper.int.node", 15);
290*b0d29bc4SBrooks Davis     expected.set_string("deeper.dynamic.first", "value1");
291*b0d29bc4SBrooks Davis     expected.set_string("deeper.dynamic.second", "value2.2");
292*b0d29bc4SBrooks Davis     expected.set_string("deeper.dynamic.third", "value3");
293*b0d29bc4SBrooks Davis     ATF_REQUIRE(expected == combined);
294*b0d29bc4SBrooks Davis }
295*b0d29bc4SBrooks Davis 
296*b0d29bc4SBrooks Davis 
297*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(combine__different_layout);
ATF_TEST_CASE_BODY(combine__different_layout)298*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(combine__different_layout)
299*b0d29bc4SBrooks Davis {
300*b0d29bc4SBrooks Davis     config::tree t1;
301*b0d29bc4SBrooks Davis     t1.define< config::int_node >("common.base1");
302*b0d29bc4SBrooks Davis     t1.define< config::int_node >("common.base2");
303*b0d29bc4SBrooks Davis     t1.define_dynamic("dynamic.base");
304*b0d29bc4SBrooks Davis     t1.define< config::int_node >("unset.base");
305*b0d29bc4SBrooks Davis 
306*b0d29bc4SBrooks Davis     config::tree t2;
307*b0d29bc4SBrooks Davis     t2.define< config::int_node >("common.base2");
308*b0d29bc4SBrooks Davis     t2.define< config::int_node >("common.base3");
309*b0d29bc4SBrooks Davis     t2.define_dynamic("dynamic.other");
310*b0d29bc4SBrooks Davis     t2.define< config::int_node >("unset.other");
311*b0d29bc4SBrooks Davis 
312*b0d29bc4SBrooks Davis     t1.set< config::int_node >("common.base1", 1);
313*b0d29bc4SBrooks Davis     t1.set< config::int_node >("common.base2", 2);
314*b0d29bc4SBrooks Davis     t1.set_string("dynamic.base.first", "foo");
315*b0d29bc4SBrooks Davis     t1.set_string("dynamic.base.second", "bar");
316*b0d29bc4SBrooks Davis 
317*b0d29bc4SBrooks Davis     t2.set< config::int_node >("common.base2", 4);
318*b0d29bc4SBrooks Davis     t2.set< config::int_node >("common.base3", 3);
319*b0d29bc4SBrooks Davis     t2.set_string("dynamic.other.first", "FOO");
320*b0d29bc4SBrooks Davis     t2.set_string("dynamic.other.second", "BAR");
321*b0d29bc4SBrooks Davis 
322*b0d29bc4SBrooks Davis     config::tree combined = t1.combine(t2);
323*b0d29bc4SBrooks Davis 
324*b0d29bc4SBrooks Davis     config::tree expected;
325*b0d29bc4SBrooks Davis     expected.define< config::int_node >("common.base1");
326*b0d29bc4SBrooks Davis     expected.define< config::int_node >("common.base2");
327*b0d29bc4SBrooks Davis     expected.define< config::int_node >("common.base3");
328*b0d29bc4SBrooks Davis     expected.define_dynamic("dynamic.base");
329*b0d29bc4SBrooks Davis     expected.define_dynamic("dynamic.other");
330*b0d29bc4SBrooks Davis     expected.define< config::int_node >("unset.base");
331*b0d29bc4SBrooks Davis     expected.define< config::int_node >("unset.other");
332*b0d29bc4SBrooks Davis 
333*b0d29bc4SBrooks Davis     expected.set< config::int_node >("common.base1", 1);
334*b0d29bc4SBrooks Davis     expected.set< config::int_node >("common.base2", 4);
335*b0d29bc4SBrooks Davis     expected.set< config::int_node >("common.base3", 3);
336*b0d29bc4SBrooks Davis     expected.set_string("dynamic.base.first", "foo");
337*b0d29bc4SBrooks Davis     expected.set_string("dynamic.base.second", "bar");
338*b0d29bc4SBrooks Davis     expected.set_string("dynamic.other.first", "FOO");
339*b0d29bc4SBrooks Davis     expected.set_string("dynamic.other.second", "BAR");
340*b0d29bc4SBrooks Davis 
341*b0d29bc4SBrooks Davis     ATF_REQUIRE(expected == combined);
342*b0d29bc4SBrooks Davis 
343*b0d29bc4SBrooks Davis     // The combined tree should have respected existing but unset nodes.  Check
344*b0d29bc4SBrooks Davis     // that these calls do not crash.
345*b0d29bc4SBrooks Davis     combined.set< config::int_node >("unset.base", 5);
346*b0d29bc4SBrooks Davis     combined.set< config::int_node >("unset.other", 5);
347*b0d29bc4SBrooks Davis }
348*b0d29bc4SBrooks Davis 
349*b0d29bc4SBrooks Davis 
350*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(combine__dynamic_wins);
ATF_TEST_CASE_BODY(combine__dynamic_wins)351*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(combine__dynamic_wins)
352*b0d29bc4SBrooks Davis {
353*b0d29bc4SBrooks Davis     config::tree t1;
354*b0d29bc4SBrooks Davis     t1.define< config::int_node >("inner.leaf1");
355*b0d29bc4SBrooks Davis     t1.set< config::int_node >("inner.leaf1", 3);
356*b0d29bc4SBrooks Davis 
357*b0d29bc4SBrooks Davis     config::tree t2;
358*b0d29bc4SBrooks Davis     t2.define_dynamic("inner");
359*b0d29bc4SBrooks Davis     t2.set_string("inner.leaf2", "4");
360*b0d29bc4SBrooks Davis 
361*b0d29bc4SBrooks Davis     config::tree combined = t1.combine(t2);
362*b0d29bc4SBrooks Davis 
363*b0d29bc4SBrooks Davis     config::tree expected;
364*b0d29bc4SBrooks Davis     expected.define_dynamic("inner");
365*b0d29bc4SBrooks Davis     expected.set_string("inner.leaf1", "3");
366*b0d29bc4SBrooks Davis     expected.set_string("inner.leaf2", "4");
367*b0d29bc4SBrooks Davis 
368*b0d29bc4SBrooks Davis     ATF_REQUIRE(expected == combined);
369*b0d29bc4SBrooks Davis 
370*b0d29bc4SBrooks Davis     // The combined inner node should have become dynamic so this call should
371*b0d29bc4SBrooks Davis     // not fail.
372*b0d29bc4SBrooks Davis     combined.set_string("inner.leaf3", "5");
373*b0d29bc4SBrooks Davis }
374*b0d29bc4SBrooks Davis 
375*b0d29bc4SBrooks Davis 
376*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(combine__inner_leaf_mismatch);
ATF_TEST_CASE_BODY(combine__inner_leaf_mismatch)377*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(combine__inner_leaf_mismatch)
378*b0d29bc4SBrooks Davis {
379*b0d29bc4SBrooks Davis     config::tree t1;
380*b0d29bc4SBrooks Davis     t1.define< config::int_node >("top.foo.bar");
381*b0d29bc4SBrooks Davis 
382*b0d29bc4SBrooks Davis     config::tree t2;
383*b0d29bc4SBrooks Davis     t2.define< config::int_node >("top.foo");
384*b0d29bc4SBrooks Davis 
385*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(config::bad_combination_error,
386*b0d29bc4SBrooks Davis                          "'top.foo' is an inner node in the base tree but a "
387*b0d29bc4SBrooks Davis                          "leaf node in the overrides tree",
388*b0d29bc4SBrooks Davis                          t1.combine(t2));
389*b0d29bc4SBrooks Davis 
390*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(config::bad_combination_error,
391*b0d29bc4SBrooks Davis                          "'top.foo' is a leaf node in the base tree but an "
392*b0d29bc4SBrooks Davis                          "inner node in the overrides tree",
393*b0d29bc4SBrooks Davis                          t2.combine(t1));
394*b0d29bc4SBrooks Davis }
395*b0d29bc4SBrooks Davis 
396*b0d29bc4SBrooks Davis 
397*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(lookup__invalid_key);
ATF_TEST_CASE_BODY(lookup__invalid_key)398*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(lookup__invalid_key)
399*b0d29bc4SBrooks Davis {
400*b0d29bc4SBrooks Davis     config::tree tree;
401*b0d29bc4SBrooks Davis 
402*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::invalid_key_error,
403*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("."));
404*b0d29bc4SBrooks Davis }
405*b0d29bc4SBrooks Davis 
406*b0d29bc4SBrooks Davis 
407*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(lookup__unknown_key);
ATF_TEST_CASE_BODY(lookup__unknown_key)408*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(lookup__unknown_key)
409*b0d29bc4SBrooks Davis {
410*b0d29bc4SBrooks Davis     config::tree tree;
411*b0d29bc4SBrooks Davis 
412*b0d29bc4SBrooks Davis     tree.define< config::int_node >("foo.bar");
413*b0d29bc4SBrooks Davis     tree.define< config::int_node >("a.b.c");
414*b0d29bc4SBrooks Davis     tree.define_dynamic("a.d");
415*b0d29bc4SBrooks Davis     tree.set< config::int_node >("a.b.c", 123);
416*b0d29bc4SBrooks Davis     tree.set< config::int_node >("a.d.100", 0);
417*b0d29bc4SBrooks Davis 
418*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
419*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("abc"));
420*b0d29bc4SBrooks Davis 
421*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
422*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("foo"));
423*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
424*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("foo.bar"));
425*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
426*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("foo.bar.baz"));
427*b0d29bc4SBrooks Davis 
428*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
429*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("a"));
430*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
431*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("a.b"));
432*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
433*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("a.c"));
434*b0d29bc4SBrooks Davis     (void)tree.lookup< config::int_node >("a.b.c");
435*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
436*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("a.b.c.d"));
437*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
438*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("a.d"));
439*b0d29bc4SBrooks Davis     (void)tree.lookup< config::int_node >("a.d.100");
440*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
441*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("a.d.101"));
442*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
443*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("a.d.100.3"));
444*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
445*b0d29bc4SBrooks Davis                       tree.lookup< config::int_node >("a.d.e"));
446*b0d29bc4SBrooks Davis }
447*b0d29bc4SBrooks Davis 
448*b0d29bc4SBrooks Davis 
449*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(is_set__one_level);
ATF_TEST_CASE_BODY(is_set__one_level)450*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(is_set__one_level)
451*b0d29bc4SBrooks Davis {
452*b0d29bc4SBrooks Davis     config::tree tree;
453*b0d29bc4SBrooks Davis 
454*b0d29bc4SBrooks Davis     tree.define< config::int_node >("var1");
455*b0d29bc4SBrooks Davis     tree.define< config::string_node >("var2");
456*b0d29bc4SBrooks Davis     tree.define< config::bool_node >("var3");
457*b0d29bc4SBrooks Davis 
458*b0d29bc4SBrooks Davis     tree.set< config::int_node >("var1", 42);
459*b0d29bc4SBrooks Davis     tree.set< config::bool_node >("var3", false);
460*b0d29bc4SBrooks Davis 
461*b0d29bc4SBrooks Davis     ATF_REQUIRE( tree.is_set("var1"));
462*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("var2"));
463*b0d29bc4SBrooks Davis     ATF_REQUIRE( tree.is_set("var3"));
464*b0d29bc4SBrooks Davis }
465*b0d29bc4SBrooks Davis 
466*b0d29bc4SBrooks Davis 
467*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(is_set__multiple_levels);
ATF_TEST_CASE_BODY(is_set__multiple_levels)468*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(is_set__multiple_levels)
469*b0d29bc4SBrooks Davis {
470*b0d29bc4SBrooks Davis     config::tree tree;
471*b0d29bc4SBrooks Davis 
472*b0d29bc4SBrooks Davis     tree.define< config::int_node >("a.b.var1");
473*b0d29bc4SBrooks Davis     tree.define< config::string_node >("a.b.var2");
474*b0d29bc4SBrooks Davis     tree.define< config::bool_node >("e.var3");
475*b0d29bc4SBrooks Davis 
476*b0d29bc4SBrooks Davis     tree.set< config::int_node >("a.b.var1", 42);
477*b0d29bc4SBrooks Davis     tree.set< config::bool_node >("e.var3", false);
478*b0d29bc4SBrooks Davis 
479*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("a"));
480*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("a.b"));
481*b0d29bc4SBrooks Davis     ATF_REQUIRE( tree.is_set("a.b.var1"));
482*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("a.b.var1.trailing"));
483*b0d29bc4SBrooks Davis 
484*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("a"));
485*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("a.b"));
486*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("a.b.var2"));
487*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("a.b.var2.trailing"));
488*b0d29bc4SBrooks Davis 
489*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("e"));
490*b0d29bc4SBrooks Davis     ATF_REQUIRE( tree.is_set("e.var3"));
491*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("e.var3.trailing"));
492*b0d29bc4SBrooks Davis }
493*b0d29bc4SBrooks Davis 
494*b0d29bc4SBrooks Davis 
495*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(is_set__invalid_key);
ATF_TEST_CASE_BODY(is_set__invalid_key)496*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(is_set__invalid_key)
497*b0d29bc4SBrooks Davis {
498*b0d29bc4SBrooks Davis     config::tree tree;
499*b0d29bc4SBrooks Davis 
500*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::invalid_key_error, tree.is_set(".abc"));
501*b0d29bc4SBrooks Davis }
502*b0d29bc4SBrooks Davis 
503*b0d29bc4SBrooks Davis 
504*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(set__invalid_key);
ATF_TEST_CASE_BODY(set__invalid_key)505*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(set__invalid_key)
506*b0d29bc4SBrooks Davis {
507*b0d29bc4SBrooks Davis     config::tree tree;
508*b0d29bc4SBrooks Davis 
509*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::invalid_key_error,
510*b0d29bc4SBrooks Davis                       tree.set< config::int_node >("foo.", 54));
511*b0d29bc4SBrooks Davis }
512*b0d29bc4SBrooks Davis 
513*b0d29bc4SBrooks Davis 
514*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(set__invalid_key_value);
ATF_TEST_CASE_BODY(set__invalid_key_value)515*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(set__invalid_key_value)
516*b0d29bc4SBrooks Davis {
517*b0d29bc4SBrooks Davis     config::tree tree;
518*b0d29bc4SBrooks Davis 
519*b0d29bc4SBrooks Davis     tree.define< config::int_node >("foo.bar");
520*b0d29bc4SBrooks Davis     tree.define_dynamic("a.d");
521*b0d29bc4SBrooks Davis 
522*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::invalid_key_value,
523*b0d29bc4SBrooks Davis                       tree.set< config::int_node >("foo", 3));
524*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::invalid_key_value,
525*b0d29bc4SBrooks Davis                       tree.set< config::int_node >("a", -10));
526*b0d29bc4SBrooks Davis }
527*b0d29bc4SBrooks Davis 
528*b0d29bc4SBrooks Davis 
529*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(set__unknown_key);
ATF_TEST_CASE_BODY(set__unknown_key)530*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(set__unknown_key)
531*b0d29bc4SBrooks Davis {
532*b0d29bc4SBrooks Davis     config::tree tree;
533*b0d29bc4SBrooks Davis 
534*b0d29bc4SBrooks Davis     tree.define< config::int_node >("foo.bar");
535*b0d29bc4SBrooks Davis     tree.define< config::int_node >("a.b.c");
536*b0d29bc4SBrooks Davis     tree.define_dynamic("a.d");
537*b0d29bc4SBrooks Davis     tree.set< config::int_node >("a.b.c", 123);
538*b0d29bc4SBrooks Davis     tree.set< config::string_node >("a.d.3", "foo");
539*b0d29bc4SBrooks Davis 
540*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
541*b0d29bc4SBrooks Davis                       tree.set< config::int_node >("abc", 2));
542*b0d29bc4SBrooks Davis 
543*b0d29bc4SBrooks Davis     tree.set< config::int_node >("foo.bar", 15);
544*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
545*b0d29bc4SBrooks Davis                       tree.set< config::int_node >("foo.bar.baz", 0));
546*b0d29bc4SBrooks Davis 
547*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
548*b0d29bc4SBrooks Davis                       tree.set< config::int_node >("a.c", 100));
549*b0d29bc4SBrooks Davis     tree.set< config::int_node >("a.b.c", -3);
550*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
551*b0d29bc4SBrooks Davis                       tree.set< config::int_node >("a.b.c.d", 82));
552*b0d29bc4SBrooks Davis     tree.set< config::string_node >("a.d.3", "bar");
553*b0d29bc4SBrooks Davis     tree.set< config::string_node >("a.d.4", "bar");
554*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
555*b0d29bc4SBrooks Davis                       tree.set< config::int_node >("a.d.4.5", 82));
556*b0d29bc4SBrooks Davis     tree.set< config::int_node >("a.d.5.6", 82);
557*b0d29bc4SBrooks Davis }
558*b0d29bc4SBrooks Davis 
559*b0d29bc4SBrooks Davis 
560*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(set__unknown_key_not_strict);
ATF_TEST_CASE_BODY(set__unknown_key_not_strict)561*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(set__unknown_key_not_strict)
562*b0d29bc4SBrooks Davis {
563*b0d29bc4SBrooks Davis     config::tree tree(false);
564*b0d29bc4SBrooks Davis 
565*b0d29bc4SBrooks Davis     tree.define< config::int_node >("foo.bar");
566*b0d29bc4SBrooks Davis     tree.define< config::int_node >("a.b.c");
567*b0d29bc4SBrooks Davis     tree.define_dynamic("a.d");
568*b0d29bc4SBrooks Davis     tree.set< config::int_node >("a.b.c", 123);
569*b0d29bc4SBrooks Davis     tree.set< config::string_node >("a.d.3", "foo");
570*b0d29bc4SBrooks Davis 
571*b0d29bc4SBrooks Davis     tree.set< config::int_node >("abc", 2);
572*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("abc"));
573*b0d29bc4SBrooks Davis 
574*b0d29bc4SBrooks Davis     tree.set< config::int_node >("foo.bar", 15);
575*b0d29bc4SBrooks Davis     tree.set< config::int_node >("foo.bar.baz", 0);
576*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("foo.bar.baz"));
577*b0d29bc4SBrooks Davis 
578*b0d29bc4SBrooks Davis     tree.set< config::int_node >("a.c", 100);
579*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("a.c"));
580*b0d29bc4SBrooks Davis }
581*b0d29bc4SBrooks Davis 
582*b0d29bc4SBrooks Davis 
583*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(push_lua__ok);
ATF_TEST_CASE_BODY(push_lua__ok)584*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(push_lua__ok)
585*b0d29bc4SBrooks Davis {
586*b0d29bc4SBrooks Davis     config::tree tree;
587*b0d29bc4SBrooks Davis 
588*b0d29bc4SBrooks Davis     tree.define< config::int_node >("top.integer");
589*b0d29bc4SBrooks Davis     tree.define< wrapped_int_node >("top.custom");
590*b0d29bc4SBrooks Davis     tree.define_dynamic("dynamic");
591*b0d29bc4SBrooks Davis     tree.set< config::int_node >("top.integer", 5);
592*b0d29bc4SBrooks Davis     tree.set< wrapped_int_node >("top.custom", int_wrapper(10));
593*b0d29bc4SBrooks Davis     tree.set_string("dynamic.first", "foo");
594*b0d29bc4SBrooks Davis 
595*b0d29bc4SBrooks Davis     lutok::state state;
596*b0d29bc4SBrooks Davis     tree.push_lua("top.integer", state);
597*b0d29bc4SBrooks Davis     tree.push_lua("top.custom", state);
598*b0d29bc4SBrooks Davis     tree.push_lua("dynamic.first", state);
599*b0d29bc4SBrooks Davis     ATF_REQUIRE(state.is_number(-3));
600*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(5, state.to_integer(-3));
601*b0d29bc4SBrooks Davis     ATF_REQUIRE(state.is_number(-2));
602*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(10, state.to_integer(-2));
603*b0d29bc4SBrooks Davis     ATF_REQUIRE(state.is_string(-1));
604*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("foo", state.to_string(-1));
605*b0d29bc4SBrooks Davis     state.pop(3);
606*b0d29bc4SBrooks Davis }
607*b0d29bc4SBrooks Davis 
608*b0d29bc4SBrooks Davis 
609*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(set_lua__ok);
ATF_TEST_CASE_BODY(set_lua__ok)610*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(set_lua__ok)
611*b0d29bc4SBrooks Davis {
612*b0d29bc4SBrooks Davis     config::tree tree;
613*b0d29bc4SBrooks Davis 
614*b0d29bc4SBrooks Davis     tree.define< config::int_node >("top.integer");
615*b0d29bc4SBrooks Davis     tree.define< wrapped_int_node >("top.custom");
616*b0d29bc4SBrooks Davis     tree.define_dynamic("dynamic");
617*b0d29bc4SBrooks Davis 
618*b0d29bc4SBrooks Davis     {
619*b0d29bc4SBrooks Davis         lutok::state state;
620*b0d29bc4SBrooks Davis         state.push_integer(5);
621*b0d29bc4SBrooks Davis         state.push_integer(10);
622*b0d29bc4SBrooks Davis         state.push_string("foo");
623*b0d29bc4SBrooks Davis         tree.set_lua("top.integer", state, -3);
624*b0d29bc4SBrooks Davis         tree.set_lua("top.custom", state, -2);
625*b0d29bc4SBrooks Davis         tree.set_lua("dynamic.first", state, -1);
626*b0d29bc4SBrooks Davis         state.pop(3);
627*b0d29bc4SBrooks Davis     }
628*b0d29bc4SBrooks Davis 
629*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(5, tree.lookup< config::int_node >("top.integer"));
630*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(10, tree.lookup< wrapped_int_node >("top.custom").value());
631*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("foo", tree.lookup< config::string_node >("dynamic.first"));
632*b0d29bc4SBrooks Davis }
633*b0d29bc4SBrooks Davis 
634*b0d29bc4SBrooks Davis 
635*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(lookup_rw);
ATF_TEST_CASE_BODY(lookup_rw)636*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(lookup_rw)
637*b0d29bc4SBrooks Davis {
638*b0d29bc4SBrooks Davis     config::tree tree;
639*b0d29bc4SBrooks Davis 
640*b0d29bc4SBrooks Davis     tree.define< config::int_node >("var1");
641*b0d29bc4SBrooks Davis     tree.define< config::bool_node >("var3");
642*b0d29bc4SBrooks Davis 
643*b0d29bc4SBrooks Davis     tree.set< config::int_node >("var1", 42);
644*b0d29bc4SBrooks Davis     tree.set< config::bool_node >("var3", false);
645*b0d29bc4SBrooks Davis 
646*b0d29bc4SBrooks Davis     tree.lookup_rw< config::int_node >("var1") += 10;
647*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(52, tree.lookup< config::int_node >("var1"));
648*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.lookup< config::bool_node >("var3"));
649*b0d29bc4SBrooks Davis }
650*b0d29bc4SBrooks Davis 
651*b0d29bc4SBrooks Davis 
652*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(lookup_string__ok);
ATF_TEST_CASE_BODY(lookup_string__ok)653*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(lookup_string__ok)
654*b0d29bc4SBrooks Davis {
655*b0d29bc4SBrooks Davis     config::tree tree;
656*b0d29bc4SBrooks Davis 
657*b0d29bc4SBrooks Davis     tree.define< config::int_node >("var1");
658*b0d29bc4SBrooks Davis     tree.define< config::string_node >("b.var2");
659*b0d29bc4SBrooks Davis     tree.define< config::bool_node >("c.d.var3");
660*b0d29bc4SBrooks Davis 
661*b0d29bc4SBrooks Davis     tree.set< config::int_node >("var1", 42);
662*b0d29bc4SBrooks Davis     tree.set< config::string_node >("b.var2", "hello");
663*b0d29bc4SBrooks Davis     tree.set< config::bool_node >("c.d.var3", false);
664*b0d29bc4SBrooks Davis 
665*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("42", tree.lookup_string("var1"));
666*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("hello", tree.lookup_string("b.var2"));
667*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("false", tree.lookup_string("c.d.var3"));
668*b0d29bc4SBrooks Davis }
669*b0d29bc4SBrooks Davis 
670*b0d29bc4SBrooks Davis 
671*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(lookup_string__invalid_key);
ATF_TEST_CASE_BODY(lookup_string__invalid_key)672*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(lookup_string__invalid_key)
673*b0d29bc4SBrooks Davis {
674*b0d29bc4SBrooks Davis     config::tree tree;
675*b0d29bc4SBrooks Davis 
676*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::invalid_key_error, tree.lookup_string(""));
677*b0d29bc4SBrooks Davis }
678*b0d29bc4SBrooks Davis 
679*b0d29bc4SBrooks Davis 
680*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(lookup_string__unknown_key);
ATF_TEST_CASE_BODY(lookup_string__unknown_key)681*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(lookup_string__unknown_key)
682*b0d29bc4SBrooks Davis {
683*b0d29bc4SBrooks Davis     config::tree tree;
684*b0d29bc4SBrooks Davis 
685*b0d29bc4SBrooks Davis     tree.define< config::int_node >("a.b.c");
686*b0d29bc4SBrooks Davis 
687*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error, tree.lookup_string("a.b"));
688*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error, tree.lookup_string("a.b.c.d"));
689*b0d29bc4SBrooks Davis }
690*b0d29bc4SBrooks Davis 
691*b0d29bc4SBrooks Davis 
692*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(set_string__ok);
ATF_TEST_CASE_BODY(set_string__ok)693*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(set_string__ok)
694*b0d29bc4SBrooks Davis {
695*b0d29bc4SBrooks Davis     config::tree tree;
696*b0d29bc4SBrooks Davis 
697*b0d29bc4SBrooks Davis     tree.define< config::int_node >("foo.bar.1");
698*b0d29bc4SBrooks Davis     tree.define< config::string_node >("foo.bar.2");
699*b0d29bc4SBrooks Davis     tree.define_dynamic("sub.tree");
700*b0d29bc4SBrooks Davis 
701*b0d29bc4SBrooks Davis     tree.set_string("foo.bar.1", "42");
702*b0d29bc4SBrooks Davis     tree.set_string("foo.bar.2", "hello");
703*b0d29bc4SBrooks Davis     tree.set_string("sub.tree.2", "15");
704*b0d29bc4SBrooks Davis     tree.set_string("sub.tree.3.4", "bye");
705*b0d29bc4SBrooks Davis 
706*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(42, tree.lookup< config::int_node >("foo.bar.1"));
707*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("hello", tree.lookup< config::string_node >("foo.bar.2"));
708*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("15", tree.lookup< config::string_node >("sub.tree.2"));
709*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("bye", tree.lookup< config::string_node >("sub.tree.3.4"));
710*b0d29bc4SBrooks Davis }
711*b0d29bc4SBrooks Davis 
712*b0d29bc4SBrooks Davis 
713*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(set_string__invalid_key);
ATF_TEST_CASE_BODY(set_string__invalid_key)714*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(set_string__invalid_key)
715*b0d29bc4SBrooks Davis {
716*b0d29bc4SBrooks Davis     config::tree tree;
717*b0d29bc4SBrooks Davis 
718*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::invalid_key_error, tree.set_string(".", "foo"));
719*b0d29bc4SBrooks Davis }
720*b0d29bc4SBrooks Davis 
721*b0d29bc4SBrooks Davis 
722*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(set_string__invalid_key_value);
ATF_TEST_CASE_BODY(set_string__invalid_key_value)723*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(set_string__invalid_key_value)
724*b0d29bc4SBrooks Davis {
725*b0d29bc4SBrooks Davis     config::tree tree;
726*b0d29bc4SBrooks Davis 
727*b0d29bc4SBrooks Davis     tree.define< config::int_node >("foo.bar");
728*b0d29bc4SBrooks Davis 
729*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::invalid_key_value,
730*b0d29bc4SBrooks Davis                       tree.set_string("foo", "abc"));
731*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::invalid_key_value,
732*b0d29bc4SBrooks Davis                       tree.set_string("foo.bar", " -3"));
733*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::invalid_key_value,
734*b0d29bc4SBrooks Davis                       tree.set_string("foo.bar", "3 "));
735*b0d29bc4SBrooks Davis }
736*b0d29bc4SBrooks Davis 
737*b0d29bc4SBrooks Davis 
738*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(set_string__unknown_key);
ATF_TEST_CASE_BODY(set_string__unknown_key)739*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(set_string__unknown_key)
740*b0d29bc4SBrooks Davis {
741*b0d29bc4SBrooks Davis     config::tree tree;
742*b0d29bc4SBrooks Davis 
743*b0d29bc4SBrooks Davis     tree.define< config::int_node >("foo.bar");
744*b0d29bc4SBrooks Davis     tree.define< config::int_node >("a.b.c");
745*b0d29bc4SBrooks Davis     tree.define_dynamic("a.d");
746*b0d29bc4SBrooks Davis     tree.set_string("a.b.c", "123");
747*b0d29bc4SBrooks Davis     tree.set_string("a.d.3", "foo");
748*b0d29bc4SBrooks Davis 
749*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error, tree.set_string("abc", "2"));
750*b0d29bc4SBrooks Davis 
751*b0d29bc4SBrooks Davis     tree.set_string("foo.bar", "15");
752*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
753*b0d29bc4SBrooks Davis                       tree.set_string("foo.bar.baz", "0"));
754*b0d29bc4SBrooks Davis 
755*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
756*b0d29bc4SBrooks Davis                       tree.set_string("a.c", "100"));
757*b0d29bc4SBrooks Davis     tree.set_string("a.b.c", "-3");
758*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
759*b0d29bc4SBrooks Davis                       tree.set_string("a.b.c.d", "82"));
760*b0d29bc4SBrooks Davis     tree.set_string("a.d.3", "bar");
761*b0d29bc4SBrooks Davis     tree.set_string("a.d.4", "bar");
762*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
763*b0d29bc4SBrooks Davis                       tree.set_string("a.d.4.5", "82"));
764*b0d29bc4SBrooks Davis     tree.set_string("a.d.5.6", "82");
765*b0d29bc4SBrooks Davis }
766*b0d29bc4SBrooks Davis 
767*b0d29bc4SBrooks Davis 
768*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(set_string__unknown_key_not_strict);
ATF_TEST_CASE_BODY(set_string__unknown_key_not_strict)769*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(set_string__unknown_key_not_strict)
770*b0d29bc4SBrooks Davis {
771*b0d29bc4SBrooks Davis     config::tree tree(false);
772*b0d29bc4SBrooks Davis 
773*b0d29bc4SBrooks Davis     tree.define< config::int_node >("foo.bar");
774*b0d29bc4SBrooks Davis     tree.define< config::int_node >("a.b.c");
775*b0d29bc4SBrooks Davis     tree.define_dynamic("a.d");
776*b0d29bc4SBrooks Davis     tree.set_string("a.b.c", "123");
777*b0d29bc4SBrooks Davis     tree.set_string("a.d.3", "foo");
778*b0d29bc4SBrooks Davis 
779*b0d29bc4SBrooks Davis     tree.set_string("abc", "2");
780*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("abc"));
781*b0d29bc4SBrooks Davis 
782*b0d29bc4SBrooks Davis     tree.set_string("foo.bar", "15");
783*b0d29bc4SBrooks Davis     tree.set_string("foo.bar.baz", "0");
784*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("foo.bar.baz"));
785*b0d29bc4SBrooks Davis 
786*b0d29bc4SBrooks Davis     tree.set_string("a.c", "100");
787*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("a.c"));
788*b0d29bc4SBrooks Davis }
789*b0d29bc4SBrooks Davis 
790*b0d29bc4SBrooks Davis 
791*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(all_properties__none);
ATF_TEST_CASE_BODY(all_properties__none)792*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(all_properties__none)
793*b0d29bc4SBrooks Davis {
794*b0d29bc4SBrooks Davis     const config::tree tree;
795*b0d29bc4SBrooks Davis     ATF_REQUIRE(tree.all_properties().empty());
796*b0d29bc4SBrooks Davis }
797*b0d29bc4SBrooks Davis 
798*b0d29bc4SBrooks Davis 
799*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(all_properties__all_set);
ATF_TEST_CASE_BODY(all_properties__all_set)800*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(all_properties__all_set)
801*b0d29bc4SBrooks Davis {
802*b0d29bc4SBrooks Davis     config::tree tree;
803*b0d29bc4SBrooks Davis 
804*b0d29bc4SBrooks Davis     tree.define< config::int_node >("plain");
805*b0d29bc4SBrooks Davis     tree.set< config::int_node >("plain", 1234);
806*b0d29bc4SBrooks Davis 
807*b0d29bc4SBrooks Davis     tree.define< config::int_node >("static.first");
808*b0d29bc4SBrooks Davis     tree.set< config::int_node >("static.first", -3);
809*b0d29bc4SBrooks Davis     tree.define< config::string_node >("static.second");
810*b0d29bc4SBrooks Davis     tree.set< config::string_node >("static.second", "some text");
811*b0d29bc4SBrooks Davis 
812*b0d29bc4SBrooks Davis     tree.define_dynamic("dynamic");
813*b0d29bc4SBrooks Davis     tree.set< config::string_node >("dynamic.first", "hello");
814*b0d29bc4SBrooks Davis     tree.set< config::string_node >("dynamic.second", "bye");
815*b0d29bc4SBrooks Davis 
816*b0d29bc4SBrooks Davis     config::properties_map exp_properties;
817*b0d29bc4SBrooks Davis     exp_properties["plain"] = "1234";
818*b0d29bc4SBrooks Davis     exp_properties["static.first"] = "-3";
819*b0d29bc4SBrooks Davis     exp_properties["static.second"] = "some text";
820*b0d29bc4SBrooks Davis     exp_properties["dynamic.first"] = "hello";
821*b0d29bc4SBrooks Davis     exp_properties["dynamic.second"] = "bye";
822*b0d29bc4SBrooks Davis 
823*b0d29bc4SBrooks Davis     const config::properties_map properties = tree.all_properties();
824*b0d29bc4SBrooks Davis     ATF_REQUIRE(exp_properties == properties);
825*b0d29bc4SBrooks Davis }
826*b0d29bc4SBrooks Davis 
827*b0d29bc4SBrooks Davis 
828*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(all_properties__some_unset);
ATF_TEST_CASE_BODY(all_properties__some_unset)829*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(all_properties__some_unset)
830*b0d29bc4SBrooks Davis {
831*b0d29bc4SBrooks Davis     config::tree tree;
832*b0d29bc4SBrooks Davis 
833*b0d29bc4SBrooks Davis     tree.define< config::int_node >("static.first");
834*b0d29bc4SBrooks Davis     tree.set< config::int_node >("static.first", -3);
835*b0d29bc4SBrooks Davis     tree.define< config::string_node >("static.second");
836*b0d29bc4SBrooks Davis 
837*b0d29bc4SBrooks Davis     tree.define_dynamic("dynamic");
838*b0d29bc4SBrooks Davis 
839*b0d29bc4SBrooks Davis     config::properties_map exp_properties;
840*b0d29bc4SBrooks Davis     exp_properties["static.first"] = "-3";
841*b0d29bc4SBrooks Davis 
842*b0d29bc4SBrooks Davis     const config::properties_map properties = tree.all_properties();
843*b0d29bc4SBrooks Davis     ATF_REQUIRE(exp_properties == properties);
844*b0d29bc4SBrooks Davis }
845*b0d29bc4SBrooks Davis 
846*b0d29bc4SBrooks Davis 
847*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(all_properties__subtree__inner);
ATF_TEST_CASE_BODY(all_properties__subtree__inner)848*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(all_properties__subtree__inner)
849*b0d29bc4SBrooks Davis {
850*b0d29bc4SBrooks Davis     config::tree tree;
851*b0d29bc4SBrooks Davis 
852*b0d29bc4SBrooks Davis     tree.define< config::int_node >("root.a.b.c.first");
853*b0d29bc4SBrooks Davis     tree.define< config::int_node >("root.a.b.c.second");
854*b0d29bc4SBrooks Davis     tree.define< config::int_node >("root.a.d.first");
855*b0d29bc4SBrooks Davis 
856*b0d29bc4SBrooks Davis     tree.set< config::int_node >("root.a.b.c.first", 1);
857*b0d29bc4SBrooks Davis     tree.set< config::int_node >("root.a.b.c.second", 2);
858*b0d29bc4SBrooks Davis     tree.set< config::int_node >("root.a.d.first", 3);
859*b0d29bc4SBrooks Davis 
860*b0d29bc4SBrooks Davis     {
861*b0d29bc4SBrooks Davis         config::properties_map exp_properties;
862*b0d29bc4SBrooks Davis         exp_properties["root.a.b.c.first"] = "1";
863*b0d29bc4SBrooks Davis         exp_properties["root.a.b.c.second"] = "2";
864*b0d29bc4SBrooks Davis         exp_properties["root.a.d.first"] = "3";
865*b0d29bc4SBrooks Davis         ATF_REQUIRE(exp_properties == tree.all_properties("root"));
866*b0d29bc4SBrooks Davis         ATF_REQUIRE(exp_properties == tree.all_properties("root.a"));
867*b0d29bc4SBrooks Davis     }
868*b0d29bc4SBrooks Davis 
869*b0d29bc4SBrooks Davis     {
870*b0d29bc4SBrooks Davis         config::properties_map exp_properties;
871*b0d29bc4SBrooks Davis         exp_properties["root.a.b.c.first"] = "1";
872*b0d29bc4SBrooks Davis         exp_properties["root.a.b.c.second"] = "2";
873*b0d29bc4SBrooks Davis         ATF_REQUIRE(exp_properties == tree.all_properties("root.a.b"));
874*b0d29bc4SBrooks Davis         ATF_REQUIRE(exp_properties == tree.all_properties("root.a.b.c"));
875*b0d29bc4SBrooks Davis     }
876*b0d29bc4SBrooks Davis 
877*b0d29bc4SBrooks Davis     {
878*b0d29bc4SBrooks Davis         config::properties_map exp_properties;
879*b0d29bc4SBrooks Davis         exp_properties["root.a.d.first"] = "3";
880*b0d29bc4SBrooks Davis         ATF_REQUIRE(exp_properties == tree.all_properties("root.a.d"));
881*b0d29bc4SBrooks Davis     }
882*b0d29bc4SBrooks Davis }
883*b0d29bc4SBrooks Davis 
884*b0d29bc4SBrooks Davis 
885*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(all_properties__subtree__leaf);
ATF_TEST_CASE_BODY(all_properties__subtree__leaf)886*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(all_properties__subtree__leaf)
887*b0d29bc4SBrooks Davis {
888*b0d29bc4SBrooks Davis     config::tree tree;
889*b0d29bc4SBrooks Davis 
890*b0d29bc4SBrooks Davis     tree.define< config::int_node >("root.a.b.c.first");
891*b0d29bc4SBrooks Davis     tree.set< config::int_node >("root.a.b.c.first", 1);
892*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(config::value_error, "Cannot export.*leaf",
893*b0d29bc4SBrooks Davis                          tree.all_properties("root.a.b.c.first"));
894*b0d29bc4SBrooks Davis }
895*b0d29bc4SBrooks Davis 
896*b0d29bc4SBrooks Davis 
897*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(all_properties__subtree__strip_key);
ATF_TEST_CASE_BODY(all_properties__subtree__strip_key)898*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(all_properties__subtree__strip_key)
899*b0d29bc4SBrooks Davis {
900*b0d29bc4SBrooks Davis     config::tree tree;
901*b0d29bc4SBrooks Davis 
902*b0d29bc4SBrooks Davis     tree.define< config::int_node >("root.a.b.c.first");
903*b0d29bc4SBrooks Davis     tree.define< config::int_node >("root.a.b.c.second");
904*b0d29bc4SBrooks Davis     tree.define< config::int_node >("root.a.d.first");
905*b0d29bc4SBrooks Davis 
906*b0d29bc4SBrooks Davis     tree.set< config::int_node >("root.a.b.c.first", 1);
907*b0d29bc4SBrooks Davis     tree.set< config::int_node >("root.a.b.c.second", 2);
908*b0d29bc4SBrooks Davis     tree.set< config::int_node >("root.a.d.first", 3);
909*b0d29bc4SBrooks Davis 
910*b0d29bc4SBrooks Davis     config::properties_map exp_properties;
911*b0d29bc4SBrooks Davis     exp_properties["b.c.first"] = "1";
912*b0d29bc4SBrooks Davis     exp_properties["b.c.second"] = "2";
913*b0d29bc4SBrooks Davis     exp_properties["d.first"] = "3";
914*b0d29bc4SBrooks Davis     ATF_REQUIRE(exp_properties == tree.all_properties("root.a", true));
915*b0d29bc4SBrooks Davis }
916*b0d29bc4SBrooks Davis 
917*b0d29bc4SBrooks Davis 
918*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(all_properties__subtree__invalid_key);
ATF_TEST_CASE_BODY(all_properties__subtree__invalid_key)919*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(all_properties__subtree__invalid_key)
920*b0d29bc4SBrooks Davis {
921*b0d29bc4SBrooks Davis     config::tree tree;
922*b0d29bc4SBrooks Davis 
923*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::invalid_key_error, tree.all_properties("."));
924*b0d29bc4SBrooks Davis }
925*b0d29bc4SBrooks Davis 
926*b0d29bc4SBrooks Davis 
927*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(all_properties__subtree__unknown_key);
ATF_TEST_CASE_BODY(all_properties__subtree__unknown_key)928*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(all_properties__subtree__unknown_key)
929*b0d29bc4SBrooks Davis {
930*b0d29bc4SBrooks Davis     config::tree tree;
931*b0d29bc4SBrooks Davis 
932*b0d29bc4SBrooks Davis     tree.define< config::int_node >("root.a.b.c.first");
933*b0d29bc4SBrooks Davis     tree.set< config::int_node >("root.a.b.c.first", 1);
934*b0d29bc4SBrooks Davis     tree.define< config::int_node >("root.a.b.c.unset");
935*b0d29bc4SBrooks Davis 
936*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW(config::unknown_key_error,
937*b0d29bc4SBrooks Davis                       tree.all_properties("root.a.b.c.first.foo"));
938*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(config::value_error, "Cannot export.*leaf",
939*b0d29bc4SBrooks Davis                          tree.all_properties("root.a.b.c.unset"));
940*b0d29bc4SBrooks Davis }
941*b0d29bc4SBrooks Davis 
942*b0d29bc4SBrooks Davis 
943*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__empty);
ATF_TEST_CASE_BODY(operators_eq_and_ne__empty)944*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(operators_eq_and_ne__empty)
945*b0d29bc4SBrooks Davis {
946*b0d29bc4SBrooks Davis     config::tree t1;
947*b0d29bc4SBrooks Davis     config::tree t2;
948*b0d29bc4SBrooks Davis     ATF_REQUIRE(  t1 == t2);
949*b0d29bc4SBrooks Davis     ATF_REQUIRE(!(t1 != t2));
950*b0d29bc4SBrooks Davis }
951*b0d29bc4SBrooks Davis 
952*b0d29bc4SBrooks Davis 
953*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__shallow_copy);
ATF_TEST_CASE_BODY(operators_eq_and_ne__shallow_copy)954*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(operators_eq_and_ne__shallow_copy)
955*b0d29bc4SBrooks Davis {
956*b0d29bc4SBrooks Davis     config::tree t1;
957*b0d29bc4SBrooks Davis     t1.define< config::int_node >("root.a.b.c.first");
958*b0d29bc4SBrooks Davis     t1.set< config::int_node >("root.a.b.c.first", 1);
959*b0d29bc4SBrooks Davis     config::tree t2 = t1;
960*b0d29bc4SBrooks Davis     ATF_REQUIRE(  t1 == t2);
961*b0d29bc4SBrooks Davis     ATF_REQUIRE(!(t1 != t2));
962*b0d29bc4SBrooks Davis }
963*b0d29bc4SBrooks Davis 
964*b0d29bc4SBrooks Davis 
965*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__deep_copy);
ATF_TEST_CASE_BODY(operators_eq_and_ne__deep_copy)966*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(operators_eq_and_ne__deep_copy)
967*b0d29bc4SBrooks Davis {
968*b0d29bc4SBrooks Davis     config::tree t1;
969*b0d29bc4SBrooks Davis     t1.define< config::int_node >("root.a.b.c.first");
970*b0d29bc4SBrooks Davis     t1.set< config::int_node >("root.a.b.c.first", 1);
971*b0d29bc4SBrooks Davis     config::tree t2 = t1.deep_copy();
972*b0d29bc4SBrooks Davis     ATF_REQUIRE(  t1 == t2);
973*b0d29bc4SBrooks Davis     ATF_REQUIRE(!(t1 != t2));
974*b0d29bc4SBrooks Davis }
975*b0d29bc4SBrooks Davis 
976*b0d29bc4SBrooks Davis 
977*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__some_contents);
ATF_TEST_CASE_BODY(operators_eq_and_ne__some_contents)978*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(operators_eq_and_ne__some_contents)
979*b0d29bc4SBrooks Davis {
980*b0d29bc4SBrooks Davis     config::tree t1, t2;
981*b0d29bc4SBrooks Davis 
982*b0d29bc4SBrooks Davis     t1.define< config::int_node >("root.a.b.c.first");
983*b0d29bc4SBrooks Davis     t1.set< config::int_node >("root.a.b.c.first", 1);
984*b0d29bc4SBrooks Davis     ATF_REQUIRE(!(t1 == t2));
985*b0d29bc4SBrooks Davis     ATF_REQUIRE(  t1 != t2);
986*b0d29bc4SBrooks Davis 
987*b0d29bc4SBrooks Davis     t2.define< config::int_node >("root.a.b.c.first");
988*b0d29bc4SBrooks Davis     t2.set< config::int_node >("root.a.b.c.first", 1);
989*b0d29bc4SBrooks Davis     ATF_REQUIRE(  t1 == t2);
990*b0d29bc4SBrooks Davis     ATF_REQUIRE(!(t1 != t2));
991*b0d29bc4SBrooks Davis 
992*b0d29bc4SBrooks Davis     t1.set< config::int_node >("root.a.b.c.first", 2);
993*b0d29bc4SBrooks Davis     ATF_REQUIRE(!(t1 == t2));
994*b0d29bc4SBrooks Davis     ATF_REQUIRE(  t1 != t2);
995*b0d29bc4SBrooks Davis 
996*b0d29bc4SBrooks Davis     t2.set< config::int_node >("root.a.b.c.first", 2);
997*b0d29bc4SBrooks Davis     ATF_REQUIRE(  t1 == t2);
998*b0d29bc4SBrooks Davis     ATF_REQUIRE(!(t1 != t2));
999*b0d29bc4SBrooks Davis 
1000*b0d29bc4SBrooks Davis     t1.define< config::string_node >("another.key");
1001*b0d29bc4SBrooks Davis     t1.set< config::string_node >("another.key", "some text");
1002*b0d29bc4SBrooks Davis     ATF_REQUIRE(!(t1 == t2));
1003*b0d29bc4SBrooks Davis     ATF_REQUIRE(  t1 != t2);
1004*b0d29bc4SBrooks Davis 
1005*b0d29bc4SBrooks Davis     t2.define< config::string_node >("another.key");
1006*b0d29bc4SBrooks Davis     t2.set< config::string_node >("another.key", "some text");
1007*b0d29bc4SBrooks Davis     ATF_REQUIRE(  t1 == t2);
1008*b0d29bc4SBrooks Davis     ATF_REQUIRE(!(t1 != t2));
1009*b0d29bc4SBrooks Davis }
1010*b0d29bc4SBrooks Davis 
1011*b0d29bc4SBrooks Davis 
1012*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(custom_leaf__no_default_ctor);
ATF_TEST_CASE_BODY(custom_leaf__no_default_ctor)1013*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(custom_leaf__no_default_ctor)
1014*b0d29bc4SBrooks Davis {
1015*b0d29bc4SBrooks Davis     config::tree tree;
1016*b0d29bc4SBrooks Davis 
1017*b0d29bc4SBrooks Davis     tree.define< wrapped_int_node >("test1");
1018*b0d29bc4SBrooks Davis     tree.define< wrapped_int_node >("test2");
1019*b0d29bc4SBrooks Davis     tree.set< wrapped_int_node >("test1", int_wrapper(5));
1020*b0d29bc4SBrooks Davis     tree.set< wrapped_int_node >("test2", int_wrapper(10));
1021*b0d29bc4SBrooks Davis     const int_wrapper& test1 = tree.lookup< wrapped_int_node >("test1");
1022*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(5, test1.value());
1023*b0d29bc4SBrooks Davis     const int_wrapper& test2 = tree.lookup< wrapped_int_node >("test2");
1024*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(10, test2.value());
1025*b0d29bc4SBrooks Davis }
1026*b0d29bc4SBrooks Davis 
1027*b0d29bc4SBrooks Davis 
ATF_INIT_TEST_CASES(tcs)1028*b0d29bc4SBrooks Davis ATF_INIT_TEST_CASES(tcs)
1029*b0d29bc4SBrooks Davis {
1030*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, define_set_lookup__one_level);
1031*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, define_set_lookup__multiple_levels);
1032*b0d29bc4SBrooks Davis 
1033*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, deep_copy__empty);
1034*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, deep_copy__some);
1035*b0d29bc4SBrooks Davis 
1036*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, combine__empty);
1037*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, combine__same_layout__no_overrides);
1038*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, combine__same_layout__no_base);
1039*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, combine__same_layout__mix);
1040*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, combine__different_layout);
1041*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, combine__dynamic_wins);
1042*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, combine__inner_leaf_mismatch);
1043*b0d29bc4SBrooks Davis 
1044*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, lookup__invalid_key);
1045*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, lookup__unknown_key);
1046*b0d29bc4SBrooks Davis 
1047*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, is_set__one_level);
1048*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, is_set__multiple_levels);
1049*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, is_set__invalid_key);
1050*b0d29bc4SBrooks Davis 
1051*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, set__invalid_key);
1052*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, set__invalid_key_value);
1053*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, set__unknown_key);
1054*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, set__unknown_key_not_strict);
1055*b0d29bc4SBrooks Davis 
1056*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, push_lua__ok);
1057*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, set_lua__ok);
1058*b0d29bc4SBrooks Davis 
1059*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, lookup_rw);
1060*b0d29bc4SBrooks Davis 
1061*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, lookup_string__ok);
1062*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, lookup_string__invalid_key);
1063*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, lookup_string__unknown_key);
1064*b0d29bc4SBrooks Davis 
1065*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, set_string__ok);
1066*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, set_string__invalid_key);
1067*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, set_string__invalid_key_value);
1068*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, set_string__unknown_key);
1069*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, set_string__unknown_key_not_strict);
1070*b0d29bc4SBrooks Davis 
1071*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, all_properties__none);
1072*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, all_properties__all_set);
1073*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, all_properties__some_unset);
1074*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, all_properties__subtree__inner);
1075*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, all_properties__subtree__leaf);
1076*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, all_properties__subtree__strip_key);
1077*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, all_properties__subtree__invalid_key);
1078*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, all_properties__subtree__unknown_key);
1079*b0d29bc4SBrooks Davis 
1080*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__empty);
1081*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__shallow_copy);
1082*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__deep_copy);
1083*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__some_contents);
1084*b0d29bc4SBrooks Davis 
1085*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, custom_leaf__no_default_ctor);
1086*b0d29bc4SBrooks Davis }
1087