Skip to content
This repository was archived by the owner on Jul 18, 2024. It is now read-only.

Commit 51edc29

Browse files
Add process statistics
1 parent d98cff2 commit 51edc29

File tree

6 files changed

+91
-18
lines changed

6 files changed

+91
-18
lines changed

CSharpInteractive.Tests/ProcessMonitorTests.cs

+10-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public class ProcessMonitorTests
99
{
1010
private readonly Mock<ILog<ProcessMonitor>> _log = new();
1111
private readonly Mock<IEnvironment> _environment = new();
12+
private readonly Mock<IStatistics> _statistics = new();
1213
private readonly Mock<IStartInfo> _startInfo = new();
1314

1415
public ProcessMonitorTests()
@@ -70,7 +71,8 @@ internal void ShouldCreateResultWhenFinishedWithSuccess(ProcessState state, stri
7071
var result = monitor.Finished(_startInfo.Object, 22, state, 33);
7172

7273
// Then
73-
result.Description.ShouldBe([new Text("99 \"Abc xyz\" process ", color), new Text(stateDescription, color), new Text(" (in 22 ms)"), new Text(" with exit code 33"), new Text(".")]);
74+
result.Description.ShouldBe([new Text("99 \"Abc xyz\" process ", color), new Text(stateDescription, Color.Success), new Text(" (in 22 ms)"), new Text(" with exit code 33"), new Text(".")]);
75+
_statistics.Verify(i => i.RegisterProcessResult(result));
7476
}
7577

7678
[Fact]
@@ -85,7 +87,8 @@ public void ShouldCreateResultWhenFailed()
8587
var result = monitor.Finished(_startInfo.Object, 22, ProcessState.Failed, 33);
8688

8789
// Then
88-
result.Description.ShouldBe([new Text("99 \"Abc xyz\" process ", Color.Highlighted), new Text("failed", Color.Highlighted), new Text(" (in 22 ms)"), new Text(" with exit code 33"), new Text(".")]);
90+
result.Description.ShouldBe([new Text("99 \"Abc xyz\" process ", Color.Highlighted), new Text("failed", Color.Error), new Text(" (in 22 ms)"), new Text(" with exit code 33"), new Text(".")]);
91+
_statistics.Verify(i => i.RegisterProcessResult(result));
8992
}
9093

9194
[Fact]
@@ -99,7 +102,8 @@ public void ShouldCreateResultWhenFailedToStart()
99102
var result = monitor.Finished(_startInfo.Object, 22, ProcessState.Failed);
100103

101104
// Then
102-
result.Description.ShouldBe([new Text("\"Abc xyz\" process ", Color.Highlighted), new Text("failed to start", Color.Highlighted), new Text(" (in 22 ms)"), new Text(".")]);
105+
result.Description.ShouldBe([new Text("\"Abc xyz\" process ", Color.Highlighted), new Text("failed to start", Color.Error), new Text(" (in 22 ms)"), new Text(".")]);
106+
_statistics.Verify(i => i.RegisterProcessResult(result));
103107
}
104108

105109
[Fact]
@@ -114,9 +118,10 @@ public void ShouldCreateResultWhenCanceled()
114118
var result = monitor.Finished(_startInfo.Object, 22, ProcessState.Canceled);
115119

116120
// Then
117-
result.Description.ShouldBe([new Text("99 \"Abc xyz\" process ", Color.Highlighted), new Text("canceled", Color.Highlighted), new Text(" (in 22 ms)"), new Text(".")]);
121+
result.Description.ShouldBe([new Text("99 \"Abc xyz\" process ", Color.Highlighted), new Text("canceled", Color.Warning), new Text(" (in 22 ms)"), new Text(".")]);
122+
_statistics.Verify(i => i.RegisterProcessResult(result));
118123
}
119124

120125
private ProcessMonitor CreateInstance() =>
121-
new(_log.Object, _environment.Object);
126+
new(_log.Object, _environment.Object, _statistics.Object);
122127
}

CSharpInteractive/IStatistics.cs

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ internal interface IStatistics
55
IReadOnlyCollection<string> Errors { get; }
66

77
IReadOnlyCollection<string> Warnings { get; }
8+
9+
IReadOnlyCollection<ProcessResult> ProcessResults { get; }
810

911
TimeSpan TimeElapsed { get; }
1012

@@ -13,4 +15,6 @@ internal interface IStatistics
1315
void RegisterError(string error);
1416

1517
void RegisterWarning(string warning);
18+
19+
void RegisterProcessResult(ProcessResult result);
1620
}

CSharpInteractive/ProcessMonitor.cs

+30-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ namespace CSharpInteractive;
55

66
internal class ProcessMonitor(
77
ILog<ProcessMonitor> log,
8-
IEnvironment environment) : IProcessMonitor
8+
IEnvironment environment,
9+
IStatistics statistics) : IProcessMonitor
910
{
1011
private int? _processId;
1112

@@ -38,27 +39,46 @@ public void Started(IStartInfo startInfo, int processId)
3839
}
3940
}
4041

