Skip to content

Commit d18f598

Browse files
committed
consolidate and clean up a few tests
1 parent fe66356 commit d18f598

File tree

6 files changed

+440
-603
lines changed

6 files changed

+440
-603
lines changed

src/System.CommandLine.Tests/Binding/SetHandlerTests.cs

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/System.CommandLine.Tests/Help/HelpBuilderTests.Customization.cs

Lines changed: 249 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// Copyright (c) .NET Foundation and contributors. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4+
using System.Collections.Generic;
45
using System.CommandLine.Help;
56
using System.IO;
7+
using System.Linq;
68
using FluentAssertions;
79
using Xunit;
810
using static System.Environment;
@@ -29,9 +31,9 @@ public Customization()
2931
private HelpBuilder GetHelpBuilder(int maxWidth) => new (maxWidth);
3032

3133
[Fact]
32-
public void Option_can_customize_default_value()
34+
public void Option_can_customize_displayed_default_value()
3335
{
34-
var option = new Option<string>("--the-option") { DefaultValueFactory = (_) => "not 42" };
36+
var option = new Option<string>("--the-option") { DefaultValueFactory = _ => "not 42" };
3537
var command = new Command("the-command", "command help")
3638
{
3739
option
@@ -136,9 +138,9 @@ public void Option_can_customize_second_column_text_based_on_parse_result()
136138
ctx.Command.Equals(commandA)
137139
? optionADescription
138140
: optionBDescription);
139-
command.Options.Add(new HelpOption()
141+
command.Options.Add(new HelpOption
140142
{
141-
Action = new HelpAction()
143+
Action = new HelpAction
142144
{
143145
Builder = helpBuilder
144146
}
@@ -201,7 +203,7 @@ public void Command_arguments_can_customize_second_column_text()
201203
var argument = new Argument<string>("some-arg")
202204
{
203205
Description = "Default description",
204-
DefaultValueFactory = (_) => "not 42"
206+
DefaultValueFactory = _ => "not 42"
205207
};
206208
var command = new Command("the-command", "command help")
207209
{
@@ -313,9 +315,9 @@ public void Argument_can_fallback_to_default_when_customizing(
313315

314316
CommandLineConfiguration config = new (command);
315317

316-
command.Options.Add(new HelpOption()
318+
command.Options.Add(new HelpOption
317319
{
318-
Action = new HelpAction()
320+
Action = new HelpAction
319321
{
320322
Builder = helpBuilder
321323
}
@@ -325,6 +327,246 @@ public void Argument_can_fallback_to_default_when_customizing(
325327
command.Parse("test -h", config).Invoke();
326328
config.Output.ToString().Should().MatchRegex(expected);
327329
}
330+
331+
332+
[Fact]
333+
public void Individual_symbols_can_be_customized()
334+
{
335+
var subcommand = new Command("subcommand", "The default command description");
336+
var option = new Option<int>("-x") { Description = "The default option description" };
337+
var argument = new Argument<int>("int-value") { Description = "The default argument description" };
338+
339+
var rootCommand = new RootCommand
340+
{
341+
subcommand,
342+
option,
343+
argument,
344+
};
345+
346+
CommandLineConfiguration config = new(rootCommand)
347+
{
348+
Output = new StringWriter()
349+
};
350+
351+
ParseResult parseResult = rootCommand.Parse("-h", config);
352+
353+
if (parseResult.Action is HelpAction helpAction)
354+
{
355+
helpAction.Builder.CustomizeSymbol(subcommand, secondColumnText: "The custom command description");
356+
helpAction.Builder.CustomizeSymbol(option, secondColumnText: "The custom option description");
357+
helpAction.Builder.CustomizeSymbol(argument, secondColumnText: "The custom argument description");
358+
}
359+
360+
parseResult.Invoke();
361+
362+
config.Output
363+
.ToString()
364+
.Should()
365+
.ContainAll("The custom command description",
366+
"The custom option description",
367+
"The custom argument description");
368+
}
369+
370+
[Fact]
371+
public void Help_sections_can_be_replaced()
372+
{
373+
CommandLineConfiguration config = new(new RootCommand())
374+
{
375+
Output = new StringWriter()
376+
};
377+
378+
ParseResult parseResult = config.Parse("-h");
379+
380+
if (parseResult.Action is HelpAction helpAction)
381+
{
382+
helpAction.Builder.CustomizeLayout(CustomLayout);
383+
}
384+
385+
parseResult.Invoke();
386+
387+
config.Output.ToString().Should().Be($"one{NewLine}{NewLine}two{NewLine}{NewLine}three{NewLine}{NewLine}{NewLine}");
388+
389+
IEnumerable<Action<HelpContext>> CustomLayout(HelpContext _)
390+
{
391+
yield return ctx => ctx.Output.WriteLine("one");
392+
yield return ctx => ctx.Output.WriteLine("two");
393+
yield return ctx => ctx.Output.WriteLine("three");
394+
}
395+
}
396+
397+
[Fact]
398+
public void Help_sections_can_be_supplemented()
399+
{
400+
CommandLineConfiguration config = new(new RootCommand("hello"))
401+
{
402+
Output = new StringWriter(),
403+
};
404+
405+
ParseResult parseResult = config.Parse("-h");
406+
407+
if (parseResult.Action is HelpAction helpAction)
408+
{
409+
helpAction.Builder.CustomizeLayout(CustomLayout);
410+
}
411+
412+
parseResult.Invoke();
413+
414+
var output = config.Output.ToString();
415+
var defaultHelp = GetDefaultHelp(config.RootCommand);
416+
417+
var expected = $"first{NewLine}{NewLine}{defaultHelp}last{NewLine}{NewLine}";
418+
419+
output.Should().Be(expected);
420+
421+
IEnumerable<Action<HelpContext>> CustomLayout(HelpContext _)
422+
{
423+
yield return ctx => ctx.Output.WriteLine("first");
424+
425+
foreach (var section in HelpBuilder.Default.GetLayout())
426+
{
427+
yield return section;
428+
}
429+
430+
yield return ctx => ctx.Output.WriteLine("last");
431+
}
432+
}
433+
434+
[Fact]
435+
public void Layout_can_be_composed_dynamically_based_on_context()
436+
{
437+
HelpBuilder helpBuilder = new();
438+
var commandWithTypicalHelp = new Command("typical");
439+
var commandWithCustomHelp = new Command("custom");
440+
var command = new RootCommand
441+
{
442+
commandWithTypicalHelp,
443+
commandWithCustomHelp
444+
};
445+
446+
command.Options.OfType<HelpOption>().Single().Action = new HelpAction()
447+
{
448+
Builder = helpBuilder
449+
};
450+
451+
var config = new CommandLineConfiguration(command);
452+
helpBuilder.CustomizeLayout(c =>
453+
c.Command == commandWithTypicalHelp
454+
? HelpBuilder.Default.GetLayout()
455+
: new Action<HelpContext>[]
456+
{
457+
c => c.Output.WriteLine("Custom layout!")
458+
}
459+
.Concat(HelpBuilder.Default.GetLayout()));
460+
461+
var typicalOutput = new StringWriter();
462+
config.Output = typicalOutput;
463+
command.Parse("typical -h", config).Invoke();
464+
465+
var customOutput = new StringWriter();
466+
config.Output = customOutput;
467+
command.Parse("custom -h", config).Invoke();
468+
469+
typicalOutput.ToString().Should().Be(GetDefaultHelp(commandWithTypicalHelp, false));
470+
customOutput.ToString().Should().Be($"Custom layout!{NewLine}{NewLine}{GetDefaultHelp(commandWithCustomHelp, false)}");
471+
}
472+
473+
[Fact]
474+
public void Help_default_sections_can_be_wrapped()
475+
{
476+
Command command = new("test")
477+
{
478+
new Option<string>("--option")
479+
{
480+
Description = "option description",
481+
HelpName = "option"
482+
},
483+
new HelpOption
484+
{
485+
Action = new HelpAction
486+
{
487+
Builder = new HelpBuilder(30)
488+
}
489+
}
490+
};
491+
492+
CommandLineConfiguration config = new(command)
493+
{
494+
Output = new StringWriter()
495+
};
496+
497+
config.Invoke("test -h");
498+
499+
string result = config.Output.ToString();
500+
result.Should().Be(
501+
$"Description:{NewLine}{NewLine}" +
502+
$"Usage:{NewLine} test [options]{NewLine}{NewLine}" +
503+
$"Options:{NewLine}" +
504+
$" --option option {NewLine}" +
505+
$" <option> description{NewLine}" +
506+
$" -?, -h, Show help and {NewLine}" +
507+
$" --help usage {NewLine}" +
508+
$" information{NewLine}{NewLine}{NewLine}");
509+
}
510+
511+
[Fact]
512+
public void Help_customized_sections_can_be_wrapped()
513+
{
514+
CommandLineConfiguration config = new(new RootCommand())
515+
{
516+
Output = new StringWriter()
517+
};
518+
519+
ParseResult parseResult = config.Parse("-h");
520+
521+
if (parseResult.Action is HelpAction helpAction)
522+
{
523+
helpAction.Builder = new HelpBuilder(10);
524+
helpAction.Builder.CustomizeLayout(CustomLayout);
525+
}
526+
527+
parseResult.Invoke();
528+
529+
string result = config.Output.ToString();
530+
result.Should().Be($" 123 123{NewLine} 456 456{NewLine} 78 789{NewLine} 0{NewLine}{NewLine}{NewLine}");
531+
532+
IEnumerable<Action<HelpContext>> CustomLayout(HelpContext _)
533+
{
534+
yield return ctx => ctx.HelpBuilder.WriteColumns(new[] { new TwoColumnHelpRow("12345678", "1234567890") }, ctx);
535+
}
536+
}
537+
538+
private string GetDefaultHelp(Command command, bool trimOneNewline = true)
539+
{
540+
// The command might have already defined a HelpOption with custom settings,
541+
// we need to overwrite it to get the actual defaults.
542+
HelpOption defaultHelp = new();
543+
// HelpOption overrides Equals and treats every other instance of same type as equal
544+
int index = command.Options.IndexOf(defaultHelp);
545+
if (index >= 0)
546+
{
547+
command.Options[index] = defaultHelp;
548+
}
549+
else
550+
{
551+
command.Options.Add(defaultHelp);
552+
}
553+
554+
CommandLineConfiguration config = new(command)
555+
{
556+
Output = new StringWriter()
557+
};
558+
559+
config.Invoke("-h");
560+
561+
var output = config.Output.ToString();
562+
563+
if (trimOneNewline)
564+
{
565+
output = output.Substring(0, output.Length - NewLine.Length);
566+
}
567+
568+
return output;
569+
}
328570
}
329571
}
330572
}

0 commit comments

Comments
 (0)