/// <summary>
 /// When true
 /// </summary>
 /// <param name="appRunner"></param>
 /// <param name="case">The case to apply</param>
 /// <param name="applyToNameOverrides">Case should be applied to names overridden in attributes.</param>
 /// <returns></returns>
 public static AppRunner UseNameCasing(this AppRunner appRunner, Case @case, bool applyToNameOverrides = false)
 {
     return(applyToNameOverrides
         ? appRunner.Configure(b => b.NameTransformation = (attributes, memberName, nameOverride, commandNodeType) =>
                                                           (nameOverride ?? memberName).ChangeCase(@case))
         : appRunner.Configure(b => b.NameTransformation = (attributes, memberName, nameOverride, commandNodeType) =>
                                                           nameOverride ?? memberName.ChangeCase(@case)));
 }
示例#2
0
        /// <summary>Run the console in memory and get the results that would be output to the shell</summary>
        public static AppRunnerResult RunInMem(this AppRunner runner,
                                               string[] args,
                                               Action <string> logLine = null,
                                               Func <TestConsole, string> onReadLine = null,
                                               IEnumerable <string> pipedInput       = null,
                                               IPromptResponder promptResponder      = null,
                                               TestConfig config = null)
        {
            logLine = logLine ?? Console.WriteLine;
            config  = config ?? TestConfig.Default;

            IDisposable logProvider = config.PrintCommandDotNetLogs
                ? TestToolsLogProvider.InitLogProvider(logLine)
                : new DisposableAction(() => { });

            using (logProvider)
            {
                var testConsole = new TestConsole(
                    onReadLine,
                    pipedInput,
                    promptResponder == null
                        ? (Func <TestConsole, ConsoleKeyInfo>)null
                        : promptResponder.OnReadKey);
                runner.Configure(c => c.Console = testConsole);

                CommandContext context = null;
                Task <int> CaptureCommandContext(CommandContext commandContext, ExecutionDelegate next)
                {
                    context = commandContext;
                    return(next(commandContext));
                }

                runner.Configure(c => c.UseMiddleware(CaptureCommandContext, MiddlewareStages.PreTokenize));
                var captures = InjectTestCaptures(runner);

                try
                {
                    var exitCode = runner.Run(args);
                    return(new AppRunnerResult(exitCode, runner, context, testConsole, captures, config)
                           .LogResult(logLine));
                }
                catch (Exception e)
                {
                    var result = new AppRunnerResult(1, runner, context, testConsole, captures, config, e);
                    if (config.OnError.CaptureAndReturnResult)
                    {
                        testConsole.Error.WriteLine(e.Message);
                        logLine(e.Message);
                        logLine(e.StackTrace);
                        return(result.LogResult(logLine, onError: true));
                    }

                    result.LogResult(logLine, onError: true);
                    throw;
                }
            }
        }
示例#3
0
        internal static AppRunner SetArgumentDefaultsFrom(AppRunner appRunner,
                                                          Func <IArgument, ArgumentDefault>[] getDefaultValueCallbacks)
        {
            // run before help command so help will display the updated defaults
            return(appRunner.Configure(c =>
            {
                var config = c.Services.Get <Config>();
                if (config == null)
                {
                    config = new Config
                    {
                        GetDefaultValueCallbacks = getDefaultValueCallbacks
                    };
                    c.Services.Add(config);

                    // run before help so the default values can be displayed in the help text
                    c.UseMiddleware(SetDefaults,
                                    MiddlewareSteps.SetArgumentDefaults.Stage,
                                    MiddlewareSteps.SetArgumentDefaults.Order);
                }
                else
                {
                    config.GetDefaultValueCallbacks =
                        config.GetDefaultValueCallbacks.Union(getDefaultValueCallbacks).ToArray();
                }
            }));
        }
