BadScript 2
Loading...
Searching...
No Matches
HelpTextTests.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 System;
4using System.Collections.Generic;
5using System.Globalization;
6using System.Linq;
7using System.Reflection;
8using System.Text;
9using Xunit;
10using FluentAssertions;
15
17{
18 public class HelpTextTests : IDisposable
19 {
20 private readonly HeadingInfo headingInfo = new HeadingInfo("CommandLine.Tests.dll", "1.9.4.131");
21
22 public void Dispose()
23 {
25 }
26
27 [Fact]
29 {
30 string.Empty.Should().BeEquivalentTo(new HelpText().ToString());
31 }
32
33 [Theory]
34 [InlineData(true)]
35 [InlineData(false)]
36 public void Create_instance_without_options(bool newlineBetweenSections)
37 {
38 // Fixture setup
39 // Exercize system
40 var sut =
41 new HelpText(new HeadingInfo("Unit-tests", "2.0"), new CopyrightInfo(true, "Author", 2005, 2013));
42 sut.AddNewLineBetweenHelpSections = newlineBetweenSections;
43 sut.AddPreOptionsLine("pre-options line 1")
44 .AddPreOptionsLine("pre-options line 2")
45 .AddPostOptionsLine("post-options line 1")
46 .AddPostOptionsLine("post-options line 2");
47
48 // Verify outcome
49 var expected = new List<string>()
50 {
51 "Unit-tests 2.0",
52 "Copyright (C) 2005 - 2013 Author",
53 "pre-options line 1",
54 "pre-options line 2",
55 "post-options line 1",
56 "post-options line 2"
57 };
58
59 if (newlineBetweenSections)
60 {
61 expected.Insert(2, "");
62 expected.Insert(5, "");
63 }
64
65 var lines = sut.ToString().ToLines();
66 lines.Should().StartWith(expected);
67 }
68
69 [Theory]
70 [InlineData(true)]
71 [InlineData(false)]
72 public void Create_instance_with_options(bool newlineBetweenSections)
73 {
74 // Fixture setup
75 // Exercize system
76 var sut = new HelpText { AddDashesToOption = true, AddNewLineBetweenHelpSections = newlineBetweenSections }
77 .AddPreOptionsLine("pre-options")
78 .AddOptions(new NotParsed<Simple_Options>(TypeInfo.Create(typeof(Simple_Options)), Enumerable.Empty<Error>()))
79 .AddPostOptionsLine("post-options");
80
81 // Verify outcome
82 var expected = new []
83 {
84 "",
85 "pre-options",
86 "",
87 "--stringvalue Define a string value here.",
88 "-s, --shortandlong Example with both short and long name.",
89 "-i Define a int sequence here.",
90 "-x Define a boolean or switch value here.",
91 "--help Display this help screen.",
92 "--version Display version information.",
93 "value pos. 0 Define a long value here.",
94 "",
95 "post-options"
96 };
97
98 var lines = sut.ToString().ToLines().TrimStringArray();
99 lines.Should().StartWith(expected);
100 }
101
102 [Fact]
104 {
105 // Fixture setup
106 // Exercize system
107 var sut = new HelpText { AddDashesToOption = true, AddEnumValuesToHelpText = true, MaximumDisplayWidth = 80 }
108 .AddPreOptionsLine("pre-options")
110 .AddPostOptionsLine("post-options");
111
112 // Verify outcome
113
114 var lines = sut.ToString().ToNotEmptyLines().TrimStringArray();
115 lines[0].Should().BeEquivalentTo("pre-options");
116 lines[1].Should().BeEquivalentTo("--stringvalue Define a string value here.");
117 lines[2].Should().BeEquivalentTo("--shape Define a enum value here. Valid values: Circle, Square,");
118 lines[3].Should().BeEquivalentTo("Triangle");
119 lines[4].Should().BeEquivalentTo("--help Display this help screen.");
120 lines[5].Should().BeEquivalentTo("--version Display version information.");
121 lines[6].Should().BeEquivalentTo("post-options");
122 // Teardown
123 }
124
125 [Fact]
127 {
128 // Fixture setup
129 // Exercize system
130 var sut = new HelpText { AddDashesToOption = true }
131 .AddPreOptionsLine("pre-options")
133 .AddPostOptionsLine("post-options");
134
135 // Verify outcome
136
137 var lines = sut.ToString().ToNotEmptyLines().TrimStringArray();
138 lines[0].Should().BeEquivalentTo("pre-options");
139 lines[1].Should().BeEquivalentTo("--stringvalue Define a string value here.");
140 lines[2].Should().BeEquivalentTo("--shape Define a enum value here.");
141 lines[3].Should().BeEquivalentTo("--help Display this help screen.");
142 lines[4].Should().BeEquivalentTo("--version Display version information.");
143 lines[5].Should().BeEquivalentTo("post-options");
144 // Teardown
145 }
146
147 [Fact]
149 {
150 // Fixture setup
151 // Exercize system
152 var sut =
153 new HelpText("Meta Value.").AddOptions(
155
156 // Verify outcome
157 var lines = sut.ToString().ToNotEmptyLines().TrimStringArray();
158
159 lines[2].Should().BeEquivalentTo("i FILE, input-file=FILE Required. Specify input FILE to be processed.");
160 // Teardown
161 }
162
163 [Fact]
165 {
166 // Fixture setup
167 // Exercize system
168 var sut = new HelpText(headingInfo);
169 sut.MaximumDisplayWidth = 40;
170 sut.AddOptions(
173 Enumerable.Empty<Error>()));
174
175 // Verify outcome
176 var lines = sut.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None);
177 lines[2].Should().BeEquivalentTo(" v, verbose This is the description"); //"The first line should have the arguments and the start of the Help Text.");
178 //string formattingMessage = "Beyond the second line should be formatted as though it's in a column.";
179 lines[3].Should().BeEquivalentTo(" of the verbosity to test");
180 lines[4].Should().BeEquivalentTo(" out the wrapping");
181 lines[5].Should().BeEquivalentTo(" capabilities of the Help");
182 lines[6].Should().BeEquivalentTo(" Text.");
183 // Teardown
184 }
185
186 [Fact]
188 {
189 // Fixture setup
190 // Exercize system
191 var sut = new HelpText(headingInfo) { MaximumDisplayWidth = 100 };
192 sut.AddOptions(
195 Enumerable.Empty<Error>()));
196
197 // Verify outcome
198 var lines = sut.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None);
199 lines[2].Should().BeEquivalentTo(" v, verbose This is the description of the verbosity to test out the wrapping capabilities of"); //"The first line should have the arguments and the start of the Help Text.");
200 //string formattingMessage = "Beyond the second line should be formatted as though it's in a column.";
201 lines[3].Should().BeEquivalentTo(" the Help Text.");
202 // Teardown
203 }
204
205 [Fact]
207 {
208 // Fixture setup
209 // Exercize system
210 var sut = new HelpText(headingInfo);
211 sut.MaximumDisplayWidth = 80;
212 sut.AddOptions(
215 Enumerable.Empty<Error>()));
216
217 // Verify outcome
218 var lines = sut.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None);
219 lines[2].Should().BeEquivalentTo(" v, verbose This is the description of the verbosity to test out the"); //"The first line should have the arguments and the start of the Help Text.");
220 //string formattingMessage = "Beyond the second line should be formatted as though it's in a column.";
221 lines[3].Should().BeEquivalentTo(" wrapping capabilities of the Help Text.");
222 // Teardown
223 }
224
225 [Fact]
227 {
228 // Fixture setup
229 // Exercize system
230 var sut = new HelpText(headingInfo);
231 sut.MaximumDisplayWidth = 40;
232 sut.AddOptions(
235 Enumerable.Empty<Error>()));
236
237 // Verify outcome
238 var lines = sut.ToString().ToNotEmptyLines();
239 lines[1].Should().BeEquivalentTo(" v, verbose Before");
240 lines[2].Should().BeEquivalentTo(" 012345678901234567890123");
241 lines[3].Should().BeEquivalentTo(" After");
242 lines[4].Should().BeEquivalentTo(" input-file Before");
243 lines[5].Should().BeEquivalentTo(" 012345678901234567890123");
244 lines[6].Should().BeEquivalentTo(" 456789 After");
245 // Teardown
246 }
247
248 [Fact]
250 {
251 // Fixture setup
252 // Exercize system
253 var sut = new HelpText("Heading Info.");
254 sut.MaximumDisplayWidth = 40;
255 sut.AddPreOptionsLine("Before 0123456789012345678901234567890123456789012 After")
257 .AddPostOptionsLine("Before 0123456789012345678901234567890123456789 After");
258
259 // Verify outcome
260 var lines = sut.ToString().ToNotEmptyLines();
261 lines[1].Should().BeEquivalentTo("Before");
262 lines[2].Should().BeEquivalentTo("0123456789012345678901234567890123456789");
263 lines[3].Should().BeEquivalentTo("012 After");
264 lines[lines.Length - 3].Should().BeEquivalentTo("Before");
265 lines[lines.Length - 2].Should().BeEquivalentTo("0123456789012345678901234567890123456789");
266 lines[lines.Length - 1].Should().BeEquivalentTo("After");
267
268 // Teardown
269 }
270
271 [Fact]
273 {
274 // Fixture setup
275 var optionsInGroup = new List<NameInfo>
276 {
277 new NameInfo("t", "testOption1"),
278 new NameInfo("c", "testOption2")
279 };
280 var fakeResult = new NotParsed<object>(
282 new Error[]
283 {
284 new BadFormatTokenError("badtoken"),
285 new MissingValueOptionError(new NameInfo("x", "switch")),
286 new UnknownOptionError("unknown"),
287 new MissingRequiredOptionError(new NameInfo("", "missing")),
288 new SequenceOutOfRangeError(new NameInfo("s", "sequence")),
290 new BadVerbSelectedError("badverb"),
291 new HelpRequestedError(), // should be ignored
292 new HelpVerbRequestedError(null, null, false), // should be ignored
293 new MissingGroupOptionError("bad-option-group", optionsInGroup),
294 });
295 Func<Error, string> fakeRenderer = err =>
296 {
297 switch (err.Tag)
298 {
299 case ErrorType.BadFormatTokenError:
300 return "ERR " + ((BadFormatTokenError)err).Token;
301 case ErrorType.MissingValueOptionError:
302 return "ERR " + ((MissingValueOptionError)err).NameInfo.NameText;
303 case ErrorType.UnknownOptionError:
304 return "ERR " + ((UnknownOptionError)err).Token;
305 case ErrorType.MissingRequiredOptionError:
306 return "ERR " + ((MissingRequiredOptionError)err).NameInfo.NameText;
307 case ErrorType.SequenceOutOfRangeError:
308 return "ERR " + ((SequenceOutOfRangeError)err).NameInfo.NameText;
309 case ErrorType.NoVerbSelectedError:
310 return "ERR no-verb-selected";
311 case ErrorType.BadVerbSelectedError:
312 return "ERR " + ((BadVerbSelectedError)err).Token;
313 case ErrorType.MissingGroupOptionError:
314 {
315 var groupErr = (MissingGroupOptionError)err;
316 return "ERR " + groupErr.Group + ": " + string.Join("---", groupErr.Names.Select(n => n.NameText));
317 }
318 default:
319 throw new InvalidOperationException();
320 }
321 };
322 Func<IEnumerable<MutuallyExclusiveSetError>, string> fakeMutExclRenderer =
323 _ => string.Empty;
324
325 // Exercize system
326 var errorsText = HelpText.RenderParsingErrorsText(fakeResult, fakeRenderer, fakeMutExclRenderer, 2);
327
328 // Verify outcome
329 var lines = errorsText.ToNotEmptyLines();
330 lines[0].Should().BeEquivalentTo(" ERR badtoken");
331 lines[1].Should().BeEquivalentTo(" ERR x, switch");
332 lines[2].Should().BeEquivalentTo(" ERR unknown");
333 lines[3].Should().BeEquivalentTo(" ERR missing");
334 lines[4].Should().BeEquivalentTo(" ERR s, sequence");
335 lines[5].Should().BeEquivalentTo(" ERR no-verb-selected");
336 lines[6].Should().BeEquivalentTo(" ERR badverb");
337 lines[7].Should().BeEquivalentTo(" ERR bad-option-group: t, testOption1---c, testOption2");
338 // Teardown
339 }
340
341 [Fact]
343 {
344 // Fixture setup
345 var fakeResult = new NotParsed<Simple_Options>(
347 new Error[]
348 {
349 new BadFormatTokenError("badtoken"),
350 new SequenceOutOfRangeError(new NameInfo("i", ""))
351 });
352
353 // Exercize system
354 var helpText = HelpText.AutoBuild(fakeResult);
355
356 // Verify outcome
357 var lines = helpText.ToString().ToLines().TrimStringArray();
358 lines[0].Should().Be(HeadingInfo.Default.ToString());
359 lines[1].Should().Be(CopyrightInfo.Default.ToString());
360 lines[2].Should().BeEmpty();
361 lines[3].Should().BeEquivalentTo("ERROR(S):");
362 lines[4].Should().BeEquivalentTo("Token 'badtoken' is not recognized.");
363 lines[5].Should().BeEquivalentTo("A sequence option 'i' is defined with fewer or more items than required.");
364 lines[6].Should().BeEmpty();
365 lines[7].Should().BeEquivalentTo("--stringvalue Define a string value here.");
366 lines[8].Should().BeEmpty();
367 lines[9].Should().BeEquivalentTo("-s, --shortandlong Example with both short and long name.");
368 lines[10].Should().BeEmpty();
369 lines[11].Should().BeEquivalentTo("-i Define a int sequence here.");
370 lines[12].Should().BeEmpty();
371 lines[13].Should().BeEquivalentTo("-x Define a boolean or switch value here.");
372 lines[14].Should().BeEmpty();
373 lines[15].Should().BeEquivalentTo("--help Display this help screen.");
374 // Teardown
375 }
376
377 [Fact]
379 {
380 // Fixture setup
381 var fakeResult = new NotParsed<object>(
383 new Error[]
384 {
385 new HelpVerbRequestedError("commit", typeof(Commit_Verb), true)
386 });
387
388 // Exercize system
389 var helpText = HelpText.AutoBuild(fakeResult);
390
391 // Verify outcome
392 var lines = helpText.ToString().ToLines().TrimStringArray();
393
394 lines[0].Should().Be(HeadingInfo.Default.ToString());
395 lines[1].Should().Be(CopyrightInfo.Default.ToString());
396 lines[2].Should().BeEmpty();
397 lines[3].Should().BeEquivalentTo("-p, --patch Use the interactive patch selection interface to chose which");
398 lines[4].Should().BeEquivalentTo("changes to commit.");
399 lines[5].Should().BeEmpty();
400 lines[6].Should().BeEquivalentTo("--amend Used to amend the tip of the current branch.");
401 lines[7].Should().BeEmpty();
402 lines[8].Should().BeEquivalentTo("-m, --message Use the given message as the commit message.");
403 lines[9].Should().BeEmpty();
404 lines[10].Should().BeEquivalentTo("--help Display this help screen.");
405 // Teardown
406 }
407
408 [Fact]
410 {
411 // Fixture setup
412 var fakeResult = new NotParsed<object>(
414 new Error[]
415 {
416 new HelpVerbRequestedError("commit", typeof(Commit_Verb), true)
417 });
418
419 // Exercize system
420 var helpText = HelpText.AutoBuild(fakeResult, maxDisplayWidth: 100);
421
422 // Verify outcome
423 var lines = helpText.ToString().ToNotEmptyLines().TrimStringArray();
424 lines[0].Should().Be(HeadingInfo.Default.ToString());
425 lines[1].Should().Be(CopyrightInfo.Default.ToString());
426 lines[2].Should().BeEquivalentTo("-p, --patch Use the interactive patch selection interface to chose which changes to commit.");
427 lines[3].Should().BeEquivalentTo("--amend Used to amend the tip of the current branch.");
428 lines[4].Should().BeEquivalentTo("-m, --message Use the given message as the commit message.");
429 lines[5].Should().BeEquivalentTo("--help Display this help screen.");
430 // Teardown
431 }
432
433 [Fact]
435 {
436 // Fixture setup
437 var verbTypes = Enumerable.Empty<Type>().Concat(
438 new[] { typeof(Add_Verb), typeof(Commit_Verb), typeof(Clone_Verb) });
439 var fakeResult = new NotParsed<object>(
441 verbTypes),
442 new Error[] { new HelpVerbRequestedError(null, null, false) });
443
444 // Exercize system
445 var helpText = HelpText.AutoBuild(fakeResult);
446
447 // Verify outcome
448 var lines = helpText.ToString().ToNotEmptyLines().TrimStringArray();
449
450 lines[0].Should().Be(HeadingInfo.Default.ToString());
451 lines[1].Should().Be(CopyrightInfo.Default.ToString());
452 lines[2].Should().BeEquivalentTo("add Add file contents to the index.");
453 lines[3].Should().BeEquivalentTo("commit Record changes to the repository.");
454 lines[4].Should().BeEquivalentTo("clone Clone a repository into a new directory.");
455 lines[5].Should().BeEquivalentTo("help Display more information on a specific command.");
456 lines[6].Should().BeEquivalentTo("version Display version information.");
457 // Teardown
458 }
459
460 [Fact]
462 {
463 // Fixture setup
464 // Exercize system
465 var sut = new HelpText { AddDashesToOption = true, AdditionalNewLineAfterOption = false }
466 .AddPreOptionsLine("pre-options")
468 .AddPostOptionsLine("post-options");
469
470 // Verify outcome
471
472 var lines = sut.ToString().ToLines().TrimStringArray();
473 lines[0].Should().BeEmpty();
474 lines[1].Should().BeEquivalentTo("pre-options");
475 lines[2].Should().BeEmpty();
476 lines[3].Should().BeEquivalentTo("--stringvalue=STR Define a string value here.");
477 lines[4].Should().BeEquivalentTo("-i INTSEQ Define a int sequence here.");
478 lines[5].Should().BeEquivalentTo("-x Define a boolean or switch value here.");
479 lines[6].Should().BeEquivalentTo("--help Display this help screen.");
480 lines[7].Should().BeEquivalentTo("--version Display version information.");
481 lines[8].Should().BeEquivalentTo("number (pos. 0) NUM Define a long value here.");
482 lines[9].Should().BeEquivalentTo("paintcolor (pos. 1) COLOR Define a color value here.");
483 lines[10].Should().BeEmpty();
484 lines[11].Should().BeEquivalentTo("post-options", lines[11]);
485 // Teardown
486 }
487
488 [Fact]
490 {
491 // Fixture setup
494 TypeInfo.Create(typeof(Options_With_Usage_Attribute)), Enumerable.Empty<Error>());
495
496 // Exercize system
497 var text = HelpText.RenderUsageText(result);
498
499 // Verify outcome
500 var lines = text.ToNotEmptyLines();
501
502 // Teardown
503 lines[0].Should().BeEquivalentTo("Normal scenario:");
504 lines[1].Should().BeEquivalentTo(" mono testapp.exe --input file.bin --output out.bin");
505 lines[2].Should().BeEquivalentTo("Logging warnings:");
506 lines[3].Should().BeEquivalentTo(" mono testapp.exe -w --input file.bin");
507 lines[4].Should().BeEquivalentTo("Logging errors:");
508 lines[5].Should().BeEquivalentTo(" mono testapp.exe -e --input file.bin");
509 lines[6].Should().BeEquivalentTo(" mono testapp.exe --errs --input=file.bin");
510 lines[7].Should().BeEquivalentTo("List:");
511 lines[8].Should().BeEquivalentTo(" mono testapp.exe -l 1,2");
512 lines[9].Should().BeEquivalentTo("Value:");
513 lines[10].Should().BeEquivalentTo(" mono testapp.exe value");
514 }
515
516 [Theory]
517 [InlineData(true)]
518 [InlineData(false)]
520 {
521 // Fixture setup
522 var fakeResult = new NotParsed<Options_With_Usage_Attribute>(
524 new Error[]
525 {
526 new BadFormatTokenError("badtoken")
527 });
528
529 // Exercize system
530 var helpText = HelpText.AutoBuild(fakeResult,
531 h =>
532 {
533 h.AddNewLineBetweenHelpSections = newlineBetweenSections;
534 return HelpText.DefaultParsingErrorsHandler(fakeResult, h);
535 },
536 e => e
537 );
538
539 // Verify outcome
540 var expected = new List<string>()
541 {
544 "",
545 "ERROR(S):",
546 "Token 'badtoken' is not recognized.",
547 "USAGE:",
548 "Normal scenario:",
549 "mono testapp.exe --input file.bin --output out.bin",
550 "Logging warnings:",
551 "mono testapp.exe -w --input file.bin",
552 "Logging errors:",
553 "mono testapp.exe -e --input file.bin",
554 "mono testapp.exe --errs --input=file.bin",
555 "List:",
556 "mono testapp.exe -l 1,2",
557 "Value:",
558 "mono testapp.exe value",
559 "",
560 "-i, --input Set input file.",
561 "",
562 "-i, --output Set output file.",
563 "",
564 "--verbose Set verbosity level.",
565 "",
566 "-w, --warns Log warnings.",
567 "",
568 "-e, --errs Log errors.",
569 "",
570 "-l List.",
571 "",
572 "--help Display this help screen.",
573 "",
574 "--version Display version information.",
575 "",
576 "value pos. 0 Value."
577 };
578
579 if (newlineBetweenSections)
580 expected.Insert(5, "");
581
582 var text = helpText.ToString();
583 var lines = text.ToLines().TrimStringArray();
584
585 lines.Should().StartWith(expected);
586 }
587
588 [Theory]
589 [InlineData(true, true)]
590 [InlineData(true, false)]
591 [InlineData(false, true)]
592 [InlineData(false, false)]
593 public void AutoBuild_with_errors_and_preoptions_renders_correctly(bool startWithNewline, bool newlineBetweenSections)
594 {
595 // Fixture setup
598 new Error[]
599 {
600 new BadFormatTokenError("badtoken")
601 });
602
603 // Exercize system
604 var helpText = HelpText.AutoBuild(fakeResult,
605 h =>
606 {
607 h.AddNewLineBetweenHelpSections = newlineBetweenSections;
608 h.AddPreOptionsLine((startWithNewline ? Environment.NewLine : null) + "pre-options");
609 return HelpText.DefaultParsingErrorsHandler(fakeResult, h);
610 },
611 e => e
612 );
613
614 // Verify outcome
615 var expected = new List<string>()
616 {
619 "pre-options",
620 "",
621 "ERROR(S):",
622 "Token 'badtoken' is not recognized.",
623 "",
624 "-v, --verbose",
625 "",
626 "--input-file"
627 };
628
629 if (newlineBetweenSections || startWithNewline)
630 expected.Insert(2, "");
631
632 var text = helpText.ToString();
633 var lines = text.ToLines().TrimStringArray();
634
635 lines.Should().StartWith(expected);
636 }
637
638 [Fact]
640 {
641 // Fixture setup
642 var handlers = new CultureInfo("en-US").MakeCultureHandlers();
643 var fakeResult =
645 typeof(Options_With_Default_Set_To_Sequence).ToTypeInfo(),
646 new Error[] { new BadFormatTokenError("badtoken") });
647
648 // Exercize system
649 handlers.ChangeCulture();
650 var helpText = HelpText.AutoBuild(fakeResult);
651 handlers.ResetCulture();
652
653 // Verify outcome
654 var text = helpText.ToString();
655 var lines = text.ToNotEmptyLines().TrimStringArray();
656
657 lines[4].Should().Be("-z, --strseq (Default: a b c)");
658 lines[5].Should().Be("-y, --intseq (Default: 1 2 3)");
659 lines[6].Should().Be("-q, --dblseq (Default: 1.1 2.2 3.3)");
660
661 // Teardown
662 }
663
664 [Fact]
666 {
667 string expectedCopyright = $"Copyright (C) {DateTime.Now.Year} author";
668
669 ReflectionHelper.SetAttributeOverride(new Attribute[0]);
670
672 TypeInfo.Create(typeof(Simple_Options)), new Error[0]);
673 HelpText actualResult = HelpText.AutoBuild(fakeResult, ht => ht, ex => ex);
674 actualResult.Copyright.Should().Be(expectedCopyright);
675 }
676
677
678 [Fact]
680 {
681 string expectedTitle = "Title";
682 string expectedVersion = "1.2.3.4";
683
685 {
686 new AssemblyTitleAttribute(expectedTitle),
687 new AssemblyInformationalVersionAttribute(expectedVersion)
688 });
689
691 TypeInfo.Create(typeof(Simple_Options)), new Error[0]);
692 HelpText actualResult = HelpText.AutoBuild(fakeResult, ht => ht, ex => ex);
693 actualResult.Heading.Should().Be(string.Format("{0} {1}", expectedTitle, expectedVersion));
694 }
695
696 [Fact]
698 {
699 string expectedCompany = "Company";
700
702 {
703 new AssemblyCompanyAttribute(expectedCompany)
704 });
705
707 TypeInfo.Create(typeof(Simple_Options)), new Error[0]);
708 bool onErrorCalled = false;
709 HelpText actualResult = HelpText.AutoBuild(fakeResult, ht =>
710 {
711 onErrorCalled = true;
712 return ht;
713 }, ex => ex);
714
715 onErrorCalled.Should().BeFalse(); // Other attributes have fallback logic
716 actualResult.Copyright.Should().Be(string.Format("Copyright (C) {0} {1}", DateTime.Now.Year, expectedCompany));
717 }
718
719 [Fact]
721 {
722 StringBuilder b = new StringBuilder();
724 "Test ",
725 1);
726
727 Assert.Equal("T" + Environment.NewLine + "e" + Environment.NewLine + "s" + Environment.NewLine + "t", b.ToString());
728 }
729
730 [Fact]
732 {
733 // Fixture setup
734 // Exercize system
735 var sut = new HelpText { AddDashesToOption = true }
737 Enumerable.Empty<Error>()));
738
739 // Verify outcome
740
741 var lines = sut.ToString().ToNotEmptyLines();
742 lines[0].Should().BeEquivalentTo(" --stringvalue This is a help text description.");
743 lines[1].Should().BeEquivalentTo(" It has multiple lines.");
744 lines[2].Should().BeEquivalentTo(" We also want to ensure that indentation is correct.");
745
746 // Teardown
747 }
748
749 [Fact]
751 {
752 // Fixture setup
753 // Exercize system
754 var sut = new HelpText { AddDashesToOption = true }
756 Enumerable.Empty<Error>()));
757
758 // Verify outcome
759
760 var lines = sut.ToString().ToNotEmptyLines();
761 lines[3].Should().BeEquivalentTo(" --stringvalu2 This is a help text description where we want");
762 lines[4].Should().BeEquivalentTo(" the left pad after a linebreak to be honoured so that");
763 lines[5].Should().BeEquivalentTo(" we can sub-indent within a description.");
764
765 // Teardown
766 }
767
768 [Fact]
770 {
771 // Fixture setup
772 // Exercise system
773 var sut = new HelpText { AddDashesToOption = true, MaximumDisplayWidth = 60 }
775 Enumerable.Empty<Error>()));
776
777 // Verify outcome
778
779 var lines = sut.ToString().ToNotEmptyLines();
780 lines[0].Should().BeEquivalentTo(" --stringvalue This is a help text description where we");
781 lines[1].Should().BeEquivalentTo(" want:");
782 lines[2].Should().BeEquivalentTo(" * The left pad after a linebreak to");
783 lines[3].Should().BeEquivalentTo(" be honoured and the indentation to be");
784 lines[4].Should().BeEquivalentTo(" preserved across to the next line");
785 lines[5].Should().BeEquivalentTo(" * The ability to return to no indent.");
786 lines[6].Should().BeEquivalentTo(" Like this.");
787
788 // Teardown
789 }
790
791 [Fact]
793 {
794 // Fixture setup
795 // Exercize system
796 var sut = new HelpText { AddDashesToOption = true }
798 Enumerable.Empty<Error>()));
799
800 // Verify outcome
801
802 var lines = sut.ToString().ToNotEmptyLines();
803 lines[0].Should().BeEquivalentTo(" --stringvalue This is a help text description");
804 lines[1].Should().BeEquivalentTo(" It has multiple lines.");
805 lines[2].Should().BeEquivalentTo(" Third line");
806
807 // Teardown
808 }
809
810 [Fact]
812 {
813 // Fixture setup
814 // Exercise system
815 var sut = new HelpText { AddDashesToOption = true, MaximumDisplayWidth = 10 }
817 Enumerable.Empty<Error>()));
818
819 // Verify outcome
820
821 Assert.True(sut.ToString().Length > 0);
822
823 // Teardown
824 }
825
826 [Fact]
828 {
829 // Fixture setup
830 var handlers = new CultureInfo("en-US").MakeCultureHandlers();
831 var fakeResult =
833 typeof(Options_With_Default_Set_To_Sequence).ToTypeInfo(),
834 Enumerable.Empty<Error>()
835 );
836
837 // Exercize system
838 handlers.ChangeCulture();
839 var helpText = HelpText.AutoBuild(fakeResult);
840 handlers.ResetCulture();
841
842 // Verify outcome
843 var text = helpText.ToString();
844 var lines = text.ToLines().TrimStringArray();
845
846 lines[3].Should().Be("-z, --strseq (Default: a b c)");
847 lines[5].Should().Be("-y, --intseq (Default: 1 2 3)");
848 lines[7].Should().Be("-q, --dblseq (Default: 1.1 2.2 3.3)");
849
850 // Teardown
851 }
852
853 [Fact]
855 {
856 var sut = new HelpText(headingInfo) { AddDashesToOption = true, MaximumDisplayWidth = 100 }
857 .AddOptions(
859
860 var text = sut.ToString();
861 var lines = text.ToLines().TrimStringArray();
862
863
864 lines[0].Should().BeEquivalentTo(headingInfo.ToString());
865 lines[1].Should().BeEmpty();
866 lines[2].Should().BeEquivalentTo("--stringvalue (Group: string-group) Define a string value here.");
867 lines[3].Should().BeEquivalentTo("-s, --shortandlong (Group: string-group) Example with both short and long name.");
868 lines[4].Should().BeEquivalentTo("-x Define a boolean or switch value here.");
869 lines[5].Should().BeEquivalentTo("--help Display this help screen.");
870 lines[6].Should().BeEquivalentTo("--version Display version information.");
871 }
872
873 [Fact]
875 {
876 var sut = new HelpText(headingInfo) { AddDashesToOption = true, MaximumDisplayWidth = 100 }
877 .AddOptions(
879
880 var text = sut.ToString();
881 var lines = text.ToLines().TrimStringArray();
882
883
884 lines[0].Should().BeEquivalentTo(headingInfo.ToString());
885 lines[1].Should().BeEmpty();
886 lines[2].Should().BeEquivalentTo("--stringvalue (Group: string-group) Define a string value here.");
887 lines[3].Should().BeEquivalentTo("-s, --shortandlong (Group: string-group) Example with both short and long name.");
888 lines[4].Should().BeEquivalentTo("-x Define a boolean or switch value here.");
889 lines[5].Should().BeEquivalentTo("--help Display this help screen.");
890 lines[6].Should().BeEquivalentTo("--version Display version information.");
891 }
892
893 [Fact]
895 {
896 var sut = new HelpText(headingInfo) { AddDashesToOption = true, MaximumDisplayWidth = 100 }
897 .AddOptions(
899
900 var text = sut.ToString();
901 var lines = text.ToLines().TrimStringArray();
902
903
904 lines[0].Should().BeEquivalentTo(headingInfo.ToString());
905 lines[1].Should().BeEmpty();
906 lines[2].Should().BeEquivalentTo("--stringvalue (Group: string-group) Define a string value here.");
907 lines[3].Should().BeEquivalentTo("-s, --shortandlong (Group: string-group) Example with both short and long name.");
908 lines[4].Should().BeEquivalentTo("-x (Group: second-group) Define a boolean or switch value here.");
909 lines[5].Should().BeEquivalentTo("-i (Group: second-group) Define a int sequence here.");
910 lines[6].Should().BeEquivalentTo("--help Display this help screen.");
911 lines[7].Should().BeEquivalentTo("--version Display version information.");
912 }
913
914 #region Custom Help
915
916 [Fact]
917 [Trait("Category", "CustomHelp")]
919 {
920 string expectedCopyright = "Copyright (c) 2019 Global.com";
921 var expectedHeading = "MyApp 2.0.0-beta";
924 new Error[] { new HelpRequestedError() });
925 bool onErrorCalled = false;
926 HelpText actualResult = HelpText.AutoBuild(fakeResult, ht =>
927 {
928 ht.AdditionalNewLineAfterOption = false;
929 ht.Heading = "MyApp 2.0.0-beta";
930 ht.Copyright = "Copyright (c) 2019 Global.com";
931 return ht;
932 });
933 actualResult.Copyright.Should().Be(expectedCopyright);
934 actualResult.Heading.Should().Be(expectedHeading);
935 }
936
937 [Fact]
938 [Trait("Category", "CustomHelp")]
940 {
941 string expectedTitle = "Title";
942 string expectedVersion = "1.2.3.4";
943
945 {
946 new AssemblyTitleAttribute(expectedTitle),
947 new AssemblyInformationalVersionAttribute(expectedVersion)
948 });
949
952 new Error[] { new VersionRequestedError() });
953
954 HelpText helpText = HelpText.AutoBuild(fakeResult, ht => ht);
955 helpText.ToString().Trim().Should().Be($"{expectedTitle} {expectedVersion}");
956 }
957 [Fact]
958 [Trait("Category", "CustomHelp")]
960 {
961 // Fixture setup
962 var fakeResult = new NotParsed<object>(
964 new Error[]
965 {
966 new HelpVerbRequestedError("commit", typeof(Commit_Verb), true)
967 });
968
969 // Exercize system
970 var helpText = HelpText.AutoBuild(fakeResult, h => {
971 h.AdditionalNewLineAfterOption = false;
972 return h;
973 });
974
975 // Verify outcome
976 var lines = helpText.ToString().ToLines().TrimStringArray();
977 var i = 0;
978 lines[i++].Should().Be(HeadingInfo.Default.ToString());
979 lines[i++].Should().Be(CopyrightInfo.Default.ToString());
980 lines[i++].Should().BeEmpty();
981 lines[i++].Should().BeEquivalentTo("-p, --patch Use the interactive patch selection interface to chose which");
982 lines[i++].Should().BeEquivalentTo("changes to commit.");
983 lines[i++].Should().BeEquivalentTo("--amend Used to amend the tip of the current branch.");
984 lines[i++].Should().BeEquivalentTo("-m, --message Use the given message as the commit message.");
985 lines[i++].Should().BeEquivalentTo("--help Display this help screen.");
986
987 }
988 [Fact]
989 [Trait("Category", "CustomHelp")]
991 {
992 // Fixture setup
993 var fakeResult = new NotParsed<Simple_Options>(
995 new Error[]
996 {
997 new BadFormatTokenError("badtoken"),
998 new SequenceOutOfRangeError(new NameInfo("i", ""))
999 });
1000
1001 // Exercize system
1002 var helpText = HelpText.AutoBuild(fakeResult, h => h);
1003
1004 // Verify outcome
1005 var lines = helpText.ToString().ToLines().TrimStringArray();
1006 lines[0].Should().Be(HeadingInfo.Default.ToString());
1007 lines[1].Should().Be(CopyrightInfo.Default.ToString());
1008 lines[2].Should().BeEmpty();
1009 lines[3].Should().BeEquivalentTo("ERROR(S):");
1010 lines[4].Should().BeEquivalentTo("Token 'badtoken' is not recognized.");
1011 lines[5].Should().BeEquivalentTo("A sequence option 'i' is defined with fewer or more items than required.");
1012 lines[6].Should().BeEmpty();
1013 lines[7].Should().BeEquivalentTo("--stringvalue Define a string value here.");
1014 lines[8].Should().BeEmpty();
1015 lines[9].Should().BeEquivalentTo("-s, --shortandlong Example with both short and long name.");
1016 lines[10].Should().BeEmpty();
1017 lines[11].Should().BeEquivalentTo("-i Define a int sequence here.");
1018 lines[12].Should().BeEmpty();
1019 lines[13].Should().BeEquivalentTo("-x Define a boolean or switch value here.");
1020 lines[14].Should().BeEmpty();
1021 lines[15].Should().BeEquivalentTo("--help Display this help screen.");
1022
1023 }
1024 #endregion
1025 }
1026}
Models an error generated when an invalid token is detected.
Definition Error.cs:286
Models an error generated when an unknown verb is detected.
Definition Error.cs:445
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 a user explicitly requests help in verb commands scenario.
Definition Error.cs:463
static void SetAttributeOverride(IEnumerable< Attribute > overrides)
Assembly attribute overrides for testing.
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 name information, used in CommandLine.Error instances.
Definition NameInfo.cs:11
Models an error generated when no verb is selected.
Definition Error.cs:495
It contains a sequence of CommandLine.Error.
Models a null result when constructing a ParserResult<T> in a faling verbs scenario.
Models a parser result. When inherited by CommandLine.Parsed<T>, it contains an instance of type T w...
Models an error generated when a sequence value lacks elements.
Definition Error.cs:427
void When_help_text_is_longer_than_width_it_will_wrap_around_as_if_in_a_column_given_width_of_100()
void Options_Should_Render_OptionGroup_When_Available_And_Should_Not_Render_Required()
void Invoke_AutoBuild_for_Verbs_with_unknown_verb_returns_appropriate_formatted_text()
void Invoke_AutoBuild_for_Verbs_with_specific_verb_returns_appropriate_formatted_text()
void When_help_text_is_longer_than_width_it_will_wrap_around_as_if_in_a_column_given_width_of_40()
void HelpTextPreservesIndentationAcrossWordWrapWithSmallMaximumDisplayWidth()
void Invoke_AutoBuild_for_Options_with_Usage_returns_appropriate_formatted_text(bool newlineBetweenSections)
void AutoBuild_with_errors_and_preoptions_renders_correctly(bool startWithNewline, bool newlineBetweenSections)
void Invoke_AutoBuild_for_Verbs_with_specific_verb_returns_appropriate_formatted_text_given_display_width_100()
void Create_instance_without_options(bool newlineBetweenSections)
void Invoke_Custom_AutoBuild_for_Verbs_with_specific_verb_and_no_AdditionalNewLineAfterOption_returns_appropriate_formatted_text()
void Invoke_AutoBuild_for_Options_with_custom_help_returns_appropriate_formatted_text()
void When_help_text_has_hidden_option_it_should_not_be_added_to_help_text_output()
void Create_instance_with_options(bool newlineBetweenSections)
Models the heading part of an help text. You can assign it where you assign any System....
static HeadingInfo Default
Gets the default heading instance. The title is retrieved from AssemblyTitleAttribute,...
override string ToString()
Returns the heading as a System.String.
HelpText AddPreOptionsLine(string value)
Adds a text line after copyright and before options usage strings.
Definition HelpText.cs:494
HelpText AddPostOptionsLine(string value)
Adds a text line at the bottom, after options usage string.
Definition HelpText.cs:505
static void AddLine(StringBuilder builder, string value, int maximumLength)
Definition HelpText.cs:879
string Copyright
Gets or sets the copyright string. You can directly assign a CommandLine.Text.CopyrightInfo instance.
Definition HelpText.cs:174
string Heading
Gets or sets the heading string. You can directly assign a CommandLine.Text.HeadingInfo instance.
Definition HelpText.cs:156
override string ToString()
Returns the help screen as a System.String.
Definition HelpText.cs:830
static TypeInfo Create(Type current)
Models an error generated when an unknown option is detected.
Definition Error.cs:383
Models an error generated when a user explicitly requests version.
Definition Error.cs:504
ErrorType
Discriminator enumeration of CommandLine.Error derivates.
Definition Error.cs:13