4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
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
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.
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.
19 // The Original Code is Fraunhofer FOKUS code.
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.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief ParsedCommand unit tests */
31 //#include "ParsedCommand.test.hh"
32 //#include "ParsedCommand.test.ih"
39 #include <senf/Utils/auto_unit_test.hh>
40 #include <boost/test/test_tools.hpp>
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
47 int cb1(int a, double b) { return int(a+b); }
48 double cb2() { return 1.2; }
50 std::string cb4(std::ostream & os) { os << "text\n"; return "value"; }
51 void cb5(std::ostream & os, std::string const & v) { os << "Value: " << v << "\n"; }
55 void operator()(senf::console::ParseCommandInfo::TokensRange const &,
56 std::string & out) const
60 void testFormatter(double, std::ostream & os)
61 { os << "formatter"; }
64 SENF_AUTO_UNIT_TEST(parsedCommand)
66 namespace fty = senf::console::factory;
68 senf::console::Executor executor;
69 senf::console::CommandParser parser;
70 senf::console::ScopedDirectory<> dir;
71 senf::console::root().add("test", dir);
75 dir.add("cb1", fty::Command(&cb1));
76 parser.parse("test/cb1 2 3.2",
77 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 ));
78 BOOST_CHECK_EQUAL( ss.str(), "5\n" );
83 dir.add("cb2", fty::Command(&cb2));
84 parser.parse("test/cb2",
85 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 ));
86 BOOST_CHECK_EQUAL( ss.str(), "1.2\n" );
91 dir.add("cb3", fty::Command(&cb3));
92 parser.parse("test/cb3 234",
93 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 ));
94 BOOST_CHECK_EQUAL( ss.str(), "" );
99 dir.add("cb4", fty::Command(&cb4));
100 parser.parse("test/cb4",
101 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 ));
102 BOOST_CHECK_EQUAL( ss.str(), "text\n" "value\n" );
106 std::stringstream ss;
107 dir.add("cb5", fty::Command(&cb5));
108 parser.parse("test/cb5 1234",
109 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 ));
110 BOOST_CHECK_EQUAL( ss.str(), "Value: 1234\n" );
114 std::stringstream ss;
117 parser.parse("test/cb1 2 3.2 foo",
118 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )),
119 senf::console::SyntaxErrorException );
122 parser.parse("test/cb1 2",
123 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )),
124 senf::console::SyntaxErrorException );
127 parser.parse("test/cb1 2 foo",
128 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )),
129 senf::console::SyntaxErrorException );
133 namespace kw = senf::console::kw;
134 std::stringstream ss;
136 // Just for the fun of it, use a functor and not a function pointer as parser ...
139 .arg( kw::parser = TestParser() )
142 parser.parse("test/cb6 false",
143 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )) );
144 BOOST_CHECK_EQUAL( ss.str(), "Value: true\n" );
148 std::stringstream ss;
150 // This tests adding boost::function objects and at the same time validates, that
151 // compatible types also work
153 fty::Command(boost::function<float()>(&cb2))
154 .formatter( &testFormatter )
157 parser.parse("test/cb7",
158 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )) );
159 BOOST_CHECK_EQUAL( ss.str(), "formatter\n" );
163 std::stringstream ss;
165 using namespace senf::console::kw;
167 dir.add("cb", fty::Command(&cb1)
169 "Ops fortunate, ops me ut orgia vociferatio contumax per, rudo re loco emitto\n"
170 "intolerabiliter ita iugo. Subcribo gravo. Devenio luna fonticulus Castanea\n"
171 "horum fascino Os interpretor non ipse conjuratio hora, qui filius denuntio ait\n"
172 "sono te odium Anhelo. Dum Cedo audax celox alius una Agnosco hic, ibi retineo\n"
173 "lux sto ioco. Per Re dono. Copiose reus scitus jus diligens sis scapulare\n"
174 "Servitium transi." )
180 "Lo nam balnearius Opprimo Pennatus, no decentia sui, dicto esse se pulchritudo,\n"
181 "pupa Sive res indifferenter. Captivo pa." )
183 .arg( description = "Bar didelfrump di desgorb. Nu widsoflar brimeldrgf." )
185 .arg( name = "checkup",
186 type_name = "number",
187 description = "Florgel, dargel and durgel",
189 default_doc = "(double) 2.1" )
192 senf::console::OverloadedCommandNode & cbNode (
193 dir.add("cb", fty::Command(&cb5)
195 "Uus Primordia fundo falsidicus corium, diurnitas humo pro leto. Sui Ueraciter\n"
196 "hio eruca lenis qua Agalmate ut fors penitentia. Iugum obdormio anxio nuncupo\n"
197 "iam, in vos nam Custodi." )
198 .arg( "text", default_value = "" ) )
201 senf::IGNORE( cbNode );
204 parser.parse("test/cb 111 222.4",
205 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )) );
207 parser.parse("test/cb 222",
208 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )) );
210 parser.parse("test/cb foo",
211 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )) );
213 parser.parse("test/cb",
214 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )) );
216 BOOST_CHECK_EQUAL( ss.str(), "333\n" "224\n" "Value: foo\n" "Value: \n" );
218 BOOST_CHECK_EQUAL( dir("cb").shorthelp(), "Ops fortunate." );
222 std::stringstream ss;
223 senf::console::root()["test"]("cb").help(ss);
227 " 1- cb arg11:int [checkup:number]\n"
228 " 2- cb [text:string]\n"
231 " arg11 Bar didelfrump di desgorb. Nu widsoflar brimeldrgf.\n"
232 " checkup Florgel, dargel and durgel\n"
233 " default: (double) 2.1\n"
237 "Ops fortunate, ops me ut orgia vociferatio contumax per, rudo re loco emitto\n"
238 "intolerabiliter ita iugo. Subcribo gravo. Devenio luna fonticulus Castanea\n"
239 "horum fascino Os interpretor non ipse conjuratio hora, qui filius denuntio ait\n"
240 "sono te odium Anhelo. Dum Cedo audax celox alius una Agnosco hic, ibi retineo\n"
241 "lux sto ioco. Per Re dono. Copiose reus scitus jus diligens sis scapulare\n"
242 "Servitium transi.\n"
245 "Lo nam balnearius Opprimo Pennatus, no decentia sui, dicto esse se pulchritudo,\n"
246 "pupa Sive res indifferenter. Captivo pa.\n"
249 "Uus Primordia fundo falsidicus corium, diurnitas humo pro leto. Sui Ueraciter\n"
250 "hio eruca lenis qua Agalmate ut fors penitentia. Iugum obdormio anxio nuncupo\n"
251 "iam, in vos nam Custodi.\n" );
258 senf::console::ScopedDirectory<Test> dir;
261 Test(std::string const & name) : dir(this), name_ (name) {
262 dir.add("name", senf::console::factory::Command(
263 SENF_MEMBINDFNP(std::string, Test, name, (std::string const &))));
266 std::string name(std::string const & suffix) {
267 return name_ + suffix;
273 SENF_AUTO_UNIT_TEST(memberParsedCommand)
275 senf::console::Executor executor;
276 senf::console::CommandParser parser;
277 senf::console::ScopedDirectory<> dir;
278 senf::console::root().add("test", dir);
282 dir.add("obj", obj.dir);
284 std::stringstream ss;
285 parser.parse("test/obj/name \": foo\"",
286 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 ));
287 BOOST_CHECK_EQUAL( ss.str(), "bar: foo\n" );
293 senf::console::DirectoryNode::ptr dircb()
295 namespace fty = senf::console::factory;
297 senf::console::DirectoryNode & dir (
298 senf::console::root()["test"].add("dircb", fty::Directory()));
299 dir.add("cb1", fty::Command(&cb1));
300 return dir.thisptr();
305 SENF_AUTO_UNIT_TEST(directoryReturn)
307 namespace fty = senf::console::factory;
309 senf::console::Executor executor;
310 senf::console::CommandParser parser;
311 senf::console::ScopedDirectory<> dir;
312 senf::console::root().add("test", dir);
313 dir.add("test", fty::Command(&dircb));
316 std::stringstream ss;
318 parser.parse("test/test { ll; }",
319 boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )) );
320 BOOST_CHECK_EQUAL( ss.str(),
321 "<Directory at '/test/dircb'>\n"
329 COMPILE_FAIL(argParser)
331 senf::console::ScopedDirectory<> dir;
333 // Fails, since there are only two arguments defined
340 COMPILE_FAIL(defaultDoc)
342 senf::console::ScopedDirectory<> dir;
343 using namespace senf::console::kw;
345 // Fails, since default_value is missing but default_doc is given
347 .arg(default_doc = "doc");
352 //-/////////////////////////////////////////////////////////////////////////////////////////////////
359 // comment-column: 40
360 // c-file-style: "senf"
361 // indent-tabs-mode: nil
362 // ispell-local-dictionary: "american"
363 // compile-command: "scons -u test"