xref: /freebsd/contrib/kyua/utils/config/lua_module_test.cpp (revision b0d29bc47dba79f6f38e67eabadfb4b32ffd9390)
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/lua_module.hpp"
30*b0d29bc4SBrooks Davis 
31*b0d29bc4SBrooks Davis #include <atf-c++.hpp>
32*b0d29bc4SBrooks Davis 
33*b0d29bc4SBrooks Davis #include <lutok/exceptions.hpp>
34*b0d29bc4SBrooks Davis #include <lutok/operations.hpp>
35*b0d29bc4SBrooks Davis #include <lutok/state.ipp>
36*b0d29bc4SBrooks Davis 
37*b0d29bc4SBrooks Davis #include "utils/config/tree.ipp"
38*b0d29bc4SBrooks Davis #include "utils/defs.hpp"
39*b0d29bc4SBrooks Davis 
40*b0d29bc4SBrooks Davis namespace config = utils::config;
41*b0d29bc4SBrooks Davis 
42*b0d29bc4SBrooks Davis 
43*b0d29bc4SBrooks Davis namespace {
44*b0d29bc4SBrooks Davis 
45*b0d29bc4SBrooks Davis 
46*b0d29bc4SBrooks Davis /// Non-native type to use as a leaf node.
47*b0d29bc4SBrooks Davis struct custom_type {
48*b0d29bc4SBrooks Davis     /// The value recorded in the object.
49*b0d29bc4SBrooks Davis     int value;
50*b0d29bc4SBrooks Davis 
51*b0d29bc4SBrooks Davis     /// Constructs a new object.
52*b0d29bc4SBrooks Davis     ///
53*b0d29bc4SBrooks Davis     /// \param value_ The value to store in the object.
54*b0d29bc4SBrooks Davis     explicit custom_type(const int value_) :
55*b0d29bc4SBrooks Davis         value(value_)
56*b0d29bc4SBrooks Davis     {
57*b0d29bc4SBrooks Davis     }
58*b0d29bc4SBrooks Davis };
59*b0d29bc4SBrooks Davis 
60*b0d29bc4SBrooks Davis 
61*b0d29bc4SBrooks Davis /// Custom implementation of a node type for testing purposes.
62*b0d29bc4SBrooks Davis class custom_node : public config::typed_leaf_node< custom_type > {
63*b0d29bc4SBrooks Davis public:
64*b0d29bc4SBrooks Davis     /// Copies the node.
65*b0d29bc4SBrooks Davis     ///
66*b0d29bc4SBrooks Davis     /// \return A dynamically-allocated node.
67*b0d29bc4SBrooks Davis     virtual base_node*
68*b0d29bc4SBrooks Davis     deep_copy(void) const
69*b0d29bc4SBrooks Davis     {
70*b0d29bc4SBrooks Davis         std::auto_ptr< custom_node > new_node(new custom_node());
71*b0d29bc4SBrooks Davis         new_node->_value = _value;
72*b0d29bc4SBrooks Davis         return new_node.release();
73*b0d29bc4SBrooks Davis     }
74*b0d29bc4SBrooks Davis 
75*b0d29bc4SBrooks Davis     /// Pushes the node's value onto the Lua stack.
76*b0d29bc4SBrooks Davis     ///
77*b0d29bc4SBrooks Davis     /// \param state The Lua state onto which to push the value.
78*b0d29bc4SBrooks Davis     void
79*b0d29bc4SBrooks Davis     push_lua(lutok::state& state) const
80*b0d29bc4SBrooks Davis     {
81*b0d29bc4SBrooks Davis         state.push_integer(value().value * 5);
82*b0d29bc4SBrooks Davis     }
83*b0d29bc4SBrooks Davis 
84*b0d29bc4SBrooks Davis     /// Sets the value of the node from an entry in the Lua stack.
85*b0d29bc4SBrooks Davis     ///
86*b0d29bc4SBrooks Davis     /// \param state The Lua state from which to get the value.
87*b0d29bc4SBrooks Davis     /// \param value_index The stack index in which the value resides.
88*b0d29bc4SBrooks Davis     void
89*b0d29bc4SBrooks Davis     set_lua(lutok::state& state, const int value_index)
90*b0d29bc4SBrooks Davis     {
91*b0d29bc4SBrooks Davis         ATF_REQUIRE(state.is_number(value_index));
92*b0d29bc4SBrooks Davis         set(custom_type(state.to_integer(value_index) * 2));
93*b0d29bc4SBrooks Davis     }
94*b0d29bc4SBrooks Davis 
95*b0d29bc4SBrooks Davis     /// Sets the value of the node from a raw string representation.
96*b0d29bc4SBrooks Davis     ///
97*b0d29bc4SBrooks Davis     /// \post The test case is marked as failed, as this function is not
98*b0d29bc4SBrooks Davis     /// supposed to be invoked by the lua_module code.
99*b0d29bc4SBrooks Davis     void
100*b0d29bc4SBrooks Davis     set_string(const std::string& /* raw_value */)
101*b0d29bc4SBrooks Davis     {
102*b0d29bc4SBrooks Davis         ATF_FAIL("Should not be used");
103*b0d29bc4SBrooks Davis     }
104*b0d29bc4SBrooks Davis 
105*b0d29bc4SBrooks Davis     /// Converts the contents of the node to a string.
106*b0d29bc4SBrooks Davis     ///
107*b0d29bc4SBrooks Davis     /// \post The test case is marked as failed, as this function is not
108*b0d29bc4SBrooks Davis     /// supposed to be invoked by the lua_module code.
109*b0d29bc4SBrooks Davis     ///
110*b0d29bc4SBrooks Davis     /// \return Nothing.
111*b0d29bc4SBrooks Davis     std::string
112*b0d29bc4SBrooks Davis     to_string(void) const
113*b0d29bc4SBrooks Davis     {
114*b0d29bc4SBrooks Davis         ATF_FAIL("Should not be used");
115*b0d29bc4SBrooks Davis     }
116*b0d29bc4SBrooks Davis };
117*b0d29bc4SBrooks Davis 
118*b0d29bc4SBrooks Davis 
119*b0d29bc4SBrooks Davis }  // anonymous namespace
120*b0d29bc4SBrooks Davis 
121*b0d29bc4SBrooks Davis 
122*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(top__valid_types);
123*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(top__valid_types)
124*b0d29bc4SBrooks Davis {
125*b0d29bc4SBrooks Davis     config::tree tree;
126*b0d29bc4SBrooks Davis     tree.define< config::bool_node >("top_boolean");
127*b0d29bc4SBrooks Davis     tree.define< config::int_node >("top_integer");
128*b0d29bc4SBrooks Davis     tree.define< config::string_node >("top_string");
129*b0d29bc4SBrooks Davis 
130*b0d29bc4SBrooks Davis     {
131*b0d29bc4SBrooks Davis         lutok::state state;
132*b0d29bc4SBrooks Davis         config::redirect(state, tree);
133*b0d29bc4SBrooks Davis         lutok::do_string(state,
134*b0d29bc4SBrooks Davis                          "top_boolean = true\n"
135*b0d29bc4SBrooks Davis                          "top_integer = 12345\n"
136*b0d29bc4SBrooks Davis                          "top_string = 'a foo'\n",
137*b0d29bc4SBrooks Davis                          0, 0, 0);
138*b0d29bc4SBrooks Davis     }
139*b0d29bc4SBrooks Davis 
140*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(true, tree.lookup< config::bool_node >("top_boolean"));
141*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(12345, tree.lookup< config::int_node >("top_integer"));
142*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("a foo", tree.lookup< config::string_node >("top_string"));
143*b0d29bc4SBrooks Davis }
144*b0d29bc4SBrooks Davis 
145*b0d29bc4SBrooks Davis 
146*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(top__invalid_types);
147*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(top__invalid_types)
148*b0d29bc4SBrooks Davis {
149*b0d29bc4SBrooks Davis     config::tree tree;
150*b0d29bc4SBrooks Davis     tree.define< config::bool_node >("top_boolean");
151*b0d29bc4SBrooks Davis     tree.define< config::int_node >("top_integer");
152*b0d29bc4SBrooks Davis 
153*b0d29bc4SBrooks Davis     {
154*b0d29bc4SBrooks Davis         lutok::state state;
155*b0d29bc4SBrooks Davis         config::redirect(state, tree);
156*b0d29bc4SBrooks Davis         ATF_REQUIRE_THROW_RE(
157*b0d29bc4SBrooks Davis             lutok::error,
158*b0d29bc4SBrooks Davis             "Invalid value for property 'top_boolean': Not a boolean",
159*b0d29bc4SBrooks Davis             lutok::do_string(state,
160*b0d29bc4SBrooks Davis                              "top_boolean = true\n"
161*b0d29bc4SBrooks Davis                              "top_integer = 8\n"
162*b0d29bc4SBrooks Davis                              "top_boolean = 'foo'\n",
163*b0d29bc4SBrooks Davis                              0, 0, 0));
164*b0d29bc4SBrooks Davis     }
165*b0d29bc4SBrooks Davis 
166*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(true, tree.lookup< config::bool_node >("top_boolean"));
167*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(8, tree.lookup< config::int_node >("top_integer"));
168*b0d29bc4SBrooks Davis }
169*b0d29bc4SBrooks Davis 
170*b0d29bc4SBrooks Davis 
171*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(top__reuse);
172*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(top__reuse)
173*b0d29bc4SBrooks Davis {
174*b0d29bc4SBrooks Davis     config::tree tree;
175*b0d29bc4SBrooks Davis     tree.define< config::int_node >("first");
176*b0d29bc4SBrooks Davis     tree.define< config::int_node >("second");
177*b0d29bc4SBrooks Davis 
178*b0d29bc4SBrooks Davis     {
179*b0d29bc4SBrooks Davis         lutok::state state;
180*b0d29bc4SBrooks Davis         config::redirect(state, tree);
181*b0d29bc4SBrooks Davis         lutok::do_string(state, "first = 100; second = first * 2", 0, 0, 0);
182*b0d29bc4SBrooks Davis     }
183*b0d29bc4SBrooks Davis 
184*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(100, tree.lookup< config::int_node >("first"));
185*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(200, tree.lookup< config::int_node >("second"));
186*b0d29bc4SBrooks Davis }
187*b0d29bc4SBrooks Davis 
188*b0d29bc4SBrooks Davis 
189*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(top__reset);
190*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(top__reset)
191*b0d29bc4SBrooks Davis {
192*b0d29bc4SBrooks Davis     config::tree tree;
193*b0d29bc4SBrooks Davis     tree.define< config::int_node >("first");
194*b0d29bc4SBrooks Davis 
195*b0d29bc4SBrooks Davis     {
196*b0d29bc4SBrooks Davis         lutok::state state;
197*b0d29bc4SBrooks Davis         config::redirect(state, tree);
198*b0d29bc4SBrooks Davis         lutok::do_string(state, "first = 100; first = 200", 0, 0, 0);
199*b0d29bc4SBrooks Davis     }
200*b0d29bc4SBrooks Davis 
201*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(200, tree.lookup< config::int_node >("first"));
202*b0d29bc4SBrooks Davis }
203*b0d29bc4SBrooks Davis 
204*b0d29bc4SBrooks Davis 
205*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(top__already_set_on_entry);
206*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(top__already_set_on_entry)
207*b0d29bc4SBrooks Davis {
208*b0d29bc4SBrooks Davis     config::tree tree;
209*b0d29bc4SBrooks Davis     tree.define< config::int_node >("first");
210*b0d29bc4SBrooks Davis     tree.set< config::int_node >("first", 100);
211*b0d29bc4SBrooks Davis 
212*b0d29bc4SBrooks Davis     {
213*b0d29bc4SBrooks Davis         lutok::state state;
214*b0d29bc4SBrooks Davis         config::redirect(state, tree);
215*b0d29bc4SBrooks Davis         lutok::do_string(state, "first = first * 15", 0, 0, 0);
216*b0d29bc4SBrooks Davis     }
217*b0d29bc4SBrooks Davis 
218*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1500, tree.lookup< config::int_node >("first"));
219*b0d29bc4SBrooks Davis }
220*b0d29bc4SBrooks Davis 
221*b0d29bc4SBrooks Davis 
222*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(subtree__valid_types);
223*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(subtree__valid_types)
224*b0d29bc4SBrooks Davis {
225*b0d29bc4SBrooks Davis     config::tree tree;
226*b0d29bc4SBrooks Davis     tree.define< config::bool_node >("root.boolean");
227*b0d29bc4SBrooks Davis     tree.define< config::int_node >("root.a.integer");
228*b0d29bc4SBrooks Davis     tree.define< config::string_node >("root.string");
229*b0d29bc4SBrooks Davis 
230*b0d29bc4SBrooks Davis     {
231*b0d29bc4SBrooks Davis         lutok::state state;
232*b0d29bc4SBrooks Davis         config::redirect(state, tree);
233*b0d29bc4SBrooks Davis         lutok::do_string(state,
234*b0d29bc4SBrooks Davis                          "root.boolean = true\n"
235*b0d29bc4SBrooks Davis                          "root.a.integer = 12345\n"
236*b0d29bc4SBrooks Davis                          "root.string = 'a foo'\n",
237*b0d29bc4SBrooks Davis                          0, 0, 0);
238*b0d29bc4SBrooks Davis     }
239*b0d29bc4SBrooks Davis 
240*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(true, tree.lookup< config::bool_node >("root.boolean"));
241*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(12345, tree.lookup< config::int_node >("root.a.integer"));
242*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("a foo", tree.lookup< config::string_node >("root.string"));
243*b0d29bc4SBrooks Davis }
244*b0d29bc4SBrooks Davis 
245*b0d29bc4SBrooks Davis 
246*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(subtree__reuse);
247*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(subtree__reuse)
248*b0d29bc4SBrooks Davis {
249*b0d29bc4SBrooks Davis     config::tree tree;
250*b0d29bc4SBrooks Davis     tree.define< config::int_node >("a.first");
251*b0d29bc4SBrooks Davis     tree.define< config::int_node >("a.second");
252*b0d29bc4SBrooks Davis 
253*b0d29bc4SBrooks Davis     {
254*b0d29bc4SBrooks Davis         lutok::state state;
255*b0d29bc4SBrooks Davis         config::redirect(state, tree);
256*b0d29bc4SBrooks Davis         lutok::do_string(state, "a.first = 100; a.second = a.first * 2",
257*b0d29bc4SBrooks Davis                          0, 0, 0);
258*b0d29bc4SBrooks Davis     }
259*b0d29bc4SBrooks Davis 
260*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(100, tree.lookup< config::int_node >("a.first"));
261*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(200, tree.lookup< config::int_node >("a.second"));
262*b0d29bc4SBrooks Davis }
263*b0d29bc4SBrooks Davis 
264*b0d29bc4SBrooks Davis 
265*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(subtree__reset);
266*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(subtree__reset)
267*b0d29bc4SBrooks Davis {
268*b0d29bc4SBrooks Davis     config::tree tree;
269*b0d29bc4SBrooks Davis     tree.define< config::int_node >("a.first");
270*b0d29bc4SBrooks Davis 
271*b0d29bc4SBrooks Davis     {
272*b0d29bc4SBrooks Davis         lutok::state state;
273*b0d29bc4SBrooks Davis         config::redirect(state, tree);
274*b0d29bc4SBrooks Davis         lutok::do_string(state, "a.first = 100; a.first = 200", 0, 0, 0);
275*b0d29bc4SBrooks Davis     }
276*b0d29bc4SBrooks Davis 
277*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(200, tree.lookup< config::int_node >("a.first"));
278*b0d29bc4SBrooks Davis }
279*b0d29bc4SBrooks Davis 
280*b0d29bc4SBrooks Davis 
281*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(subtree__already_set_on_entry);
282*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(subtree__already_set_on_entry)
283*b0d29bc4SBrooks Davis {
284*b0d29bc4SBrooks Davis     config::tree tree;
285*b0d29bc4SBrooks Davis     tree.define< config::int_node >("a.first");
286*b0d29bc4SBrooks Davis     tree.set< config::int_node >("a.first", 100);
287*b0d29bc4SBrooks Davis 
288*b0d29bc4SBrooks Davis     {
289*b0d29bc4SBrooks Davis         lutok::state state;
290*b0d29bc4SBrooks Davis         config::redirect(state, tree);
291*b0d29bc4SBrooks Davis         lutok::do_string(state, "a.first = a.first * 15", 0, 0, 0);
292*b0d29bc4SBrooks Davis     }
293*b0d29bc4SBrooks Davis 
294*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1500, tree.lookup< config::int_node >("a.first"));
295*b0d29bc4SBrooks Davis }
296*b0d29bc4SBrooks Davis 
297*b0d29bc4SBrooks Davis 
298*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(subtree__override_inner);
299*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(subtree__override_inner)
300*b0d29bc4SBrooks Davis {
301*b0d29bc4SBrooks Davis     config::tree tree;
302*b0d29bc4SBrooks Davis     tree.define_dynamic("root");
303*b0d29bc4SBrooks Davis 
304*b0d29bc4SBrooks Davis     {
305*b0d29bc4SBrooks Davis         lutok::state state;
306*b0d29bc4SBrooks Davis         config::redirect(state, tree);
307*b0d29bc4SBrooks Davis         lutok::do_string(state, "root.test = 'a'", 0, 0, 0);
308*b0d29bc4SBrooks Davis         ATF_REQUIRE_THROW_RE(lutok::error, "Invalid value for property 'root'",
309*b0d29bc4SBrooks Davis                              lutok::do_string(state, "root = 'b'", 0, 0, 0));
310*b0d29bc4SBrooks Davis         // Ensure that the previous assignment to 'root' did not cause any
311*b0d29bc4SBrooks Davis         // inconsistencies in the environment that would prevent a new
312*b0d29bc4SBrooks Davis         // assignment from working.
313*b0d29bc4SBrooks Davis         lutok::do_string(state, "root.test2 = 'c'", 0, 0, 0);
314*b0d29bc4SBrooks Davis     }
315*b0d29bc4SBrooks Davis 
316*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("a", tree.lookup< config::string_node >("root.test"));
317*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("c", tree.lookup< config::string_node >("root.test2"));
318*b0d29bc4SBrooks Davis }
319*b0d29bc4SBrooks Davis 
320*b0d29bc4SBrooks Davis 
321*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(dynamic_subtree__strings);
322*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(dynamic_subtree__strings)
323*b0d29bc4SBrooks Davis {
324*b0d29bc4SBrooks Davis     config::tree tree;
325*b0d29bc4SBrooks Davis     tree.define_dynamic("root");
326*b0d29bc4SBrooks Davis 
327*b0d29bc4SBrooks Davis     lutok::state state;
328*b0d29bc4SBrooks Davis     config::redirect(state, tree);
329*b0d29bc4SBrooks Davis     lutok::do_string(state,
330*b0d29bc4SBrooks Davis                      "root.key1 = 1234\n"
331*b0d29bc4SBrooks Davis                      "root.a.b.key2 = 'foo bar'\n",
332*b0d29bc4SBrooks Davis                      0, 0, 0);
333*b0d29bc4SBrooks Davis 
334*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("1234", tree.lookup< config::string_node >("root.key1"));
335*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("foo bar",
336*b0d29bc4SBrooks Davis                    tree.lookup< config::string_node >("root.a.b.key2"));
337*b0d29bc4SBrooks Davis }
338*b0d29bc4SBrooks Davis 
339*b0d29bc4SBrooks Davis 
340*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(dynamic_subtree__invalid_types);
341*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(dynamic_subtree__invalid_types)
342*b0d29bc4SBrooks Davis {
343*b0d29bc4SBrooks Davis     config::tree tree;
344*b0d29bc4SBrooks Davis     tree.define_dynamic("root");
345*b0d29bc4SBrooks Davis 
346*b0d29bc4SBrooks Davis     lutok::state state;
347*b0d29bc4SBrooks Davis     config::redirect(state, tree);
348*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(lutok::error,
349*b0d29bc4SBrooks Davis                          "Invalid value for property 'root.boolean': "
350*b0d29bc4SBrooks Davis                          "Not a string",
351*b0d29bc4SBrooks Davis                          lutok::do_string(state, "root.boolean = true",
352*b0d29bc4SBrooks Davis                                           0, 0, 0));
353*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(lutok::error,
354*b0d29bc4SBrooks Davis                          "Invalid value for property 'root.table': "
355*b0d29bc4SBrooks Davis                          "Not a string",
356*b0d29bc4SBrooks Davis                          lutok::do_string(state, "root.table = {}",
357*b0d29bc4SBrooks Davis                                           0, 0, 0));
358*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("root.boolean"));
359*b0d29bc4SBrooks Davis     ATF_REQUIRE(!tree.is_set("root.table"));
360*b0d29bc4SBrooks Davis }
361*b0d29bc4SBrooks Davis 
362*b0d29bc4SBrooks Davis 
363*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(locals);
364*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(locals)
365*b0d29bc4SBrooks Davis {
366*b0d29bc4SBrooks Davis     config::tree tree;
367*b0d29bc4SBrooks Davis     tree.define< config::int_node >("the_key");
368*b0d29bc4SBrooks Davis 
369*b0d29bc4SBrooks Davis     {
370*b0d29bc4SBrooks Davis         lutok::state state;
371*b0d29bc4SBrooks Davis         config::redirect(state, tree);
372*b0d29bc4SBrooks Davis         lutok::do_string(state,
373*b0d29bc4SBrooks Davis                          "local function generate()\n"
374*b0d29bc4SBrooks Davis                          "    return 15\n"
375*b0d29bc4SBrooks Davis                          "end\n"
376*b0d29bc4SBrooks Davis                          "local test_var = 20\n"
377*b0d29bc4SBrooks Davis                          "the_key = generate() + test_var\n",
378*b0d29bc4SBrooks Davis                          0, 0, 0);
379*b0d29bc4SBrooks Davis     }
380*b0d29bc4SBrooks Davis 
381*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(35, tree.lookup< config::int_node >("the_key"));
382*b0d29bc4SBrooks Davis }
383*b0d29bc4SBrooks Davis 
384*b0d29bc4SBrooks Davis 
385*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(custom_node);
386*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(custom_node)
387*b0d29bc4SBrooks Davis {
388*b0d29bc4SBrooks Davis     config::tree tree;
389*b0d29bc4SBrooks Davis     tree.define< custom_node >("key1");
390*b0d29bc4SBrooks Davis     tree.define< custom_node >("key2");
391*b0d29bc4SBrooks Davis     tree.set< custom_node >("key2", custom_type(10));
392*b0d29bc4SBrooks Davis 
393*b0d29bc4SBrooks Davis     {
394*b0d29bc4SBrooks Davis         lutok::state state;
395*b0d29bc4SBrooks Davis         config::redirect(state, tree);
396*b0d29bc4SBrooks Davis         lutok::do_string(state, "key1 = 512\n", 0, 0, 0);
397*b0d29bc4SBrooks Davis         lutok::do_string(state, "key2 = key2 * 2\n", 0, 0, 0);
398*b0d29bc4SBrooks Davis     }
399*b0d29bc4SBrooks Davis 
400*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1024, tree.lookup< custom_node >("key1").value);
401*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(200, tree.lookup< custom_node >("key2").value);
402*b0d29bc4SBrooks Davis }
403*b0d29bc4SBrooks Davis 
404*b0d29bc4SBrooks Davis 
405*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(invalid_key);
406*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(invalid_key)
407*b0d29bc4SBrooks Davis {
408*b0d29bc4SBrooks Davis     config::tree tree;
409*b0d29bc4SBrooks Davis 
410*b0d29bc4SBrooks Davis     lutok::state state;
411*b0d29bc4SBrooks Davis     config::redirect(state, tree);
412*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(lutok::error, "Empty component in key 'root.'",
413*b0d29bc4SBrooks Davis                          lutok::do_string(state, "root['']['a'] = 12345\n",
414*b0d29bc4SBrooks Davis                                           0, 0, 0));
415*b0d29bc4SBrooks Davis }
416*b0d29bc4SBrooks Davis 
417*b0d29bc4SBrooks Davis 
418*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(unknown_key);
419*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(unknown_key)
420*b0d29bc4SBrooks Davis {
421*b0d29bc4SBrooks Davis     config::tree tree;
422*b0d29bc4SBrooks Davis     tree.define< config::bool_node >("static.bool");
423*b0d29bc4SBrooks Davis 
424*b0d29bc4SBrooks Davis     lutok::state state;
425*b0d29bc4SBrooks Davis     config::redirect(state, tree);
426*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(lutok::error,
427*b0d29bc4SBrooks Davis                          "Unknown configuration property 'static.int'",
428*b0d29bc4SBrooks Davis                          lutok::do_string(state,
429*b0d29bc4SBrooks Davis                                           "static.int = 12345\n",
430*b0d29bc4SBrooks Davis                                           0, 0, 0));
431*b0d29bc4SBrooks Davis }
432*b0d29bc4SBrooks Davis 
433*b0d29bc4SBrooks Davis 
434*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(value_error);
435*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(value_error)
436*b0d29bc4SBrooks Davis {
437*b0d29bc4SBrooks Davis     config::tree tree;
438*b0d29bc4SBrooks Davis     tree.define< config::bool_node >("a.b");
439*b0d29bc4SBrooks Davis 
440*b0d29bc4SBrooks Davis     lutok::state state;
441*b0d29bc4SBrooks Davis     config::redirect(state, tree);
442*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(lutok::error,
443*b0d29bc4SBrooks Davis                          "Invalid value for property 'a.b': Not a boolean",
444*b0d29bc4SBrooks Davis                          lutok::do_string(state, "a.b = 12345\n", 0, 0, 0));
445*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(lutok::error,
446*b0d29bc4SBrooks Davis                          "Invalid value for property 'a': ",
447*b0d29bc4SBrooks Davis                          lutok::do_string(state, "a = 1\n", 0, 0, 0));
448*b0d29bc4SBrooks Davis }
449*b0d29bc4SBrooks Davis 
450*b0d29bc4SBrooks Davis 
451*b0d29bc4SBrooks Davis ATF_INIT_TEST_CASES(tcs)
452*b0d29bc4SBrooks Davis {
453*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, top__valid_types);
454*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, top__invalid_types);
455*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, top__reuse);
456*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, top__reset);
457*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, top__already_set_on_entry);
458*b0d29bc4SBrooks Davis 
459*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, subtree__valid_types);
460*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, subtree__reuse);
461*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, subtree__reset);
462*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, subtree__already_set_on_entry);
463*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, subtree__override_inner);
464*b0d29bc4SBrooks Davis 
465*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, dynamic_subtree__strings);
466*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, dynamic_subtree__invalid_types);
467*b0d29bc4SBrooks Davis 
468*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, locals);
469*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, custom_node);
470*b0d29bc4SBrooks Davis 
471*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, invalid_key);
472*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, unknown_key);
473*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, value_error);
474*b0d29bc4SBrooks Davis }
475