41-
public ProcessResult Finished(IStartInfo startInfo, long elapsedMilliseconds, ProcessState state, int? exitCode = default, Exception? error = default) =>
42-
new(
42+
public ProcessResult Finished(IStartInfo startInfo, long elapsedMilliseconds, ProcessState state, int? exitCode = default, Exception? error = default)
43+
{
44+
var result = new ProcessResult(
4345
startInfo,
4446
state,
4547
elapsedMilliseconds,
46-
GetFooter(startInfo,exitCode, elapsedMilliseconds, state).ToArray(),
48+
GetFooter(startInfo, exitCode, elapsedMilliseconds, state).ToArray(),
4749
exitCode,
4850
error);
51+
52+
statistics.RegisterProcessResult(result);
53+
return result;
54+
}
4955

5056
private IEnumerable<Text> GetFooter(IStartInfo startInfo, int? exitCode, long elapsedMilliseconds, ProcessState? state)
5157
{
5258
// ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault
53-
var stateText = state switch
59+
string? stateText;
60+
Color stateColor;
61+
// ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault
62+
switch (state)
5463
{
55-
ProcessState.Failed => exitCode.HasValue ? "failed" : "failed to start",
56-
ProcessState.Canceled => "canceled",
57-
_ => "finished"
58-
};
64+
case ProcessState.Failed:
65+
stateText = exitCode.HasValue ? "failed" : "failed to start";
66+
stateColor = Color.Error;
67+
break;
68+
69+
case ProcessState.Canceled:
70+
stateText = "canceled";
71+
stateColor = Color.Warning;
72+
break;
73+
74+
default:
75+
stateText = "finished";
76+
stateColor = Color.Success;
77+
break;
78+
}
5979

6080
yield return new Text($"{startInfo.GetDescription(_processId)} process ", Color.Highlighted);
61-
yield return new Text(stateText, Color.Highlighted);
81+
yield return new Text(stateText, stateColor);
6282
yield return new Text($" (in {elapsedMilliseconds} ms)");
6383
if (exitCode.HasValue)
6484
{

CSharpInteractive/Statistics.cs

+20
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ internal class Statistics : IStatistics
1010
private readonly Stopwatch _stopwatch = new();
1111
private readonly List<string> _errors = [];
1212
private readonly List<string> _warnings = [];
13+
private readonly List<ProcessResult> _processResult = [];
1314

1415
public IReadOnlyCollection<string> Errors
1516
{
@@ -33,6 +34,17 @@ public IReadOnlyCollection<string> Warnings
3334
}
3435
}
3536

37+
public IReadOnlyCollection<ProcessResult> ProcessResults
38+
{
39+
get
40+
{
41+
lock (_processResult)
42+
{
43+
return new ReadOnlyCollection<ProcessResult>(_processResult);
44+
}
45+
}
46+
}
47+
3648
public TimeSpan TimeElapsed => _stopwatch.Elapsed;
3749

3850
public IDisposable Start()
@@ -64,4 +76,12 @@ public void RegisterWarning(string warning)
6476
}
6577
}
6678
}
79+
80+
public void RegisterProcessResult(ProcessResult result)
81+
{
82+
lock (_processResult)
83+
{
84+
_processResult.Add(result);
85+
}
86+
}
6787
}

CSharpInteractive/StatisticsPresenter.cs

+11-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,23 @@ internal class StatisticsPresenter(ILog<StatisticsPresenter> log) : IPresenter<I
88
{
99
public void Show(IStatistics statistics)
1010
{
11-
foreach (var error in statistics.Errors)
11+
log.Info();
12+
log.Info(new Text("Summary:", Color.Header));
13+
14+
foreach (var processResult in statistics.ProcessResults)
1215
{
13-
log.Info(Text.Tab, new Text(error, Color.Error));
16+
log.Info(Text.Tab + processResult.Description);
1417
}
15-
18+
1619
foreach (var warning in statistics.Warnings)
1720
{
1821
log.Info(Text.Tab, new Text(warning, Color.Warning));
1922
}
23+
24+
foreach (var error in statistics.Errors)
25+
{
26+
log.Info(Text.Tab, new Text(error, Color.Error));
27+
}
2028

2129
if (statistics.Warnings.Count > 0)
2230
{

CSharpInteractive/Text.cs

+16
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ public override string ToString()
3333

3434
return sb.ToString();
3535
}
36+
37+
public static Text[] operator +(Text text1, Text text2)
38+
{
39+
var newText = new Text[2];
40+
newText[0] = text1;
41+
newText[1] = text2;
42+
return newText;
43+
}
3644

3745
public static Text[] operator +(Text[] text, Text text2)
3846
{
@@ -49,4 +57,12 @@ public override string ToString()
4957
Array.Copy(text, 0, newText, 1, text.Length);
5058
return newText;
5159
}
60+
61+
public static Text[] Join(Text[] text1, Text[] text2)
62+
{
63+
var newText = new Text[text1.Length + text2.Length];
64+
Array.Copy(text1, 0, newText, 0, text1.Length);
65+
Array.Copy(text2, 0, newText, text1.Length, text2.Length);
66+
return newText;
67+
}
5268
}

0 commit comments

Comments
 (0)