示例#4
0
        private static AppRunner RegisterContainer(this AppRunner appRunner, AppConfigs configs)
        {
            var config = configs.Default ?? new AppConfig();

            var containerBuilder = new ContainerBuilder();

            containerBuilder.RegisterInstance(configs);
            containerBuilder.RegisterInstance(config);

            containerBuilder.RegisterType <BitBucketRepoCommand>().InstancePerLifetimeScope();
            containerBuilder.RegisterType <GlobalConfigCommand>().InstancePerLifetimeScope();
            containerBuilder.RegisterType <LocalRepoCommand>().InstancePerLifetimeScope();

            containerBuilder.RegisterType <BbService>().InstancePerLifetimeScope();
            containerBuilder.RegisterType <GitService>().InstancePerLifetimeScope();

            containerBuilder.RegisterServerBbApi(config);

            containerBuilder.RegisterType <CommandContextHolder>().InstancePerLifetimeScope();
            containerBuilder.Register(c => c.Resolve <CommandContextHolder>().Context)
            .As <CommandContext>()
            .InstancePerLifetimeScope();
            containerBuilder
            .Register(c => c.Resolve <CommandContext>().Console)
            .As <IConsole>()
            .InstancePerLifetimeScope();

            appRunner.Configure(r => r.UseMiddleware(
                                    SetCommandContextForDependencyResolver,
                                    MiddlewareSteps.DependencyResolver.BeginScope + 1));

            return(appRunner.UseAutofac(containerBuilder.Build()));
        }
示例#5
0
        /// <summary>Run the console in memory and get the results that would be output to the shell</summary>
        public static AppRunnerResult RunInMem(this AppRunner runner,
                                               string[] args,
                                               ILogger logger,
                                               Func <TestConsole, string> onReadLine = null,
                                               IEnumerable <string> pipedInput       = null,
                                               IPromptResponder promptResponder      = null)
        {
            TestToolsLogProvider.InitLogProvider(logger);

            var testConsole = new TestConsole(
                onReadLine,
                pipedInput,
                promptResponder == null
                    ? (Func <TestConsole, ConsoleKeyInfo>)null
                    : promptResponder.OnReadKey);

            runner.Configure(c => c.Console = testConsole);
            var outputs = InjectTestOutputs(runner);

            try
            {
                var exitCode   = runner.Run(args);
                var consoleOut = testConsole.Joined.ToString();

                logger?.WriteLine("\nconsole output:\n");
                logger?.WriteLine(consoleOut);
                return(new AppRunnerResult(exitCode, testConsole, outputs));
            }
            catch (Exception e)
            {
                logger?.WriteLine("\nconsole output:\n");
                logger?.WriteLine(testConsole.Joined.ToString());
                throw;
            }
        }
示例#6
0
 internal static AppRunner UseTimerDirective(this AppRunner appRunner)
 {
     return(appRunner.Configure(c =>
     {
         c.UseMiddleware(TimerDirective, MiddlewareSteps.DebugDirective - 1);
     }));
 }
示例#7
0
        public static AppRunner GiveCancellationTokenToFlurl(this AppRunner appRunner)
        {
            FlurlHttp.GlobalSettings.HttpClientFactory = new MyDefaultHttpClientFactory();

            return(appRunner.Configure(cfg =>
                                       cfg.UseMiddleware(SetCancellationTokenToFlurl, MiddlewareStages.PostBindValuesPreInvoke)));
        }
示例#8
0
        private static TestOutputs InjectTestOutputs(AppRunner runner)
        {
            TestOutputs outputs = new TestOutputs();

            runner.Configure(c => c.UseMiddleware((context, next) =>
            {
                context.InvocationPipeline.All
                .Select(i => i.Instance)
                .ForEach(instance =>
                {
                    instance.GetType()
                    .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                    .Where(p => p.PropertyType == typeof(TestOutputs))
                    .ForEach(p =>
                    {
                        // principal of least surprise
                        // if the test class sets the instance, then use that instance
                        var value = (TestOutputs)p.GetValue(instance);
                        if (value == null)
                        {
                            p.SetValue(instance, outputs);
                        }
                        else
                        {
                            outputs.UseOutputsFromInstance(value);
                        }
                    });
                });
                return(next(context));
            }, MiddlewareStages.PostBindValuesPreInvoke));

            return(outputs);
        }
