Exemple #1
0
        public async Task Property_of_type_nullable_TimeSpan_is_bound_as_null_if_the_argument_value_is_not_set()
        {
            // Arrange
            var(console, stdOut, _) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <SupportedArgumentTypesCommand>()
                              .UseConsole(console)
                              .Build();

            // Act
            int exitCode = await application.RunAsync(new[]
            {
                "cmd", "--timespan-nullable"
            });

            var commandInstance = stdOut.GetString().DeserializeJson <SupportedArgumentTypesCommand>();

            // Assert
            exitCode.Should().Be(ExitCodes.Success);

            commandInstance.Should().BeEquivalentTo(new SupportedArgumentTypesCommand
            {
                TimeSpanNullable = null
            });
        }
Exemple #2
0
        public async Task Custom_directive_should_have_non_empty_name()
        {
            // Arrange
            var(console, stdOut, stdErr) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <NamedCommand>()
                              .UseConsole(console)
                              .AddDirective <PreviewDirective>()
                              .AddDirective <EmptyNameDirective>()
                              .Build();

            // Act
            int exitCode = await application.RunAsync(
                new[] { "[preview]", "named", "param", "-abc", "--option", "foo" },
                new Dictionary <string, string>());

            // Assert
            exitCode.Should().Be(ExitCodes.Error);
            stdOut.GetString().Should().BeNullOrWhiteSpace();
            stdErr.GetString().Should().NotBeNullOrWhiteSpace();
            stdErr.GetString().Should().Contain("[  ]");

            _output.WriteLine(stdOut.GetString());
            _output.WriteLine(stdErr.GetString());
        }
Exemple #3
0
        public async Task Preview_directive_can_be_specified_to_print_provided_arguments_as_they_were_parsed()
        {
            // Arrange
            var(console, stdOut, _) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <NamedCommand>()
                              .UseConsole(console)
                              .AddDirective <PreviewDirective>()
                              .Build();

            // Act
            int exitCode = await application.RunAsync(
                new[] { "[preview]", "named", "param", "-abc", "--option", "foo" },
                new Dictionary <string, string>());

            // Assert
            exitCode.Should().Be(ExitCodes.Success);
            stdOut.GetString().Should().NotBeNullOrWhiteSpace();
            stdOut.GetString().Should().ContainAll(
                "named", "<param>", "[-a]", "[-b]", "[-c]", "[--option \"foo\"]"
                );

            _output.WriteLine(stdOut.GetString());
        }
Exemple #4
0
        public async Task Default_directive_should_allow_default_command_to_execute_when_there_is_a_name_conflict()
        {
            // Arrange
            var(console, stdOut, _) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <DefaultCommandWithParameter>()
                              .AddCommand <NamedCommand>()
                              .UseConsole(console)
                              .AddDirective <DefaultDirective>()
                              .Build();

            // Act
            int exitCode = await application.RunAsync(
                new[] { "[!]", "named" },
                new Dictionary <string, string>());

            // Assert
            exitCode.Should().Be(ExitCodes.Success);
            stdOut.GetString().Should().NotBeNullOrWhiteSpace();
            stdOut.GetString().Should().ContainAll(
                "named", DefaultCommandWithParameter.ExpectedOutputText
                );

            _output.WriteLine(stdOut.GetString());
        }
Exemple #5
0
        public async Task Normal_mode_application_cannot_process_interactive_directive()
        {
            // Arrange
            var(console, stdOut, stdErr) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <NamedCommand>()
                              .UseConsole(console)
                              .AddDirective <PreviewDirective>()
                              .Build();

            // Act
            int exitCode = await application.RunAsync(
                new[] { "[interactive]" },
                new Dictionary <string, string>());

            // Assert
            exitCode.Should().Be(ExitCodes.Error);
            stdOut.GetString().Should().BeNullOrWhiteSpace();
            stdOut.GetString().Should().NotContainAll("-h", "--help");
            stdErr.GetString().Should().NotBeNullOrWhiteSpace();
            stdErr.GetString().Should().Contain("This application does not support interactive mode.");

            _output.WriteLine(stdOut.GetString());
            _output.WriteLine(stdErr.GetString());
        }
