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 39 namespace config = utils::config; 40 41 42 namespace { 43 44 45 /// Typed leaf node that specializes the validate() method. 46 class 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. 62 class 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 82 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__deep_copy); 83 ATF_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 97 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__is_set_and_set); 98 ATF_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 107 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__value_and_set); 108 ATF_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 118 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__push_lua); 119 ATF_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 132 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_lua__ok); 133 ATF_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 145 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_lua__invalid_value); 146 ATF_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 158 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_string__ok); 159 ATF_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 169 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__set_string__invalid_value); 170 ATF_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 178 ATF_TEST_CASE_WITHOUT_HEAD(bool_node__to_string); 179 ATF_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 189 ATF_TEST_CASE_WITHOUT_HEAD(int_node__deep_copy); 190 ATF_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 204 ATF_TEST_CASE_WITHOUT_HEAD(int_node__is_set_and_set); 205 ATF_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 214 ATF_TEST_CASE_WITHOUT_HEAD(int_node__value_and_set); 215 ATF_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 225 ATF_TEST_CASE_WITHOUT_HEAD(int_node__push_lua); 226 ATF_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 239 ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_lua__ok); 240 ATF_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 255 ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_lua__invalid_value); 256 ATF_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 268 ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_string__ok); 269 ATF_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 279 ATF_TEST_CASE_WITHOUT_HEAD(int_node__set_string__invalid_value); 280 ATF_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 288 ATF_TEST_CASE_WITHOUT_HEAD(int_node__to_string); 289 ATF_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 299 ATF_TEST_CASE_WITHOUT_HEAD(string_node__deep_copy); 300 ATF_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 314 ATF_TEST_CASE_WITHOUT_HEAD(string_node__is_set_and_set); 315 ATF_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 324 ATF_TEST_CASE_WITHOUT_HEAD(string_node__value_and_set); 325 ATF_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 335 ATF_TEST_CASE_WITHOUT_HEAD(string_node__push_lua); 336 ATF_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 349 ATF_TEST_CASE_WITHOUT_HEAD(string_node__set_lua__ok); 350 ATF_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 365 ATF_TEST_CASE_WITHOUT_HEAD(string_node__set_lua__invalid_value); 366 ATF_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 378 ATF_TEST_CASE_WITHOUT_HEAD(string_node__set_string); 379 ATF_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 389 ATF_TEST_CASE_WITHOUT_HEAD(string_node__to_string); 390 ATF_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 400 ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__deep_copy); 401 ATF_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 419 ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__is_set_and_set); 420 ATF_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 432 ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__value_and_set); 433 ATF_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 448 ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__set_string); 449 ATF_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 470 ATF_TEST_CASE_WITHOUT_HEAD(strings_set_node__to_string); 471 ATF_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 482 ATF_TEST_CASE_WITHOUT_HEAD(typed_leaf_node__validate_set); 483 ATF_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 492 ATF_TEST_CASE_WITHOUT_HEAD(typed_leaf_node__validate_set_string); 493 ATF_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 502 ATF_TEST_CASE_WITHOUT_HEAD(base_set_node__validate_set); 503 ATF_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 517 ATF_TEST_CASE_WITHOUT_HEAD(base_set_node__validate_set_string); 518 ATF_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 527 ATF_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