示例#9
0
        internal static AppRunner SetArgumentDefaultsFrom(AppRunner appRunner,
                                                          Func <IArgument, ArgumentDefault?>[] getDefaultValueCallbacks)
        {
            if (getDefaultValueCallbacks == null)
            {
                throw new ArgumentNullException(nameof(getDefaultValueCallbacks));
            }

            // run before help command so help will display the updated defaults
            return(appRunner.Configure(c =>
            {
                var config = c.Services.GetOrDefault <Config>();
                if (config == null)
                {
                    // run before help so the default values can be displayed in the help text
                    c.UseMiddleware(SetDefaults, MiddlewareSteps.SetArgumentDefaults);
                    c.Services.Add(config = new Config(getDefaultValueCallbacks));
                }
                else
                {
                    config.GetDefaultValueCallbacks =
                        config.GetDefaultValueCallbacks.Union(getDefaultValueCallbacks).ToArray();
                }
            }));
        }
示例#10
0
 public static AppRunner UseInteractiveMode(this AppRunner appRunner, string appName)
 {
     return(appRunner.Configure(c =>
     {
         // use the existing appRunner to reuse the configuration.
         c.UseParameterResolver(ctx => new InteractiveSession(appRunner, appName, ctx));
     }));
 }
示例#11
0
 /// <summary>
 /// Override the resources to localize or change the text used in the <see cref="SpectreArgumentPrompter"/>
 /// </summary>
 /// <param name="appRunner">the <see cref="AppRunner"/> instance</param>
 /// <param name="resourcesOverride">
 /// The resources to use. If this method is not called,
 /// <see cref="AppSettings"/>.<see cref="AppSettings.Localize"/> will be used if available.</param>
 /// <returns></returns>
 public static AppRunner UseSpectreResources(this AppRunner appRunner, Resources resourcesOverride)
 {
     return(appRunner.Configure(c =>
     {
         c.Services.GetOrCreate <SpectreAppConfig>().ResourcesSet = true;
         Resources.A = resourcesOverride;
     }));
 }
 /// <summary>Enables FluentValidation for <see cref="IArgumentModel"/>s</summary>
 /// <param name="appRunner">the <see cref="AppRunner"/></param>
 /// <param name="showHelpOnError">when true, help will be display for the target command after the validation errors</param>
 public static AppRunner UseFluentValidation(this AppRunner appRunner, bool showHelpOnError = false)
 {
     return(appRunner.Configure(c =>
     {
         c.Services.Add(new Config(showHelpOnError));
         c.UseMiddleware(Middleware, MiddlewareStages.PostBindValuesPreInvoke);
     }));
 }
 public static AppRunner UseDataAnnotationValidations(this AppRunner appRunner, bool showHelpOnError = false)
 {
     return(appRunner.Configure(c =>
     {
         c.UseMiddleware(DataAnnotationsValidation, MiddlewareSteps.DataAnnotations);
         c.Services.Add(new Config(showHelpOnError));
     }));
 }
示例#14
0
 internal static AppRunner UseParseDirective(this AppRunner appRunner)
 {
     return(appRunner.Configure(c =>
     {
         c.UseMiddleware(ConfigureParseReportByTokenTransform, MiddlewareStages.PreTokenize);
         c.UseMiddleware(ParseReportByArg, MiddlewareStages.BindValues, MiddlewareSteps.BindValues.Order + 100);
     }));
 }