Exemple #6
0
        public async Task Command_may_throw_a_specialized_exception_which_shows_only_the_help_text()
        {
            // Arrange
            await using var stdOut = new MemoryStream();
            await using var stdErr = new MemoryStream();

            var console = new VirtualConsole(output: stdOut);

            var application = new CliApplicationBuilder()
                              .AddCommand(typeof(ShowHelpTextOnlyCommand))
                              .AddCommand(typeof(ShowHelpTextOnlySubCommand))
                              .UseConsole(console)
                              .Build();

            // Act
            await application.RunAsync(new[] { "exc" });

            var stdOutData = console.Output.Encoding.GetString(stdOut.ToArray()).TrimEnd();
            var stdErrData = console.Output.Encoding.GetString(stdErr.ToArray()).TrimEnd();

            // Assert
            stdErrData.Should().BeEmpty();
            stdOutData.Should().ContainAll(
                "Usage",
                "[command]",
                "Options",
                "-h|--help", "Shows help text.",
                "Commands",
                "sub",
                "You can run", "to show help on a specific command."
                );
        }
        public async Task Option_of_non_scalar_type_can_use_an_environment_variable_as_fallback_and_extract_multiple_values()
        {
            var(console, stdOut, _) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <WithEnvironmentVariablesCommand>()
                              .UseConsole(console)
                              .Build();

            // Act
            int exitCode = await application.RunAsync(
                new[] { "cmd" },
                new Dictionary <string, string>
            {
                ["ENV_OPT_B"] = $"foo{Path.PathSeparator}bar"
            }
                );

            var commandInstance = stdOut.GetString().DeserializeJson <WithEnvironmentVariablesCommand>();

            // Assert
            exitCode.Should().Be(ExitCodes.Success);
            commandInstance.Should().BeEquivalentTo(new WithEnvironmentVariablesCommand
            {
                OptB = new[] { "foo", "bar" }
            });
        }
