Utils/Console: Fix DirectoryNode::add(...) API
[senf.git] / senf / Utils / Console / ConfigFile.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 ConfigFile unit tests */
25
26 //#include "ConfigFile.test.hh"
27 //#include "ConfigFile.test.ih"
28
29 // Custom includes
30 #include "Console.hh"
31 #include <fstream>
32 #include <boost/filesystem/operations.hpp>
33
34 #include <senf/Utils/auto_unit_test.hh>
35 #include <boost/test/test_tools.hpp>
36
37 #define prefix_
38 ///////////////////////////////cc.p////////////////////////////////////////
39
40 namespace {
41
42     int var1 (0);
43     bool var2 (false);
44     
45     void fun1(int v) { var1 = v; }
46     void fun2() { var2 = true; }
47
48     class TempFile
49     {
50     public:
51         TempFile(std::string const & name) : name_ (name), file_ (name_.c_str()) {}
52         ~TempFile() { file_.close(); boost::filesystem::remove(name_); }
53         
54         template <class T> TempFile & operator<<(T const & v) { file_ << v; return *this; }
55         enum Closer { close }; void operator<<(Closer) { file_.close(); }
56         std::string const & name() { return name_; }
57
58     private:
59         std::string name_;
60         std::ofstream file_;
61     };
62     
63 }
64
65 SENF_AUTO_UNIT_TEST(configFile)
66 {
67     namespace fty = senf::console::factory;
68
69     TempFile cfgf ("test.cfg");
70     cfgf << "dir1/fun1 10;\n" 
71          << TempFile::close;
72     
73     senf::console::ScopedDirectory<> dir1;
74     senf::console::root().add("dir1", dir1);
75     dir1.add("fun1",fty::Command(&fun1));
76
77     {
78         senf::console::ConfigFile cfg (cfgf.name());
79
80         var1 = 0;
81         SENF_CHECK_NO_THROW( cfg.parse() );
82         BOOST_CHECK_EQUAL( var1, 10 );
83
84         var1 = 0;
85         SENF_CHECK_NO_THROW( cfg.parse() );
86         BOOST_CHECK_EQUAL( var1, 0 );
87
88         var1 = 0;
89         cfg.reset();
90         SENF_CHECK_NO_THROW( cfg.parse() );
91         BOOST_CHECK_EQUAL( var1, 10 );
92     }
93
94     {
95         senf::console::ConfigFile cfg ("i don't exist");
96         cfg.ignoreMissing();
97         SENF_CHECK_NO_THROW( cfg.parse() );
98     }
99 }
100
101 SENF_AUTO_UNIT_TEST(configFileRestrict)
102 {
103     namespace fty = senf::console::factory;
104
105     TempFile cfgf ("test.cfg");
106     cfgf << "dir1/fun1 10;\n"
107          << "dir2/fun2;\n"
108          << TempFile::close;
109     
110     senf::console::ScopedDirectory<> dir1;
111     senf::console::root().add("dir1", dir1);
112     dir1.add("fun1",fty::Command(&fun1));
113     
114     {
115         var1 = 0;
116         var2 = false;
117         senf::console::ConfigFile cfg (cfgf.name());
118         SENF_CHECK_NO_THROW( cfg.parse(dir1) );
119         BOOST_CHECK_EQUAL( var1, 10 );
120         BOOST_CHECK_EQUAL( var2, false );
121         BOOST_CHECK( cfg.parsed(dir1) );
122         BOOST_CHECK( ! cfg.complete() );
123
124         senf::console::ScopedDirectory<> dir2;
125         senf::console::root().add("dir2", dir2);
126         dir2.add("fun2",fty::Command(&fun2));
127
128         var1 = 0;
129         var2 = false;
130         SENF_CHECK_NO_THROW( cfg.parse() );
131         BOOST_CHECK_EQUAL( var1, 0 );
132         BOOST_CHECK_EQUAL( var2, true );
133         BOOST_CHECK( cfg.complete() );
134     }
135 }
136
137 SENF_AUTO_UNIT_TEST(configFileSkipGroup)
138 {
139     namespace fty = senf::console::factory;
140
141     TempFile cfgf ("test.cfg");
142     cfgf << "dir1/fun1 10;\n"
143          << "dir2 { dir3 { fun2; } fun1 5; }"
144          << TempFile::close;
145     
146     senf::console::ScopedDirectory<> dir1;
147     senf::console::root().add("dir1", dir1);
148     dir1.add("fun1",fty::Command(&fun1));
149     
150     senf::console::ScopedDirectory<> dir2;
151     senf::console::root().add("dir2", dir2);
152     
153     dir2.mkdir("dir3").add("fun2", fty::Command(&fun2));
154     dir2.add("fun1", fty::Command(&fun1));
155
156     {
157         var1 = 0;
158         var2 = false;
159         senf::console::ConfigFile cfg (cfgf.name());
160         SENF_CHECK_NO_THROW( cfg.parse(dir1) );
161         BOOST_CHECK_EQUAL( var1, 10 );
162         BOOST_CHECK_EQUAL( var2, false );
163         BOOST_CHECK( cfg.parsed(dir1) );
164
165         var1 = 0;
166         var2 = false;
167         SENF_CHECK_NO_THROW( cfg.parse(dir2["dir3"]) );
168         BOOST_CHECK_EQUAL( var1, 0 );
169         BOOST_CHECK_EQUAL( var2, true );
170         BOOST_CHECK( ! cfg.parsed(dir2) );
171
172         var1 = 0;
173         var2 = false;
174         SENF_CHECK_NO_THROW( cfg.parse() );
175         BOOST_CHECK_EQUAL( var1, 5 );
176         BOOST_CHECK_EQUAL( var2, false );
177     }
178 }
179
180 SENF_AUTO_UNIT_TEST(configRestrictAndLink)
181 {
182     namespace fty = senf::console::factory;
183
184     TempFile cfgf ("test.cfg");
185     cfgf << "dir1/fun1 10;\n"
186          << "link1 { dir3 { fun2; } fun1 5; }"
187          << TempFile::close;
188     
189     senf::console::ScopedDirectory<> dir1;
190     senf::console::root().add("dir1", dir1);
191     dir1.add("fun1",fty::Command(&fun1));
192     
193     senf::console::ScopedDirectory<> dir2;
194     dir1.add("dir2", dir2);
195     
196     dir2.mkdir("dir3").add("fun2", fty::Command(&fun2));
197     dir2.add("fun1", fty::Command(&fun1));
198
199     senf::console::ScopedDirectory<> dir4;
200     senf::console::root().add("dir4", dir4);
201     dir4.link("link1", dir2);
202
203     {
204         senf::console::ConfigFile cfg (cfgf.name(), dir4);
205
206         var1 = 0;
207         var2 = false;
208         SENF_CHECK_NO_THROW( cfg.parse(dir2["dir3"]) );
209         BOOST_CHECK_EQUAL( var1, 0 );
210         BOOST_CHECK_EQUAL( var2, true );
211
212         BOOST_CHECK_THROW( cfg.parse(), senf::console::SyntaxErrorException );
213     }
214 }
215
216 ///////////////////////////////cc.e////////////////////////////////////////
217 #undef prefix_
218
219 \f
220 // Local Variables:
221 // mode: c++
222 // fill-column: 100
223 // comment-column: 40
224 // c-file-style: "senf"
225 // indent-tabs-mode: nil
226 // ispell-local-dictionary: "american"
227 // compile-command: "scons -u test"
228 // End: