TeamCity.CSharpInteractive/BuildResult.cs (97 lines of code) (raw):
// ReSharper disable ReturnTypeCanBeEnumerable.Local
namespace TeamCity.CSharpInteractive;
using System.Diagnostics;
using System.Text;
using HostApi;
using Immutype;
[Target]
[DebuggerTypeProxy(typeof(BuildResultDebugView))]
internal class BuildResult : IBuildResult
{
private readonly Lazy<BuildStatistics> _summary;
// ReSharper disable once UnusedMember.Global
public BuildResult(IStartInfo startInfo)
: this(startInfo, Array.Empty<BuildMessage>(), Array.Empty<BuildMessage>(), Array.Empty<TestResult>(), default)
{ }
public BuildResult(
IStartInfo startInfo,
IReadOnlyList<BuildMessage> errors,
IReadOnlyList<BuildMessage> warnings,
IReadOnlyList<TestResult> tests,
int? exitCode)
{
StartInfo = startInfo;
Errors = errors;
Warnings = warnings;
Tests = tests;
ExitCode = exitCode;
_summary = new Lazy<BuildStatistics>(CalculateSummary, LazyThreadSafetyMode.ExecutionAndPublication);
}
public BuildStatistics Summary => _summary.Value;
public IStartInfo StartInfo { get; }
public IReadOnlyList<BuildMessage> Errors { get; }
public IReadOnlyList<BuildMessage> Warnings { get; }
public IReadOnlyList<TestResult> Tests { get; }
public int? ExitCode { get; }
public override string ToString()
{
var sb = new StringBuilder();
sb.Append(string.IsNullOrWhiteSpace(StartInfo.ShortName) ? "Build" : $"\"{StartInfo.ShortName}\"");
sb.Append(" is ");
sb.Append(ExitCode.HasValue ? "finished" : "not finished");
if (Summary.IsEmpty != true)
{
sb.Append(" with ");
sb.Append(Summary);
}
sb.Append('.');
return sb.ToString();
}
private BuildStatistics CalculateSummary()
{
var testItems =
from testGroup in
from testResult in Tests
group testResult by (AssemblyName: testResult.SuiteName, testResult.Name)
select testGroup.OrderByDescending(i => i.State).First();
var totalTests = 0;
var failedTests = 0;
var ignoredTests = 0;
var passedTests = 0;
foreach (var test in testItems)
{
totalTests++;
// ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault
switch (test.State)
{
case TestState.Passed:
passedTests++;
break;
case TestState.Failed:
failedTests++;
break;
case TestState.Ignored:
ignoredTests++;
break;
}
}
return new BuildStatistics(
Errors.Count,
Warnings.Count,
totalTests,
failedTests,
ignoredTests,
passedTests);
}
private class BuildResultDebugView
{
private readonly BuildResult _buildResult;
public BuildResultDebugView(BuildResult buildResult) => _buildResult = buildResult;
public BuildStatistics Summary => _buildResult.Summary;
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public IReadOnlyList<BuildMessage> Errors => _buildResult.Errors;
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public IReadOnlyList<BuildMessage> Warnings => _buildResult.Warnings;
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public IReadOnlyList<TestResult> Tests => _buildResult.Tests;
public IStartInfo StartInfo => _buildResult.StartInfo;
public int? ExitCode => _buildResult.ExitCode;
}
}