mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
appConfigurator_test.cpp
1#define CATCH_CONFIG_MAIN
2#include "../../catch2/catch.hpp"
3
4#include <fstream>
5
6#include "../../../include/app/appConfigurator.hpp"
7
8using namespace mx::app;
9
10SCENARIO( "config file parsing", "[appConfigurator]" )
11{
12 GIVEN( "a basic config file" )
13 {
14 WHEN( "no sections" )
15 {
16 writeConfigFile( "/tmp/test.conf",
17 { "", "", "", "", "", "" },
18 { "key0", "key1", "key2", "key3", "key4", "key5" },
19 { "val0", "val1", "val2", "val3", "val4", "val5" } );
20
22 config.add( "key0", "", "", 0, "", "key0", false, "", "" );
23 config.add( "key1", "", "", 0, "", "key1", false, "", "" );
24 config.add( "key2", "", "", 0, "", "key2", false, "", "" );
25 config.add( "key3", "", "", 0, "", "key3", false, "", "" );
26 config.add( "key4", "", "", 0, "", "key4", false, "", "" );
27 config.add( "key5", "", "", 0, "", "key5", false, "", "" );
28
29 config.readConfig( "/tmp/test.conf" );
30
31 std::string val;
32
33 config( val, "key0" );
34 REQUIRE( val == "val0" );
35
36 config( val, "key1" );
37 REQUIRE( val == "val1" );
38
39 config( val, "key2" );
40 REQUIRE( val == "val2" );
41
42 config( val, "key3" );
43 REQUIRE( val == "val3" );
44
45 config( val, "key4" );
46 REQUIRE( val == "val4" );
47
48 config( val, "key5" );
49 REQUIRE( val == "val5" );
50 }
51
52 WHEN( "sections, unique keys" )
53 {
54 writeConfigFile( "/tmp/test.conf",
55 { "", "", "sect1", "sect1", "sect2", "sect2" },
56 { "key0", "key1", "key2", "key3", "key4", "key5" },
57 { "val0", "val1", "val2", "val3", "val4", "val5" } );
58
60 config.add( "key0", "", "", 0, "", "key0", false, "", "" );
61 config.add( "key1", "", "", 0, "", "key1", false, "", "" );
62 config.add( "sect1.key2", "", "", 0, "sect1", "key2", false, "", "" );
63 config.add( "sect1.key3", "", "", 0, "sect1", "key3", false, "", "" );
64 config.add( "sect2.key4", "", "", 0, "sect2", "key4", false, "", "" );
65 config.add( "sect2.key5", "", "", 0, "sect2", "key5", false, "", "" );
66
67 config.readConfig( "/tmp/test.conf" );
68
69 std::string val;
70
71 config( val, "key0" );
72 REQUIRE( val == "val0" );
73
74 config( val, "key1" );
75 REQUIRE( val == "val1" );
76
77 config( val, "sect1.key2" );
78 REQUIRE( val == "val2" );
79
80 config( val, "sect1.key3" );
81 REQUIRE( val == "val3" );
82
83 config( val, "sect2.key4" );
84 REQUIRE( val == "val4" );
85
86 config( val, "sect2.key5" );
87 REQUIRE( val == "val5" );
88 }
89
90 WHEN( "sections, repeated keys still unique within sections" )
91 {
92 writeConfigFile( "/tmp/test.conf",
93 { "", "", "sect1", "sect1", "sect2", "sect2" },
94 { "key0", "key1", "key2", "key3", "key2", "key3" },
95 { "val0", "val1", "val2", "val3", "val4", "val5" } );
96
98 config.add( "key0", "", "", 0, "", "key0", false, "", "" );
99 config.add( "key1", "", "", 0, "", "key1", false, "", "" );
100 config.add( "sect1.key2", "", "", 0, "sect1", "key2", false, "", "" );
101 config.add( "sect1.key3", "", "", 0, "sect1", "key3", false, "", "" );
102 config.add( "sect2.key2", "", "", 0, "sect2", "key2", false, "", "" );
103 config.add( "sect2.key3", "", "", 0, "sect2", "key3", false, "", "" );
104
105 config.readConfig( "/tmp/test.conf" );
106
107 std::string val;
108
109 config( val, "key0" );
110 REQUIRE( val == "val0" );
111
112 config( val, "key1" );
113 REQUIRE( val == "val1" );
114
115 config( val, "sect1.key2" );
116 REQUIRE( val == "val2" );
117
118 config( val, "sect1.key3" );
119 REQUIRE( val == "val3" );
120
121 config( val, "sect2.key2" );
122 REQUIRE( val == "val4" );
123
124 config( val, "sect2.key3" );
125 REQUIRE( val == "val5" );
126 }
127 }
128
129 GIVEN( "a config file with unused entries" )
130 {
131
132 WHEN( "no sections, unused entry in middle" )
133 {
134 writeConfigFile( "/tmp/test.conf",
135 { "", "", "", "", "", "" },
136 { "key0", "key1", "key2", "key3", "key4", "key5" },
137 { "val0", "val1", "val2", "val3", "val4", "val5" } );
138
140 config.add( "key0", "", "", 0, "", "key0", false, "", "" );
141 config.add( "key1", "", "", 0, "", "key1", false, "", "" );
142 config.add( "key2", "", "", 0, "", "key2", false, "", "" );
143 config.add( "key4", "", "", 0, "", "key4", false, "", "" );
144 config.add( "key5", "", "", 0, "", "key5", false, "", "" );
145
146 config.readConfig( "/tmp/test.conf" );
147
148 std::string val;
149
150 // Check normal parsing
151 config( val, "key0" );
152 REQUIRE( val == "val0" );
153
154 config( val, "key1" );
155 REQUIRE( val == "val1" );
156
157 config( val, "key2" );
158 REQUIRE( val == "val2" );
159
160 config( val, "key4" );
161 REQUIRE( val == "val4" );
162
163 config( val, "key5" );
164 REQUIRE( val == "val5" );
165
166 // Check taht the unused on is unused
167 REQUIRE( config.m_unusedConfigs[iniFile::makeKey( "", "key3" )].used == false );
168
169 // Check that the unused one is available.
170 config.configUnused( val, "", "key3" );
171 REQUIRE( val == "val3" );
172
173 // Check taht the unused on is now used
174 REQUIRE( config.m_unusedConfigs[iniFile::makeKey( "", "key3" )].used == true );
175 }
176
177 WHEN( "sections, repeated keys, unused sections" )
178 {
179 writeConfigFile( "/tmp/test.conf",
180 { "", "", "sect1", "sect1", "sect2", "sect2", "sect3" },
181 { "key0", "key1", "key2", "key3", "key2", "key3", "key4" },
182 { "val0", "val1", "val2", "val3", "val4", "val5", "val6" } );
183
185 config.add( "key0", "", "", 0, "", "key0", false, "", "" );
186 config.add( "key1", "", "", 0, "", "key1", false, "", "" );
187 config.add( "sect2.key2", "", "", 0, "sect2", "key2", false, "", "" );
188 config.add( "sect2.key3", "", "", 0, "sect2", "key3", false, "", "" );
189
190 config.readConfig( "/tmp/test.conf" );
191
192 std::string val;
193
194 config( val, "key0" );
195 REQUIRE( val == "val0" );
196
197 config( val, "key1" );
198 REQUIRE( val == "val1" );
199
200 config( val, "sect2.key2" );
201 REQUIRE( val == "val4" );
202
203 config( val, "sect2.key3" );
204 REQUIRE( val == "val5" );
205
206 config.configUnused( val, "sect1", "key2" );
207 REQUIRE( val == "val2" );
208
209 config.configUnused( val, "sect1", "key3" );
210 REQUIRE( val == "val3" );
211
212 config.configUnused( val, "sect3", "key4" );
213 REQUIRE( val == "val6" );
214
215 std::vector<std::string> sections;
216 config.unusedSections( sections );
217 REQUIRE( sections.size() == 2 );
218 REQUIRE( ( sections[0] == "sect1" || sections[1] == "sect1" ) );
219 REQUIRE( ( sections[0] == "sect3" || sections[1] == "sect3" ) );
220 }
221 }
222
223#if 1
224 GIVEN( "a config file with repeated keys within the same section" )
225 {
226 WHEN( "no sections" )
227 {
228 writeConfigFile( "/tmp/test.conf",
229 { "", "", "", "", "", "" },
230 { "key0", "key0", "key2", "key2", "key4", "key4" },
231 { "val0", "val1", "val2", "val3", "val4", "val5" } );
232
234 config.add( "key0", "", "", 0, "", "key0", false, "", "" );
235 config.add( "key2", "", "", 0, "", "key2", false, "", "" );
236 config.add( "key4", "", "", 0, "", "key4", false, "", "" );
237
238 config.readConfig( "/tmp/test.conf" );
239
240 std::string val;
241
242 config( val, "key0" );
243 REQUIRE( val == "val0val1" );
244
245 config( val, "key2" );
246 REQUIRE( val == "val2val3" );
247
248 config( val, "key4" );
249 REQUIRE( val == "val4val5" );
250 }
251
252 WHEN( "repeated sections and keys" )
253 {
254 writeConfigFile( "/tmp/test7.conf",
255 { "", "sect1", "sect2", "sect1", "sect2", "sect2", "sect3" },
256 { "key0", "key1", "key2", "key1", "key2", "key2", "key3" },
257 { "val0", "val1", "val2", "val3", "val4", "val4.1", "val5" } );
258
260 config.add( "key0", "", "", 0, "", "key0", false, "", "" );
261 config.add( "key1", "", "", 0, "sect1", "key1", false, "", "" );
262 config.add( "key2", "", "", 0, "sect2", "key2", false, "", "" );
263 config.add( "key3", "", "", 0, "sect3", "key3", false, "", "" );
264
265 config.readConfig( "/tmp/test7.conf" );
266
267 std::string val;
268
269 config( val, "key0" );
270 REQUIRE( val == "val0" );
271
272 config( val, "key1" );
273 REQUIRE( val == "val1val3" );
274
275 config( val, "key2" );
276 REQUIRE( val == "val2val4val4.1" );
277
278 config( val, "key3" );
279 REQUIRE( val == "val5" );
280 }
281
282 WHEN( "multi-line keys" )
283 {
284 writeConfigFile( "/tmp/test.conf",
285 { "", "sect1", "sect2", "sect1", "sect2", "sect3" },
286 { "key0", "key1", "key2", "key1", "key2", "key3" },
287 { "val0\n val0.1", "val1", "val2", "val3\n val3.1", "val4", "val5" } );
288
290 config.add( "key0", "", "", 0, "", "key0", false, "", "" );
291 config.add( "key1", "", "", 0, "sect1", "key1", false, "", "" );
292 config.add( "key2", "", "", 0, "sect2", "key2", false, "", "" );
293 config.add( "key3", "", "", 0, "sect3", "key3", false, "", "" );
294
295 config.readConfig( "/tmp/test.conf" );
296
297 std::string val;
298
299 config( val, "key0" );
300 REQUIRE( val == "val0val0.1" );
301
302 config( val, "key1" );
303 REQUIRE( val == "val1val3val3.1" );
304
305 config( val, "key2" );
306 REQUIRE( val == "val2val4" );
307
308 config( val, "key3" );
309 REQUIRE( val == "val5" );
310 }
311 }
312
313 GIVEN( "a config file with vectors" )
314 {
315 WHEN( "no sections" )
316 {
317 writeConfigFile( "/tmp/test.conf",
318 { "", "", "" },
319 { "key0", "key1", "key2" },
320 { "val0,val1,val2", " val3, val4, ", "val5" } );
321
323 config.add( "key0", "", "", 0, "", "key0", false, "", "" );
324 config.add( "key1", "", "", 0, "", "key1", false, "", "" );
325 config.add( "key2", "", "", 0, "", "key2", false, "", "" );
326
327 config.readConfig( "/tmp/test.conf" );
328
329 std::vector<std::string> vals;
330
331 config( vals, "key0" );
332 REQUIRE( vals[0] == "val0" );
333 REQUIRE( vals[1] == "val1" );
334 REQUIRE( vals[2] == "val2" );
335
336 config( vals, "key1" );
337 REQUIRE( vals[0] == "val3" );
338 REQUIRE( vals[1] == "val4" );
339 REQUIRE( vals[2] == "" );
340
341 config( vals, "key2" );
342 REQUIRE( vals[0] == "val5" );
343 }
344 }
345#endif
346}
void writeConfigFile(const std::string &fname, const std::vector< std::string > &sections, const std::vector< std::string > &keywords, const std::vector< std::string > &values)
A simple config file writing function, useful for testing.
Class to manage a set of configurable values, and read their values from config/ini files and the com...
void add(const configTarget &tgt)
Add a configTarget.
static std::string makeKey(const std::string &section, const std::string &name)
Return a key generated from the section and name.
Definition iniFile.hpp:57