private static void AssertCapturedItems(IScenario scenario, AppRunnerResult results) { foreach (var expectedOutput in scenario.Then.Captured) { var expectedType = expectedOutput.GetType(); var actualOutput = results.TestCaptures.Get(expectedType); if (actualOutput == null) { throw new AssertFailedException($"{expectedType.Name} should have been captured in the test run but wasn't"); } actualOutput.ShouldBeEquivalentTo(expectedOutput, $"Captured {expectedType.Name}"); } var actualOutputs = results.TestCaptures.Captured; if (!scenario.Then.AllowUnspecifiedCaptures && actualOutputs.Count > scenario.Then.Captured.Count) { var expectedOutputTypes = new HashSet <Type>(scenario.Then.Captured.Select(o => o.GetType())); var unexpectedTypes = actualOutputs.Keys .Where(t => !expectedOutputTypes.Contains(t)) .ToOrderedCsv(); throw new AssertFailedException($"Unexpected captures: {unexpectedTypes}"); } }
private static void AssertExitCode(IScenario scenario, AppRunnerResult result, StringBuilder sb) { var expectedExitCode = scenario.Then.ExitCode.GetValueOrDefault(); if (expectedExitCode != result.ExitCode) { sb.AppendLine($"ExitCode: expected={expectedExitCode} actual={result.ExitCode}"); } }
private static void AssertExitCodeAndErrorMessage(IScenario scenario, AppRunnerResult result) { var sb = new StringBuilder(); AssertExitCode(scenario, result, sb); AssertMissingOutputTexts(scenario, result, sb); AssertUnexpectedOutputTexts(scenario, result, sb); if (sb.Length > 0) { throw new AssertFailedException(sb.ToString()); } }
/// <summary>Run and verify the scenario expectations using the given logger for output.</summary> public static AppRunnerResult VerifyScenario(this AppRunner appRunner, ILogger logger, IScenario scenario) { if (scenario.WhenArgs != null && scenario.WhenArgsArray != null) { throw new InvalidOperationException($"Both {nameof(scenario.WhenArgs)} and {nameof(scenario.WhenArgsArray)} were specified. Only one can be specified."); } AppRunnerResult results = null; var args = scenario.WhenArgsArray ?? scenario.WhenArgs.SplitArgs(); try { results = appRunner.RunInMem( args, logger, scenario.Given.OnReadLine, scenario.Given.PipedInput, scenario.Given.OnPrompt, returnResultOnError: true); AssertExitCodeAndErrorMessage(scenario, results); if (scenario.Then.Result != null) { results.OutputShouldBe(scenario.Then.Result); } if (scenario.Then.Outputs.Count > 0) { AssertOutputItems(scenario, results); } return(results); } catch (Exception e) { logger.WriteLine(scenario.ToString()); logger.WriteLine(""); PrintContext(appRunner, logger); if (results != null) { logger.WriteLine(""); logger.WriteLine("App Results:"); logger.WriteLine(results.ConsoleOutAndError); } throw; } }
private static void AssertUnexpectedHelpTexts(IScenario scenario, AppRunnerResult result, StringBuilder sb) { var unexpectedHelpTexts = scenario.Then.ResultsNotContainsTexts .Where(result.OutputContains) .ToList(); if (unexpectedHelpTexts.Count > 0) { sb.AppendLine(); sb.AppendLine($"Unexpected text in output:"); foreach (var text in unexpectedHelpTexts) { sb.AppendLine(); sb.AppendLine($" {text}"); } } }
private static void AssertMissingHelpTexts(IScenario scenario, AppRunnerResult result, StringBuilder sb) { var missingHelpTexts = scenario.Then.ResultsContainsTexts .Where(t => !result.OutputContains(t)) .ToList(); if (missingHelpTexts.Count > 0) { sb.AppendLine(); sb.AppendLine($"Missing text in output:"); foreach (var text in missingHelpTexts) { sb.AppendLine(); sb.AppendLine($" {text}"); } } }
private static void AssertUnexpectedOutputTexts(IScenario scenario, AppRunnerResult result, StringBuilder sb) { var allText = result.Console.AllText(); var unexpectedHelpTexts = scenario.Then.OutputNotContainsTexts .Where(t => allText?.Contains(t) ?? false) .ToList(); if (unexpectedHelpTexts.Count > 0) { sb.AppendLine(); sb.AppendLine("Unexpected text in output:"); foreach (var text in unexpectedHelpTexts) { sb.AppendLine(); sb.AppendLine($" {text}"); } } }
private static void AssertExitCodeAndErrorMessage(IScenario scenario, AppRunnerResult result) { var expectedExitCode = scenario.Then.ExitCode.GetValueOrDefault(); var missingHelpTexts = scenario.Then.ResultsContainsTexts .Where(t => !result.OutputContains(t)) .ToList(); var unexpectedHelpTexts = scenario.Then.ResultsNotContainsTexts .Where(result.OutputContains) .ToList(); if (expectedExitCode != result.ExitCode || missingHelpTexts.Count > 0 || unexpectedHelpTexts.Count > 0) { var sb = new StringBuilder(); sb.AppendLine($"ExitCode: expected={expectedExitCode} actual={result.ExitCode}"); if (missingHelpTexts.Count > 0) { sb.AppendLine(); sb.AppendLine($"Missing text in output:"); foreach (var text in missingHelpTexts) { sb.AppendLine(); sb.AppendLine($" {text}"); } } if (unexpectedHelpTexts.Count > 0) { sb.AppendLine(); sb.AppendLine($"Unexpected text in output:"); foreach (var text in unexpectedHelpTexts) { sb.AppendLine(); sb.AppendLine($" {text}"); } } sb.AppendLine(); sb.AppendLine("Console output <begin> ------------------------------"); sb.AppendLine(String.IsNullOrWhiteSpace(result.ConsoleOut) ? "<no output>" : result.ConsoleOut); sb.AppendLine("Console output <end> ------------------------------"); throw new AssertionFailedException(sb.ToString()); } }
public void VerifyScenario(IScenario scenario) { if (scenario.WhenArgs != null && scenario.WhenArgsArray != null) { throw new InvalidOperationException($"Both {nameof(scenario.WhenArgs)} and {nameof(scenario.WhenArgsArray)} were specified. Only one can be specified."); } if (scenario.And.AppSettings == null) { scenario.And.AppSettings = TestAppSettings.TestDefault; } AppRunnerResult results = null; try { var args = scenario.WhenArgsArray ?? scenario.WhenArgs.SplitArgs(); results = scenario.AppType.RunAppInMem(args, scenario.And.AppSettings, scenario.And.Dependencies); AssertExitCodeAndErrorMessage(scenario, results); if (scenario.Then.Result != null) { results.OutputShouldBe(scenario.Then.Result); } if (scenario.Then.Outputs.Count > 0) { AssertOutputItems(scenario, results); } } catch (Exception) { PrintContext(scenario); if (results != null) { _output.WriteLine(""); _output.WriteLine("App Results:"); _output.WriteLine(results.ConsoleOut); } throw; } }
private static void AssertExitCodeAndErrorMessage(IScenario scenario, AppRunnerResult result) { var sb = new StringBuilder(); AssertExitCode(scenario, result, sb); AssertMissingHelpTexts(scenario, result, sb); AssertUnexpectedHelpTexts(scenario, result, sb); if (sb.Length > 0) { sb.AppendLine(); sb.AppendLine("Console output <begin> ------------------------------"); sb.AppendLine(String.IsNullOrWhiteSpace(result.ConsoleOutAndError) ? "<no output>" : result.ConsoleOutAndError); sb.AppendLine("Console output <end> ------------------------------"); throw new AssertionFailedException(sb.ToString()); } }
private static void AssertOutputItems(IScenario scenario, AppRunnerResult results) { foreach (var expectedOutput in scenario.Then.Outputs) { var actualOutput = results.TestOutputs.Get(expectedOutput.GetType()); actualOutput.Should() .NotBeNull(because: $"{expectedOutput.GetType().Name} should have been output in test run"); actualOutput.Should().BeEquivalentTo(expectedOutput); } var actualOutputs = results.TestOutputs.Outputs; if (!scenario.Then.AllowUnspecifiedOutputs && actualOutputs.Count > scenario.Then.Outputs.Count) { var expectedOutputTypes = new HashSet <Type>(scenario.Then.Outputs.Select(o => o.GetType())); var unexpectedTypes = actualOutputs.Keys .Where(t => !expectedOutputTypes.Contains(t)) .ToOrderedCsv(); throw new AssertionFailedException($"Unexpected output: {unexpectedTypes}"); } }
/// <summary>Run and verify the scenario expectations using the given logger for output.</summary> public static AppRunnerResult Verify(this AppRunner appRunner, Action <string> logLine, TestConfig config, IScenario scenario) { if (scenario.When.Args != null && scenario.When.ArgsArray != null) { throw new InvalidOperationException($"Both {nameof(scenario.When)}.{nameof(scenario.When.Args)} and " + $"{nameof(scenario.When)}.{nameof(scenario.When.ArgsArray)} were specified. " + "Only one can be specified."); } logLine = logLine ?? Console.WriteLine; config = config ?? TestConfig.Default; AppRunnerResult results = null; var args = scenario.When.ArgsArray ?? scenario.When.Args.SplitArgs(); var origOnSuccess = config.OnSuccess; if (!config.OnError.CaptureAndReturnResult) { config = config.Where(c => { // silence success in RunInMem so results are not printed // twice when asserts fail below. // success will be replaced and printed again. c.OnSuccess = TestConfig.Silent.OnSuccess; c.OnError.CaptureAndReturnResult = true; }); } results = appRunner.RunInMem( args, logLine, scenario.When.OnReadLine, scenario.When.PipedInput, scenario.When.OnPrompt, config); config.OnSuccess = origOnSuccess; try { AssertExitCodeAndErrorMessage(scenario, results); scenario.Then.AssertOutput?.Invoke(results.Console.AllText()); scenario.Then.AssertContext?.Invoke(results.CommandContext); if (scenario.Then.Output != null) { results.Console.AllText().ShouldBe(scenario.Then.Output, "output"); } if (scenario.Then.Captured.Count > 0) { AssertCapturedItems(scenario, results); } results.LogResult(logLine); } catch (Exception e) { results.LogResult(logLine, onError: true); throw; } return(results); }