switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / Console / Node.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief Node unit tests */
30
31 //#include "Node.test.hh"
32 //#include "Node.test.ih"
33
34 // Custom includes
35 #include <sstream>
36 #include "Console.hh"
37 #include <boost/iterator/transform_iterator.hpp>
38
39 #include <senf/Utils/auto_unit_test.hh>
40 #include <boost/test/test_tools.hpp>
41
42 #define prefix_
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
44
45 SENF_AUTO_UNIT_TEST(genericNode)
46 {
47     namespace fty = senf::console::factory;
48
49     senf::console::GenericNode & node (
50         senf::console::root()
51         .add("dir1", fty::Directory())
52         .add("dir2", fty::Directory().doc("help info")));
53     senf::console::GenericNode::weak_ptr wp (node.thisptr());
54
55     BOOST_CHECK_EQUAL( node.name(), "dir2" );
56     BOOST_CHECK( node.parent() );
57     BOOST_CHECK_EQUAL( node.path(), "/dir1/dir2" );
58     BOOST_CHECK( node.active() );
59     std::stringstream ss;
60     node.help(ss);
61     BOOST_CHECK_EQUAL( ss.str(), "help info\n" );
62
63     {
64         senf::console::GenericNode::ptr p (senf::console::root()["dir1"].unlink());
65         BOOST_CHECK( ! node.active() );
66         BOOST_CHECK( ! wp.expired() );
67     }
68     BOOST_CHECK( wp.expired() );
69 }
70
71 namespace {
72     void callback(std::ostream & os, senf::console::ParseCommandInfo const & command)
73     {
74         os << "callback";
75     }
76
77     template <class T>
78     struct select1st {
79         typedef T result_type;
80         template <class U> result_type operator()(U const & u) const { return u.first; }
81     };
82 }
83
84 SENF_AUTO_UNIT_TEST(directoryNode)
85 {
86     namespace fty = senf::console::factory;
87
88     senf::console::DirectoryNode::ptr p (senf::console::DirectoryNode::create());
89
90     BOOST_CHECK( & senf::console::root().add("dir1", p) == p.get() );
91
92     senf::console::SimpleCommandNode & fnnode (
93         senf::console::root().add( "fn", senf::console::SimpleCommandNode::create(&callback) ));
94     BOOST_CHECK( &senf::console::root()["dir1"] == p.get() );
95     BOOST_CHECK_THROW( senf::console::root()["dir2"], senf::console::UnknownNodeNameException );
96     BOOST_CHECK_THROW( senf::console::root()("dir1"), std::bad_cast );
97     BOOST_CHECK( &senf::console::root()("fn") == &fnnode );
98     BOOST_CHECK_THROW( senf::console::root()("fn2"), senf::console::UnknownNodeNameException );
99     BOOST_CHECK_THROW( senf::console::root()["fn"], std::bad_cast );
100     BOOST_CHECK( &senf::console::root().get("dir1") == p.get() );
101
102     senf::console::root()
103         .add("dir2", fty::Directory())
104         .add("dir3", fty::Directory());
105     char const * const children[] = { "dir1", "dir2", "fn", "sys" };
106     BOOST_CHECK_EQUAL_COLLECTIONS(
107         boost::make_transform_iterator(senf::console::root().children().begin(),
108                                        select1st<std::string const &>()),
109         boost::make_transform_iterator(senf::console::root().children().end(),
110                                        select1st<std::string const &>()),
111         children,
112         children+sizeof(children)/sizeof(children[0]) );
113
114     char const * const completions[] = { "dir1", "dir2" };
115     BOOST_CHECK_EQUAL_COLLECTIONS(
116         boost::make_transform_iterator(senf::console::root().completions("dir").begin(),
117                                        select1st<std::string const &>()),
118         boost::make_transform_iterator(senf::console::root().completions("dir").end(),
119                                        select1st<std::string const &>()),
120         completions,
121         completions+sizeof(completions)/sizeof(completions[0]) );
122
123     p->doc("test doc\nline 2");
124     std::stringstream ss;
125     p->help(ss);
126     BOOST_CHECK_EQUAL( ss.str(), "test doc\nline 2\n" );
127     BOOST_CHECK_EQUAL( p->shorthelp(), "test doc" );
128     p->doc("");
129     BOOST_CHECK_EQUAL( p->shorthelp(), "" );
130     p->shortdoc("short doc");
131     BOOST_CHECK_EQUAL( p->shorthelp(), "short doc" );
132
133     ss.str("");
134     senf::console::root()["dir2"].add("dir4", fty::Directory());
135     senf::console::root()["dir2"].add("link", fty::Link(*p));
136     senf::console::root()["dir2"]["dir4"].add("link", fty::Link(senf::console::root()));
137     senf::console::dump(ss, senf::console::root()["dir2"]);
138     BOOST_CHECK_EQUAL( ss.str(),
139                        "dir3/\n"
140                        "dir4/\n"
141                        "  link@ -> /\n"
142                        "link@ -> /dir1\n" );
143
144     BOOST_CHECK( senf::console::root().remove("dir1") == p );
145     senf::console::root().remove("dir2");
146     senf::console::root().remove("fn");
147
148     BOOST_CHECK_EQUAL( std::distance(senf::console::root().children().begin(),
149                                      senf::console::root().children().end()), 1 );
150 }
151
152 SENF_AUTO_UNIT_TEST(linkNode)
153 {
154     namespace fty = senf::console::factory;
155
156     senf::console::root().add("dir1", fty::Directory());
157     senf::console::root().add("link1", fty::Link(senf::console::root()["dir1"]));
158
159     BOOST_CHECK( senf::console::root()["dir1"] == senf::console::root()["link1"] );
160
161     senf::console::root().remove("dir1");
162     senf::console::root().remove("link1");
163 }
164
165 namespace {
166     struct Functor {
167         void operator()(std::ostream & os, senf::console::ParseCommandInfo const &) {
168             os << "functor";
169         }
170     };
171 }
172
173 SENF_AUTO_UNIT_TEST(factory)
174 {
175     namespace fty = senf::console::factory;
176
177     senf::console::root().add("fn1", fty::SimpleCommand(&callback));
178     senf::console::root().add("fn2", fty::SimpleCommand(Functor()));
179
180     senf::console::ParseCommandInfo info;
181
182     {
183         std::stringstream ss;
184         senf::console::root()("fn1")(ss, info);
185         BOOST_CHECK_EQUAL( ss.str(), "callback" );
186     }
187
188     {
189         std::stringstream ss;
190         senf::console::root()("fn2")(ss, info);
191         BOOST_CHECK_EQUAL( ss.str(), "functor" );
192     }
193
194     senf::console::root().remove("fn1");
195     senf::console::root().remove("fn2");
196 }
197
198 SENF_AUTO_UNIT_TEST(simpleCommandNode)
199 {
200     senf::console::root().add("fn", senf::console::SimpleCommandNode::create(&callback))
201         .doc("help text");
202     {
203         std::stringstream ss;
204         senf::console::ParseCommandInfo info;
205         senf::console::root()("fn")(ss, info);
206         BOOST_CHECK_EQUAL( ss.str(), "callback" );
207     }
208
209     {
210         std::stringstream ss;
211         senf::console::root().get("fn").help(ss);
212         BOOST_CHECK_EQUAL( ss.str(), "help text\n" );
213     }
214
215     senf::console::root().remove("fn");
216 }
217
218 //-/////////////////////////////////////////////////////////////////////////////////////////////////
219 #undef prefix_
220
221 \f
222 // Local Variables:
223 // mode: c++
224 // fill-column: 100
225 // comment-column: 40
226 // c-file-style: "senf"
227 // indent-tabs-mode: nil
228 // ispell-local-dictionary: "american"
229 // compile-command: "scons -u test"
230 // End: