root/trunk/examples/util/config/FunctionTest.d

Revision 39, 49.9 kB (checked in by aarti_pl, 2 years ago)

- updated licences
- database package updates

Line 
1 /*******************************************************************************
2
3     License:    Boost Software License, v. 1.0
4                 Academic Free License, v. 3.0
5                 BSD License
6
7     Authors:    Marcin Kuszczak, www.zapytajmnie.com (author's christian site)
8                 This software is inspired and partially based on Boost C++
9                 library named 'program_options' and created by Vladimir Prus.
10
11     Version:    0.9.1
12     Date:       30-Apr-2008
13
14     History:    0.9.0 (08-Oct-2007) -   initial public version
15
16     Description:
17                 Function test module
18
19  ******************************************************************************/
20
21 import std.stdio;
22 import std.string;
23 import std2.conv;
24
25 import doost.core.Any;
26 import doost.util.DUnit;
27 import doost.util.config.ProgramOptions;        //Always
28 import doost.util.config.CommandLineStorage;    //Only if backend is necessary
29 import doost.util.config.ConfigFileStorage;     //Only if backend is necessary
30 import doost.util.config.EnvironmentStorage;    //Only if backend is necessary
31 import doost.util.config.DbStorage;             //Only if backend is necessary
32 import doost.util.config.Formatter;             //Only for non-standard output
33                                                 //description and for user defined
34                                                 //formatters
35
36 //import doost.util.config.Value;
37
38 version(ddbi_v62) {
39     import dbi.Database;
40     import dbi.Row;
41     import dbi.sqlite.SqliteDatabase;
42 }
43
44 //------------------------------------------------------------------------------
45
46 class MyVal {
47     this(int v) {
48         this.v=v;
49     }
50     int opEquals(MyVal v) {
51         assert(v !is null);
52         return (v.v == this.v);
53     }
54     int v;
55 }
56
57 //------------------------------------------------------------------------------
58 MyVal parseMyValue(string s) {
59     int val;
60     try {
61         val=to!(int)(s);
62     } catch (Exception) {
63         throw new InvalidOptionValueException(s);
64     }
65     return new MyVal(val);
66 }
67
68 //------------------------------------------------------------------------------
69
70 unittest {
71     testSuite.begin("ProgramOptions");
72 }
73
74 //------------------------------------------------------------------------------
75
76 unittest { testCase.execute("Opt.Description - regular options", {
77     RegularOptions ro;
78
79     ro = new RegularOptions("Command line");
80     ro.options()
81         ("help,h", "produce help message")
82         ("doTheTest,d", "maketest")
83         ("doTheCoffee,f", "makecoffee")
84         ("doTheTea,a", define!(bool)("tak|ok|1|włÄ
85 cz"), "maketea")
86         ("turnItOn,r", boolSwitch, "makecoffee")
87         ("compression,c", define!(int), "set compression level")
88         ("title,t", define!(char[]).defaultValue("title"), "set title of window")
89         ("include,i", define!(char[][]).composing.defaultValue(["default1"[], "default2"]), "include paths")
90         ("myVal", define!(MyVal).parser(&parseMyValue), "include paths")
91         ("firstname", define!(char[][]).composing, "firstname")
92         ("secondname", define!(char[][]).composing, "secondname")
93         ("nickname,n", define!(char[][]).composing, "nickname")
94         ("date", define!(char[])(r"\d\d\d\d-\d?\d-\d?\d"), "date of birth")
95         ("regexp[ression]*,g", define!(char[]), "regular expression", new RegExpOption)
96         ("number\\d\\d", define!(byte), "following numbers", new RegExpOption)
97         ("int,p", define!(char[])(r"\d\d\d"), new RegExpOption)
98         ("string,s", define!(char[]), "text parameter")
99         ("other,o", define!(double), "other parameter")
100         //Only alias option
101         (",J", define!(char[][]), "import paths")
102     ;
103 });}
104
105 //------------------------------------------------------------------------------
106
107 unittest { testCase.execute("Opt.Description - adding groups", {
108     RegularOptions ro, ro1, ro2;
109     string real_desc, expc_desc;
110
111
112     ro = new RegularOptions("First group");
113     ro.options()
114         ("help,h", "produce help message")
115         ("compression,c", define!(uint), "compression level")
116         ("date", define!(char[]), "start date")
117     ;
118
119     ro1 = new RegularOptions("Second group");
120     ro1.options()
121         ("title,t", define!(char[]), "window title")
122         ("process,p", define!(uint), "process number")
123     ;
124
125     ro2 = new RegularOptions("All options");
126     ro2.add(ro).add(ro1);
127
128     ro2 = new RegularOptions("All options");
129     ro2.add(ro, ro1);
130
131     ro2 = new RegularOptions("All options");
132     ro2.options()
133             (ro)
134             (ro1)
135     ;
136
137     real_desc = ro2.toString;
138     //std.file.write("ro2.txt", cast(void[])real_desc);
139     expc_desc ="
140         All options
141
142         First group
143             help                  produce help message
144             compression arg       compression level
145             date arg              start date
146
147         Second group
148             title arg             window title
149             process arg           process number
150     ";
151
152     //writefln("\n", real_desc);
153     assert(removechars(real_desc, " \t\n\r") == removechars(expc_desc, " \t\n\r"));
154
155     ro2 = new RegularOptions("All options");
156     ro2.options()
157         ("firstname", define!(char[][]).composing, "firstname")
158         ("secondname", define!(char[][]).composing, "secondname")
159         (ro)
160         (ro1);
161
162     real_desc = ro2.toString;
163     //std.file.write("ro2.txt", cast(void[])real_desc);
164     expc_desc ="
165         All options
166             firstname arg         firstname
167             secondname arg        secondname
168
169         First group
170             help                  produce help message
171             compression arg       compression level
172             date arg              start date
173
174         Second group
175             title arg             window title
176             process arg           process number
177     ";
178
179     //writefln("\n", real_desc);
180     assert(removechars(real_desc, " \t\n\r") == removechars(expc_desc, " \t\n\r"));
181 });}
182
183 //------------------------------------------------------------------------------
184
185 unittest { testCase.execute("CL Opt.Description - special CL options", {
186     auto spc = new CommandLineOptions;
187     spc.options()
188         ("selfpath", new SelfPath)
189         ("selfdir", new SelfDir)
190         ("selfname", new SelfName)
191         ("firstname=2, secondname=2, nickname=*", new PositionalOption)
192     ;
193
194 });}
195
196 //------------------------------------------------------------------------------
197
198 unittest { testCase.execute("CL Opt.Description - options sanity", {
199     RegularOptions ro;
200     CommandLineOptions clo;
201
202     assert(checkAssert({
203         ro = new RegularOptions;
204         ro.options()
205             ("title,t", define!(char[]), "window title")
206             ("process,t", define!(uint), "process number")
207         ;
208     }));
209
210     assert(checkAssert({
211         ro = new RegularOptions;
212         ro.options()
213             ("title", define!(char[]), "window title")
214             ("title,t", define!(uint), "process number")
215         ;
216     }));
217
218     assert(checkAssert({
219         ro = new RegularOptions;
220         ro.options()
221             ("title", define!(char[]), "window title")
222             ("title,t", define!(uint), "process number")
223         ;
224     }));
225
226     assert(checkAssert({
227         ro = new RegularOptions;
228         ro.options()
229             (".*", define!(char[]), "all other options")
230             (".*", define!(char[]), "other other options")
231         ;
232     }));
233
234     assert(checkAssert({
235         clo = new CommandLineOptions;
236         clo.options()
237             ("selfpath", new SelfPath)
238             ("selfpath", new SelfPath)
239         ;
240     }));
241
242 });}
243
244 //------------------------------------------------------------------------------
245
246 unittest { testCase.execute("CL Storage - lists", {
247     char[][] args;
248     RegularOptions ro;
249     ProgramOptions po;
250
251     args = ["bin", "--help", "--include", "'a','b','c'"];
252
253     ro = new RegularOptions("Command line");
254     ro.options()
255         ("help,h", "produce help message")
256         ("include,i", define!(char[][]).composing.defaultValue(["default1"[], "default2"]), "include paths")
257         ("firstname", define!(char[][]).composing, "firstname")
258         ("secondname", define!(char[][]).composing, "secondname")
259         ("nickname,n", define!(char[][]).composing, "nickname")
260     ;
261
262     po = (new ProgramOptions).next(
263             new CommandLineStorage(args, ro)
264          );
265
266     po.connect;
267     assert(("help" in po) !is null);
268     assert(checkException!(UnknownOptionException)({"blah" in po; }));
269
270     assert(po["include"].as!(char[][]) == ["a", "b", "c"]);
271     po.disconnect;
272
273     args = ["bin", "--include", "a,b,c", "--firstname=Anita , 'Ewa Krystyna', Paulina",
274     "--secondname", "'Korwin\\tMikke'", "-n[Aarti, Bono, Bruce]"];
275     po.storage!(CommandLineStorage).args(args);
276
277     po.connect;
278
279     trace(po["include"].as!(char[][]));
280     assert(po["include"].as!(char[][]) == ["a", "b", "c"]);
281     assert(po["firstname"].as!(char[][]) == ["Anita", "Ewa Krystyna", "Paulina"]);
282     trace(po["secondname"].as!(char[][]));
283     assert(po["secondname"].as!(char[][]) == ["Korwin\tMikke"]);
284     trace(po["nickname"].as!(char[][]));
285     assert(po["nickname"].as!(char[][]) == ["Aarti", "Bono", "Bruce"]);
286
287     po.disconnect;
288 });}
289
290 //------------------------------------------------------------------------------
291
292 unittest { testCase.execute("CL Storage - long/short options", {
293     char[][] args;
294     RegularOptions ro;
295     ProgramOptions po;
296
297     args = ["bin", "-rh"];
298
299     ro = new RegularOptions("Command line");
300     ro.options()
301         ("help,h", "produce help message")
302         ("turnItOn,r", boolSwitch, "makecoffee")
303     ;
304
305     po = (new ProgramOptions).next(
306             new CommandLineStorage(args, ro)
307          );
308
309     po.connect;
310     assert(("help" in po) !is null);
311     assert(("turnItOn" in po) !is null);
312     po.disconnect;
313
314     po.connect;
315     po.disconnect;
316 });}
317
318 //------------------------------------------------------------------------------
319
320 unittest { testCase.execute("CL Storage - response files", {
321     void[] buffer;
322     char[][] args;
323     RegularOptions ro;
324     ProgramOptions po;
325
326     buffer = cast(void[]) "-r \n--date=1975-07-04 \r\n --firstname=Ala,Ola,Sylwia
327     --secondname \n[Atkinson, Bullock]";
328
329     std.file.write("options.rsp", buffer);
330     scope(exit) std.file.remove("options.rsp");
331
332     args = ["bin", "@options.rsp"];
333
334     ro = new RegularOptions("Command line");
335     ro.options()
336         ("turnItOn,r", boolSwitch, "makecoffee")
337         ("date", define!(char[])(r"\d\d\d\d-\d?\d-\d?\d"), "date of birth")
338         ("firstname", define!(char[][]).composing, "firstname")
339         ("secondname", define!(char[][]).composing, "secondname")
340     ;
341
342     po = (new ProgramOptions).next(
343             new CommandLineStorage(args, ro)
344          );
345
346     po.connect;
347
348     assert(("turnItOn" in po) !is null);
349     assert(po["date"].as!(char[]) == "1975-07-04");
350     assert(po["firstname"].as!(char[][]) == ["Ala", "Ola", "Sylwia"]);
351     assert(po["secondname"].as!(char[][]) == ["Atkinson", "Bullock"]);
352
353     po.disconnect;
354 });}
355
356 //------------------------------------------------------------------------------
357
358 unittest { testCase.execute("CL Storage - custom values", {
359     char[][] args;
360     RegularOptions ro;
361     ProgramOptions po;
362
363     ro = new RegularOptions("Command line");
364     ro.options()
365         ("help,h", "produce help message")
366         ("compression,c", define!(int), "set compression level")
367         ("title,t", define!(char[]).defaultValue("title"), "set title of window")
368         ("doTheTest,d", "maketest")
369         ("myVal", define!(MyVal).parser(&parseMyValue), "include paths")
370     ;
371
372     args = ["bin", "--compression=8", "--myVal=7", "--help"];
373     po = (new ProgramOptions).next(
374             new CommandLineStorage(args, ro)
375          );
376
377     po.connect;
378
379     assert(("compression" in po) !is null);
380     assert(("doTheTest" in po) is null);
381     assert(po["compression"].as!(int) == 8);
382     assert(("title" in po) !is null);
383     assert(po["title"].as!(char[]) == "title");
384     assert(po["myVal"].as!(MyVal) == new MyVal(7));
385     po.disconnect;
386 });}
387
388 //------------------------------------------------------------------------------
389
390 unittest { testCase.execute("CL Storage - self path", {
391     char[][] args;
392     string str1, str2, str3;
393     RegularOptions ro;
394     CommandLineOptions clo;
395     ProgramOptions po;
396
397     version(linux) {
398         args = ["/usr/local/bin/potest", "--compression=8"];
399         str1 = "/usr/local/bin/potest";
400         str2 = "/usr/local/bin";
401         str3 = "potest";
402     } else
403     version(Win32) {
404         args = [r"C:\directory\file.exe", "--compression=8"];
405         str1 = r"C:\directory\file.exe";
406         str2 = r"C:\directory";
407         str3 = r"file.exe";
408     }
409
410     ro = new RegularOptions("Command line");
411     ro.options()
412         ("help,h", "produce help message")
413         ("compression,c", define!(int), "set compression level")
414     ;
415
416     clo = new CommandLineOptions;
417     clo.options()
418         ("selfpath", new SelfPath)
419         ("selfdir", new SelfDir)
420         ("selfname", new SelfName)
421     ;
422
423     po = (new ProgramOptions).next(
424             (new CommandLineStorage(args))
425                 .options(ro, clo)
426          );
427
428     po.connect;
429     assert(("selfpath" in po) !is null);
430     trace(po["selfpath"].as!(char[]));
431     assert(po["selfpath"].as!(char[]) == str1);
432     assert(("selfdir" in po) !is null);
433     assert(po["selfdir"].as!(char[]) == str2);
434     assert(("selfname" in po) !is null);
435     assert(po["selfname"].as!(char[]) == str3);
436     po.disconnect;
437 });}
438
439 //------------------------------------------------------------------------------
440
441 unittest { testCase.execute("CL Storage - synchronization", {
442     char[][] args;
443     RegularOptions ro;
444     ProgramOptions po;
445
446     ro = new RegularOptions("Command line");
447     ro.options()
448         ("help,h", "produce help message")
449         ("compression,c", define!(int), "set compression level")
450         ("title,t", define!(char[]).defaultValue("title"), "set title of window")
451         ("doTheTest,d", "maketest")
452     ;
453
454     args = ["bin", "--compression=8"];
455     po = (new ProgramOptions).next(
456             new CommandLineStorage(args, ro)
457          );
458     po.connect;
459     assert(po.storage!(CommandLineStorage).syncPolicy == SyncPolicy.Cached);
460     assert(po.storage!(CommandLineStorage).defaultSyncPolicy == SyncPolicy.Cached);
461     po.disconnect;
462 });}
463
464 //------------------------------------------------------------------------------
465
466 unittest { testCase.execute("CL Storage - constraints", {
467     char[][] args;
468     RegularOptions ro;
469     ProgramOptions po;
470
471     args = ["bin", "-i/usr/local", "-i/usr/", "-i/bin/", "--compression=9", "--title='Alien'"];
472
473     ro = new RegularOptions("Command line");
474     ro.options()
475         ("compression,c", define!(int), "set compression level")
476         ("title,t", define!(char[]).defaultValue("title"), "set title of window")
477         ("doTheTest,d", "maketest")
478         ("include,i", define!(char[][]).composing.defaultValue(["default1"[], "default2"]), "include paths")
479         ("myVal", define!(MyVal).parser(&parseMyValue), "include paths")
480         ("int,p", define!(char[])(r"\d\d\d"), new RegExpOption)
481         ("string,s", define!(char[]), "text parameter")
482         ("firstname", define!(char[][]).composing, "firstname")
483         ("secondname", define!(char[][]).composing, "secondname")
484         ("nickname,n", define!(char[][]).composing, "nickname")
485     ;
486
487     po = (new ProgramOptions).next(
488             new CommandLineStorage(args, ro)
489          );
490
491     po.connect;
492
493     assert(checkException!(ConstraintViolationException)({obligatoryOptions(po, ["int"]);}));
494     assert(checkException!(ConstraintViolationException)({obligatoryOptions(po.storage!(CommandLineStorage), ["int"]);}));
495     assert(checkException!(ConstraintViolationException)({conflictingOptions(po.storage!(CommandLineStorage), "compression", "title");}));
496     conflictingOptions(po.storage!(CommandLineStorage), "compression", "myVal");
497     assert(checkException!(ConstraintViolationException)({dependantOptions(po.storage!(CommandLineStorage), "compression", "string");}));
498
499     po.disconnect;
500 });}
501
502 //------------------------------------------------------------------------------
503
504 //TODO: additional test case: connect - disconnect - connect again - disconnect
505
506 unittest { testCase.execute("CL Storage - input options composing", {
507     char[][] args;
508     RegularOptions ro;
509     ProgramOptions po;
510
511     ro = new RegularOptions("Command line");
512     ro.options()
513         ("compression,c", define!(int), "set compression level")
514         ("title,t", define!(char[]).defaultValue("title"), "set title of window")
515         ("doTheTest,d", "maketest")
516         ("include,i", define!(char[][]).composing.defaultValue(["default1"[], "default2"]), "include paths")
517         ("int,p", define!(char[])(r"\d\d\d"), new RegExpOption)
518         ("string,s", define!(char[]), "text parameter")
519         ("firstname", define!(char[][]).composing, "firstname")
520         ("secondname", define!(char[][]).composing, "secondname")
521         ("nickname,n", define!(char[][]).composing, "nickname")
522     ;
523
524     args = ["bin", "-i/usr/local", "-i/usr/", "-i/bin/", "--int=265"];
525
526     po = (new ProgramOptions).next(
527             new CommandLineStorage(args, ro)
528          );
529
530     po.storage!(CommandLineStorage).args(args);
531     po.connect;
532
533     // compression is not passed as arguments, so below exception should be thrown
534     assert(checkException!(OptionHasNoValueException)({po["compression"];}));
535     assert(("compression" in po.storage!(CommandLineStorage)) is null);
536     assert(checkException!(OptionHasNoValueException)({po.storage!(CommandLineStorage)["compression"];}));
537     trace(po["include"].as!(char[][]));
538     assert(po["include"].as!(char[][]) == ["/usr/local", "/usr/", "/bin/"]);
539     po.disconnect;
540 });}
541
542 //------------------------------------------------------------------------------
543
544 unittest { testCase.execute("CL Storage - positional options", {
545     char[][] args;
546     RegularOptions ro;
547     CommandLineOptions clo;
548     ProgramOptions po;
549
550     ro = new RegularOptions("Command line");
551     ro.options()
552         ("compression,c", define!(int), "set compression level")
553         ("title,t", define!(char[]).defaultValue("title"), "set title of window")
554         ("doTheTest,d", "maketest")
555         ("include,i", define!(char[][]).composing.defaultValue(["default1"[], "default2"]), "include paths")
556         ("int,p", define!(char[])(r"\d\d\d"), new RegExpOption)
557         ("string,s", define!(char[]), "text parameter")
558         ("firstname", define!(char[][]).composing, "firstname")
559         ("secondname", define!(char[][]).composing, "secondname")
560         ("nickname,n", define!(char[][]).composing, "nickname")
561     ;
562
563     clo = new CommandLineOptions;
564     clo.options()
565         ("firstname=2, secondname=2, nickname=*", new PositionalOption)
566     ;
567
568     args = ["bin", "Ala", "Ola", "Kowalska", "Nowak", "Aarti_pl"];
569     po = (new ProgramOptions).next(
570             (new CommandLineStorage(args))
571                 .options(ro, clo)
572          );
573
574     po.connect;
575     assert(po["firstname"].as!(char[][]) == ["Ala", "Ola"]);
576     assert(po["secondname"].as!(char[][]) == ["Kowalska", "Nowak"]);
577     assert(po["nickname"].as!(char[][]) == ["Aarti_pl"]);
578     po.disconnect;
579 });}
580
581 //------------------------------------------------------------------------------
582
583 unittest { testCase.execute("CL Storage - regular expression options", {
584     char[][] args;
585     RegularOptions ro;
586     CommandLineOptions clo;
587     ProgramOptions po;
588
589     args = ["bin", "--compression", "8", "--string", "'D language'", "--regexpression=regexpstring", "--date=1975-7-4"];
590
591     ro = new RegularOptions("Command line");
592     ro.options()
593         ("doTheTest,d", "maketest")
594         ("doTheCoffee,f", "makecoffee")
595         ("doTheTea,a", define!(bool)("tak|ok|1|włÄ
596 cz|nie|0|wyłÄ
597 cz"), "maketea")
598         ("turnItOn,r", boolSwitch, "makecoffee")
599         ("compression,c", define!(int), "set compression level")
600         ("title,t", define!(char[]).defaultValue("title"), "set title of window")
601         ("include,i", define!(char[][]).composing.defaultValue(["default1"[], "default2"]), "include paths")
602         ("firstname", define!(char[][]).composing, "firstname")
603         ("secondname", define!(char[][]).composing, "secondname")
604         ("nickname,n", define!(char[][]).composing, "nickname")
605         ("date", define!(char[])(r"\d\d\d\d-\d?\d-\d?\d"), "date of birth")
606         ("regexp[ression]*,g", define!(char[]), "regular expression", new RegExpOption)
607         ("number\\d\\d", define!(byte), "following numbers", new RegExpOption)
608         ("int,p", define!(char[])(r"\d\d\d"), new RegExpOption)
609         ("string,s", define!(char[]), "text parameter")
610         ("other,o", define!(double), "other parameter")
611         //Only alias name
612         (",J", define!(char[][]), "import paths")
613     ;
614
615     clo = new CommandLineOptions;
616     clo.options()
617         ("firstname=2, secondname=2, nickname=*", new PositionalOption)
618     ;
619
620     po = (new ProgramOptions).next(
621             (new CommandLineStorage(args))
622                 .options(ro, clo)
623          );
624
625     po.connect;
626
627     assert(("regexpression" in po) !is null);
628     assert(po["regexpression"].as!(char[]) == "regexpstring");
629     assert(po["compression"].as!(int) == 8);
630     assert(po["date"].as!(char[]) == "1975-7-4");
631     trace(po["string"].as!(char[]));
632     assert(po["string"].as!(char[]) == "D language");
633
634     po.disconnect;
635
636     args = ["bin", "--regexp=regexpstring", "--number00=34", "--number01=35",
637             "--date=1975-07-04", "-c5", "-ttitle", "-df", "--doTheTea=włÄ
638 cz"];
639     po.storage!(CommandLineStorage).args(args);
640
641     po.connect;
642
643     assert(("date" in po) !is null);
644     assert(po["date"].as!(char[]) == "1975-07-04");
645     assert(("regexp" in po) !is null);
646     assert(po["regexp"].as!(char[]) == "regexpstring");
647     assert(("number00" in po) !is null);
648     assert(po["number00"].as!(byte) == 34);
649     assert(("number01" in po) !is null);
650     assert(po["number01"].as!(byte) == 35);
651     assert(("compression" in po) !is null);
652     assert(po["compression"].as!(int) == 5);
653     assert(("title" in po) !is null);
654     assert(po["title"].as!(char[]) == "title");
655     assert(("doTheTest" in po) !is null);
656     assert(("doTheCoffee" in po) !is null);
657     assert(("doTheTea" in po) !is null);
658     assert(po["doTheTea"].as!(bool) == true);
659     assert(checkException!(UnknownOptionException)({"blah" in po; }));
660
661     po.disconnect;
662 });}
663
664 //------------------------------------------------------------------------------
665
666 unittest { testCase.execute("CL Storage - option styles", {
667     char[][] args;
668     RegularOptions ro;
669     ProgramOptions po;
670
671     //guessing, caseinsensitive
672     args = ["bin", "--turnI", "--oth=0.577215664901532", "--dothetea=ok",
673     "--dothecoffee"];
674
675     ro = new RegularOptions("Command line");
676     ro.options()
677         ("help,h", "produce help message")
678         ("doTheTest,d", "maketest")
679         ("doTheCoffee,f", "makecoffee")
680         ("doTheTea,a", define!(bool)("tak|ok|1|włÄ
681 cz"), "maketea")
682         ("turnItOn,r", boolSwitch, "makecoffee")
683         ("compression,c", define!(int), "set compression level")
684         ("title,t", define!(char[]).defaultValue("title"), "set title of window")
685         ("include,i", define!(char[][]).composing.defaultValue(["default1"[], "default2"]), "include paths")
686         ("firstname", define!(char[][]).composing, "firstname")
687         ("secondname", define!(char[][]).composing, "secondname")
688         ("nickname,n", define!(char[][]).composing, "nickname")
689         ("date", define!(char[])(r"\d\d\d\d-\d?\d-\d?\d"), "date of birth")
690         ("regexp[ression]*,g", define!(char[]), "regular expression", new RegExpOption)
691         ("number\\d\\d", define!(byte), "following numbers", new RegExpOption)
692         ("int,p", define!(char[])(r"\d\d\d"), new RegExpOption)
693         ("string,s", define!(char[]), "text parameter")
694         ("other,o", define!(double), "other parameter")
695         //Only alias name
696         (",J", define!(char[][]), "import paths")
697     ;
698
699     po = (new ProgramOptions).next(
700             (new CommandLineStorage(args, ro))
701                 .style(Style.DefaultStyle | Style.AllowLongInsensitive)
702          );
703
704     po.connect;
705     assert(("turnItOn" in po) !is null);
706     assert(po["turnItOn"].as!(bool) == true);
707     assert(po["doTheTea"].as!(bool) == true);
708     assert(("doTheCoffee" in po) !is null);
709     assert(("other" in po) !is null);
710     assert(po["other"].as!(double) == 0.577215664901532);
711     po.disconnect;
712
713     //long disguised, guessing, lack of first is self
714     args = ["-compression=8", "-tit=1984"];
715
716     ro = new RegularOptions("Command line");
717     ro.options()
718         ("help,h", "produce help message")
719         ("doTheTest,d", "maketest")
720         ("doTheCoffee,f", "makecoffee")
721         ("doTheTea,a", define!(bool)("tak|ok|1|włÄ
722 cz"), "maketea")
723         ("turnItOn,r", boolSwitch, "makecoffee")
724         ("compression,c", define!(int), "set compression level")
725         ("title,t", define!(char[]).defaultValue("title"), "set title of window")
726         ("include,i", define!(char[][]).composing.defaultValue(["default1"[], "default2"]), "include paths")
727         ("firstname", define!(char[][]).composing, "firstname")
728         ("secondname", define!(char[][]).composing, "secondname")
729         ("nickname,n", define!(char[][]).composing, "nickname")
730         ("date", define!(char[])(r"\d\d\d\d-\d?\d-\d?\d"), "date of birth")
731         ("regexp[ression]*,g", define!(char[]), "regular expression", new RegExpOption)
732         ("number\\d\\d", define!(byte), "following numbers", new RegExpOption)
733         ("int,p", define!(char[])(r"\d\d\d"), new RegExpOption)
734         ("string,s", define!(char[]), "text parameter")
735         ("other,o", define!(double), "other parameter")
736         //Only alias name
737         (",J", define!(char[][]), "import paths")
738     ;
739
740     po =    (new ProgramOptions)
741                 .next(
742             (new CommandLineStorage(args))
743                 .options(ro)
744                 .style(Style.AllowLong | Style.AllowLongAdjacent | Style.AllowLongDisguise
745                     | Style.AllowLongGuessing)
746             );
747
748     po.connect;
749
750     assert(po["compression"].as!(int) == 8);
751     assert(po["title"].as!(char[]) == "1984");
752
753     po.disconnect;
754 });}
755
756 //------------------------------------------------------------------------------
757
758 unittest { testCase.execute("Config file", {
759     void[] buffer;
760     string real_desc, expc_desc;
761     RegularOptions ro;
762     ProgramOptions po;
763
764     ro = new RegularOptions("File storage");
765     ro.options()
766         ("compression", define!(int), "set compression level")
767         ("author", define!(char[]).defaultValue("drX"), "name of author")
768         ("include,i", define!(char[][]).composing, "include paths")
769         ("myname", define!(char[]), "name")
770         ("database.user", define!(char[]), "Database User")
771         ("database.password", define!(char[]), "Database Password")
772         ("database.ip", define!(char[])(r"[0|1|2]?\d?\d\.[0|1|2]?\d?\d\.[0|1|2]?\d?\d\.[0|1|2]?\d?\d"), "Database IP")
773         ("interaction.help", "activate help")
774         ("interaction.tips", "activate tips")
775         ("interaction.balloons", "activate balloons")
776     ;
777
778     buffer = cast(void[])
779 "compression=6 # Kompresja pliku
780 author=Szklarski # Autor ksiÄ
781 ÅŒki
782 include=/usr/local/import/
783
784 [interaction]
785 balloons # Activate ballons
786 ";
787
788     std.file.write("test01.cfg", buffer);
789     scope(exit) std.file.remove("test01.cfg");
790
791     po = (new ProgramOptions)
792             .next(
793          (new ConfigFileStorage("test01.cfg"))
794             .options(ro)
795          );
796
797     po.connect;
798
799     assert(po["compression"].as!(int) == 6);
800     po["compression"] = any!(int)(18);
801     po["database.ip"]= any!(char[])("127.0.0.1");
802     po["database.user"]= any!(char[])("marcin");
803     po["database.password"]= any!(char[])("******");
804     assert(po["compression"].as!(int) == 18);
805     assert(po["database.ip"].as!(char[]) == "127.0.0.1"[]);
806
807     po.synchronize;
808     po.syncPolicy(SyncPolicy.Direct);
809
810     assert(po["compression"].as!(int) == 18);
811     assert(po["database.ip"].as!(char[]) == "127.0.0.1"[]);
812     assert(po["database.user"].as!(char[]) == "marcin"[]);
813     assert(po["database.password"].as!(char[]) == "******"[]);
814     assert("interaction.balloons" in po);
815     assert(po["author"].as!(char[]) == "Szklarski");
816     po["author"] = any!(char[])("Niziurski");
817     assert(po["author"].as!(char[]) == "Niziurski");
818
819     po.syncPolicy(SyncPolicy.Cached);
820
821     assert(po["include"].as!(char[][]) == ["/usr/local/import/"]);
822     po.storage!(ConfigFileStorage)()["include"] = any!(char[][])(["/usr/local/bin/", "/bin/", "/usr/bin/"]);
823
824     po.synchronize;
825
826     assert(po["include"].as!(char[][]) == ["/usr/local/bin/", "/bin/", "/usr/bin/"]);
827     po["myname"] = any!(char[])("Aarti_pl");
828
829     po.synchronize;
830     assert(po["myname"].as!(char[]) == "Aarti_pl");
831
832     real_desc = cast(char[])std.file.read("test01.cfg");
833     expc_desc =
834 "compression = 18 # Kompresja pliku
835 author = \"Niziurski\" # Autor ksiÄ
836 ÅŒki
837 include = \"/usr/local/bin/\", \"/bin/\", \"/usr/bin/\"
838 myname = \"Aarti_pl\"
839
840 [interaction]
841 balloons                                  # Activate ballons
842
843 [database]
844 ip = \"127.0.0.1\"
845 user = \"marcin\"
846 password = \"******\"
847 ";
848
849     assert(removechars(real_desc, " \t\n\r") == removechars(expc_desc, " \t\n\r"));
850
851     po.storage!(ConfigFileStorage).remove("author");
852     po.synchronize;
853
854     real_desc = cast(char[])std.file.read("test01.cfg");
855     expc_desc =
856 "compression = 18 # Kompresja pliku
857 include = \"/usr/local/bin/\", \"/bin/\", \"/usr/bin/\"
858 myname = \"Aarti_pl\"
859
860 [interaction]
861 balloons                       # Activate ballons
862
863 [database]
864 ip = \"127.0.0.1\"
865 user = \"marcin\"
866 password = \"******\"
867 ";
868
869     assert(removechars(real_desc, " \t\n\r") == removechars(expc_desc, " \t\n\r"));
870
871     po.remove("database.password");
872     po.remove("database.ip");
873     po.synchronize;
874
875     real_desc = cast(char[])std.file.read("test01.cfg");
876     expc_desc ="
877         compression = 18 # Kompresja pliku
878         include = \"/usr/local/bin/\", \"/bin/\", \"/usr/bin/\"
879         myname = \"Aarti_pl\"
880         [interaction]
881         balloons                       # Activate ballons
882         [database]
883         user = \"marcin\"
884     ";
885
886     assert(removechars(real_desc, " \t\n\r") == removechars(expc_desc, " \t\n\r"));
887
888     po.disconnect;
889
890     po.connect;
891
892     assert(po["compression"].as!(int) == 18);
893     assert(po["myname"].as!(char[]) == "Aarti_pl");
894     po.disconnect;
895
896     buffer = cast(void[])
897 "compression=6 # Kompresja pliku
898 author=Szklarski # Autor ksiÄ
899 ÅŒki
900 include=/usr/local/import/
901 blah=5
902 ";
903
904     std.file.write("test02.cfg", buffer);
905     scope(exit) std.file.remove("test02.cfg");
906
907     po = (new ProgramOptions)
908             .next(
909          (new ConfigFileStorage("test02.cfg"))
910             .options(ro)
911          );
912
913     assert(checkException!(UnknownOptionException)({po.connect;}));
914
915     buffer = cast(void[])
916 "compression=6 # Kompresja pliku
917 author=\"Szklarski\" # Autor ksiÄ
918 ÅŒki
919 include=/usr/local/import/
920 ";
921
922     std.file.write("test03.cfg", buffer);
923     scope(exit) std.file.remove("test03.cfg");
924
925     po = (new ProgramOptions)
926             .next(
927          (new ConfigFileStorage("test03.cfg"))
928             .options(ro)
929             .syncPolicy(SyncPolicy.Direct)
930          );
931
932     po.connect;
933
934     po.storage!(ConfigFileStorage).remove("compression");
935     po.storage!(ConfigFileStorage)()["author"] = any!(char[])("Nienacki");
936     po["database.ip"] = any!(char[])("223.14.80.34");
937     po["database.password"] = any!(char[])("***");
938     po["database.user"] = any!(char[])("Magda");
939     po["interaction.help"] = any!()();
940     po["interaction.tips"] = any!()();
941
942     real_desc = cast(char[])std.file.read("test03.cfg");
943     expc_desc ="
944         author = \"Nienacki\" # Autor ksiÄ
945 ÅŒki
946         include = /usr/local/import/
947
948         [database]
949         ip = \"223.14.80.34\"
950         password = \"***\"
951         user = \"Magda\"
952
953         [interaction]
954         help
955         tips
956     ";
957
958     assert(removechars(real_desc, " \t\n\r") == removechars(expc_desc, " \t\n\r"));
959
960     po.disconnect;
961
962     real_desc = cast(char[])std.file.read("test03.cfg");
963     assert(removechars(real_desc, " \t\n\r") == removechars(expc_desc, " \t\n\r"));
964 });}
965
966 //------------------------------------------------------------------------------
967
968 unittest { testCase.execute("Env variables - simple", {
969     RegularOptions ro;
970     ProgramOptions po;
971
972     ro = new RegularOptions("Environment options");
973     ro.options()
974         ("po_include", define!(char[][]).composing, "include paths")
975         ("po_compiler", define!(char[]).defaultValue("dmd"), "default compiler")
976         ("po_linker", define!(char[]).defaultValue("link"), "default linker")
977         ("po_threads", define!(uint).defaultValue(3), "number of compilation threads")
978     ;
979
980     po = (new ProgramOptions)
981             .next(
982          (new EnvironmentStorage)
983             .options(ro)
984          );
985
986     po.connect;
987
988     assert(!("po_include" in po));
989     assert("po_compiler" in po);
990     assert(po["po_compiler"].as!(char[]) == "dmd");
991     assert("po_linker" in po);
992     assert(po["po_linker"].as!(char[]) == "link");
993     assert("po_threads" in po);
994     assert(po["po_threads"].as!(uint) == 3);
995
996     po["po_compiler"] = any!(char[])("gdb");
997     assert(po["po_compiler"].as!(char[]) == "gdb");
998     po["po_linker"] = any!(char[])("gcc");
999     assert(po["po_linker"].as!(char[]) == "gcc");
1000
1001     po.disconnect;
1002
1003     po.connect;
1004
1005     assert(po["po_compiler"].as!(char[]) == "gdb");
1006     assert(po["po_linker"].as!(char[]) == "gcc");
1007
1008     po.disconnect;
1009 });}
1010
1011 //------------------------------------------------------------------------------
1012
1013 unittest { testCase.execute("Stack", {
1014     int counter, compression;
1015     string real_desc, expc_desc;
1016     string[] args, args1;
1017     void[] buffer, buffer1;
1018     RegularOptions ro, ro1, fil, fil1;
1019     ProgramOptions po;
1020
1021     ro = new RegularOptions("Command line");
1022     ro.options()
1023         ("help,h", "produce help message")
1024         ("compression", define!(int).defaultValue(2), "set compression level")
1025         ("title", define!(char[]).defaultValue("title"), "set title of window")
1026         ("include,i", define!(char[][]).composing, "include paths")
1027     ;
1028
1029     ro1 = new RegularOptions("Command line");
1030     ro1.options()
1031         ("help,h", "produce help message")
1032         ("title", define!(char[]).defaultValue("title"), "set title of window")
1033         ("include,i", define!(char[][]).composing, "include paths")
1034     ;
1035
1036     fil = new RegularOptions("File storage");
1037     fil.options()
1038         ("compression", define!(int), "set compression level")
1039         ("author", define!(char[]).defaultValue("drX"), "name of author")
1040         ("include,i", define!(char[][]).composing, "include paths")
1041     ;
1042
1043     fil1 = new RegularOptions("File storage 1");
1044     fil1.options()
1045         ("comment", define!(char[]).defaultValue("my comment"), "comment to last news")
1046         ("list,l", "list all paths")
1047         ("title", define!(char[]).defaultValue("title"), "title of window")
1048     ;
1049
1050
1051     buffer = cast(void[])
1052 "compression=6
1053 author=Szklarski
1054 include=/usr/local/import/
1055 ";
1056
1057     std.file.write("test04.cfg", buffer);
1058     scope(exit) std.file.remove("test04.cfg");
1059
1060     buffer1 = cast(void[])
1061 "title=mytitle\n";
1062
1063     std.file.write("test05.cfg", buffer1);
1064     scope(exit) std.file.remove("test05.cfg");
1065
1066     args = ["bin", "-i/usr/local", "-i/usr/", "-i/bin/", "-h"];
1067     args1 = ["bin", "-i/usr/local", "-i/usr/", "-i/bin/"];
1068
1069     po = (new ProgramOptions)
1070             .next(
1071          (new CommandLineStorage(args))
1072             .options(ro)
1073             .next(
1074          (new ConfigFileStorage("test04.cfg"))
1075             .options(fil)
1076             .next(
1077          (new ConfigFileStorage("test05.cfg"))
1078             .options(fil1)
1079             .formatter(new BasicFormatter)
1080          )));
1081
1082     counter = 0;
1083     void call(Event e) {
1084         //writefln("Called: ", e.name, " with value: ", e.value.value.type);
1085         counter++;
1086     }
1087
1088     po.callback("compression", [&call, delegate void(Event e) {compression = e.value.as!(int);}]);
1089     po.notifyPolicy(NotifyPolicy.Default | NotifyPolicy.OnSelfModify);
1090
1091     po.connect;
1092     assert(("help" in po) !is null);
1093     assert(("compression" in po) !is null);
1094     assert(po["compression"].as!(int) == 6);
1095     assert(po["author"].as!(char[]) == "Szklarski");
1096
1097     assert(po.composedOptions("include").as!(char[][]) == ["/usr/local", "/usr/", "/bin/", "/usr/local/import/"]);
1098     assert(po.composedOptions("title").as!(char[][]) == ["title", "mytitle"]);
1099
1100     po.storage!(CommandLineStorage)()["compression"] = any!(int)(2);
1101     assert(po.storage!(CommandLineStorage)["compression"].as!(int) == 2);
1102     assert(po["compression"].as!(int) == 2);
1103     po["compression"]=any!(int)(15);
1104     assert(po["compression"].as!(int) == 15);
1105     assert(po.storage!(CommandLineStorage)["compression"].as!(int) == 15);
1106     assert(po.storage!(ConfigFileStorage)["compression"].as!(int) == 15);
1107     po["help"]=any!()();
1108     assert(po["help"] !is null);
1109
1110     real_desc = po.storage!(CommandLineStorage).toString;
1111     expc_desc ="
1112         Command line
1113         -h [--help]              produce help message
1114         --compression arg (=2)   set compression level
1115         --title arg (=\"title\") set title of window
1116         -i [--include] arg       include paths
1117     ";
1118
1119     //writefln(real_desc);
1120     assert(removechars(real_desc, " \t\n\r") == removechars(expc_desc, " \t\n\r"));
1121
1122     real_desc = po.storage!(ConfigFileStorage)().storage!(ConfigFileStorage)().toString;
1123     expc_desc ="
1124         File storage 1
1125         comment arg (=\"my comment\") comment to last news
1126         list                      list all paths
1127         title arg (=\"title\")        title of window
1128     ";
1129     assert(removechars(real_desc, " \t\n\r") == removechars(expc_desc, " \t\n\r"));
1130
1131     real_desc = po.toString;
1132     expc_desc ="
1133         Command line
1134         -h [--help]            produce help message
1135         --compression arg (=2) set compression level
1136         --title arg (=\"title\")   set title of window
1137         -i [--include] arg     include paths
1138
1139         File storage 1
1140         comment arg (=\"my comment\") comment to last news
1141         list                      list all paths
1142         title arg (=\"title\")        title of window
1143     ";
1144
1145     assert(removechars(real_desc, " \t\n\r") == removechars(expc_desc, " \t\n\r"));
1146     //Two hits: po["compression"]=any!(int)(15);
1147     //First hit is for not persistant CommandLineStorage and second one for
1148     //persistant ConfigFileStorage
1149     //po.storage!(CommandLineStorage)()["compression"]=any!(int)(2);
1150     //Above is not counted as assigning replaces default value, which is threated
1151     //as self insert not self modification.
1152
1153     assert(counter == 2);
1154     assert(compression == 15);
1155
1156     assert(po.storage!(ConfigFileStorage)().storage!(ConfigFileStorage)()["title"].as!(char[])=="mytitle");
1157
1158     po.disconnect;
1159
1160     po = (new ProgramOptions)
1161             .next(
1162          (new CommandLineStorage(args1, ro1))
1163          );
1164
1165     po.connect;
1166
1167     assert(checkException!(UnknownOptionException)({po["compression"]=any!(int)(15);}));
1168     assert(("help" in po) is null);
1169
1170     po.disconnect;
1171 });}
1172
1173 //------------------------------------------------------------------------------
1174
1175 unittest { testCase.execute("Stack - options 'Very Easy Init'", {
1176     //Though, you can sometimes get lost in parenthesises ;-)
1177
1178     string[] args;
1179     void[] buffer;
1180     ProgramOptions po;
1181
1182     args = ["bin", "-rh"];
1183
1184     buffer = cast(void[]) "compression=6\n"
1185                           "author=Szklarski\n"
1186                           "include=/usr/local/import/\n";
1187
1188     std.file.write("test10.cfg", buffer);
1189     scope(exit) std.file.remove("test10.cfg");
1190
1191     po =    (new ProgramOptions)
1192                 .caption("pi.exe - program to calculate PI with any precision \n"
1193                          "in less than 1 second. (c)2007 Aarti_pl"
1194                         )
1195                 .next(
1196             (new CommandLineStorage(args))
1197                 .caption("Command line options:\n"
1198                          "usage: pi.exe [options] file1, file2 ...."
1199                         )
1200                 .options()
1201                     ("help,h", "produce help message")
1202                     ("turnItOn,r", boolSwitch, "makecoffee")
1203                     ("selfdir", new SelfDir)
1204                     ("selfname", new SelfName)
1205                     ()
1206                 .next(
1207             (new ConfigFileStorage("test10.cfg"))
1208                 .caption("Config file options:\n"
1209                          "usage: change contents of pi.ini file in program binary directory"
1210                         )
1211                 .options()
1212                     ("compression", define!(int), "set compression level")
1213                     ("author", define!(char[]).defaultValue("drX"), "name of author")
1214                     ("include,i", define!(char[][]).composing, "include paths")
1215                     ()
1216                 .formatter(new BasicFormatter)
1217             ));
1218
1219     po.connect;
1220     assert(("help" in po) !is null);
1221     assert(("turnItOn" in po) !is null);
1222     assert(po["compression"].as!(int) == 6);
1223     po.disconnect;
1224
1225     po.connect;
1226     po.disconnect;
1227 });}
1228
1229 //------------------------------------------------------------------------------
1230
1231 unittest { testCase.execute("Stack - downStackSync", {
1232     void[] buffer, buffer1;
1233     string real_desc, expc_desc;
1234     string[] args;
1235     RegularOptions ro, fil, fil1;
1236     ProgramOptions po;
1237
1238
1239     ro = new RegularOptions("Command line");
1240     ro.options()
1241         ("compression", define!(int).defaultValue(2), "set compression level")
1242     ;
1243
1244     fil = new RegularOptions("File storage");
1245     fil.options()
1246         ("compression", define!(int), "set compression level")
1247     ;
1248
1249     fil1 = new RegularOptions("File storage 1");
1250     fil1.options()
1251         ("comment", define!(char[]).defaultValue("my comment"), "comment to last news")
1252     ;
1253
1254
1255     buffer = cast(void[])
1256 "compression=6\n";
1257
1258     std.file.write("test06.cfg", buffer);
1259     scope(exit) std.file.remove("test06.cfg");
1260
1261     buffer1 = cast(void[]) "";
1262     std.file.write("test07.cfg", buffer1);
1263     scope(exit) std.file.remove("test07.cfg");
1264
1265     args = ["bin", "--compression=128"];
1266
1267     po = (new ProgramOptions)
1268             .next(
1269          (new CommandLineStorage(args))
1270             .options(ro)
1271             .next(
1272          (new ConfigFileStorage("test06.cfg"))
1273             .options(fil)
1274             .next(
1275          (new ConfigFileStorage("test07.cfg"))
1276             .options(fil1)
1277          )));
1278
1279     po.connect;
1280
1281     po.downStackSync("compression");
1282     po.synchronize;
1283
1284     real_desc = cast(char[])std.file.read("test06.cfg");
1285     expc_desc ="compression = 128";
1286     assert(removechars(real_desc, " \t\n\r") == removechars(expc_desc, " \t\n\r"));
1287
1288     po.disconnect;
1289 });}
1290
1291 //------------------------------------------------------------------------------
1292
1293 unittest { testCase.execute("Stack - defined/assigned/collected", {
1294     void[] buffer;
1295     string[] args;
1296     string[] opts1, opts2, opts3;
1297     RegularOptions ro, fil;
1298     ProgramOptions po;
1299
1300     ro = new RegularOptions("Command line");
1301     ro.options()
1302         ("compression", define!(int).defaultValue(2), "set compression level")
1303         ("name", define!(char[]), "name of zip")
1304         ("help,h", "help for options")
1305         (r"chanel\d", define!(int), "chanel number", new RegExpOption)
1306     ;
1307
1308     fil = new RegularOptions("Properties file");
1309     fil.options()
1310         ("compression", define!(int), "set compression level")
1311         ("package", define!(char[]), "package name")
1312         (r"port\d\d\d,h", boolSwitch, "port to activate", new RegExpOption)
1313     ;
1314
1315     buffer = cast(void[])
1316 "compression=6
1317 port128
1318 port024
1319 port228
1320 ";
1321
1322     std.file.write("test08.cfg", buffer);
1323     scope(exit) std.file.remove("test08.cfg");
1324
1325     args = ["bin", "--compression=8", "--help"];
1326
1327     po = (new ProgramOptions)
1328             .next(
1329          (new CommandLineStorage(args))
1330             .options(ro)
1331             .next(
1332          (new ConfigFileStorage("test08.cfg"))
1333             .options(fil)
1334          ));
1335
1336     po.connect;
1337
1338     opts1=po.storage!(CommandLineStorage).definedOptions;
1339     opts2=po.storage!(CommandLineStorage).assignedOptions;
1340     opts3=po.storage!(CommandLineStorage).collectedOptions;
1341     //std.file.write("result1.txt", std.string.format(opts1));
1342     //std.file.write("result2.txt", std.string.format(opts2));
1343     //std.file.write("result3.txt", std.string.format(opts3));
1344     assert(opts1==["compression","name","help", r"chanel\d"]);
1345     assert(opts2==["help","compression"]);
1346     assert(opts3==null);
1347
1348     opts1=po.definedOptions;
1349     opts2=po.assignedOptions;
1350     opts3=po.collectedOptions;
1351     //std.file.write("result1.txt", std.string.format(opts1));
1352     //std.file.write("result2.txt", std.string.format(opts2));
1353     //std.file.write("result3.txt", std.string.format(opts3));
1354     assert(opts1==[r"chanel\d",r"port\d\d\d","help","compression","package","name"]);
1355     assert(opts2==["port128","help","port228","compression","port024"]);
1356     assert(opts3==["port128","port228","port024"]);
1357
1358     po.disconnect;
1359 });}
1360
1361 //------------------------------------------------------------------------------
1362
1363 unittest { testCase.execute("Stack - no args for CL", {
1364     void[] buffer;
1365     string[] args;
1366     RegularOptions ro, fil;
1367     ProgramOptions po;
1368
1369     ro = new RegularOptions("Command line");
1370     ro.options()
1371         ("compression", define!(int).defaultValue(2), "set compression level")
1372         ("name", define!(char[]), "name of zip")
1373         ("help,h", "help for options")
1374         (r"chanel\d", define!(int), "chanel number", new RegExpOption)
1375     ;
1376
1377     fil = new RegularOptions("Properties file");
1378     fil.options()
1379         ("compression", define!(int), "set compression level")
1380         ("package", define!(char[]), "package name")
1381         (r"port\d\d\d,h", boolSwitch, "port to activate", new RegExpOption)
1382     ;
1383
1384     buffer = cast(void[])
1385 "compression=6
1386 port128
1387 port024
1388 port228
1389 ";
1390     std.file.write("test09.cfg", buffer);
1391     scope(exit) std.file.remove("test09.cfg");
1392
1393     args = ["bin"];
1394
1395     po = (new ProgramOptions)
1396             .next(
1397          (new CommandLineStorage(args))
1398             .options(ro)
1399             .next(
1400          (new ConfigFileStorage("test09.cfg"))
1401             .options(fil)
1402          ));
1403
1404     po.connect;
1405
1406     assert(("help" in po) is null);
1407     assert(("name" in po) is null);
1408     assert(("compression" in po) !is null);
1409     assert(po["compression"].as!(int) == 6);
1410
1411     po.disconnect;
1412 });}
1413
1414 //------------------------------------------------------------------------------
1415 //NOTE: to allow following test you should have installed and compilled
1416 //DDBI revision 62 and add '-version=ddbi_v62' to compiler command line
1417 version(ddbi_v62) {
1418 unittest { testCase.execute("DbStorage - basic", {
1419     RegularOptions ro;
1420     ProgramOptions po;
1421
1422     ro = new RegularOptions("Command line");
1423     ro.options()
1424         ("compression", define!(int).defaultValue(2), "set compression level")
1425         ("name", define!(char[]), "name of zip")
1426         ("help,h", "help for options")
1427         (r"chanel\d", define!(int), "chanel number", new RegExpOption)
1428     ;
1429
1430     Database db = new SqliteDatabase("test.db");
1431     scope(exit) db.close;
1432
1433     po = (new ProgramOptions).next(
1434             (new DbStorage(db, "TB_PARAMS", ro))
1435          );
1436
1437     po.connect;
1438
1439     assert(("help" in po) is null);
1440
1441     po["compression"] = any!(int)(52);
1442
1443     assert(("compression" in po) !is null);
1444     assert(po["compression"].as!(int) == 52);
1445
1446     po["name"] = any!(char[])("Aarti_pl");
1447     assert(po["name"].as!(char[]) == "Aarti_pl");
1448
1449     po["name"] = any!(char[])("Wacek");
1450     assert(po["name"].as!(char[]) == "Wacek");
1451
1452     //NOTE: for unknown reasons when using execute() in DbStorage below test fails
1453     foreach(o; po.assignedOptions)
1454         po.remove(o);
1455
1456     assert(po.assignedOptions == null);
1457
1458     po.disconnect;
1459 });}
1460 }
1461
1462 //------------------------------------------------------------------------------
1463
1464 unittest {
1465     testSuite.finish;
1466 }
1467
1468 //------------------------------------------------------------------------------
1469
1470 /*******************************************************************************
1471     Program entry point
1472  ******************************************************************************/
1473 int main(char[][] args) {
1474     try {
1475         char sep = ';';
1476         version(linux) sep=':';
1477
1478         auto po =   (new ProgramOptions)
1479                         .next(
1480                     (new CommandLineStorage(args))
1481                         .caption("Command line options")
1482                         .options()
1483                             ("help,h", "produce help message")
1484                             ("compression", define!(int), "set compression level")
1485                             ("list", define!(int[][]), "complicated list")
1486                             ("sync", "stores given from command line options in persistent backend")
1487                             ()
1488                         .next(
1489                     (new EnvironmentStorage)
1490                         .options()
1491                             ("Path,PATH", define!(char[][]).separator(sep), "paths defined in system")
1492                             ()
1493                         .next(
1494                     (new ConfigFileStorage("file1.cfg"))
1495                         .options()
1496                             ("optimization", define!(int), "level")
1497                             ("include-path", define!(char[][]), "include paths")
1498                             ("compression", define!(int), "set compression level")
1499                             ()
1500                         .next(
1501                     (new ConfigFileStorage("file2.cfg"))
1502                         .options()
1503                             ("name", define!(char[]), "name of game")
1504                             ("pi", define!(double), "value of eternity")
1505                             ()
1506                     ))));
1507
1508         po.connect();
1509
1510         if ("help" in po) {
1511             writefln(po);
1512             return 0;
1513         }
1514
1515         if ("compression" in po) {
1516             writefln("Compression level was set to ", po["compression"]);
1517         } else {
1518             writefln("Compression level was not set.");
1519         }
1520
1521         if ("optimization" in po) {
1522             writefln("Optimization set to: ", po["optimization"]);
1523         }
1524
1525         if ("pi" in po) {
1526             writefln("Pi set to: ", po["pi"]);
1527         }
1528
1529         if ("name" in po) {
1530             writefln("Name set to: ", po["name"]);
1531         }
1532
1533         if ("PATH" in po) {
1534             writefln("\n\nThere are following directories in your system path: \n");
1535
1536             foreach(p; po["Path"].as!(char[][])) {
1537                 writefln(p);
1538             }
1539         }
1540
1541         if ("sync" in po) {
1542             foreach(o; po.storage!(CommandLineStorage).assignedOptions)
1543                 if (o!="sync") po.downStackSync(o);
1544         }
1545
1546         po.disconnect;
1547
1548     }
1549     catch(ProgramOptionsException e) {
1550         writefln("Exception: ", e);
1551         return 1;
1552     }
1553
1554     return 0;
1555 }
Note: See TracBrowser for help on using the browser.