node.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /* node.cpp - node tests
  2. * Copyright (C) 2017-2018 caryoscelus
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <catch.hpp>
  18. #include <iostream>
  19. #include <boost/uuid/uuid_io.hpp>
  20. #include <core/node_info/node_info.h>
  21. #include <core/node_info/copy.h>
  22. #include <core/node/traverse.h>
  23. #include <core/node/list.h>
  24. #include <core/context.h>
  25. #include "new_node.h"
  26. #include "zero_context.h"
  27. using namespace rainynite;
  28. using namespace rainynite::core;
  29. using Real = double;
  30. string value_to_string(AbstractReference node) {
  31. if (node->get_type() == typeid(Real)) {
  32. auto t = static_pointer_cast<Value<Real>>(node);
  33. return std::to_string(t->mod());
  34. }
  35. return "";
  36. }
  37. unsigned count_nodes(AbstractReference root, TraverseDepth depth = TraverseDepth::Once) {
  38. unsigned result = 0;
  39. traverse_once<bool>(root, [&result](AbstractReference) -> optional<bool> {
  40. ++result;
  41. return {};
  42. }, depth);
  43. return result;
  44. }
  45. TEST_CASE("Traverse node tree", "[node]") {
  46. auto one = make_value<Real>(1.0);
  47. CHECK(count_nodes(one) == 1);
  48. auto add = make_shared<Add>();
  49. CHECK(count_nodes(add) == 3);
  50. add->set_property("a", one);
  51. CHECK(count_nodes(add) == 3);
  52. add->set_property("b", one);
  53. CHECK(count_nodes(add) == 2);
  54. CHECK(count_nodes(add, TraverseDepth::Deeper) == 3);
  55. }
  56. TEST_CASE("Traverse list node", "[node]") {
  57. auto list = make_node<ListValue<Real>>();
  58. auto one = make_value<Real>(1.0);
  59. list->push_back(one);
  60. CHECK(count_nodes(list) == 2);
  61. list->push_back(one);
  62. CHECK(count_nodes(list) == 2);
  63. CHECK(count_nodes(list, TraverseDepth::Deeper) == 3);
  64. }
  65. TEST_CASE("Shallow node copy", "[node]") {
  66. SECTION("Simple") {
  67. auto one = make_value<Real>(1.0);
  68. auto two = shallow_copy(*one);
  69. CHECK(one->get_id() != two->get_id());
  70. auto one_value = dynamic_cast<Value<Real>*>(one.get());
  71. auto two_value = dynamic_cast<Value<Real>*>(two.get());
  72. two_value->set(2.0);
  73. CHECK(one_value->mod() == 1.0);
  74. CHECK(two_value->mod() == 2.0);
  75. }
  76. SECTION("Complex") {
  77. auto one = make_value<Real>(1.0);
  78. auto add = make_node_with_name_as<AbstractNode>("Add/Real");
  79. add->set_property("a", one);
  80. add->set_property("b", one);
  81. auto add_again = shallow_copy_as<AbstractNode>(dynamic_cast<AbstractValue const&>(*add));
  82. add->set_property("a", shallow_copy(*one));
  83. add->get_property_as<double>("a")->set(2.0);
  84. CHECK(add->get_property_as<double>("a")->mod() == 2.0);
  85. CHECK(add->get_property_as<double>("b")->mod() == 1.0);
  86. CHECK(add_again->get_property_as<double>("a")->mod() == 1.0);
  87. CHECK(add_again->get_property_as<double>("b")->mod() == 1.0);
  88. }
  89. }
  90. TEST_CASE("Node children change notify", "[node]") {
  91. auto add = make_node_with_name_as<AbstractNode>("Add/Real");
  92. bool changed = false;
  93. dynamic_cast<AbstractValue*>(add.get())->subscribe([&changed](){
  94. changed = true;
  95. });
  96. auto one = make_value<double>(1.0);
  97. add->set_property("a", one);
  98. CHECK(changed);
  99. changed = false;
  100. one->set(2.0);
  101. CHECK(changed);
  102. changed = false;
  103. auto zero = add->get_property_as<double>("b");
  104. zero->set(1.0);
  105. CHECK(changed);
  106. }
  107. TEST_CASE("List node children change notify", "[node]") {
  108. auto one = make_value<double>(1.0);
  109. auto list = make_node<ListValue<double>>();
  110. bool changed = false;
  111. list->subscribe([&changed](){
  112. changed = true;
  113. });
  114. list->push_back(one);
  115. one->set(2.0);
  116. CHECK(changed);
  117. }
  118. TEST_CASE("Removing custom properties", "[node]") {
  119. auto add = make_node_with_name_as<AbstractNode>("Add/Real");
  120. auto add_links = dynamic_pointer_cast<AbstractListLinked>(add);
  121. CHECK(add_links->link_count() == 2);
  122. auto zero = make_value<double>(0.0);
  123. add->set_property("_custom_0", zero);
  124. CHECK(add_links->link_count() == 3);
  125. CHECK(add->get_name_id("_custom_0") == 2);
  126. CHECK(add->get_name_at(2) == "_custom_0");
  127. CHECK(add->get_link_map()["_custom_0"] == zero);
  128. add->set_property("_custom_1", make_value<double>(1.0));
  129. CHECK(add_links->link_count() == 4);
  130. CHECK(add->get_property_as<double>("_custom_0")->value(zero_context()) == 0);
  131. CHECK(add->get_property_as<double>("_custom_1")->value(zero_context()) == 1);
  132. add->remove_property("_custom_0");
  133. CHECK(add_links->link_count() == 3);
  134. CHECK(add->get_property_as<double>("_custom_1")->value(zero_context()) == 1);
  135. }