BadScript 2
Loading...
Searching...
No Matches
InstanceBuilderTests.cs
Go to the documentation of this file.
1// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information.
2
3using Microsoft.FSharp.Core;
7
8using CSharpx;
9
10using FluentAssertions;
11
12using System;
13using System.Collections.Generic;
14using System.Globalization;
15using System.Linq;
16using Xunit;
17
19{
21 {
22 private static ParserResult<T> InvokeBuild<T>(string[] arguments, bool autoHelp = true, bool autoVersion = true, bool multiInstance = false)
23 where T : new()
24 {
25 return InstanceBuilder.Build(
26 Maybe.Just<Func<T>>(() => new T()),
27 (args, optionSpecs) => Tokenizer.ConfigureTokenizer(StringComparer.Ordinal, false, false)(args, optionSpecs),
28 arguments,
29 StringComparer.Ordinal,
30 false,
31 CultureInfo.InvariantCulture,
32 autoHelp,
33 autoVersion,
34 multiInstance,
35 Enumerable.Empty<ErrorType>());
36 }
37
38 private static ParserResult<T> InvokeBuildEnumValuesCaseIgnore<T>(string[] arguments)
39 where T : new()
40 {
41 return InstanceBuilder.Build(
42 Maybe.Just<Func<T>>(() => new T()),
43 (args, optionSpecs) => Tokenizer.ConfigureTokenizer(StringComparer.Ordinal, false, false)(args, optionSpecs),
44 arguments,
45 StringComparer.Ordinal,
46 true,
47 CultureInfo.InvariantCulture,
48 true,
49 true,
50 Enumerable.Empty<ErrorType>());
51 }
52
53 private static ParserResult<T> InvokeBuildImmutable<T>(string[] arguments)
54 {
55 return InstanceBuilder.Build(
56 Maybe.Nothing<Func<T>>(),
57 (args, optionSpecs) => Tokenizer.ConfigureTokenizer(StringComparer.Ordinal, false, false)(args, optionSpecs),
58 arguments,
59 StringComparer.Ordinal,
60 false,
61 CultureInfo.InvariantCulture,
62 true,
63 true,
64 Enumerable.Empty<ErrorType>());
65 }
66
67 [Fact]
69 {
70 // Fixture setup
71 var expectedResult = new NotParsed<Simple_Options>(
72 TypeInfo.Create(typeof(Simple_Options)), new Error[] { new HelpRequestedError() });
73
74 // Exercize system
75 var result = InvokeBuild<Simple_Options>(
76 new[] { "--help" });
77
78 // Verify outcome
79 result.Should().BeEquivalentTo(expectedResult);
80 }
81
82 [Theory]
83 [InlineData(new[] { "-123" }, -123L)]
84 [InlineData(new[] { "-1" }, -1L)]
85 [InlineData(new[] { "-9223372036854775807" }, -9223372036854775807)] // long.MaxValue * -1
86 public void Parse_negative_long_value(string[] arguments, long expected)
87 {
88 // Fixture setup in attributes
89
90 // Exercize system
91 var result = InvokeBuild<Simple_Options>(
92 arguments);
93
94 // Verify outcome
95 ((Parsed<Simple_Options>)result).Value.LongValue.Should().Be(expected);
96 }
97
98 [Theory]
99 [InlineData(new[] { "0.123" }, .123D)]
100 [InlineData(new[] { "-0.123" }, -0.123D)]
101 [InlineData(new[] { "1.0123456789" }, 1.0123456789D)]
102 [InlineData(new[] { "-1.0123456789" }, -1.0123456789D)]
103 [InlineData(new[] { "0" }, 0D)]
104 public void Parse_double_value(string[] arguments, double expected)
105 {
106 // Fixture setup in attributes
107
108 // Exercize system
109 var result = InvokeBuild<Simple_Options_With_Double_Value>(
110 arguments);
111
112 // Verify outcome
113 ((Parsed<Simple_Options_With_Double_Value>)result).Value.DoubleValue.Should().Be(expected);
114 }
115
116 [Theory]
117 [InlineData(new[] { "--int-seq", "1", "20", "300", "4000" }, new[] { 1, 20, 300, 4000 })]
118 [InlineData(new[] { "--int-seq=1", "20", "300", "4000" }, new[] { 1, 20, 300, 4000 })]
119 [InlineData(new[] { "--int-seq", "2147483647" }, new[] { 2147483647 })]
120 [InlineData(new[] { "--int-seq=2147483647" }, new[] { 2147483647 })]
121 [InlineData(new[] { "--int-seq", "-1", "20", "-3", "0" }, new[] { -1, 20, -3, 0 })]
122 [InlineData(new[] { "--int-seq=-1", "20", "-3", "0" }, new[] { -1, 20, -3, 0 })]
123 public void Parse_int_sequence(string[] arguments, int[] expected)
124 {
125 // Fixture setup in attributes
126
127 // Exercize system
128 var result = InvokeBuild<Options_With_Sequence>(
129 arguments);
130
131 // Verify outcome
132 ((Parsed<Options_With_Sequence>)result).Value.IntSequence.Should().BeEquivalentTo(expected);
133 }
134
135 [Theory]
136 [InlineData(new[] { "-i", "10", "20", "30" }, new[] { 10, 20, 30 })]
137 [InlineData(new[] { "-i", "10", "20", "30", "40" }, new[] { 10, 20, 30, 40 })]
138 [InlineData(new[] { "-i10", "20", "30" }, new[] { 10, 20, 30 })]
139 [InlineData(new[] { "-i10", "20", "30", "40" }, new[] { 10, 20, 30, 40 })]
140 public void Parse_int_sequence_with_range(string[] arguments, int[] expected)
141 {
142 // Fixture setup in attributes
143
144 // Exercize system
145 var result = InvokeBuild<Simple_Options>(
146 arguments);
147
148 // Verify outcome
149 ((Parsed<Simple_Options>)result).Value.IntSequence.Should().BeEquivalentTo(expected);
150 }
151
152 [Theory]
153 [InlineData(new[] { "-s", "just-one" }, new[] { "just-one" })]
154 [InlineData(new[] { "-sjust-one-samearg" }, new[] { "just-one-samearg" })]
155 [InlineData(new[] { "-s", "also-two", "are-ok" }, new[] { "also-two", "are-ok" })]
156 [InlineData(new[] { "--string-seq", "one", "two", "three" }, new[] { "one", "two", "three" })]
157 [InlineData(new[] { "--string-seq=one", "two", "three", "4" }, new[] { "one", "two", "three", "4" })]
158 public void Parse_string_sequence_with_only_min_constraint(string[] arguments, string[] expected)
159 {
160 // Fixture setup with attributes
161
162 // Exercize system
163 var result = InvokeBuild<Options_With_Sequence_And_Only_Min_Constraint>(
164 arguments);
165
166 // Verify outcome
167 ((Parsed<Options_With_Sequence_And_Only_Min_Constraint>)result).Value.StringSequence.Should().BeEquivalentTo(expected);
168 }
169
170 [Theory]
171 [InlineData(new[] { "-s", "just-one" }, new[] { "just-one" })]
172 [InlineData(new[] { "-sjust-one-samearg" }, new[] { "just-one-samearg" })]
173 [InlineData(new[] { "-s", "also-two", "are-ok" }, new[] { "also-two", "are-ok" })]
174 [InlineData(new[] { "--string-seq", "one", "two", "three" }, new[] { "one", "two", "three" })]
175 public void Parse_string_sequence_with_only_max_constraint(string[] arguments, string[] expected)
176 {
177 // Fixture setup with attributes
178
179 // Exercize system
180 var result = InvokeBuild<Options_With_Sequence_And_Only_Max_Constraint>(
181 arguments);
182
183 // Verify outcome
184 ((Parsed<Options_With_Sequence_And_Only_Max_Constraint>)result).Value.StringSequence.Should().BeEquivalentTo(expected);
185 }
186
187 [Fact]
189 {
190 // Fixture setup
191 var expectedResult = new[] { new MissingValueOptionError(new NameInfo("s", "string-seq")) };
192
193 // Exercize system
194 var result = InvokeBuild<Options_With_Sequence_And_Only_Min_Constraint>(
195 new[] { "-s" });
196
197 // Verify outcome
198 ((NotParsed<Options_With_Sequence_And_Only_Min_Constraint>)result).Errors.Should().BeEquivalentTo(expectedResult);
199 }
200
201 [Fact]
203 {
204 // Fixture setup
205 var expectedResult = new[] { new SequenceOutOfRangeError(NameInfo.EmptyName) };
206
207 // Exercize system
208 var result = InvokeBuild<Options_With_Sequence_And_Only_Min_Constraint_For_Value>(
209 new string[] { });
210
211 // Verify outcome
212 ((NotParsed<Options_With_Sequence_And_Only_Min_Constraint_For_Value>)result).Errors.Should().BeEquivalentTo(expectedResult);
213 }
214
215 [Fact]
217 {
218 // Fixture setup
219 var expectedResult = new[] { "one", "two", "three" };
220
221 // Exercize system
222 var result = InvokeBuild<Options_With_Sequence_And_Only_Max_Constraint>(
223 new[] { "--string-seq=one", "two", "three", "this-is-too-much" });
224
225 // Verify outcome
226 ((Parsed<Options_With_Sequence_And_Only_Max_Constraint>)result).Value.StringSequence.Should().BeEquivalentTo(expectedResult);
227 // The "this-is-too-much" arg would end up assigned to a Value; since there is no Value, it is silently dropped
228 }
229
230 [Fact]
232 {
233 // Fixture setup
234 var expectedResult = new[] { new SequenceOutOfRangeError(NameInfo.EmptyName) };
235
236 // Exercize system
237 var result = InvokeBuild<Options_With_Sequence_And_Only_Max_Constraint_For_Value>(
238 new[] { "one", "two", "three", "this-is-too-much" });
239
240 // Verify outcome
241 ((NotParsed<Options_With_Sequence_And_Only_Max_Constraint_For_Value>)result).Errors.Should().BeEquivalentTo(expectedResult);
242 }
243
244 [Theory]
245 [InlineData(new[] { "--colors", "Red" }, Colors.Red)]
246 [InlineData(new[] { "--colors", "Green" }, Colors.Green)]
247 [InlineData(new[] { "--colors", "Blue" }, Colors.Blue)]
248 [InlineData(new[] { "--colors", "0" }, Colors.Red)]
249 [InlineData(new[] { "--colors", "1" }, Colors.Green)]
250 [InlineData(new[] { "--colors", "2" }, Colors.Blue)]
251 public void Parse_enum_value(string[] arguments, Colors expected)
252 {
253 // Fixture setup in attribute
254
255 // Exercize system
256 var result = InvokeBuild<Simple_Options_With_Enum>(
257 arguments);
258
259 // Verify outcome
260 expected.Should().BeEquivalentTo(((Parsed<Simple_Options_With_Enum>)result).Value.Colors);
261 }
262
263 [Theory]
264 [InlineData(new[] { "--colors", "red" }, Colors.Red)]
265 [InlineData(new[] { "--colors", "green" }, Colors.Green)]
266 [InlineData(new[] { "--colors", "blue" }, Colors.Blue)]
267 [InlineData(new[] { "--colors", "0" }, Colors.Red)]
268 [InlineData(new[] { "--colors", "1" }, Colors.Green)]
269 [InlineData(new[] { "--colors", "2" }, Colors.Blue)]
270 public void Parse_enum_value_ignore_case(string[] arguments, Colors expected)
271 {
272 // Fixture setup in attribute
273
274 // Exercize system
275 var result = InvokeBuildEnumValuesCaseIgnore<Simple_Options_With_Enum>(
276 arguments);
277
278 // Verify outcome
279 expected.Should().BeEquivalentTo(((Parsed<Simple_Options_With_Enum>)result).Value.Colors);
280 }
281
282 [Fact]
284 {
285 // Fixture setup
286 var expectedResult = new[] { new BadFormatConversionError(new NameInfo("", "colors")) };
287
288 // Exercize system
289 var result = InvokeBuild<Simple_Options_With_Enum>(
290 new[] { "--colors", "3" });
291
292 // Verify outcome
293 ((NotParsed<Simple_Options_With_Enum>)result).Errors.Should().BeEquivalentTo(expectedResult);
294 }
295
296 [Fact]
298 {
299 // Fixture setup
300 var expectedResult = new[] { new BadFormatConversionError(new NameInfo("", "colors")) };
301
302 // Exercize system
303 var result = InvokeBuild<Simple_Options_With_Enum>(
304 new[] { "--colors", "Yellow" });
305
306 // Verify outcome
307 ((NotParsed<Simple_Options_With_Enum>)result).Errors.Should().BeEquivalentTo(expectedResult);
308 }
309
310 [Fact]
312 {
313 // Fixture setup
314 var expectedResult = new[] { new BadFormatConversionError(new NameInfo("", "colors")) };
315
316 // Exercize system
317 var result = InvokeBuild<Simple_Options_With_Enum>(
318 new[] { "--colors", "RED" });
319
320 // Verify outcome
321 ((NotParsed<Simple_Options_With_Enum>)result).Errors.Should().BeEquivalentTo(expectedResult);
322 }
323
324 [Fact]
326 {
327 // Fixture setup
328 var expectedResult = new Simple_Options_With_Values
329 {
330 StringValue = string.Empty,
331 LongValue = 10L,
332 StringSequence = new[] { "a", "b", "c" },
333 IntValue = 20
334 };
335
336 // Exercize system
337 var result = InvokeBuild<Simple_Options_With_Values>(
338 new[] { "10", "a", "b", "c", "20" });
339
340 // Verify outcome
341 expectedResult.Should().BeEquivalentTo(((Parsed<Simple_Options_With_Values>)result).Value);
342 }
343
344 [Theory]
345 [InlineData(new[] { "987654321" }, new[] { 987654321L })]
346 [InlineData(new[] { "1", "2", "3", "4", "5", "6" }, new[] { 1L, 2L, 3L, 4L, 5L, 6L })]
347 [InlineData(new string[] { }, new long[] { })]
348 [InlineData(new[] { "-1", "2", "9876543210", "-4", "0" }, new[] { -1L, 2L, 9876543210L, -4L, 0L })]
349 [InlineData(new[] { "0", "200000", "300000", "400000", "-500000", "600000", "700000", "800000", "900000", "-99999999" }, new[] { 0L, 200000L, 300000L, 400000L, -500000L, 600000L, 700000L, 800000L, 900000L, -99999999L })]
350 public void Parse_sequence_value_without_range_constraints(string[] arguments, long[] expected)
351 {
352 // Fixture setup in attributes
353
354 // Exercize system
355 var result = InvokeBuild<Options_With_Sequence_Without_Range_For_Value>(
356 arguments);
357
358 // Verify outcome
359 expected.Should().BeEquivalentTo(((Parsed<Options_With_Sequence_Without_Range_For_Value>)result).Value.LongSequence);
360 }
361
362 [Theory]
363 [InlineData(new[] { "--long-seq", "1;1234;59678" }, new[] { 1L, 1234L, 59678L })]
364 [InlineData(new[] { "--long-seq=1;1234;59678" }, new[] { 1L, 1234L, 59678L })]
365 [InlineData(new[] { "--long-seq", "-978;1234;59678;0" }, new[] { -978L, 1234L, 59678L, 0L })]
366 [InlineData(new[] { "--long-seq=-978;1234;59678;0" }, new[] { -978L, 1234L, 59678L, 0L })]
367 public void Parse_long_sequence_with_separator(string[] arguments, long[] expected)
368 {
369 // Fixture setup in attributes
370
371 // Exercize system
372 var result = InvokeBuild<Options_With_Sequence_Having_Separator_Set>(
373 arguments);
374
375 // Verify outcome
376 expected.Should().BeEquivalentTo(((Parsed<Options_With_Sequence_Having_Separator_Set>)result).Value.LongSequence);
377 }
378
379 [Theory]
380 [InlineData(new[] { "-s", "here-one-elem-but-no-sep" }, new[] { "here-one-elem-but-no-sep" })]
381 [InlineData(new[] { "-shere-one-elem-but-no-sep" }, new[] { "here-one-elem-but-no-sep" })]
382 [InlineData(new[] { "-s", "eml1@xyz.com,test@unit.org,xyz@srv.it" }, new[] { "eml1@xyz.com", "test@unit.org", "xyz@srv.it" })]
383 [InlineData(new[] { "-sInlineData@iscool.org,test@unit.org,xyz@srv.it,another,the-last-one" }, new[] { "InlineData@iscool.org", "test@unit.org", "xyz@srv.it", "another", "the-last-one" })]
384 public void Parse_string_sequence_with_separator(string[] arguments, string[] expected)
385 {
386 // Fixture setup in attributes
387
388 // Exercize system
389 var result = InvokeBuild<Options_With_Sequence_Having_Separator_Set>(
390 arguments);
391
392 // Verify outcome
393 expected.Should().BeEquivalentTo(((Parsed<Options_With_Sequence_Having_Separator_Set>)result).Value.StringSequence);
394 }
395
399 [Fact]
401 {
402 // Fixture setup
403 var expectedResult = new Simple_Options_With_Values
404 {
405 StringValue = "str1",
406 LongValue = 10L,
407 StringSequence = new[] { "-a", "--bee", "-c" },
408 IntValue = 20
409 };
410 var arguments = new[] { "--stringvalue", "str1", "--", "10", "-a", "--bee", "-c", "20" };
411
412 // Exercize system
413 var result = InstanceBuilder.Build(
414 Maybe.Just<Func<Simple_Options_With_Values>>(() => new Simple_Options_With_Values()),
415 (a, optionSpecs) =>
417 args => Tokenizer.Tokenize(args, name => NameLookup.Contains(name, optionSpecs, StringComparer.Ordinal))),
418 arguments,
419 StringComparer.Ordinal,
420 false,
421 CultureInfo.InvariantCulture,
422 true,
423 true,
424 Enumerable.Empty<ErrorType>());
425
426 // Verify outcome
427 expectedResult.Should().BeEquivalentTo(((Parsed<Simple_Options_With_Values>)result).Value);
428 }
429
430 [Fact]
432 {
433 // Fixture setup
434 var expectedResult = new[]
435 {
436 new MutuallyExclusiveSetError(new NameInfo("", "weburl"), string.Empty),
437 new MutuallyExclusiveSetError(new NameInfo("", "ftpurl"), string.Empty)
438 };
439
440 // Exercize system
441 var result = InvokeBuild<Options_With_Two_Sets>(
442 new[] { "--weburl", "http://mywebsite.org/", "--ftpurl", "fpt://ftpsite.org/" });
443
444 // Verify outcome
445 ((NotParsed<Options_With_Two_Sets>)result).Errors.Should().BeEquivalentTo(expectedResult);
446 }
447
448 [Fact]
450 {
451 // Fixture setup
453 {
454 FtpUrl = "str1",
455 WebUrl = "str2"
456 };
457 // Exercize system
458 var result = InvokeBuild<Options_With_Required_Set_To_True_Within_Same_Set>(
459 new[] { "--ftpurl", "str1", "--weburl", "str2" });
460
461 // Verify outcome
462 expectedResult.Should().BeEquivalentTo(((Parsed<Options_With_Required_Set_To_True_Within_Same_Set>)result).Value);
463 // Teardown
464 }
465
466 [Fact]
468 {
469 // Fixture setup
470 var expectedResult = new[]
471 {
472 new MissingRequiredOptionError(new NameInfo("", "ftpurl")),
473 new MissingRequiredOptionError(new NameInfo("", "weburl"))
474 };
475 // Exercize system
476 var result = InvokeBuild<Options_With_Required_Set_To_True_Within_Same_Set>(
477 new string[] { });
478
479 // Verify outcome
480 ((NotParsed<Options_With_Required_Set_To_True_Within_Same_Set>)result).Errors.Should().BeEquivalentTo(expectedResult);
481 }
482
483 [Fact]
485 {
486 // Fixture setup
487 var expectedResult = new[] { new MissingRequiredOptionError(new NameInfo("", "str")) };
488
489 // Exercize system
490 var result = InvokeBuild<Options_With_Required_Set_To_True>(
491 new string[] { });
492
493 // Verify outcome
494 ((NotParsed<Options_With_Required_Set_To_True>)result).Errors.Should().BeEquivalentTo(expectedResult);
495 }
496
497 [Fact]
499 {
500 // Fixture setup
501 var expectedResult = new[] { new SequenceOutOfRangeError(new NameInfo("i", "")) };
502
503 // Exercize system
504 var result = InvokeBuild<Simple_Options>(
505 new[] { "-i", "10" });
506
507 // Verify outcome
508 ((NotParsed<Simple_Options>)result).Errors.Should().BeEquivalentTo(expectedResult);
509 }
510
511 [Fact]
513 {
514 // Fixture setup
515 var expectedResult = new[] { new UnknownOptionError("xyz") };
516
517 // Exercize system
518 var result = InvokeBuild<Simple_Options>(
519 new[] { "--stringvalue", "abc", "--xyz" });
520
521 // Verify outcome
522 ((NotParsed<Simple_Options>)result).Errors.Should().BeEquivalentTo(expectedResult);
523 }
524
525 [Fact]
527 {
528 // Fixture setup
529 var expectedResult = new[] { new UnknownOptionError("z") };
530
531 // Exercize system
532 var result = InvokeBuild<Simple_Options>(
533 new[] { "-z", "-x" });
534
535 // Verify outcome
536 ((NotParsed<Simple_Options>)result).Errors.Should().BeEquivalentTo(expectedResult);
537 }
538
539 [Fact]
541 {
542 // Fixture setup
543 var expectedResult = new[] { new UnknownOptionError("z") };
544
545 // Exercize system
546 var result = InvokeBuild<Simple_Options>(
547 new[] { "-zx" });
548
549 // Verify outcome
550 ((NotParsed<Simple_Options>)result).Errors.Should().BeEquivalentTo(expectedResult);
551 }
552
553 [Theory]
554 [InlineData(new[] { "--stringvalue", "this-value" }, "this-value")]
555 [InlineData(new[] { "--stringvalue=this-other" }, "this-other")]
556 public void Omitting_names_assumes_identifier_as_long_name(string[] arguments, string expected)
557 {
558 // Fixture setup in attributes
559
560 // Exercize system
561 var result = InvokeBuild<Simple_Options>(
562 arguments);
563
564 // Verify outcome
565 ((Parsed<Simple_Options>)result).Value.StringValue.Should().BeEquivalentTo(expected);
566 }
567
568 [Fact]
570 {
571 // Fixture setup
572 var expectedResult = new[] { new MissingRequiredOptionError(NameInfo.EmptyName) };
573
574 // Exercize system
575 var result = InvokeBuild<Options_With_Required_Set_To_True_For_Values>(
576 new string[] { });
577
578 // Verify outcome
579 ((NotParsed<Options_With_Required_Set_To_True_For_Values>)result).Errors.Should().BeEquivalentTo(expectedResult);
580 }
581
582 [Theory]
583 [InlineData(new[] { "--stringvalue", "中文" }, "中文")] // Chinese
584 [InlineData(new[] { "--stringvalue=中文" }, "中文")]
585 [InlineData(new[] { "--stringvalue", "日本人" }, "日本人")] // Japanese
586 [InlineData(new[] { "--stringvalue=日本人" }, "日本人")]
587 public void Parse_utf8_string_correctly(string[] arguments, string expected)
588 {
589 // Fixture setup in attributes
590
591 // Exercize system
592 var result = InvokeBuild<Simple_Options>(
593 arguments);
594
595 // Verify outcome
596 expected.Should().BeEquivalentTo(((Parsed<Simple_Options>)result).Value.StringValue);
597 }
598
599 [Fact]
601 {
602 // Fixture setup
603 var expectedResult = new[] { new SequenceOutOfRangeError(NameInfo.EmptyName) };
604
605 // Exercize system
606 var result = InvokeBuild<Options_With_Sequence_Having_Both_Min_And_Max_Equal>(
607 new[] { "one", "two", "this-is-too-much" });
608
609 // Verify outcome
610 ((NotParsed<Options_With_Sequence_Having_Both_Min_And_Max_Equal>)result).Errors.Should().BeEquivalentTo(expectedResult);
611 }
612
613 [Theory]
614 [InlineData(new[] { "-i", "10" }, 10)]
615 [InlineData(new string[] { }, null)]
616 [InlineData(new[] { "-i9999" }, 9999)]
617 [InlineData(new[] { "--nullable-int=-1" }, -1)]
618 public void Parse_nullable_int(string[] arguments, int? expected)
619 {
620 // Fixture setup in attributes
621
622 // Exercize system
623 var result = InvokeBuild<Options_With_Nullables>(
624 arguments);
625
626 // Verify outcome
627 expected.Should().Be(((Parsed<Options_With_Nullables>)result).Value.NullableInt);
628 }
629
630 [Theory]
631 [InlineData(new[] { "10" }, 10L)]
632 [InlineData(new string[] { }, null)]
633 [InlineData(new[] { "9999" }, 9999L)]
634 [InlineData(new[] { "-1" }, -1L)]
635 public void Parse_nullable_long(string[] arguments, long? expected)
636 {
637 // Fixture setup in attributes
638
639 // Exercize system
640 var result = InvokeBuild<Options_With_Nullables>(
641 arguments);
642
643 // Verify outcome
644 expected.Should().Be(((Parsed<Options_With_Nullables>)result).Value.NullableLong);
645 }
646
647#if !SKIP_FSHARP
648 [Theory]
649 [InlineData(new[] { "--filename", "log-20150626.txt" }, "log-20150626.txt", true)]
650 [InlineData(new string[] { }, null, false)]
651 public void Parse_fsharp_option_string(string[] arguments, string expectedValue, bool expectedSome)
652 {
653 // Fixture setup in attributes
654
655 // Exercize system
656 var result = InvokeBuild<Options_With_FSharpOption>(
657 arguments);
658
659 // Verify outcome
660 if (((Parsed<Options_With_FSharpOption>)result).Value.FileName != null)
661 {
662 expectedValue.Should().BeEquivalentTo(((Parsed<Options_With_FSharpOption>)result).Value.FileName.Value);
663 }
664 expectedSome.Should().Be(FSharpOption<string>.get_IsSome(((Parsed<Options_With_FSharpOption>)result).Value.FileName));
665 }
666
667 [Theory]
668 [InlineData(new[] { "1234567" }, 1234567, true)]
669 [InlineData(new string[] { }, default(int), false)]
670 public void Parse_fsharp_option_int(string[] arguments, int expectedValue, bool expectedSome)
671 {
672 // Fixture setup in attributes
673
674 // Exercize system
675 var result = InvokeBuild<Options_With_FSharpOption>(
676 arguments);
677
678 // Verify outcome
679 if (((Parsed<Options_With_FSharpOption>)result).Value.Offset != null)
680 {
681 expectedValue.Should().Be(((Parsed<Options_With_FSharpOption>)result).Value.Offset.Value);
682 }
683 expectedSome.Should().Be(FSharpOption<int>.get_IsSome(((Parsed<Options_With_FSharpOption>)result).Value.Offset));
684 }
685#endif
686
687
688 [Fact]
690 {
691 // Exercize system
692 Action test = () => InvokeBuild<Options_With_Min_Set_To_Zero>(
693 new string[] { });
694
695 // Verify outcome
696 Assert.Throws<InvalidOperationException>(test);
697 }
698
699 [Fact]
701 {
702 // Exercize system
703 Action test = () => InvokeBuild<Options_With_Max_Set_To_Zero>(
704 new string[] { });
705
706 // Verify outcome
707 Assert.Throws<InvalidOperationException>(test);
708 }
709
710 [Fact]
712 {
713 // Exercize system
714 Action test = () => InvokeBuild<Options_With_Both_Min_And_Max_Set_To_Zero>(
715 new string[] { });
716
717 // Verify outcome
718 Assert.Throws<InvalidOperationException>(test);
719 }
720
721 [Theory]
722 [InlineData(new[] { "--weburl", "value.com", "--verbose" }, ParserResultType.Parsed, 0)]
723 [InlineData(new[] { "--ftpurl", "value.org", "--interactive" }, ParserResultType.Parsed, 0)]
724 [InlineData(new[] { "--weburl", "value.com", "--verbose", "--interactive" }, ParserResultType.Parsed, 0)]
725 [InlineData(new[] { "--ftpurl=fvalue", "--weburl=wvalue" }, ParserResultType.NotParsed, 2)]
726 [InlineData(new[] { "--interactive", "--weburl=wvalue", "--verbose", "--ftpurl=wvalue" }, ParserResultType.NotParsed, 2)]
727 public void Empty_set_options_allowed_with_mutually_exclusive_sets(string[] arguments, ParserResultType type, int expected)
728 {
729 // Exercize system
730 var result = InvokeBuild<Options_With_Named_And_Empty_Sets>(
731 arguments);
732
733 // Verify outcome
734 if (type == ParserResultType.NotParsed)
735 {
736 ((NotParsed<Options_With_Named_And_Empty_Sets>)result).Errors.Should().HaveCount(x => x == expected);
737 }
738 else if (type == ParserResultType.Parsed)
739 {
740 result.Should().BeOfType<Parsed<Options_With_Named_And_Empty_Sets>>();
741 }
742 }
743
744 [Theory]
745 [InlineData(new[] { "--stringvalue", "abc", "--stringvalue", "def" }, 1)]
746 public void Specifying_options_two_or_more_times_generates_RepeatedOptionError(string[] arguments, int expected)
747 {
748 // Exercize system
749 var result = InvokeBuild<Simple_Options>(
750 arguments);
751
752 // Verify outcome
753 ((NotParsed<Simple_Options>)result).Errors.Should().HaveCount(x => x == expected);
754 }
755
756 [Theory]
757 [InlineData(new[] { "-s", "abc", "-s", "def" }, 1)]
759 {
760 // Exercize system
761 var result = InvokeBuild<Simple_Options>(
762 arguments);
763
764 // Verify outcome
765 ((NotParsed<Simple_Options>)result).Errors.Should().HaveCount(x => x == expected);
766 }
767
768 [Theory]
769 [InlineData(new[] { "--shortandlong", "abc", "--shortandlong", "def" }, 1)]
771 {
772 // Exercize system
773 var result = InvokeBuild<Simple_Options>(
774 arguments);
775
776 // Verify outcome
777 ((NotParsed<Simple_Options>)result).Errors.Should().HaveCount(x => x == expected);
778 }
779
780 [Theory]
781 [InlineData(new[] { "-s", "abc", "--shortandlong", "def" }, 1)]
783 {
784 // Exercize system
785 var result = InvokeBuild<Simple_Options>(
786 arguments);
787
788 // Verify outcome
789 ((NotParsed<Simple_Options>)result).Errors.Should().HaveCount(x => x == expected);
790 }
791
792 [Theory]
793 [InlineData(new[] { "--inputfile=file1.bin" }, "file1.bin")]
794 [InlineData(new[] { "--inputfile", "file2.txt" }, "file2.txt")]
795 public void Can_define_options_on_explicit_interface_properties(string[] arguments, string expected)
796 {
797 // Exercize system
798 var result = InvokeBuild<Options_With_Only_Explicit_Interface>(
799 arguments);
800
801 // Verify outcome
802 expected.Should().BeEquivalentTo(((IInterface_With_Two_Scalar_Options)((Parsed<Options_With_Only_Explicit_Interface>)result).Value).InputFile);
803 }
804
805
806 [Theory]
807 [InlineData(new[] { "--inputfile=file1.bin" }, "file1.bin")]
808 [InlineData(new[] { "--inputfile", "file2.txt" }, "file2.txt")]
809 public void Can_define_options_on_interface_properties(string[] arguments, string expected)
810 {
811 // Exercize system
812 var result = InvokeBuild<Options_With_Interface>(
813 arguments);
814
815 // Verify outcome
816 expected.Should().BeEquivalentTo(((Parsed<Options_With_Interface>)result).Value.InputFile);
817 }
818
819 [Theory]
820 [InlineData(new[] { "--weburl=value.com" }, ParserResultType.Parsed, 0)]
821 [InlineData(new[] { "--ftpurl=value.org" }, ParserResultType.Parsed, 0)]
822 [InlineData(new[] { "--weburl=value.com", "-a" }, ParserResultType.Parsed, 0)]
823 [InlineData(new[] { "--ftpurl=value.org", "-a" }, ParserResultType.Parsed, 0)]
824 [InlineData(new[] { "--weburl=value.com", "--ftpurl=value.org" }, ParserResultType.NotParsed, 2)]
825 [InlineData(new[] { "--weburl=value.com", "--ftpurl=value.org", "-a" }, ParserResultType.NotParsed, 2)]
826 [InlineData(new string[] { }, ParserResultType.NotParsed, 2)]
827 public void Enforce_required_within_mutually_exclusive_set_only(string[] arguments, ParserResultType type, int expected)
828 {
829 // Exercize system
830 var result = InvokeBuild<Options_With_Two_Option_Required_Set_To_True_And_Two_Sets>(
831 arguments);
832
833 // Verify outcome
834 if (type == ParserResultType.NotParsed)
835 {
836 ((NotParsed<Options_With_Two_Option_Required_Set_To_True_And_Two_Sets>)result).Errors.Should().HaveCount(x => x == expected);
837 }
838 else if (type == ParserResultType.Parsed)
839 {
841 }
842 }
843
844 [Theory]
845 [MemberData(nameof(RequiredValueStringData))]
847 {
848 // Fixture setup in attributes
849
850 // Exercize system
851 var result = InvokeBuild<Options_With_Required_Set_To_True_For_Values>(
852 arguments);
853
854 // Verify outcome
855 expected.Should().BeEquivalentTo(((Parsed<Options_With_Required_Set_To_True_For_Values>)result).Value);
856 }
857
858 [Theory]
859 [MemberData(nameof(ScalarSequenceStringAdjacentData))]
861 {
862 // Fixture setup in attributes
863
864 // Exercize system
865 var result = InvokeBuild<Options_With_Scalar_Value_And_Adjacent_SequenceString>(
866 arguments);
867
868 // Verify outcome
869 expected.Should().BeEquivalentTo(((Parsed<Options_With_Scalar_Value_And_Adjacent_SequenceString>)result).Value);
870 }
871
872 [Fact]
873 public void Parse_to_mutable()
874 {
875 // Fixture setup
876 var expectedResult = new Simple_Options { StringValue = "strval0", IntSequence = new[] { 9, 7, 8 }, BoolValue = true, LongValue = 9876543210L };
877
878 // Exercize system
879 var result = InvokeBuild<Simple_Options>(
880 new[] { "--stringvalue=strval0", "-i", "9", "7", "8", "-x", "9876543210" });
881
882 // Verify outcome
883 expectedResult.Should().BeEquivalentTo(((Parsed<Simple_Options>)result).Value);
884 }
885
886 [Theory]
887 [InlineData(new string[] { }, 2)]
888 [InlineData(new[] { "--str=val0" }, 1)]
889 [InlineData(new[] { "--long=9" }, 1)]
890 [InlineData(new[] { "--int=7" }, 2)]
891 [InlineData(new[] { "--str", "val1", "--int=3" }, 1)]
892 [InlineData(new[] { "--long", "9", "--int=11" }, 1)]
893 public void Breaking_required_constraint_generate_MissingRequiredOptionError(string[] arguments, int expected)
894 {
895 // Exercize system
896 var result = InvokeBuild<Options_With_Two_Options_Having_Required_Set_To_True>(
897 arguments);
898
899 // Verify outcome
901 errors.OfType<MissingRequiredOptionError>().Should().HaveCount(x => x == expected);
902 }
903
904 [Theory]
905 [MemberData(nameof(ImmutableInstanceData))]
906 public void Parse_to_immutable_instance(string[] arguments, Immutable_Simple_Options expected)
907 {
908 // Fixture setup in attributes
909
910 // Exercize system
911 var result = InvokeBuildImmutable<Immutable_Simple_Options>(
912 arguments);
913
914 // Verify outcome
915 expected.Should().BeEquivalentTo(((Parsed<Immutable_Simple_Options>)result).Value);
916 }
917
918 [Theory]
919 [MemberData(nameof(ImmutableInstanceDataArgs))]
920 [Trait("Category", "Immutable")]
922 {
923 // Fixture setup in attributes
924
925 // Exercize system
926 Action act = () => InvokeBuildImmutable<Immutable_Simple_Options_Invalid_Ctor_Args>(
927 arguments);
928
929 // Verify outcome
930 var expectedMsg =
931 "Type CommandLine.Tests.Fakes.Immutable_Simple_Options_Invalid_Ctor_Args appears to be Immutable with invalid constructor. Check that constructor arguments have the same name and order of their underlying Type. Constructor Parameters can be ordered as: '(stringvalue, intsequence, boolvalue, longvalue)'";
932 act.Should().Throw<InvalidOperationException>().WithMessage(expectedMsg);
933 }
934
935 [Fact]
937 {
938 // Fixture setup
939 var expectedResult = new Options_With_Uri_And_SimpleType { EndPoint = new Uri("http://localhost/test/"), MyValue = new MySimpleType("custom-value") };
940
941 // Exercize system
942 var result = InvokeBuild<Options_With_Uri_And_SimpleType>(
943 new[] { "--endpoint=http://localhost/test/", "custom-value" });
944
945 // Verify outcome
946 expectedResult.Should().BeEquivalentTo(((Parsed<Options_With_Uri_And_SimpleType>)result).Value);
947 }
948
949 [Fact]
951 {
952 // Fixture setup
953 var expectedResult = new[] { new SetValueExceptionError(new NameInfo("e", ""), new ArgumentException(), "bad") };
954
955 // Exercize system
956 var result = InvokeBuild<Options_With_Property_Throwing_Exception>(
957 new[] { "-e", "bad" });
958
959 // Verify outcome
960 ((NotParsed<Options_With_Property_Throwing_Exception>)result).Errors.Should().BeEquivalentTo(expectedResult);
961 }
962
963 [Fact]
965 {
966 // Fixture setup
967 string name = nameof(Options_With_InvalidDefaults.FileName).ToLower();
968 var expectedResult = new[] { new SetValueExceptionError(new NameInfo("", name),
969 new ArgumentException(InvalidAttributeConfigurationError.ErrorMessage), "bad") };
970
971 // Exercize system
972 var result = InvokeBuild<Options_With_InvalidDefaults>(
973 new[] { name, "bad" });
974
975 // Verify outcome
976 ((NotParsed<Options_With_InvalidDefaults>)result).Errors.Should().BeEquivalentTo(expectedResult);
977 }
978
979
980 [Theory]
981 [InlineData(new[] { "--stringvalue", "x-" }, "x-")]
982 [InlineData(new[] { "--stringvalue", "x--" }, "x--")]
983 [InlineData(new[] { "--stringvalue", "x---" }, "x---")]
984 [InlineData(new[] { "--stringvalue=x-x" }, "x-x")]
985 [InlineData(new[] { "--stringvalue=x--x" }, "x--x")]
986 [InlineData(new[] { "--stringvalue=x---x" }, "x---x")]
987 [InlineData(new[] { "--stringvalue", "5366ebc4-7aa7-4d5a-909c-a415a291a5ad" }, "5366ebc4-7aa7-4d5a-909c-a415a291a5ad")]
988 [InlineData(new[] { "--stringvalue=5366ebc4-7aa7-4d5a-909c-a415a291a5ad" }, "5366ebc4-7aa7-4d5a-909c-a415a291a5ad")]
989 public void Parse_string_with_dashes_except_in_beginning(string[] arguments, string expected)
990 {
991 // Fixture setup in attributes
992
993 // Exercize system
994 var result = InvokeBuild<Simple_Options>(
995 arguments);
996
997 // Verify outcome
998 expected.Should().BeEquivalentTo(((Parsed<Simple_Options>)result).Value.StringValue);
999 }
1000
1001 [Theory]
1002 [InlineData(new[] { "--help" }, ErrorType.UnknownOptionError)]
1004 {
1005 // Fixture setup in attributes
1006
1007 // Exercize system
1008 var result = InvokeBuild<Simple_Options>(arguments, autoHelp: false);
1009
1010 // Verify outcome
1011 result.Should().BeOfType<NotParsed<Simple_Options>>()
1012 .Which.Errors.Should().ContainSingle()
1013 .Which.Tag.Should().Be(errorType);
1014 }
1015
1016 [Theory]
1017 [InlineData(new[] { "--help" }, true)]
1018 [InlineData(new[] { "-h" }, true)]
1019 [InlineData(new[] { "-x" }, false)]
1020 public void Parse_with_custom_help_option(string[] arguments, bool isHelp)
1021 {
1022 // Fixture setup in attributes
1023
1024 // Exercize system
1025 var result = InvokeBuild<Options_With_Custom_Help_Option>(arguments, autoHelp: false);
1026
1027 // Verify outcome
1028 result.Should().BeOfType<Parsed<Options_With_Custom_Help_Option>>()
1029 .Which.Value.Help.Should().Be(isHelp);
1030 }
1031
1032 [Theory]
1033 [InlineData(new[] { "--version" }, ErrorType.UnknownOptionError)]
1035 {
1036 // Fixture setup in attributes
1037
1038 // Exercize system
1039 var result = InvokeBuild<Simple_Options>(arguments, autoVersion: false);
1040
1041 // Verify outcome
1042 result.Should().BeOfType<NotParsed<Simple_Options>>()
1043 .Which.Errors.Should().ContainSingle()
1044 .Which.Tag.Should().Be(errorType);
1045 }
1046
1047 [Theory]
1048 [InlineData(new[] { "--version" }, true)]
1049 [InlineData(new[] { "-v" }, true)]
1050 [InlineData(new[] { "-s", "s" }, false)]
1051 public void Parse_with_custom_version_option(string[] arguments, bool isVersion)
1052 {
1053 // Fixture setup in attributes
1054
1055 // Exercize system
1056 var result = InvokeBuild<Options_With_Custom_Version_Option>(arguments, autoVersion: false);
1057
1058 // Verify outcome
1059 result.Should().BeOfType<Parsed<Options_With_Custom_Version_Option>>()
1060 .Which.Value.MyVersion.Should().Be(isVersion);
1061 }
1062
1063 [Theory]
1064 [MemberData(nameof(GuidData))]
1065 public void Parse_Guid(string[] arguments, Options_With_Guid expected)
1066 {
1067 // Fixture setup in attributes
1068
1069 // Exercize system
1070 var result = InvokeBuild<Options_With_Guid>(
1071 arguments);
1072
1073 // Verify outcome
1074 expected.Should().BeEquivalentTo(((Parsed<Options_With_Guid>)result).Value);
1075 }
1076
1077 [Fact]
1078 public void Parse_TimeSpan()
1079 {
1080 // Fixture setup
1081 var expectedResult = new Options_With_TimeSpan { Duration = TimeSpan.FromMinutes(42) };
1082
1083 // Exercize system
1084 var result = InvokeBuild<Options_With_TimeSpan>(
1085 new[] { "--duration=00:42:00" });
1086
1087 // Verify outcome
1088 expectedResult.Should().BeEquivalentTo(((Parsed<Options_With_TimeSpan>)result).Value);
1089 }
1090
1091 #region Issue 579
1092 [Fact]
1094 {
1095 // Exercize system
1096 var result = InvokeBuild<Options_With_TimeSpan>(new[] { "--duration=\"00:42:00\"" });
1097
1098 var outcome = result as NotParsed<Options_With_TimeSpan>;
1099
1100 // Verify outcome
1101 outcome.Should().NotBeNull();
1102 outcome.Errors.Should().NotBeNullOrEmpty()
1103 .And.HaveCount(1)
1104 .And.OnlyContain(e => e.GetType().Equals(typeof(BadFormatConversionError)));
1105 }
1106 #endregion
1107
1108 [Fact]
1110 {
1111 Action act = () => InvokeBuild<ValueWithNoSetterOptions>(new string[] { "Test" }, false, false);
1112
1113 act.Should().Throw<InvalidOperationException>()
1114 .Which.Message.Should().Be("Type CommandLine.Tests.Unit.Core.InstanceBuilderTests+ValueWithNoSetterOptions appears to be immutable, but no constructor found to accept values.");
1115 }
1116
1117 [Fact]
1119 {
1120 Action act = () => InvokeBuild<ValueWithNoSetterOptions>(new string[] { "--help" });
1121
1122 act.Should().Throw<InvalidOperationException>()
1123 .Which.Message.Should().Be("Type CommandLine.Tests.Unit.Core.InstanceBuilderTests+ValueWithNoSetterOptions appears to be immutable, but no constructor found to accept values.");
1124 }
1125
1126 [Fact]
1128 {
1129 // Fixture setup
1130 var optionNames = new List<NameInfo>
1131 {
1132 new NameInfo("", "option1"),
1133 new NameInfo("", "option2")
1134 };
1135 var expectedResult = new[] { new MissingGroupOptionError("err-group", optionNames) };
1136
1137 // Exercize system
1138 var result = InvokeBuild<Options_With_Group>(
1139 new[] { "-v 10.42" });
1140
1141 // Verify outcome
1142 ((NotParsed<Options_With_Group>)result).Errors.Should().BeEquivalentTo(expectedResult);
1143 }
1144
1145 [Fact]
1147 {
1148 // Fixture setup
1149 var optionNames1 = new List<NameInfo>
1150 {
1151 new NameInfo("", "option11"),
1152 new NameInfo("", "option12")
1153 };
1154 var optionNames2 = new List<NameInfo>
1155 {
1156 new NameInfo("", "option21"),
1157 new NameInfo("", "option22")
1158 };
1159 var expectedResult = new[]
1160 {
1161 new MissingGroupOptionError("err-group", optionNames1),
1162 new MissingGroupOptionError("err-group2", optionNames2)
1163 };
1164
1165 // Exercize system
1166 var result = InvokeBuild<Options_With_Multiple_Groups>(
1167 new[] { "-v 10.42" });
1168
1169 // Verify outcome
1170 ((NotParsed<Options_With_Multiple_Groups>)result).Errors.Should().BeEquivalentTo(expectedResult);
1171 }
1172
1173 [Theory]
1174 [InlineData("-v", "10.5", "--option1", "test1", "--option2", "test2")]
1175 [InlineData("-v", "10.5", "--option1", "test1")]
1176 [InlineData("-v", "10.5", "--option2", "test2")]
1178 {
1179 // Exercize system
1180 var result = InvokeBuild<Options_With_Group>(args);
1181
1182 // Verify outcome
1183 result.Should().BeOfType<Parsed<Options_With_Group>>();
1184 }
1185
1186 [Fact]
1188 {
1189 // Fixture setup
1190 var optionNames = new List<NameInfo>
1191 {
1192 new NameInfo("", "stingvalue"),
1193 new NameInfo("s", "shortandlong")
1194 };
1195 var expectedResult = new[] { new MissingGroupOptionError("string-group", optionNames) };
1196
1197 // Exercize system
1198 var result = InvokeBuild<Simple_Options_With_Required_OptionGroup>(new string[] { "-x" });
1199
1200 // Verify outcome
1201 result.Should().BeOfType<NotParsed<Simple_Options_With_Required_OptionGroup>>();
1203
1204 errors.Should().HaveCount(1);
1205 errors.Should().BeEquivalentTo(expectedResult);
1206 }
1207
1208 [Fact]
1210 {
1211 var expectedResult = new[]
1212 {
1213 new MissingRequiredOptionError(new NameInfo("", "stringvalue")),
1214 new MissingRequiredOptionError(new NameInfo("s", "shortandlong"))
1215 };
1216
1217 // Exercize system
1218 var result = InvokeBuild<Simple_Options_With_OptionGroup_WithDefaultValue>(new string[] { "-x" });
1219
1220 // Verify outcome
1223
1224 errors.Should().BeEquivalentTo(expectedResult);
1225 }
1226
1227 [Fact]
1229 {
1230 // Exercize system
1231 var result = InvokeBuild<Simple_Options_With_OptionGroup_WithOptionDefaultValue>(new string[] { "-x" });
1232
1233 // Verify outcome
1235 }
1236
1237 [Fact]
1239 {
1240 var expectedResult = new[]
1241 {
1242 new GroupOptionAmbiguityError(new NameInfo("", "stringvalue")),
1243 new GroupOptionAmbiguityError(new NameInfo("s", "shortandlong"))
1244 };
1245
1246 // Exercize system
1247 var result = InvokeBuild<Simple_Options_With_OptionGroup_MutuallyExclusiveSet>(new string[] { "-x" });
1248
1249 // Verify outcome
1252
1253 errors.Should().BeEquivalentTo(expectedResult);
1254 }
1255
1256 [Fact]
1258 {
1259 var expected = new[] { 1, 2, 3 };
1260 var result = InvokeBuild<Options_With_Sequence>(
1261 new[] { "--int-seq", "1", "2", "--int-seq", "3" },
1262 multiInstance: true);
1263
1264 ((Parsed<Options_With_Sequence>)result).Value.IntSequence.Should().BeEquivalentTo(expected);
1265 }
1266
1267 #region custom types
1268
1269
1270 [Theory]
1271 [InlineData(new[] { "-c", "localhost:8080" }, "localhost", 8080)]
1272 public void Parse_custom_struct_type(string[] arguments, string expectedServer, int expectedPort)
1273 {
1274 //Arrange
1275
1276 // Act
1277 var result = InvokeBuild<CustomStructOptions>(arguments);
1278
1279 // Assert
1280 var customValue = ((Parsed<CustomStructOptions>)result).Value.Custom;
1281 customValue.Server.Should().Be(expectedServer);
1282 customValue.Port.Should().Be(expectedPort);
1283 customValue.Input.Should().Be(arguments[1]);
1284 }
1285
1286 [Theory]
1287 [InlineData(new[] { "-c", "localhost:8080" }, "localhost", 8080)]
1288 public void Parse_custom_class_type(string[] arguments, string expectedServer, int expectedPort)
1289 {
1290 //Arrange
1291
1292 // Act
1293 var result = InvokeBuild<CustomClassOptions>(arguments);
1294
1295 // Assert
1296 var customValue = ((Parsed<CustomClassOptions>)result).Value.Custom;
1297 customValue.Server.Should().Be(expectedServer);
1298 customValue.Port.Should().Be(expectedPort);
1299 customValue.Input.Should().Be(arguments[1]);
1300 }
1301
1302 #endregion
1304 {
1305 [Value(0, MetaName = "Test", Default = 0)]
1306 public int TestValue { get; }
1307 }
1308
1309
1310 public static IEnumerable<object[]> RequiredValueStringData
1311 {
1312 get
1313 {
1314 yield return new object[] { new[] { "value-string" }, new Options_With_Required_Set_To_True_For_Values { StringValue = "value-string" } };
1315 yield return new object[] { new[] { "another-string", "999" }, new Options_With_Required_Set_To_True_For_Values { StringValue = "another-string", IntValue = 999 } };
1316 yield return new object[] { new[] { "str with spaces", "-1234567890" }, new Options_With_Required_Set_To_True_For_Values { StringValue = "str with spaces", IntValue = -1234567890 } };
1317 yield return new object[] { new[] { "1234567890", "1234567890" }, new Options_With_Required_Set_To_True_For_Values { StringValue = "1234567890", IntValue = 1234567890 } };
1318 yield return new object[] { new[] { "-1234567890", "1234567890" }, new Options_With_Required_Set_To_True_For_Values { StringValue = "-1234567890", IntValue = 1234567890 } };
1319 }
1320 }
1321
1322 public static IEnumerable<object[]> ScalarSequenceStringAdjacentData
1323 {
1324 get
1325 {
1326 yield return new object[] { new[] { "to-value" }, new Options_With_Scalar_Value_And_Adjacent_SequenceString { StringValueWithIndexZero = "to-value", StringOptionSequence = new string[] { } } };
1327 yield return new object[] { new[] { "to-value", "-s", "to-seq-0" }, new Options_With_Scalar_Value_And_Adjacent_SequenceString { StringValueWithIndexZero = "to-value", StringOptionSequence = new[] { "to-seq-0" } } };
1328 yield return new object[] { new[] { "to-value", "-s", "to-seq-0", "to-seq-1" }, new Options_With_Scalar_Value_And_Adjacent_SequenceString { StringValueWithIndexZero = "to-value", StringOptionSequence = new[] { "to-seq-0", "to-seq-1" } } };
1329 yield return new object[] { new[] { "-s", "cant-capture", "value-anymore" }, new Options_With_Scalar_Value_And_Adjacent_SequenceString { StringOptionSequence = new[] { "cant-capture", "value-anymore" } } };
1330 yield return new object[] { new[] { "-s", "just-one" }, new Options_With_Scalar_Value_And_Adjacent_SequenceString { StringOptionSequence = new[] { "just-one" } } };
1331
1332 }
1333 }
1334
1335 public static IEnumerable<object[]> ImmutableInstanceData
1336 {
1337 get
1338 {
1339 yield return new object[] { new string[] { }, new Immutable_Simple_Options(null, new int[] { }, default(bool), default(long)) };
1340 yield return new object[] { new[] { "--stringvalue=strval0" }, new Immutable_Simple_Options("strval0", new int[] { }, default(bool), default(long)) };
1341 yield return new object[] { new[] { "-i", "9", "7", "8" }, new Immutable_Simple_Options(null, new[] { 9, 7, 8 }, default(bool), default(long)) };
1342 yield return new object[] { new[] { "-x" }, new Immutable_Simple_Options(null, new int[] { }, true, default(long)) };
1343 yield return new object[] { new[] { "9876543210" }, new Immutable_Simple_Options(null, new int[] { }, default(bool), 9876543210L) };
1344 yield return new object[] { new[] { "--stringvalue=strval0", "-i", "9", "7", "8", "-x", "9876543210" }, new Immutable_Simple_Options("strval0", new[] { 9, 7, 8 }, true, 9876543210L) };
1345 }
1346 }
1347 public static IEnumerable<object[]> ImmutableInstanceDataArgs
1348 {
1349 get
1350 {
1351 yield return new object[] { new string[] { } } ;
1352 yield return new object[] {new [] {"--stringvalue=strval0"}};
1353 yield return new object[] { new[] { "-i", "9", "7", "8" } };
1354 yield return new object[] { new[] { "-x" }};
1355 yield return new object[] { new[] { "9876543210" }};
1356 yield return new object[] { new[] { "--stringvalue=strval0", "-i", "9", "7", "8", "-x", "9876543210" }};
1357 }
1358 }
1359
1360 public static IEnumerable<object[]> GuidData
1361 {
1362 get
1363 {
1364 var guid0 = Guid.NewGuid();
1365 var guid1 = Guid.NewGuid();
1366 yield return new object[] { new[] { "--txid", guid0.ToStringInvariant() }, new Options_With_Guid { TransactionId = guid0 } };
1367 yield return new object[] { new[] { "--txid=" + guid1.ToStringInvariant() }, new Options_With_Guid { TransactionId = guid1 } };
1368 yield return new object[] { new[] { "-t", guid0.ToStringInvariant() }, new Options_With_Guid { TransactionId = guid0 } };
1369 yield return new object[] { new[] { "-t" + guid1.ToStringInvariant() }, new Options_With_Guid { TransactionId = guid1 } };
1370 }
1371 }
1372 }
1373}
The Maybe type models an optional value. A value of type Maybe a either contains a value of type a (r...
Definition Maybe.cs:33
Models an error generated when a value conversion fails.
Definition Error.cs:418
static NameLookupResult Contains(string name, IEnumerable< OptionSpecification > specifications, StringComparer comparer)
Definition NameLookup.cs:20
static Func< IEnumerable< string >, IEnumerable< OptionSpecification >, Result< IEnumerable< Token >, Error > > ConfigureTokenizer(StringComparer nameComparer, bool ignoreUnknownArguments, bool enableDashDash)
Definition Tokenizer.cs:166
static Result< IEnumerable< Token >, Error > Tokenize(IEnumerable< string > arguments, Func< string, NameLookupResult > nameLookup)
Definition Tokenizer.cs:18
static Result< IEnumerable< Token >, Error > PreprocessDashDash(IEnumerable< string > arguments, Func< IEnumerable< string >, Result< IEnumerable< Token >, Error > > tokenizer)
Definition Tokenizer.cs:54
Value(string text)
Definition Token.cs:90
Base type of all errors.
Definition Error.cs:110
Models an error generated when a user explicitly requests help.
Definition Error.cs:454
Models an error generated when an invalid token is detected.
Definition Error.cs:536
Models an error generated when a required option is required.
Definition Error.cs:392
Models an error generated when an option lacks its value.
Definition Error.cs:374
Models an error generated when a an option from another set is defined.
Definition Error.cs:401
Models name information, used in CommandLine.Error instances.
Definition NameInfo.cs:11
static readonly NameInfo EmptyName
Represents an empty name information. Used when CommandLine.Error are tied to values,...
Definition NameInfo.cs:16
It contains a sequence of CommandLine.Error.
It contains an instance of type T with parsed values.
Models a parser result. When inherited by CommandLine.Parsed<T>, it contains an instance of type T w...
IEnumerable< Error > Errors
Gets the sequence of parsing errors. If there are no errors, then an empty IEnumerable is returned.
T Value
Gets the instance with parsed values. If one or more errors occures, default is returned.
Models an error generated when a sequence value lacks elements.
Definition Error.cs:427
Models as error generated when exception is thrown at Property.SetValue.
Definition Error.cs:513
void Parse_int_sequence(string[] arguments, int[] expected)
void Parse_without_auto_version_should_not_recognize_version_option(string[] arguments, ErrorType errorType)
void Parse_nullable_int(string[] arguments, int? expected)
void Omitting_names_assumes_identifier_as_long_name(string[] arguments, string expected)
void Parse_with_custom_version_option(string[] arguments, bool isVersion)
void Parse_double_value(string[] arguments, double expected)
static ParserResult< T > InvokeBuild< T >(string[] arguments, bool autoHelp=true, bool autoVersion=true, bool multiInstance=false)
void Parse_fsharp_option_int(string[] arguments, int expectedValue, bool expectedSome)
void Parse_long_sequence_with_separator(string[] arguments, long[] expected)
void Can_define_options_on_interface_properties(string[] arguments, string expected)
void Specifying_options_two_or_more_times_with_short_options_generates_RepeatedOptionError(string[] arguments, int expected)
void Parse_without_auto_help_should_not_recognize_help_option(string[] arguments, ErrorType errorType)
void Specifying_options_two_or_more_times_with_long_options_generates_RepeatedOptionError(string[] arguments, int expected)
void Parse_string_sequence_with_only_max_constraint(string[] arguments, string[] expected)
void Breaking_required_constraint_generate_MissingRequiredOptionError(string[] arguments, int expected)
void Enforce_required_within_mutually_exclusive_set_only(string[] arguments, ParserResultType type, int expected)
void Specifying_options_two_or_more_times_with_mixed_short_long_options_generates_RepeatedOptionError(string[] arguments, int expected)
void Parse_string_with_dashes_except_in_beginning(string[] arguments, string expected)
void Can_define_options_on_explicit_interface_properties(string[] arguments, string expected)
static ParserResult< T > InvokeBuildEnumValuesCaseIgnore< T >(string[] arguments)
void Parse_utf8_string_correctly(string[] arguments, string expected)
void Parse_negative_long_value(string[] arguments, long expected)
void Parse_Guid(string[] arguments, Options_With_Guid expected)
void Parse_int_sequence_with_range(string[] arguments, int[] expected)
void Parse_string_scalar_with_required_constraint_as_value(string[] arguments, Options_With_Required_Set_To_True_For_Values expected)
void Parse_custom_class_type(string[] arguments, string expectedServer, int expectedPort)
void Parse_to_immutable_instance(string[] arguments, Immutable_Simple_Options expected)
void Parse_nullable_long(string[] arguments, long? expected)
void Parse_enum_value_ignore_case(string[] arguments, Colors expected)
static ParserResult< T > InvokeBuildImmutable< T >(string[] arguments)
void Parse_with_custom_help_option(string[] arguments, bool isHelp)
void Parse_string_sequence_with_separator(string[] arguments, string[] expected)
void Parse_enum_value(string[] arguments, Colors expected)
static IEnumerable< object[]> ScalarSequenceStringAdjacentData
void Parse_to_immutable_instance_with_Invalid_Ctor_Args(string[] arguments)
void Parse_sequence_value_without_range_constraints(string[] arguments, long[] expected)
void Specifying_options_two_or_more_times_generates_RepeatedOptionError(string[] arguments, int expected)
void Parse_custom_struct_type(string[] arguments, string expectedServer, int expectedPort)
void Options_In_Group_With_Values_Does_Not_Generate_MissingGroupOptionError(params string[] args)
void Empty_set_options_allowed_with_mutually_exclusive_sets(string[] arguments, ParserResultType type, int expected)
void Double_dash_force_subsequent_arguments_as_values()
https://github.com/gsscoder/commandline/issues/31
void Parse_fsharp_option_string(string[] arguments, string expectedValue, bool expectedSome)
void Parse_string_scalar_and_sequence_adjacent(string[] arguments, Options_With_Scalar_Value_And_Adjacent_SequenceString expected)
void Parse_string_sequence_with_only_min_constraint(string[] arguments, string[] expected)
static TypeInfo Create(Type current)
Models an error generated when an unknown option is detected.
Definition Error.cs:383
ParserResultType
Discriminator enumeration of CommandLine.ParserResultType derivates.
ErrorType
Discriminator enumeration of CommandLine.Error derivates.
Definition Error.cs:13