示例#1
0
QuiddityCommand::ptr QuiddityCommand::make_command_from_tree(InfoTree::ptr tree) {
  QuiddityCommand::ptr command = std::make_shared<QuiddityCommand>();
  std::string command_str = tree->branch_get_value("command");
  command->set_id(QuiddityCommand::get_id_from_string(command_str.c_str()));
  command->time_ = tree->branch_get_value("calling time");
  {
    std::string args_str("arguments.");
    auto arguments = tree->get_child_keys(args_str);
    for (auto& it : arguments) {
      std::string arg = tree->branch_get_value(args_str + it);
      if (!arg.empty()) {
        command->add_arg(arg);
      } else {
        command->add_arg("null");
      }
    }
  }
  {
    std::string vect_str("vector argument.");
    auto arguments = tree->get_child_keys(vect_str);
    std::vector<std::string> string_vect_arg;
    for (auto& it : arguments) {
      std::string arg = tree->branch_get_value(vect_str + it);
      if (!arg.empty()) {
        string_vect_arg.push_back(arg);
      } else {
        string_vect_arg.push_back("null");
      }
    }
    command->set_vector_arg(string_vect_arg);
  }
  {
    std::string res_str("results.");
    auto results = tree->get_child_keys(res_str);
    std::vector<std::string> expected_result;
    for (auto& it : results) {
      std::string res = tree->branch_get_value(res_str + it);
      if (!res.empty()) expected_result.push_back(res);
    }
    command->expected_result_ = expected_result;
  }
  return command;
}
//---------------- test
int main() {
  using namespace switcher;

  auto string_compare = [](const std::string& first, const std::string& second) {
    return (0 == first.compare(second));
  };

  {  // node data as std::string
    InfoTree::ptr tree = InfoTree::make(std::string("truc"));
    assert(tree->is_leaf());
    std::string data = tree->get_value();
    assert(0 == data.compare("truc"));
  }
  {  // node data as const char * (converted to std::string)
    InfoTree::ptr tree = InfoTree::make("test");
    assert(tree->is_leaf());
  }
  {  // node data as float
    InfoTree::ptr tree = InfoTree::make(1.2f);
    float val = tree->get_value();
    assert(1.2f == val);
  }
  {  // graft a multiple childs and get them
    InfoTree::ptr tree = InfoTree::make();
    tree->graft("...child1....child2..", InfoTree::make(1.2f));
    assert(!tree->is_leaf());
    InfoTree::ptr child2 = tree->get_tree("..child1.child2");
    assert(child2);
    assert(child2->is_leaf());
    float data = child2->get_value();
    assert(1.2f == data);
    InfoTree::ptr child1 = tree->get_tree(".child1..");
    assert(!child1->is_leaf());
    assert(tree->get_tree("child1.foo")->empty());  // this is not a child
  }
  {  // graft a childs and prune it
    InfoTree::ptr tree = InfoTree::make();
    tree->graft("child1.child2", InfoTree::make());
    assert(!tree->is_leaf());
    InfoTree::ptr child1 = tree->prune("child1");
    assert(child1);
    assert(tree->is_leaf());
    assert(!child1->is_leaf());
    // child2 from the pruned child1
    InfoTree::ptr child2 = child1->prune("child2");
    assert(child2);
    assert(child1->is_leaf());
    assert(child2->is_leaf());
  }
  {  // absolute prune
    InfoTree::ptr tree = InfoTree::make();
    tree->graft("child1.child2", InfoTree::make());
    InfoTree::ptr child2 = tree->prune("child1.child2");
    assert(!tree->is_leaf());
    assert(tree->branch_is_leaf("child1"));
  }
  {  // is_leaf with path
    InfoTree::ptr tree = InfoTree::make();
    tree->graft("child1", InfoTree::make());
    tree->graft("child1.child2", InfoTree::make());
    tree->graft("child1.child2.child3", InfoTree::make());
    assert(tree->branch_is_leaf("child1.child2.child3"));
    assert(!tree->branch_is_leaf("child1.child2"));
    assert(!tree->branch_is_leaf("child1"));
    assert(!tree->branch_is_leaf("foofoo"));
  }
  {  // set/get data with path
    InfoTree::ptr tree = InfoTree::make();
    // tree->set_value ("", 1.2f);  // this is not possible
    // float tree_data = tree->get_value (".");  // this is not possible
    // assert (1.2f == tree_data);
    tree->graft("child1.child2", InfoTree::make());
    assert(tree->branch_set_value("child1.child2", nullptr));
    assert(tree->branch_set_value("child1", 1.2f));
    std::string child2_data = tree->branch_get_value("child1.child2");
    assert("" == child2_data);
    float child1_data = tree->branch_get_value("child1");
    assert(1.2f == child1_data);
  }
  {  // removing using empty data
    InfoTree::ptr tree = InfoTree::make();
    tree->set_value("test");
    assert(tree->has_data());
    tree->set_value(Any());
    assert(!tree->has_data());
    tree->graft("child1.child2", InfoTree::make());
    assert(tree->branch_set_value("child1.child2", "test"));
    assert(tree->branch_set_value("child1", "test"));
    assert(tree->branch_has_data("child1.child2"));
    assert(tree->branch_has_data("child1"));
    assert(tree->branch_set_value("child1.child2", Any()));
    assert(tree->branch_set_value("child1", Any()));
    assert(!tree->branch_has_data("child1.child2"));
    assert(!tree->branch_has_data("child1"));
  }
  {  // Any to string
    Any n;
    Any a(std::string("test"));
    Any b(1.2f);
    Widget widget;
    Any w(std::move(widget));
    SerializableWidget serializable_widget;
    Any sw(serializable_widget);

    std::stringstream ss;
    ss << n << "-" << a << "-" << b << "-" << w << "-" << sw;
    // std::cout << ss.str () << '\n';
    assert(0 == ss.str().compare("null-test-1.200000-not serializable-hello"));
  }
  {  // basic serialization
    InfoTree::ptr tree = InfoTree::make();
    tree->graft(".child1.child2", InfoTree::make("switch"));
    tree->graft(".child1.child3", InfoTree::make(1.2f));
    tree->graft(".child1.child2.bla1", InfoTree::make("wire"));
    tree->graft(".child1.child2.bla2", InfoTree::make("hub"));

    std::string serialized = BasicSerializer::serialize(tree.get());
    // std::cout << serialized << '\n';

    InfoTree::ptr tree2 = BasicSerializer::deserialize(serialized);
    assert(tree2);
    std::string serialized2 = BasicSerializer::serialize(tree2.get());
    // std::cout << serialized2 << '\n';

    assert(serialized == serialized2);
  }
  {
    // JSON serialization with child1.child2 as an array
    InfoTree::ptr tree = InfoTree::make();

    // if children are grafted to child3, its value
    // will be serialized with "key_value, as follow:
    // "child3" : {
    //  "key_value" : 1.2,
    //  "child4" : "float"
    //  }
    tree->graft(".child1.child3", InfoTree::make(1.2f));
    tree->graft(".child1.child3.child4", InfoTree::make("a string value"));
    tree->graft(".int_type", InfoTree::make(9));
    tree->graft(".bool_type", InfoTree::make(true));
    tree->graft(".float_type", InfoTree::make(3.14));
    tree->graft(".null_type", InfoTree::make());

    // if the array is made with a value, it will not be serialized
    // a node trageted as an array should be created like this :
    // tree->graft (".child1.child2", InfoTree::make ());
    // however, this is accepted:
    tree->graft(".child1.child2", InfoTree::make("switch"));
    //
    InfoTree::ptr elem1 = InfoTree::make();
    elem1->graft("equipment", InfoTree::make("door"));
    elem1->graft("color", InfoTree::make("red"));
    InfoTree::ptr elem2 = InfoTree::make();
    elem2->graft("equipment", InfoTree::make("door"));
    elem2->graft("color", InfoTree::make("black"));
    tree->graft(".child1.child2.red_door", elem1);
    tree->graft(".child1.child2.black_door", elem2);
    tree->tag_as_array(".child1.child2", true);

    std::string serialized = JSONSerializer::serialize(tree.get());
    // std::cout << serialized << '\n';
    auto deserialized_tree = JSONSerializer::deserialize(serialized);
    auto deserialized_string = JSONSerializer::serialize(deserialized_tree.get());
    // std::cout << deserialized_string << '\n';
    assert(serialized == deserialized_string);

    // test copy
    auto tree_cpy = InfoTree::copy(tree.get());
    assert(serialized == JSONSerializer::serialize(tree_cpy.get()));
    auto tree_cpy2 = tree->branch_get_copy(".");
    assert(serialized == JSONSerializer::serialize(tree_cpy2.get()));
  }

  {  // get childs keys inserting in an existing container
    InfoTree::ptr tree = InfoTree::make();
    std::list<std::string> childs{
        "child1", "child2", "child3", "child4", "child5", "child6", "child7", "child8", "child9"};
    std::for_each(childs.begin(), childs.end(), [tree](const std::string& val) {
      tree->graft(".root." + val, InfoTree::make("val"));
    });
    std::vector<std::string> child_keys;
    auto insert_it = std::insert_iterator<decltype(child_keys)>(child_keys, child_keys.begin());
    tree->copy_and_insert_child_keys(".root", insert_it);
    assert(std::equal(childs.begin(),
                      childs.end(),
                      child_keys.begin(),
                      [](const std::string& first, const std::string& second) {
                        return (0 == first.compare(second));
                      }));
  }

  {  // get childs keys in a newly allocated container
    InfoTree::ptr tree = InfoTree::make();
    std::list<std::string> childs{
        "child1", "child2", "child3", "child4", "child5", "child6", "child7", "child8", "child9"};
    std::for_each(childs.begin(), childs.end(), [tree](const std::string& val) {
      tree->graft(".root." + val, InfoTree::make("val"));
    });

    // using a default container
    auto child_keys_list = tree->get_child_keys(".root");
    assert(std::equal(childs.begin(), childs.end(), child_keys_list.begin(), string_compare));
  }

  {  // copy_leaf_values
    InfoTree::ptr tree = InfoTree::make();
    std::list<std::string> original_values{"0", "1", "2"};
    for (auto& it : original_values)
      tree->graft(std::string(".branch.item" + it), InfoTree::make(it));
    tree->graft(".other.branch", InfoTree::make());  // not into copy_leaf_values
    tree->tag_as_array("branch.", true);
    // std::string serialized = JSONSerializer::serialize(tree);
    // std::cout << serialized << '\n';
    std::list<std::string> values = tree->copy_leaf_values(".branch");
    assert(
        std::equal(original_values.begin(), original_values.end(), values.begin(), string_compare));
    // for (auto &it : values)
    //   std::cout << it << '\n';
  }

  {  // collecting data
    InfoTree::ptr tree = InfoTree::make();
    tree->graft("root.1.id", InfoTree::make(0));
    tree->graft("root.2.1.id", InfoTree::make(2));
    tree->graft("root.3.21.id", InfoTree::make(4));
    tree->graft("root.4.id", InfoTree::make(8));
    tree->graft("root.5.id", InfoTree::make(16));
    tree->graft("root.5.id.id", InfoTree::make(1));  // subtree of root.5.id
    tree->graft("root.1.2.id", InfoTree::make(3));   // sibling of root.1.id
    auto collected =
        InfoTree::collect_values(tree.get(),
                                 [](const std::string& key, InfoTree::ptrc) { return key == "id"; },
                                 false);  // do not continue search on siblings and subtree
    assert(5 == collected.size());
    std::vector<int> values{0, 2, 4, 8, 16};
    for (auto& it : collected) {
      assert(values.end() != std::find(values.cbegin(), values.cend(), it.copy_as<int>()));
    }
  }

  return 0;
}