示例#15
0
 internal static AppRunner UseDebugDirective(this AppRunner appRunner, bool?waitForDebuggerToAttach = null)
 {
     return(appRunner.Configure(c =>
     {
         c.UseMiddleware(AttachDebugger, MiddlewareSteps.DebugDirective);
         c.Services.Add(new DebugDirectiveContext(waitForDebuggerToAttach ?? !InTestHarness));
     }));
 }
 internal static AppRunner UseVersionMiddleware(AppRunner appRunner)
 {
     return(appRunner.Configure(c =>
     {
         c.UseMiddleware(DisplayVersionIfSpecified, MiddlewareSteps.Version);
         c.BuildEvents.OnCommandCreated += AddVersionOption;
     }));
 }
示例#17
0
 internal static AppRunner UseParseDirective(this AppRunner appRunner)
 {
     return(appRunner.Configure(c =>
     {
         c.UseMiddleware(ConfigureReportHooks, MiddlewareStages.PreTokenize);
         c.UseMiddleware(ExitAfterTokenization, MiddlewareStages.Tokenize, MiddlewareSteps.CreateRootCommand.Order - 100);
     }));
 }
示例#18
0
 /// <summary>Enables FluentValidation for <see cref="IArgumentModel"/>s</summary>
 /// <param name="appRunner">the <see cref="AppRunner"/></param>
 /// <param name="showHelpOnError">when true, help will be display for the target command after the validation errors</param>
 public static AppRunner UseFluentValidation(this AppRunner appRunner, bool showHelpOnError = false)
 {
     return(appRunner.Configure(c =>
     {
         c.UseMiddleware(FluentValidationForModels, MiddlewareSteps.FluentValidation);
         c.Services.Add(new Config(showHelpOnError));
     }));
 }
示例#19
0
 internal static AppRunner UseHelpMiddleware(this AppRunner appRunner)
 {
     return(appRunner.Configure(c =>
     {
         c.BuildEvents.OnCommandCreated += AddHelpOption;
         c.UseMiddleware(DisplayHelp, MiddlewareSteps.Help.Stage, MiddlewareSteps.Help.Order);
     }));
 }
 internal static AppRunner AssertAfterRun(this AppRunner appRunner, Action <AppRunnerResult> assert)
 {
     return(appRunner.Configure(cfg =>
     {
         var postRunActions = cfg.Services.GetOrAdd(() => new List <Action <AppRunnerResult> >());
         postRunActions.Add(assert);
     }));
 }
示例#21
0
 internal static AppRunner UseCancellationHandlers(AppRunner appRunner)
 {
     return(appRunner.Configure(c =>
     {
         c.UseMiddleware(AddCancellationTokens, MiddlewareSteps.CancellationHandler);
         c.OnRunCompleted += args => CancellationHandlers.EndRun(args.CommandContext);
     }));
 }
示例#22
0
 internal static AppRunner UseHelpMiddleware(this AppRunner appRunner)
 {
     return(appRunner.Configure(c =>
     {
         c.BuildEvents.OnCommandCreated += AddHelpOption;
         c.UseMiddleware(CheckIfShouldShowHelp, MiddlewareSteps.Help.CheckIfShouldShowHelp);
         c.UseMiddleware(PrintHelp, MiddlewareSteps.Help.PrintHelpOnExit);
     }));
 }
        private AppRunnerResult RunInMem(int carNumber, string ownerName,
                                         ExecutionMiddleware postBindValues = null,
                                         ExecutionMiddleware preBindValues  = null)
        {
            var appRunner = new AppRunner <App>();

            if (postBindValues != null)
            {
                appRunner.Configure(c => c.UseMiddleware(postBindValues, MiddlewareStages.PostBindValuesPreInvoke, int.MaxValue));
            }
            if (preBindValues != null)
            {
                appRunner.Configure(c => c.UseMiddleware(preBindValues, MiddlewareStages.PostParseInputPreBindValues, int.MaxValue));
            }

            var args = $"NotifyOwner --Number {carNumber} --owner {ownerName}".SplitArgs();

            return(appRunner.RunInMem(args));
        }
        // This code is not covered by automation.  I couldn't find a way to mimic and verify these events.
        // Tested manually using CancelMeApp in CommandDotNet.Examples

        internal static AppRunner UseCancellationHandlers(AppRunner appRunner)
        {
            var handlers = new Handlers();

            return(appRunner.Configure(c =>
            {
                c.CancellationToken = handlers.CancellationToken;
                c.OnRunCompleted += _ => handlers.RemoveHandlers();
            }));
        }
 public static AppRunner SetDefaults(this AppRunner appRunner, IDictionary <string, object> defaults)
 {
     // run before help command so help will display the updated defaults
     return(appRunner.Configure(c =>
     {
         c.UseMiddleware((ctx, next) => SetDefaults(ctx, next, defaults),
                         MiddlewareStages.PostParseInputPreBindValues,
                         BeforeHelpMiddleware);
     }));
 }
示例#26
0
 /// <summary>
 /// Injects a middleware to capture state at specific point. <br/>
 /// This method does not prevent referenced objects from being mutated after capture. <br/>
 /// It is the responsibility of capture action to clone data to prevent mutation.
 /// </summary>
 public static AppRunner CaptureState(this AppRunner runner, Action <CommandContext> capture,
                                      MiddlewareStages middlewareStage, short?orderWithinStage = null, bool exitAfterCapture = false)
 {
     return(runner.Configure(b => b.UseMiddleware((context, next) =>
     {
         capture(context);
         return exitAfterCapture
             ? ExitCodes.Success
             : next(context);
     }, middlewareStage, orderWithinStage)));
 }
        public static AppRunner UseCancellationHandler(this AppRunner appRunner)
        {
            System.Console.CancelKeyPress += Console_CancelKeyPress;
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            AppDomain.CurrentDomain.ProcessExit        += CurrentDomain_ProcessExit;

            return(appRunner.Configure(c =>
            {
                c.CancellationToken = TokenSource.Token;
            }));
        }
示例#28
0
 /// <summary>
 /// Injects a middleware to capture state at specific point. <br/>
 /// This method does not prevent referenced objects from being mutated after capture. <br/>
 /// It is the responsibility of capture action to clone data to prevent mutation.
 /// </summary>
 public static AppRunner CaptureState(this AppRunner runner, Action <CommandContext> capture,
                                      MiddlewareStages middlewareStage, int?orderWithinStage = null, bool exitAfterCapture = false)
 {
     return(runner.Configure(b => b.UseMiddleware((context, next) =>
     {
         capture(context);
         return exitAfterCapture
             ? Task.FromResult <int>(0)
             : next(context);
     }, middlewareStage, orderWithinStage)));
 }
 internal static AppRunner UseClassDefMiddleware(this AppRunner appRunner, Type rootCommandType)
 {
     return(appRunner.Configure(c =>
     {
         c.UseMiddleware(CreateRootCommand, MiddlewareSteps.CreateRootCommand);
         c.UseMiddleware(AssembleInvocationPipelineMiddleware, MiddlewareSteps.AssembleInvocationPipeline);
         c.UseMiddleware(BindValuesMiddleware.BindValues, MiddlewareSteps.BindValues);
         c.UseMiddleware(ResolveCommandClassesMiddleware.ResolveCommandClassInstances, MiddlewareSteps.ResolveCommandClasses);
         c.UseMiddleware(InvokeInvocationPipelineMiddleware, MiddlewareSteps.InvokeCommand);
         c.Services.Add(new Config(rootCommandType));
     }));
 }
        private static TestOutputs InjectTestOutputs(AppRunner runner)
        {
            var outputs = new TestOutputs();

            runner.Configure(c =>
            {
                c.Services.Add(outputs);
                c.UseMiddleware(InjectTestOutputs, MiddlewareStages.PostBindValuesPreInvoke);
            });

            return(outputs);
        }