Exemple #8
0
    public async Task Default_type_activator_can_initialize_a_type_if_it_has_a_parameterless_constructor()
    {
        // Arrange
        var commandType = DynamicCommandBuilder.Compile(
            // language=cs
            @"
[Command]
public class Command : ICommand
{
    public ValueTask ExecuteAsync(IConsole console)
    {
        console.Output.WriteLine(""foo"");
        return default;
    }
}");

        var application = new CliApplicationBuilder()
                          .AddCommand(commandType)
                          .UseConsole(FakeConsole)
                          .UseTypeActivator(new DefaultTypeActivator())
                          .Build();

        // Act
        var exitCode = await application.RunAsync(
            Array.Empty <string>(),
            new Dictionary <string, string>()
            );

        var stdOut = FakeConsole.ReadOutputString();

        // Assert
        exitCode.Should().Be(0);
        stdOut.Trim().Should().Be("foo");
    }
Exemple #9
0
    public async Task Default_type_activator_fails_if_the_type_does_not_have_a_parameterless_constructor()
    {
        // Arrange
        var commandType = DynamicCommandBuilder.Compile(
            // language=cs
            @"
[Command]
public class Command : ICommand
{
    public Command(string foo) {}

    public ValueTask ExecuteAsync(IConsole console) => default;
}");

        var application = new CliApplicationBuilder()
                          .AddCommand(commandType)
                          .UseConsole(FakeConsole)
                          .UseTypeActivator(new DefaultTypeActivator())
                          .Build();

        // Act
        var exitCode = await application.RunAsync(
            Array.Empty <string>(),
            new Dictionary <string, string>()
            );

        var stdErr = FakeConsole.ReadErrorString();

        // Assert
        exitCode.Should().NotBe(0);
        stdErr.Should().Contain("Failed to create an instance of type");
    }
Exemple #10
0
        public async Task Help_text_for_a_specific_named_sub_command_is_printed_if_provided_arguments_match_its_name_and_contain_the_help_option()
        {
            // Arrange
            var(console, stdOut, _) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <DefaultCommand>()
                              .AddCommand <NamedCommand>()
                              .AddCommand <NamedSubCommand>()
                              .UseConsole(console)
                              .Build();

            // Act
            int exitCode = await application.RunAsync(new[] { "named", "sub", "--help" });

            // Assert
            exitCode.Should().Be(ExitCodes.Success);
            stdOut.GetString().Should().ContainAll(
                "Named sub command description",
                "Usage",
                "named", "sub"
                );

            _output.WriteLine(stdOut.GetString());
        }
Exemple #11
0
    public async Task Delegate_type_activator_fails_if_the_underlying_function_returns_null()
    {
        // Arrange
        var commandType = DynamicCommandBuilder.Compile(
            // language=cs
            @"
[Command]
public class Command : ICommand
{
    public ValueTask ExecuteAsync(IConsole console)
    {
        console.Output.WriteLine(""foo"");
        return default;
    }
}");

        var application = new CliApplicationBuilder()
                          .AddCommand(commandType)
                          .UseConsole(FakeConsole)
                          .UseTypeActivator(_ => null !)
                          .Build();

        // Act
        var exitCode = await application.RunAsync(
            Array.Empty <string>(),
            new Dictionary <string, string>()
            );

        var stdErr = FakeConsole.ReadErrorString();

        // Assert
        exitCode.Should().NotBe(0);
        stdErr.Should().Contain("Failed to create an instance of type");
    }
Exemple #12
0
        public async Task RunAsync_Cancellation_Test()
        {
            // Arrange
            using var cancellationTokenSource = new CancellationTokenSource();
            await using var stdoutStream      = new StringWriter();

            var console = new VirtualConsole(stdoutStream, cancellationTokenSource.Token);

            var application = new CliApplicationBuilder()
                              .AddCommand(typeof(CancellableCommand))
                              .UseConsole(console)
                              .Build();
            var args = new[] { "cancel" };

            // Act
            var runTask = application.RunAsync(args);

            cancellationTokenSource.Cancel();
            var exitCode = await runTask.ConfigureAwait(false);

            var stdOut = stdoutStream.ToString().Trim();

            // Assert
            exitCode.Should().Be(-2146233029);
            stdOut.Should().Be("Printed");
        }
Exemple #13
0
        public async Task RunAsync_Test(IReadOnlyList <Type> commandTypes, IReadOnlyList <string> commandLineArguments,
                                        string?expectedStdOut = null)
        {
            // Arrange
            await using var stdoutStream = new StringWriter();

            var console = new VirtualConsole(stdoutStream);
            var environmentVariablesProvider = new EnvironmentVariablesProviderStub();

            var application = new CliApplicationBuilder()
                              .AddCommands(commandTypes)
                              .UseVersionText(TestVersionText)
                              .UseConsole(console)
                              .UseEnvironmentVariablesProvider(environmentVariablesProvider)
                              .Build();

            // Act
            var exitCode = await application.RunAsync(commandLineArguments);

            var stdOut = stdoutStream.ToString().Trim();

            // Assert
            exitCode.Should().Be(0);

            if (expectedStdOut != null)
            {
                stdOut.Should().Be(expectedStdOut);
            }
            else
            {
                stdOut.Should().NotBeNullOrWhiteSpace();
            }
        }
Exemple #14
0
        public async Task Property_of_a_nullable_enum_type_is_bound_by_parsing_the_argument_value_as_name_if_it_is_set()
        {
            // Arrange
            var(console, stdOut, _) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <SupportedArgumentTypesCommand>()
                              .UseConsole(console)
                              .Build();

            // Act
            int exitCode = await application.RunAsync(new[]
            {
                "cmd", "--enum-nullable", "value3"
            });

            var commandInstance = stdOut.GetString().DeserializeJson <SupportedArgumentTypesCommand>();

            // Assert
            exitCode.Should().Be(ExitCodes.Success);

            commandInstance.Should().BeEquivalentTo(new SupportedArgumentTypesCommand
            {
                EnumNullable = CustomEnum.Value3
            });
        }
Exemple #15
0
        public async Task Command_may_throw_a_specialized_exception_which_shows_only_a_stack_trace_and_no_help_text()
        {
            // Arrange
            await using var stdErr = new MemoryStream();
            var console = new VirtualConsole(error: stdErr);

            var application = new CliApplicationBuilder()
                              .AddCommand(typeof(GenericExceptionCommand))
                              .UseConsole(console)
                              .Build();

            // Act
            var exitCode = await application.RunAsync(
                new[] { "exc", "-m", "Kaput" },
                new Dictionary <string, string>());

            var stdErrData = console.Error.Encoding.GetString(stdErr.ToArray()).TrimEnd();

            // Assert
            exitCode.Should().NotBe(0);
            stdErrData.Should().ContainAll(
                "System.Exception:",
                "Kaput", "at",
                "CliFx.Tests");
        }
Exemple #16
0
        public async Task Help_text_shows_application_metadata()
        {
            // Arrange
            var application = new CliApplicationBuilder()
                              .UseConsole(FakeConsole)
                              .SetTitle("App title")
                              .SetDescription("App description")
                              .SetVersion("App version")
                              .Build();

            // Act
            var exitCode = await application.RunAsync(
                new[] { "--help" },
                new Dictionary <string, string>()
                );

            var stdOut = FakeConsole.ReadOutputString();

            // Assert
            exitCode.Should().Be(0);
            stdOut.Should().ContainAll(
                "App title",
                "App description",
                "App version"
                );
        }
Exemple #17
0
        public async Task Command_shows_help_text_on_exceptions_related_to_invalid_user_input()
        {
            // Arrange
            await using var stdOut = new MemoryStream();
            await using var stdErr = new MemoryStream();
            var console = new VirtualConsole(output: stdOut, error: stdErr);

            var application = new CliApplicationBuilder()
                              .AddCommand(typeof(InvalidUserInputCommand))
                              .UseConsole(console)
                              .Build();

            // Act
            var exitCode = await application.RunAsync(
                new[] { "not-a-valid-command", "-r", "foo" },
                new Dictionary <string, string>());

            var stdErrData = console.Error.Encoding.GetString(stdErr.ToArray()).TrimEnd();
            var stdOutData = console.Output.Encoding.GetString(stdOut.ToArray()).TrimEnd();

            // Assert
            exitCode.Should().NotBe(0);
            stdErrData.Should().ContainAll(
                "Can't find a command that matches the following arguments:",
                "not-a-valid-command");
            stdOutData.Should().ContainAll(
                "Usage",
                "[command]",
                "Options",
                "-h|--help", "Shows help text.",
                "Commands",
                "inv",
                "You can run", "to show help on a specific command.");
        }
Exemple #18
0
        public async Task Help_text_shows_command_description()
        {
            // Arrange
            var commandType = DynamicCommandBuilder.Compile(
                // language=cs
                @"
[Command(Description = ""Description of the default command."")]
public class DefaultCommand : ICommand
{
    public ValueTask ExecuteAsync(IConsole console) => default;
}
");

            var application = new CliApplicationBuilder()
                              .AddCommand(commandType)
                              .UseConsole(FakeConsole)
                              .Build();

            // Act
            var exitCode = await application.RunAsync(
                new[] { "--help" },
                new Dictionary <string, string>()
                );

            var stdOut = FakeConsole.ReadOutputString();

            // Assert
            exitCode.Should().Be(0);
            stdOut.Should().ContainAllInOrder(
                "DESCRIPTION",
                "Description of the default command."
                );
        }
        public async Task Option_only_uses_an_environment_variable_as_fallback_if_the_name_matches_case_sensitively()
        {
            var(console, stdOut, _) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <WithEnvironmentVariablesCommand>()
                              .UseConsole(console)
                              .Build();

            // Act
            int exitCode = await application.RunAsync(
                new[] { "cmd" },
                new Dictionary <string, string>
            {
                ["ENV_opt_A"] = "incorrect",
                ["ENV_OPT_A"] = "correct"
            }
                );

            var commandInstance = stdOut.GetString().DeserializeJson <WithEnvironmentVariablesCommand>();

            // Assert
            exitCode.Should().Be(ExitCodes.Success);
            commandInstance.Should().BeEquivalentTo(new WithEnvironmentVariablesCommand
            {
                OptA = "correct"
            });
        }
Exemple #20
0
        public async Task Help_text_is_printed_if_provided_arguments_contain_the_help_option()
        {
            // Arrange
            var commandType = DynamicCommandBuilder.Compile(
                // language=cs
                @"
[Command]
public class DefaultCommand : ICommand
{
    public ValueTask ExecuteAsync(IConsole console) => default;
}
");

            var application = new CliApplicationBuilder()
                              .AddCommand(commandType)
                              .UseConsole(FakeConsole)
                              .SetDescription("This will be in help text")
                              .Build();

            // Act
            var exitCode = await application.RunAsync(
                new[] { "--help" },
                new Dictionary <string, string>()
                );

            var stdOut = FakeConsole.ReadOutputString();

            // Assert
            exitCode.Should().Be(0);
            stdOut.Should().Contain("This will be in help text");
        }
Exemple #21
0
        public async Task Custom_directive_should_run()
        {
            // Arrange
            var(console, stdOut, _) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <NamedCommand>()
                              .UseConsole(console)
                              .AddDirective <PreviewDirective>()
                              .AddDirective <CustomDirective>()
                              .AddDirective <CustomStopDirective>()
                              .Build();

            // Act
            int exitCode = await application.RunAsync(
                new[] { "[custom]", "named" },
                new Dictionary <string, string>());

            // Assert
            exitCode.Should().Be(ExitCodes.Success);
            stdOut.GetString().Should().NotBeNullOrWhiteSpace();
            stdOut.GetString().Should().ContainAll(
                CustomDirective.ExpectedOutput, NamedCommand.ExpectedOutputText
                );

            _output.WriteLine(stdOut.GetString());
        }
Exemple #22
0
        public async Task Help_text_shows_the_implicit_help_and_version_options_on_the_default_command()
        {
            // Arrange
            var commandType = DynamicCommandBuilder.Compile(
                // language=cs
                @"
[Command]
public class Command : ICommand
{
    public ValueTask ExecuteAsync(IConsole console) => default;
}
");

            var application = new CliApplicationBuilder()
                              .AddCommand(commandType)
                              .UseConsole(FakeConsole)
                              .Build();

            // Act
            var exitCode = await application.RunAsync(
                new[] { "--help" },
                new Dictionary <string, string>()
                );

            var stdOut = FakeConsole.ReadOutputString();

            // Assert
            exitCode.Should().Be(0);
            stdOut.Should().ContainAllInOrder(
                "OPTIONS",
                "-h", "--help", "Shows help text",
                "--version", "Shows version information"
                );
        }
Exemple #23
0
        public async Task Custom_interactive_directive_should_not_run_in_normal_mode()
        {
            // Arrange
            var(console, stdOut, stdErr) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <NamedCommand>()
                              .UseConsole(console)
                              .AddDirective <PreviewDirective>()
                              .AddDirective <CustomDirective>()
                              .AddDirective <CustomStopDirective>()
                              .AddDirective <CustomInteractiveModeOnlyDirective>()
                              .Build();

            // Act
            int exitCode = await application.RunAsync(
                new[] { "[custom-interactive]", "named", "param", "-abc", "--option", "foo" },
                new Dictionary <string, string>());

            // Assert
            exitCode.Should().NotBe(0);
            stdOut.GetString().Should().BeNullOrWhiteSpace();
            stdOut.GetString().Should().NotContainAll(
                "@ [custom-interactive]", "Description", "Usage", "Directives", "[custom]"
                );
            stdErr.GetString().Should().ContainAll(
                "Directive", "[custom-interactive]", "is for interactive mode only."
                );

            _output.WriteLine(stdOut.GetString());
        }
Exemple #24
0
        public async Task Application_without_interactive_mode_cannot_execute_interactive_only_commands()
        {
            // Arrange
            var(console, stdOut, stdErr) = VirtualConsole.CreateBuffered();

            // Act
            var app = new CliApplicationBuilder().AddCommand <BenchmarkDefaultCommand>()
                      .AddCommand <NamedInteractiveOnlyCommand>()
                      .UseConsole(console)
                      .Build();

            // Assert
            app.Should().NotBeNull();

            // Act
            int exitCode = await app.RunAsync(new string[] { "named-interactive-only" }, new Dictionary <string, string>());

            // Asert
            exitCode.Should().Be(ExitCodes.Error);
            stdOut.GetString().Should().BeNullOrWhiteSpace();
            stdErr.GetString().Should().NotBeNullOrWhiteSpace();
            stdErr.GetString().Should().Contain("can be executed only in interactive mode, but this application is using CliApplication.");

            _output.WriteLine(stdOut.GetString());
            _output.WriteLine(stdErr.GetString());
        }
Exemple #25
0
        public async Task Custom_throwable_directive_with_inner_exception_should_throw_exception()
        {
            // Arrange
            var(console, stdOut, stdErr) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <NamedCommand>()
                              .UseConsole(console)
                              .AddDirective <PreviewDirective>()
                              .AddDirective <CustomThrowableDirective>()
                              .AddDirective <CustomThrowableDirectiveWithMessage>()
                              .AddDirective <CustomThrowableDirectiveWithInnerException>()
                              .AddDirective <CustomDirective>()
                              .AddDirective <CustomStopDirective>()
                              .AddDirective <CustomInteractiveModeOnlyDirective>()
                              .Build();

            // Act
            int exitCode = await application.RunAsync(
                new[] { "[custom-throwable-with-inner-exception]", "named", "param", "-abc", "--option", "foo" },
                new Dictionary <string, string>());

            // Assert
            exitCode.Should().Be(CustomThrowableDirectiveWithInnerException.ExpectedExitCode);
            stdOut.GetString().Should().Be(CustomThrowableDirectiveWithInnerException.ExpectedOutput);
            stdErr.GetString().Should().ContainEquivalentOf(CustomThrowableDirectiveWithInnerException.ExpectedExceptionMessage);

            _output.WriteLine(stdOut.GetString());
            _output.WriteLine(stdErr.GetString());
        }
Exemple #26
0
    public async Task Command_can_throw_a_special_exception_which_exits_with_specified_code_and_message()
    {
        // Arrange
        var commandType = DynamicCommandBuilder.Compile(
            // language=cs
            @"
[Command]
public class Command : ICommand
{
    public ValueTask ExecuteAsync(IConsole console) =>
        throw new CommandException(""Something went wrong"", 69);
}
");

        var application = new CliApplicationBuilder()
                          .AddCommand(commandType)
                          .UseConsole(FakeConsole)
                          .Build();

        // Act
        var exitCode = await application.RunAsync(
            Array.Empty <string>(),
            new Dictionary <string, string>()
            );

        var stdOut = FakeConsole.ReadOutputString();
        var stdErr = FakeConsole.ReadErrorString();

        // Assert
        exitCode.Should().Be(69);
        stdOut.Should().BeEmpty();
        stdErr.Trim().Should().Be("Something went wrong");
    }
Exemple #27
0
        public async Task Interactive_only_directive_cannot_be_executed_in_normal_mode()
        {
            // Arrange
            var(console, stdOut, stdErr) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <NamedCommand>()
                              .UseConsole(console)
                              .AddDirective <CustomInteractiveModeOnlyDirective>()
                              .Build();

            // Act
            int exitCode = await application.RunAsync(
                new[] { "[custom-interactive]", "named", "param", "-abc", "--option", "foo" },
                new Dictionary <string, string>());

            // Assert
            exitCode.Should().Be(ExitCodes.Error);
            stdOut.GetString().Should().BeNullOrWhiteSpace();
            stdOut.GetString().Should().NotContainAll("-h", "--help");
            stdErr.GetString().Should().NotBeNullOrWhiteSpace();
            stdErr.GetString().Should().Contain("Directive '[custom-interactive]' is for interactive mode only. Thus, cannot be used in normal mode.");

            _output.WriteLine(stdOut.GetString());
            _output.WriteLine(stdErr.GetString());
        }
Exemple #28
0
        public async Task Application_can_be_created_with_a_fully_customized_configuration()
        {
            // Act
            var app = new CliApplicationBuilder()
                      .AddCommand <NoOpCommand>()
                      .AddCommandsFrom(typeof(NoOpCommand).Assembly)
                      .AddCommands(new[] { typeof(NoOpCommand) })
                      .AddCommandsFrom(new[] { typeof(NoOpCommand).Assembly })
                      .AddCommandsFromThisAssembly()
                      .AllowDebugMode()
                      .AllowPreviewMode()
                      .SetTitle("test")
                      .SetExecutableName("test")
                      .SetVersion("test")
                      .SetDescription("test")
                      .UseConsole(FakeConsole)
                      .UseTypeActivator(Activator.CreateInstance !)
                      .Build();

            var exitCode = await app.RunAsync(
                Array.Empty <string>(),
                new Dictionary <string, string>()
                );

            // Assert
            exitCode.Should().Be(0);
        }
        public async Task Command_can_perform_additional_cleanup_if_cancellation_is_requested()
        {
            // Can't test it with a real console because CliWrap can't send Ctrl+C

            // Arrange
            using var cts = new CancellationTokenSource();

            await using var stdOut = new MemoryStream();
            var console = new VirtualConsole(output: stdOut, cancellationToken: cts.Token);

            var application = new CliApplicationBuilder()
                              .AddCommand(typeof(CancellableCommand))
                              .UseConsole(console)
                              .Build();

            // Act
            cts.CancelAfter(TimeSpan.FromSeconds(0.2));

            var exitCode = await application.RunAsync(
                new[] { "cancel" },
                new Dictionary <string, string>());

            var stdOutData = console.Output.Encoding.GetString(stdOut.ToArray()).TrimEnd();

            // Assert
            exitCode.Should().NotBe(0);
            stdOutData.Should().Be("Cancellation requested");
        }
Exemple #30
0
        public async Task Property_of_type_DateTimeOffset_is_bound_by_parsing_the_argument_value()
        {
            // Arrange
            var(console, stdOut, _) = VirtualConsole.CreateBuffered();

            var application = new CliApplicationBuilder()
                              .AddCommand <SupportedArgumentTypesCommand>()
                              .UseConsole(console)
                              .Build();

            // Act
            int exitCode = await application.RunAsync(new[]
            {
                "cmd", "--datetime-offset", "28 Apr 1995"
            });

            var commandInstance = stdOut.GetString().DeserializeJson <SupportedArgumentTypesCommand>();

            // Assert
            exitCode.Should().Be(ExitCodes.Success);

            commandInstance.Should().BeEquivalentTo(new SupportedArgumentTypesCommand
            {
                DateTimeOffset = new DateTime(1995, 04, 28)
            });
        }