add test for basic cd parsing

Change-Id: If35d62e323d48db11dc4128fb5c2898ef4ef63a6
diff --git a/src/ast.hpp b/src/ast.hpp
index 6c60dc9..f55ab39 100644
--- a/src/ast.hpp
+++ b/src/ast.hpp
@@ -1,15 +1,18 @@
 /*
  * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
+ * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
  *
  * Written by Václav Kubernát <kubervac@fit.cvut.cz>
  *
 */
 #pragma once
 #include <boost/spirit/home/x3.hpp>
-#include <vector>
 #include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
+
 #include <boost/fusion/adapted/struct/adapt_struct.hpp>
 #include <boost/fusion/include/adapt_struct.hpp>
+#include <vector>
+
 #include "CTree.hpp"
 namespace x3 = boost::spirit::x3;
 namespace ascii = boost::spirit::x3::ascii;
@@ -22,76 +25,88 @@
 using x3::lexeme;
 using ascii::space;
 
-using nodeString = std::string;
-
-struct ParserContext
-{
+struct ParserContext {
     ParserContext(const CTree& tree);
     const CTree& m_tree;
-    std::string m_currentContext;
+    std::string m_curPath;
 };
 
 struct parser_context_tag;
 
-struct container_
-{
-    char m_first;
+struct container_ {
+    container_() {}
+    container_(const std::string& name);
+
+    bool operator==(const container_& b) const;
+
+    char m_first = ' ';
     std::string m_name;
 };
 
 BOOST_FUSION_ADAPT_STRUCT(container_, m_first, m_name)
 
-struct path_
-{
+struct path_ {
+    bool operator==(const path_& b) const;
     std::vector<container_> m_nodes;
 };
 
 BOOST_FUSION_ADAPT_STRUCT(path_, m_nodes)
 
-struct cd_
-{
+struct cd_ {
+    bool operator==(const cd_& b) const;
     path_ m_path;
 };
 
 BOOST_FUSION_ADAPT_STRUCT(cd_, m_path)
 
 
-struct container_class
-{
+struct container_class {
     template <typename T, typename Iterator, typename Context>
-        inline void on_success(Iterator const& first, Iterator const& last
-                , T& ast, Context const& context);
+    void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
+    {
+        ast.m_name = ast.m_first + ast.m_name;
+        auto& parserContext = x3::get<parser_context_tag>(context);
+        const auto& tree = parserContext.m_tree;
+
+        if (tree.isContainer(parserContext.m_curPath, ast.m_name)) {
+            if (!parserContext.m_curPath.empty()) {
+                parserContext.m_curPath += '/';
+            }
+            parserContext.m_curPath += ast.m_name;
+        } else {
+            throw InvalidNodeException("No container with the name \"" + ast.m_name + "\" in \"" + parserContext.m_curPath + "\"");
+        }
+    }
 };
 
-struct path_class
-{
+struct path_class {
     template <typename T, typename Iterator, typename Context>
-    inline void on_success(Iterator const& first, Iterator const& last
-    , T& ast, Context const& context);
+    void on_success(Iterator const&, Iterator const&, T&, Context const&)
+    {
+    }
 };
 
-struct cd_class
-{
+struct cd_class {
     template <typename T, typename Iterator, typename Context>
-    inline void on_success(Iterator const& first, Iterator const& last
-    , T& ast, Context const& context);
-
+    void on_success(Iterator const&, Iterator const&, T&, Context const&)
+    {
+    }
 };
 
 
-typedef x3::rule<container_class, container_> container_type;
-typedef x3::rule<path_class, path_> path_type;
-typedef x3::rule<cd_class, cd_> cd_type;
+x3::rule<container_class, container_> const container = "container";
+x3::rule<path_class, path_> const path = "path";
+x3::rule<cd_class, cd_> const cd = "cd";
 
-container_type const container = "container";
-path_type const path = "path";
-cd_type const cd = "cd";
 
+auto const identifier =
+    lexeme[
+        ((alpha | char_("_")) >> *(alnum | char_("_") | char_("-") | char_(".")))
+    ];
 
 auto const container_def =
-    lexeme[
-        ((alpha | x3::string("_")) >> *(alnum | x3::string("_") | x3::string("-") | x3::string(".")))
-    ];
+    identifier;
+
 auto const path_def =
     container % '/';