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

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

- another bunch of changes to make everything compile in D2.0

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