1// Copyright 2012 Google Inc. 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: 7// 8// * Redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer. 10// * Redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution. 13// * Neither the name of Google Inc. nor the names of its contributors 14// may be used to endorse or promote products derived from this software 15// without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29#include "utils/config/nodes.ipp" 30 31#include <atf-c++.hpp> 32 33#include <lutok/state.ipp> 34 35#include "utils/config/exceptions.hpp" 36#include "utils/config/keys.hpp" 37#include "utils/defs.hpp" 38 39namespace config = utils::config; 40 41 42namespace { 43 44 45/// Typed leaf node that specializes the validate() method. 46class validation_node : public config::int_node { 47 /// Checks a given value for validity against a fake value. 48 /// 49 /// \param new_value The value to validate. 50 /// 51 /// \throw value_error If the value is not valid. 52 void 53 validate(const value_type& new_value) const 54 { 55 if (new_value == 12345) 56 throw config::value_error("Custom validate method"); 57 } 58}; 59 60 61/// Set node that specializes the validate() method. 62class set_validation_node : public config::strings_set_node { 63 /// Checks a given value for validity against a fake value. 64 /// 65 /// \param new_value The value to validate. 66 /// 67 /// \throw value_error If the value is not valid. 68 void 69 validate(const value_type& new_value) const 70 { 71 for (value_type::const_iterator iter = new_value.begin(); 72 iter != new_value.end(); ++iter) 73 if (*iter == "throw") 74 throw config::value_error("Custom validate method"); 75 } 76}; 77 78 79} // anonymous namespace 80 81 82ATF_TEST_CASE_WITHOUT_HEAD(bool_node__deep_copy); 83ATF_TEST_CASE_BODY(bool_node__deep_copy) 84{ 85 config::bool_node node; 86 node.set(true); 87 config::detail::base_node* raw_copy = node.deep_copy(); 88 config::bool_node* copy = static_cast< config::bool_node* >(raw_copy); 89 ATF_REQUIRE(copy->value()); 90 copy->set(false); 91 ATF_REQUIRE(node.value()); 92 ATF_REQUIRE(!copy->value()); 93 delete copy; 94} 95 96 97ATF_TEST_CASE_WITHOUT_HEAD(bool_node__is_set_and_set); 98ATF_TEST_CASE_BODY(bool_node__is_set_and_set) 99{ 100 config::bool_node node; 101 ATF_REQUIRE(!node.is_set()); 102 node.set(false); 103 ATF_REQUIRE( node.is_set()); 104} 105 106 107ATF_TEST_CASE_WITHOUT_HEAD(bool_node__value_and_set); 108ATF_TEST_CASE_BODY(bool_node__value_and_set) 109{ 110 config::bool_node node; 111 node.set(false); 112 ATF_REQUIRE(!node.value()); 113 node.set(true); 114 ATF_REQUIRE( node.value()); 115} 116 117 118ATF_TEST_CASE_WITHOUT_HEAD(bool_node__push_lua); 119ATF_TEST_CASE_BODY(bool_node__push_lua) 120{ 121 lutok::state state; 122 123 config::bool_node node; 124 node.set(true); 125 node.push_lua(state); 126 ATF_REQUIRE(state.is_boolean(-1)); 127 ATF_REQUIRE(state.to_boolean(-1)); 128 state.pop(1); 129} 130 131 132ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_lua__ok); 133ATF_TEST_CASE_BODY(bool_node__set_lua__ok) 134{ 135 lutok::state state; 136 137 config::bool_node node; 138 state.push_boolean(false); 139 node.set_lua(state, -1); 140 state.pop(1); 141 ATF_REQUIRE(!node.value()); 142} 143 144 145ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_lua__invalid_value); 146ATF_TEST_CASE_BODY(bool_node__set_lua__invalid_value) 147{ 148 lutok::state state; 149 150 config::bool_node node; 151 state.push_string("foo bar"); 152 ATF_REQUIRE_THROW(config::value_error, node.set_lua(state, -1)); 153 state.pop(1); 154 ATF_REQUIRE(!node.is_set()); 155} 156 157 158ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_string__ok); 159ATF_TEST_CASE_BODY(bool_node__set_string__ok) 160{ 161 config::bool_node node; 162 node.set_string("false"); 163 ATF_REQUIRE(!node.value()); 164 node.set_string("true"); 165 ATF_REQUIRE( node.value()); 166} 167 168 169ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_string__invalid_value); 170ATF_TEST_CASE_BODY(bool_node__set_string__invalid_value) 171{ 172 config::bool_node node; 173 ATF_REQUIRE_THROW(config::value_error, node.set_string("12345")); 174 ATF_REQUIRE(!node.is_set()); 175} 176 177 178ATF_TEST_CASE_WITHOUT_HEAD(bool_node__to_string); 179ATF_TEST_CASE_BODY(bool_node__to_string) 180{ 181 config::bool_node node; 182 node.set(false); 183 ATF_REQUIRE_EQ("false", node.to_string()); 184 node.set(true); 185 ATF_REQUIRE_EQ("true", node.to_string()); 186} 187 188 189ATF_TEST_CASE_WITHOUT_HEAD(int_node__deep_copy); 190ATF_TEST_CASE_BODY(int_node__deep_copy) 191{ 192 config::int_node node; 193 node.set(5); 194 config::detail::base_node* raw_copy = node.deep_copy(); 195 config::int_node* copy = static_cast< config::int_node* >(raw_copy); 196 ATF_REQUIRE_EQ(5, copy->value()); 197 copy->set(10); 198 ATF_REQUIRE_EQ(5, node.value()); 199 ATF_REQUIRE_EQ(10, copy->value()); 200 delete copy; 201} 202 203 204ATF_TEST_CASE_WITHOUT_HEAD(int_node__is_set_and_set); 205ATF_TEST_CASE_BODY(int_node__is_set_and_set) 206{ 207 config::int_node node; 208 ATF_REQUIRE(!node.is_set()); 209 node.set(20); 210 ATF_REQUIRE( node.is_set()); 211} 212 213 214ATF_TEST_CASE_WITHOUT_HEAD(int_node__value_and_set); 215ATF_TEST_CASE_BODY(int_node__value_and_set) 216{ 217 config::int_node node; 218 node.set(20); 219 ATF_REQUIRE_EQ(20, node.value()); 220 node.set(0); 221 ATF_REQUIRE_EQ(0, node.value()); 222} 223 224 225ATF_TEST_CASE_WITHOUT_HEAD(int_node__push_lua); 226ATF_TEST_CASE_BODY(int_node__push_lua) 227{ 228 lutok::state state; 229 230 config::int_node node; 231 node.set(754); 232 node.push_lua(state); 233 ATF_REQUIRE(state.is_number(-1)); 234 ATF_REQUIRE_EQ(754, state.to_integer(-1)); 235 state.pop(1); 236} 237 238 239ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_lua__ok); 240ATF_TEST_CASE_BODY(int_node__set_lua__ok) 241{ 242 lutok::state state; 243 244 config::int_node node; 245 state.push_integer(123); 246 state.push_string("456"); 247 node.set_lua(state, -2); 248 ATF_REQUIRE_EQ(123, node.value()); 249 node.set_lua(state, -1); 250 ATF_REQUIRE_EQ(456, node.value()); 251 state.pop(2); 252} 253 254 255ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_lua__invalid_value); 256ATF_TEST_CASE_BODY(int_node__set_lua__invalid_value) 257{ 258 lutok::state state; 259 260 config::int_node node; 261 state.push_boolean(true); 262 ATF_REQUIRE_THROW(config::value_error, node.set_lua(state, -1)); 263 state.pop(1); 264 ATF_REQUIRE(!node.is_set()); 265} 266 267 268ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_string__ok); 269ATF_TEST_CASE_BODY(int_node__set_string__ok) 270{ 271 config::int_node node; 272 node.set_string("178"); 273 ATF_REQUIRE_EQ(178, node.value()); 274 node.set_string("-123"); 275 ATF_REQUIRE_EQ(-123, node.value()); 276} 277 278 279ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_string__invalid_value); 280ATF_TEST_CASE_BODY(int_node__set_string__invalid_value) 281{ 282 config::int_node node; 283 ATF_REQUIRE_THROW(config::value_error, node.set_string(" 23")); 284 ATF_REQUIRE(!node.is_set()); 285} 286 287 288ATF_TEST_CASE_WITHOUT_HEAD(int_node__to_string); 289ATF_TEST_CASE_BODY(int_node__to_string) 290{ 291 config::int_node node; 292 node.set(89); 293 ATF_REQUIRE_EQ("89", node.to_string()); 294 node.set(-57); 295 ATF_REQUIRE_EQ("-57", node.to_string()); 296} 297 298 299ATF_TEST_CASE_WITHOUT_HEAD(string_node__deep_copy); 300ATF_TEST_CASE_BODY(string_node__deep_copy) 301{ 302 config::string_node node; 303 node.set("first"); 304 config::detail::base_node* raw_copy = node.deep_copy(); 305 config::string_node* copy = static_cast< config::string_node* >(raw_copy); 306 ATF_REQUIRE_EQ("first", copy->value()); 307 copy->set("second"); 308 ATF_REQUIRE_EQ("first", node.value()); 309 ATF_REQUIRE_EQ("second", copy->value()); 310 delete copy; 311} 312 313 314ATF_TEST_CASE_WITHOUT_HEAD(string_node__is_set_and_set); 315ATF_TEST_CASE_BODY(string_node__is_set_and_set) 316{ 317 config::string_node node; 318 ATF_REQUIRE(!node.is_set()); 319 node.set("foo"); 320 ATF_REQUIRE( node.is_set()); 321} 322 323 324ATF_TEST_CASE_WITHOUT_HEAD(string_node__value_and_set); 325ATF_TEST_CASE_BODY(string_node__value_and_set) 326{ 327 config::string_node node; 328 node.set("foo"); 329 ATF_REQUIRE_EQ("foo", node.value()); 330 node.set(""); 331 ATF_REQUIRE_EQ("", node.value()); 332} 333 334 335ATF_TEST_CASE_WITHOUT_HEAD(string_node__push_lua); 336ATF_TEST_CASE_BODY(string_node__push_lua) 337{ 338 lutok::state state; 339 340 config::string_node node; 341 node.set("some message"); 342 node.push_lua(state); 343 ATF_REQUIRE(state.is_string(-1)); 344 ATF_REQUIRE_EQ("some message", state.to_string(-1)); 345 state.pop(1); 346} 347 348 349ATF_TEST_CASE_WITHOUT_HEAD(string_node__set_lua__ok); 350ATF_TEST_CASE_BODY(string_node__set_lua__ok) 351{ 352 lutok::state state; 353 354 config::string_node node; 355 state.push_string("text 1"); 356 state.push_integer(231); 357 node.set_lua(state, -2); 358 ATF_REQUIRE_EQ("text 1", node.value()); 359 node.set_lua(state, -1); 360 ATF_REQUIRE_EQ("231", node.value()); 361 state.pop(2); 362} 363 364 365ATF_TEST_CASE_WITHOUT_HEAD(string_node__set_lua__invalid_value); 366ATF_TEST_CASE_BODY(string_node__set_lua__invalid_value) 367{ 368 lutok::state state; 369 370 config::bool_node node; 371 state.new_table(); 372 ATF_REQUIRE_THROW(config::value_error, node.set_lua(state, -1)); 373 state.pop(1); 374 ATF_REQUIRE(!node.is_set()); 375} 376 377 378ATF_TEST_CASE_WITHOUT_HEAD(string_node__set_string); 379ATF_TEST_CASE_BODY(string_node__set_string) 380{ 381 config::string_node node; 382 node.set_string("abcd efgh"); 383 ATF_REQUIRE_EQ("abcd efgh", node.value()); 384 node.set_string(" 1234 "); 385 ATF_REQUIRE_EQ(" 1234 ", node.value()); 386} 387 388 389ATF_TEST_CASE_WITHOUT_HEAD(string_node__to_string); 390ATF_TEST_CASE_BODY(string_node__to_string) 391{ 392 config::string_node node; 393 node.set(""); 394 ATF_REQUIRE_EQ("", node.to_string()); 395 node.set("aaa"); 396 ATF_REQUIRE_EQ("aaa", node.to_string()); 397} 398 399 400ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__deep_copy); 401ATF_TEST_CASE_BODY(strings_set_node__deep_copy) 402{ 403 std::set< std::string > value; 404 config::strings_set_node node; 405 value.insert("foo"); 406 node.set(value); 407 config::detail::base_node* raw_copy = node.deep_copy(); 408 config::strings_set_node* copy = 409 static_cast< config::strings_set_node* >(raw_copy); 410 value.insert("bar"); 411 ATF_REQUIRE_EQ(1, copy->value().size()); 412 copy->set(value); 413 ATF_REQUIRE_EQ(1, node.value().size()); 414 ATF_REQUIRE_EQ(2, copy->value().size()); 415 delete copy; 416} 417 418 419ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__is_set_and_set); 420ATF_TEST_CASE_BODY(strings_set_node__is_set_and_set) 421{ 422 std::set< std::string > value; 423 value.insert("foo"); 424 425 config::strings_set_node node; 426 ATF_REQUIRE(!node.is_set()); 427 node.set(value); 428 ATF_REQUIRE( node.is_set()); 429} 430 431 432ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__value_and_set); 433ATF_TEST_CASE_BODY(strings_set_node__value_and_set) 434{ 435 std::set< std::string > value; 436 value.insert("first"); 437 438 config::strings_set_node node; 439 node.set(value); 440 ATF_REQUIRE(value == node.value()); 441 value.clear(); 442 node.set(value); 443 value.insert("second"); 444 ATF_REQUIRE(node.value().empty()); 445} 446 447 448ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__set_string); 449ATF_TEST_CASE_BODY(strings_set_node__set_string) 450{ 451 config::strings_set_node node; 452 { 453 std::set< std::string > expected; 454 expected.insert("abcd"); 455 expected.insert("efgh"); 456 457 node.set_string("abcd efgh"); 458 ATF_REQUIRE(expected == node.value()); 459 } 460 { 461 std::set< std::string > expected; 462 expected.insert("1234"); 463 464 node.set_string(" 1234 "); 465 ATF_REQUIRE(expected == node.value()); 466 } 467} 468 469 470ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__to_string); 471ATF_TEST_CASE_BODY(strings_set_node__to_string) 472{ 473 std::set< std::string > value; 474 config::strings_set_node node; 475 value.insert("second"); 476 value.insert("first"); 477 node.set(value); 478 ATF_REQUIRE_EQ("first second", node.to_string()); 479} 480 481 482ATF_TEST_CASE_WITHOUT_HEAD(typed_leaf_node__validate_set); 483ATF_TEST_CASE_BODY(typed_leaf_node__validate_set) 484{ 485 validation_node node; 486 node.set(1234); 487 ATF_REQUIRE_THROW_RE(config::value_error, "Custom validate method", 488 node.set(12345)); 489} 490 491 492ATF_TEST_CASE_WITHOUT_HEAD(typed_leaf_node__validate_set_string); 493ATF_TEST_CASE_BODY(typed_leaf_node__validate_set_string) 494{ 495 validation_node node; 496 node.set_string("1234"); 497 ATF_REQUIRE_THROW_RE(config::value_error, "Custom validate method", 498 node.set_string("12345")); 499} 500 501 502ATF_TEST_CASE_WITHOUT_HEAD(base_set_node__validate_set); 503ATF_TEST_CASE_BODY(base_set_node__validate_set) 504{ 505 set_validation_node node; 506 set_validation_node::value_type values; 507 values.insert("foo"); 508 values.insert("bar"); 509 node.set(values); 510 values.insert("throw"); 511 values.insert("baz"); 512 ATF_REQUIRE_THROW_RE(config::value_error, "Custom validate method", 513 node.set(values)); 514} 515 516 517ATF_TEST_CASE_WITHOUT_HEAD(base_set_node__validate_set_string); 518ATF_TEST_CASE_BODY(base_set_node__validate_set_string) 519{ 520 set_validation_node node; 521 node.set_string("foo bar"); 522 ATF_REQUIRE_THROW_RE(config::value_error, "Custom validate method", 523 node.set_string("foo bar throw baz")); 524} 525 526 527ATF_INIT_TEST_CASES(tcs) 528{ 529 ATF_ADD_TEST_CASE(tcs, bool_node__deep_copy); 530 ATF_ADD_TEST_CASE(tcs, bool_node__is_set_and_set); 531 ATF_ADD_TEST_CASE(tcs, bool_node__value_and_set); 532 ATF_ADD_TEST_CASE(tcs, bool_node__push_lua); 533 ATF_ADD_TEST_CASE(tcs, bool_node__set_lua__ok); 534 ATF_ADD_TEST_CASE(tcs, bool_node__set_lua__invalid_value); 535 ATF_ADD_TEST_CASE(tcs, bool_node__set_string__ok); 536 ATF_ADD_TEST_CASE(tcs, bool_node__set_string__invalid_value); 537 ATF_ADD_TEST_CASE(tcs, bool_node__to_string); 538 539 ATF_ADD_TEST_CASE(tcs, int_node__deep_copy); 540 ATF_ADD_TEST_CASE(tcs, int_node__is_set_and_set); 541 ATF_ADD_TEST_CASE(tcs, int_node__value_and_set); 542 ATF_ADD_TEST_CASE(tcs, int_node__push_lua); 543 ATF_ADD_TEST_CASE(tcs, int_node__set_lua__ok); 544 ATF_ADD_TEST_CASE(tcs, int_node__set_lua__invalid_value); 545 ATF_ADD_TEST_CASE(tcs, int_node__set_string__ok); 546 ATF_ADD_TEST_CASE(tcs, int_node__set_string__invalid_value); 547 ATF_ADD_TEST_CASE(tcs, int_node__to_string); 548 549 ATF_ADD_TEST_CASE(tcs, string_node__deep_copy); 550 ATF_ADD_TEST_CASE(tcs, string_node__is_set_and_set); 551 ATF_ADD_TEST_CASE(tcs, string_node__value_and_set); 552 ATF_ADD_TEST_CASE(tcs, string_node__push_lua); 553 ATF_ADD_TEST_CASE(tcs, string_node__set_lua__ok); 554 ATF_ADD_TEST_CASE(tcs, string_node__set_lua__invalid_value); 555 ATF_ADD_TEST_CASE(tcs, string_node__set_string); 556 ATF_ADD_TEST_CASE(tcs, string_node__to_string); 557 558 ATF_ADD_TEST_CASE(tcs, strings_set_node__deep_copy); 559 ATF_ADD_TEST_CASE(tcs, strings_set_node__is_set_and_set); 560 ATF_ADD_TEST_CASE(tcs, strings_set_node__value_and_set); 561 ATF_ADD_TEST_CASE(tcs, strings_set_node__set_string); 562 ATF_ADD_TEST_CASE(tcs, strings_set_node__to_string); 563 564 ATF_ADD_TEST_CASE(tcs, typed_leaf_node__validate_set); 565 ATF_ADD_TEST_CASE(tcs, typed_leaf_node__validate_set_string); 566 ATF_ADD_TEST_CASE(tcs, base_set_node__validate_set); 567 ATF_ADD_TEST_CASE(tcs, base_set_node__validate_set_string); 568} 569