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