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