f88b91d938d782cfa9999929f4c2afa807d84802
[senf.git] / senf / Utils / Console / Node.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Node unit tests */
25
26 //#include "Node.test.hh"
27 //#include "Node.test.ih"
28
29 // Custom includes
30 #include <sstream>
31 #include "Node.hh"
32 #include <boost/iterator/transform_iterator.hpp>
33
34 #include "../../Utils/auto_unit_test.hh"
35 #include <boost/test/test_tools.hpp>
36
37 #define prefix_
38 ///////////////////////////////cc.p////////////////////////////////////////
39
40 BOOST_AUTO_UNIT_TEST(genericNode)
41 {
42     senf::console::GenericNode & node (
43         senf::console::root().mkdir("dir1").mkdir("dir2").doc("help info"));
44     senf::console::GenericNode::weak_ptr wp (node.thisptr());
45
46     BOOST_CHECK_EQUAL( node.name(), "dir2" );
47     BOOST_CHECK( node.parent() );
48     BOOST_CHECK_EQUAL( node.path(), "/dir1/dir2" );
49     BOOST_CHECK( node.active() );
50     std::stringstream ss;
51     node.help(ss);
52     BOOST_CHECK_EQUAL( ss.str(), "help info\n" );
53     
54     {
55         senf::console::GenericNode::ptr p (senf::console::root()["dir1"].unlink());
56         BOOST_CHECK( ! node.active() );
57         BOOST_CHECK( ! wp.expired() );
58     }
59     BOOST_CHECK( wp.expired() );
60 }
61
62 namespace {
63     void callback(std::ostream & os, senf::console::ParseCommandInfo const & command)
64     {
65         os << "callback";
66     }
67
68     template <class T>
69     struct select1st {
70         typedef T result_type;
71         template <class U> result_type operator()(U const & u) const { return u.first; }
72     };
73 }
74
75 BOOST_AUTO_UNIT_TEST(directoryNode)
76 {
77     senf::console::DirectoryNode::ptr p (senf::console::DirectoryNode::create());
78
79     BOOST_CHECK( & senf::console::root().add("dir1", p) == p.get() );
80
81     senf::console::SimpleCommandNode & fnnode (
82         senf::console::root().add( "fn", senf::console::SimpleCommandNode::create(&callback) ));
83     BOOST_CHECK( &senf::console::root()["dir1"] == p.get() );
84     BOOST_CHECK_THROW( senf::console::root()["dir2"], senf::console::UnknownNodeNameException );
85     BOOST_CHECK_THROW( senf::console::root()("dir1"), std::bad_cast );
86     BOOST_CHECK( &senf::console::root()("fn") == &fnnode );
87     BOOST_CHECK_THROW( senf::console::root()("fn2"), senf::console::UnknownNodeNameException );
88     BOOST_CHECK_THROW( senf::console::root()["fn"], std::bad_cast );
89     BOOST_CHECK( &senf::console::root().get("dir1") == p.get() );
90     
91     senf::console::root().mkdir("dir2").mkdir("dir3");
92     char const * const children[] = { "dir1", "dir2", "fn", "sys" };
93     BOOST_CHECK_EQUAL_COLLECTIONS( 
94         boost::make_transform_iterator(senf::console::root().children().begin(), 
95                                        select1st<std::string const &>()),
96         boost::make_transform_iterator(senf::console::root().children().end(),
97                                        select1st<std::string const &>()),
98         children, 
99         children+sizeof(children)/sizeof(children[0]) );
100
101     char const * const completions[] = { "dir1", "dir2" };
102     BOOST_CHECK_EQUAL_COLLECTIONS(
103         boost::make_transform_iterator(senf::console::root().completions("dir").begin(), 
104                                        select1st<std::string const &>()),
105         boost::make_transform_iterator(senf::console::root().completions("dir").end(),
106                                        select1st<std::string const &>()),
107         completions, 
108         completions+sizeof(completions)/sizeof(completions[0]) );
109
110     p->doc("test doc\nline 2");
111     std::stringstream ss;
112     p->help(ss);
113     BOOST_CHECK_EQUAL( ss.str(), "test doc\nline 2\n" );
114     BOOST_CHECK_EQUAL( p->shorthelp(), "test doc" );
115     p->doc("");
116     BOOST_CHECK_EQUAL( p->shorthelp(), "" );
117     p->shortdoc("short doc");
118     BOOST_CHECK_EQUAL( p->shorthelp(), "short doc" );
119
120     ss.str("");
121     senf::console::root()["dir2"].mkdir("dir4");
122     senf::console::root()["dir2"].link("link", *p);
123     senf::console::root()["dir2"]["dir4"].link("link", senf::console::root());
124     senf::console::dump(ss, senf::console::root()["dir2"]);
125     BOOST_CHECK_EQUAL( ss.str(),
126                        "dir3/\n"
127                        "dir4/\n"
128                        "  link@ -> /\n"
129                        "link@ -> /dir1\n" );
130
131     BOOST_CHECK( senf::console::root().remove("dir1") == p );
132     senf::console::root().remove("dir2");
133     senf::console::root().remove("fn");
134
135     BOOST_CHECK_EQUAL( std::distance(senf::console::root().children().begin(),
136                                      senf::console::root().children().end()), 1 );
137 }
138
139 BOOST_AUTO_UNIT_TEST(linkNode)
140 {
141     senf::console::root().mkdir("dir1");
142     senf::console::root().link("link1", senf::console::root()["dir1"]);
143
144     BOOST_CHECK( senf::console::root()["dir1"] == senf::console::root()["link1"] );
145
146     senf::console::root().remove("dir1");
147     senf::console::root().remove("link1");
148 }
149
150 namespace {
151     struct Functor {
152         void operator()(std::ostream & os, senf::console::ParseCommandInfo const &) {
153             os << "functor";
154         }
155     };
156 }
157
158 BOOST_AUTO_UNIT_TEST(senfConsoleAddNode)
159 {
160     senf::console::root().add("fn1", &callback);
161     senf::console::root().add("fn2", Functor());
162     
163     senf::console::ParseCommandInfo info;
164
165     {
166         std::stringstream ss;
167         senf::console::root()("fn1")(ss, info);
168         BOOST_CHECK_EQUAL( ss.str(), "callback" );
169     }
170
171     {
172         std::stringstream ss;
173         senf::console::root()("fn2")(ss, info);
174         BOOST_CHECK_EQUAL( ss.str(), "functor" );
175     }
176     
177     senf::console::root().remove("fn1");
178     senf::console::root().remove("fn2");
179 }
180
181 BOOST_AUTO_UNIT_TEST(simpleCommandNode)
182 {
183     senf::console::root().add("fn", senf::console::SimpleCommandNode::create(&callback))
184         .doc("help text");
185     {
186         std::stringstream ss;
187         senf::console::ParseCommandInfo info;
188         senf::console::root()("fn")(ss, info);
189         BOOST_CHECK_EQUAL( ss.str(), "callback" );
190     }
191     
192     {
193         std::stringstream ss;
194         senf::console::root().get("fn").help(ss);
195         BOOST_CHECK_EQUAL( ss.str(), "help text\n" );
196     }
197
198     senf::console::root().remove("fn");
199 }
200
201 ///////////////////////////////cc.e////////////////////////////////////////
202 #undef prefix_
203
204 \f
205 // Local Variables:
206 // mode: c++
207 // fill-column: 100
208 // comment-column: 40
209 // c-file-style: "senf"
210 // indent-tabs-mode: nil
211 // ispell-local-dictionary: "american"
212 // compile-command: "scons -u test"
213 // End: