public async Task SetsLogLevel(string logLevel, int expected)
            {
                // Given
                string[]         args         = new[] { "build", "-l", logLevel };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.Create(args);
                bootstrapper.AddCommand <PipelinesCommand <EngineCommandSettings> >("build");
                TestLoggerProvider provider = new TestLoggerProvider
                {
                    ThrowLogLevel = LogLevel.None
                };

                bootstrapper.ConfigureServices(services => services.AddSingleton <ILoggerProvider>(provider));
                bootstrapper.AddPipeline(
                    "Foo",
                    new Core.LogMessage(LogLevel.Trace, "A"),
                    new Core.LogMessage(LogLevel.Debug, "B"),
                    new Core.LogMessage(LogLevel.Information, "C"),
                    new Core.LogMessage(LogLevel.Warning, "D"),
                    new Core.LogMessage(LogLevel.Error, "E"),
                    new Core.LogMessage(LogLevel.Critical, "F"));

                // When
                int exitCode = await bootstrapper.RunAsync();

                // Then
                exitCode.ShouldBe((int)ExitCode.Normal);
                provider.Messages.Count(x => x.FormattedMessage.StartsWith("Foo/Process")).ShouldBe(expected);
            }
            public async Task CommandLineSettingsAreCaseInsensitive()
            {
                // Given
                string[]         args         = new[] { "--setting", "foo=bar" };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.CreateDefault(args);
                bootstrapper.AddPipeline("Test");

                // When
                BootstrapperTestResult result = await bootstrapper.RunTestAsync();

                // Then
                result.ExitCode.ShouldBe((int)ExitCode.Normal);
                result.Engine.Settings["Foo"].ShouldBe("bar");
            }
            public async Task LogsVersion()
            {
                // Given
                string[]         args         = new[] { "build" };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.Create(args);
                bootstrapper.AddCommand <PipelinesCommand <EngineCommandSettings> >("build");
                bootstrapper.AddPipeline("Foo");

                // When
                BootstrapperTestResult result = await bootstrapper.RunTestAsync();

                // Then
                result.ExitCode.ShouldBe((int)ExitCode.Normal);
                result.LogMessages.ShouldContain(x => x.FormattedMessage.StartsWith("Statiq version"));
            }
            public async Task NoPipelinesWarning()
            {
                // Given
                string[]         args         = new[] { "build" };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.Create(args);
                bootstrapper.AddCommand <PipelinesCommand <EngineCommandSettings> >("build");

                // When
                BootstrapperTestResult result = await bootstrapper.RunTestAsync(LogLevel.None);

                // Then
                result.ExitCode.ShouldBe((int)ExitCode.Normal);
                result.LogMessages.ShouldContain(x =>
                                                 x.LogLevel == LogLevel.Warning &&
                                                 x.FormattedMessage == "No pipelines are configured or specified for execution.");
            }
            public async Task SetsFlagFromCommandLine()
            {
                // Given
                string[]         args         = new string[] { "--noclean" };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.CreateDefault(args);
                object           value        = null;

                bootstrapper.AddPipeline("Foo", new ExecuteConfig(Config.FromContext(x => value = x.Settings[Keys.CleanOutputPath])));

                // When
                BootstrapperTestResult result = await bootstrapper.RunTestAsync();

                // Then
                result.ExitCode.ShouldBe((int)ExitCode.Normal);
                value.ShouldBe(false);
            }
            public async Task CommandLineSettingTakesPrecedenceOverDefaultSettings()
            {
                // Given
                string[]         args         = new string[] { "-s", $"{Keys.LinkHideIndexPages}=false" };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.CreateDefault(args);
                object           variable     = null;

                bootstrapper.AddPipeline("Foo", new ExecuteConfig(Config.FromContext(x => variable = x.Settings[Keys.LinkHideIndexPages])));

                // When
                BootstrapperTestResult result = await bootstrapper.RunTestAsync();

                // Then
                result.ExitCode.ShouldBe((int)ExitCode.Normal);
                variable.ShouldBe("false");
            }
            public async Task CatalogsType()
            {
                // Given
                string[]         args         = new[] { "build", "-l", "Debug" };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.Create(args);
                bootstrapper.AddCommand <PipelinesCommand <EngineCommandSettings> >("build");
                bootstrapper.AddPipeline("Foo");

                // When
                BootstrapperTestResult result = await bootstrapper.RunTestAsync();

                // Then
                result.ExitCode.ShouldBe((int)ExitCode.Normal);
                bootstrapper.ClassCatalog.GetTypesAssignableTo <BootstrapperFixture>().Count().ShouldBe(1);
                result.LogMessages.ShouldContain(x => x.FormattedMessage.StartsWith("Cataloging types in assembly"));
            }
            public async Task CommandLineSettingTakesPrecedenceOverEnvironmentVariables()
            {
                // Given
                string[] args = new string[] { "-s", $"{nameof(CommandLineSettingTakesPrecedenceOverEnvironmentVariables)}=Bar" };
                Environment.SetEnvironmentVariable(nameof(CommandLineSettingTakesPrecedenceOverEnvironmentVariables), "Foo");
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.CreateDefault(args);
                object           variable     = null;

                bootstrapper.AddPipeline("Foo", new ExecuteConfig(Config.FromContext(x => variable = x.Settings[nameof(CommandLineSettingTakesPrecedenceOverEnvironmentVariables)])));

                // When
                BootstrapperTestResult result = await bootstrapper.RunTestAsync();

                // Then
                result.ExitCode.ShouldBe((int)ExitCode.Normal);
                variable.ShouldBe("Bar");
            }
            public async Task EnvironmentVariableConfiguration()
            {
                // Given
                string[] args = new string[] { };
                Environment.SetEnvironmentVariable(nameof(EnvironmentVariableConfiguration), "Foo");
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.CreateDefault(args);
                object           variable     = null;

                bootstrapper.AddPipeline("Foo", new ExecuteConfig(Config.FromContext(x => variable = x.Settings[nameof(EnvironmentVariableConfiguration)])));

                // When
                BootstrapperTestResult result = await bootstrapper.RunTestAsync();

                // Then
                result.ExitCode.ShouldBe((int)ExitCode.Normal);
                variable.ShouldBe("Foo");
            }
            public async Task CanReadConfigurationValues()
            {
                // Given
                string[] args = new string[] { };
                Environment.SetEnvironmentVariable(nameof(CanReadConfigurationValues), "Foo");
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.CreateDefault(args);
                object           variable     = null;

                bootstrapper.ConfigureSettings(x => variable = x[nameof(CanReadConfigurationValues)]);
                bootstrapper.AddPipeline("Foo");

                // When
                BootstrapperTestResult result = await bootstrapper.RunTestAsync();

                // Then
                result.ExitCode.ShouldBe((int)ExitCode.Normal);
                variable.ShouldBe("Foo");
            }
            public async Task AddsComputedMetadataFromCommandLine()
            {
                // Given
                string[]         args         = new[] { "--setting", "\"Foo = => 1 + 1\"" };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.CreateDefault(args);
                object           value        = null;

                bootstrapper.AddPipeline(
                    "Test",
                    new ExecuteConfig(Config.FromSettings(x => value = x["Foo"])));

                // When
                BootstrapperTestResult result = await bootstrapper.RunTestAsync();

                // Then
                result.ExitCode.ShouldBe((int)ExitCode.Normal);
                value.ShouldBe(2);
            }
            public async Task LogsVersion()
            {
                // Given
                string[]         args         = new[] { "build" };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.Create(args);
                bootstrapper.AddCommand <PipelinesCommand <EngineCommandSettings> >("build");
                TestLoggerProvider provider = new TestLoggerProvider();

                bootstrapper.ConfigureServices(services => services.AddSingleton <ILoggerProvider>(provider));
                bootstrapper.AddPipeline("Foo");

                // When
                int exitCode = await bootstrapper.RunAsync();

                // Then
                exitCode.ShouldBe((int)ExitCode.Normal);
                provider.Messages.ShouldContain(x => x.FormattedMessage.StartsWith("Statiq version"));
            }
            public async Task CommandLineSettingTakesPrecedenceOverDefaultSettings()
            {
                // Given
                string[]           args         = new string[] { "-s", $"{Keys.LinkHideIndexPages}=false" };
                App.Bootstrapper   bootstrapper = App.Bootstrapper.Factory.CreateDefault(args);
                TestLoggerProvider provider     = new TestLoggerProvider();

                bootstrapper.ConfigureServices(services => services.AddSingleton <ILoggerProvider>(provider));
                object variable = null;

                bootstrapper.AddPipeline("Foo", new ExecuteConfig(Config.FromContext(x => variable = x.Settings[Keys.LinkHideIndexPages])));

                // When
                int exitCode = await bootstrapper.RunAsync();

                // Then
                exitCode.ShouldBe((int)ExitCode.Normal);
                variable.ShouldBe("false");
            }
            public async Task CatalogsType()
            {
                // Given
                string[]         args         = new[] { "build", "-l", "Debug" };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.Create(args);
                bootstrapper.AddCommand <PipelinesCommand <EngineCommandSettings> >("build");
                TestLoggerProvider provider = new TestLoggerProvider();

                bootstrapper.ConfigureServices(services => services.AddSingleton <ILoggerProvider>(provider));
                bootstrapper.AddPipeline("Foo");

                // When
                int exitCode = await bootstrapper.RunAsync();

                // Then
                exitCode.ShouldBe((int)ExitCode.Normal);
                bootstrapper.ClassCatalog.GetTypesAssignableTo <BootstrapperFixture>().Count().ShouldBe(1);
                provider.Messages.ShouldContain(x => x.FormattedMessage.StartsWith("Cataloging types in assembly"));
            }
            public async Task CommandLineSettingTakesPrecedenceOverEnvironmentVariables()
            {
                // Given
                string[] args = new string[] { "-s", $"{nameof(CommandLineSettingTakesPrecedenceOverEnvironmentVariables)}=Bar" };
                Environment.SetEnvironmentVariable(nameof(CommandLineSettingTakesPrecedenceOverEnvironmentVariables), "Foo");
                App.Bootstrapper   bootstrapper = App.Bootstrapper.Factory.CreateDefault(args);
                TestLoggerProvider provider     = new TestLoggerProvider();

                bootstrapper.ConfigureServices(services => services.AddSingleton <ILoggerProvider>(provider));
                object variable = null;

                bootstrapper.AddPipeline("Foo", new ExecuteConfig(Config.FromContext(x => variable = x.Settings[nameof(CommandLineSettingTakesPrecedenceOverEnvironmentVariables)])));

                // When
                int exitCode = await bootstrapper.RunAsync();

                // Then
                exitCode.ShouldBe((int)ExitCode.Normal);
                variable.ShouldBe("Bar");
            }
            public async Task CanReadConfigurationValues()
            {
                // Given
                string[] args = new string[] { };
                Environment.SetEnvironmentVariable(nameof(CanReadConfigurationValues), "Foo");
                App.Bootstrapper   bootstrapper = App.Bootstrapper.Factory.CreateDefault(args);
                TestLoggerProvider provider     = new TestLoggerProvider();

                bootstrapper.ConfigureServices(services => services.AddSingleton <ILoggerProvider>(provider));
                object variable = null;

                bootstrapper.ConfigureSettings(x => variable = x[nameof(CanReadConfigurationValues)]);
                bootstrapper.AddPipeline("Foo");

                // When
                int exitCode = await bootstrapper.RunAsync();

                // Then
                exitCode.ShouldBe((int)ExitCode.Normal);
                variable.ShouldBe("Foo");
            }
            public async Task SetsLogLevel(string logLevel, int expected)
            {
                // Given
                string[]         args         = new[] { "build", "-l", logLevel };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.Create(args);
                bootstrapper.AddCommand <PipelinesCommand <EngineCommandSettings> >("build");
                bootstrapper.AddPipeline(
                    "Foo",
                    new Core.LogMessage(LogLevel.Trace, "A"),
                    new Core.LogMessage(LogLevel.Debug, "B"),
                    new Core.LogMessage(LogLevel.Information, "C"),
                    new Core.LogMessage(LogLevel.Warning, "D"),
                    new Core.LogMessage(LogLevel.Error, "E"),
                    new Core.LogMessage(LogLevel.Critical, "F"));

                // When
                BootstrapperTestResult result = await bootstrapper.RunTestAsync(LogLevel.None);

                // Then
                result.ExitCode.ShouldBe((int)ExitCode.Normal);
                result.LogMessages.Count(x => x.FormattedMessage.StartsWith("Foo/Process")).ShouldBe(expected);
            }
            public async Task NoPipelinesWarning()
            {
                // Given
                string[]         args         = new[] { "build" };
                App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.Create(args);
                bootstrapper.AddCommand <PipelinesCommand <EngineCommandSettings> >("build");
                TestLoggerProvider provider = new TestLoggerProvider
                {
                    ThrowLogLevel = LogLevel.None
                };

                bootstrapper.ConfigureServices(services => services.AddSingleton <ILoggerProvider>(provider));

                // When
                int exitCode = await bootstrapper.RunAsync();

                // Then
                exitCode.ShouldBe((int)ExitCode.Normal);
                provider.Messages.ShouldContain(x =>
                                                x.LogLevel == LogLevel.Warning &&
                                                x.FormattedMessage == "No pipelines are configured or specified for execution.");
            }