Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ee85981
Integrating interactive logger
nohwnd Jul 18, 2024
c9513d5
Format output
nohwnd Jul 19, 2024
a6d9ce6
per assembly summary
nohwnd Jul 19, 2024
ef0f958
Merge branch 'main' of https://github.com/microsoft/testfx into inter…
nohwnd Jul 22, 2024
b31df8c
Fix warnings
nohwnd Jul 22, 2024
345325b
Push fixes
nohwnd Jul 22, 2024
7c89f56
fixes
nohwnd Jul 22, 2024
914c104
refactor
nohwnd Jul 23, 2024
19e8d89
Fixes
nohwnd Jul 23, 2024
181a987
Review fixes
nohwnd Jul 23, 2024
4ef03f1
Fix framework name shortening
nohwnd Jul 23, 2024
80a4077
Merge branch 'main' into interactive-logger
nohwnd Jul 23, 2024
251f524
Remove unused class
nohwnd Jul 23, 2024
bed2dba
Add help, and clean up more code
nohwnd Jul 23, 2024
5903852
Update src/Platform/Microsoft.Testing.Platform/UI/LoggerOutcome.cs
nohwnd Jul 23, 2024
1771422
Merge branch 'main' into interactive-logger
nohwnd Jul 23, 2024
54b4c1b
bom
nohwnd Jul 23, 2024
f4053ef
Move code and add more extensions
nohwnd Jul 23, 2024
a6c06ef
Reformat
nohwnd Jul 23, 2024
df4d5de
update xlf
nohwnd Jul 23, 2024
c09775c
Apply suggestions from code review
nohwnd Jul 24, 2024
d4c8118
Use background thread
nohwnd Jul 24, 2024
219cad3
Merge branch 'interactive-logger' of https://github.com/microsoft/tes…
nohwnd Jul 24, 2024
1ae8c1e
Write warning and error with newline
nohwnd Jul 24, 2024
9a14f23
Don't write progress in host controller
nohwnd Jul 24, 2024
0036179
Merge branch 'main' into interactive-logger
nohwnd Jul 24, 2024
ffd0969
Fix newline
nohwnd Jul 24, 2024
4697e19
Fixes from pr review
nohwnd Aug 6, 2024
0a5c49e
Merge branch 'main' into interactive-logger
nohwnd Aug 6, 2024
89ad397
Tests fixed
nohwnd Aug 6, 2024
940d3f3
Tests fixed
nohwnd Aug 6, 2024
0fe3732
Remove filter
nohwnd Aug 7, 2024
b3dae94
Merge branch 'main' into interactive-logger
nohwnd Aug 7, 2024
e53f163
Fixed tests
nohwnd Aug 7, 2024
c0e1a33
Fix is test controller
nohwnd Aug 7, 2024
12c30c2
Update test/Utilities/Microsoft.Testing.TestInfrastructure/CommandLin…
nohwnd Aug 8, 2024
c570627
Update test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.In…
nohwnd Aug 8, 2024
4e443bf
Fixes before rename
nohwnd Aug 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions samples/Playground/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ public static async Task<int> Main(string[] args)
});
await discoveryResponse.WaitCompletionAsync();

ResponseListener runRequest = await client.RunTestsAsync(Guid.NewGuid(), testNodeUpdates.Select(x => x.Node).ToArray(), node =>
{
return Task.CompletedTask;
});
ResponseListener runRequest = await client.RunTestsAsync(Guid.NewGuid(), testNodeUpdates.Select(x => x.Node).ToArray(), node => Task.CompletedTask);
await runRequest.WaitCompletionAsync();

return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,28 +621,3 @@ private async Task ConsoleWriteLineAsync(string? text, ConsoleColor? color = nul
return stringBuilder.ToString();
}
}

internal static class OutputFormatter
{
public static string FormatString(string? text)
{
if (text == null)
{
return "<null>";
}

if (text == string.Empty)
{
return "<empty>";
}

#pragma warning disable IDE0046 // Convert to conditional expression
if (RoslynString.IsNullOrWhiteSpace(text))
{
return text.Replace("\r", "\\r").Replace("\n", "\\n").Replace("\t", "\\t");
}
#pragma warning restore IDE0046 // Convert to conditional expression

return text;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ internal async Task<IPlatformOutputDevice> BuildAsync(ServiceProvider servicePro
}
}

return new ConsoleOutputDevice(
return new ConsoleLoggerOutputDevice(
serviceProvider.GetTestApplicationCancellationTokenSource(),
serviceProvider.GetConsole(),
serviceProvider.GetTestApplicationModuleInfo(),
Expand All @@ -46,6 +46,7 @@ internal async Task<IPlatformOutputDevice> BuildAsync(ServiceProvider servicePro
loggingState.CommandLineParseResult.IsOptionSet(PlatformCommandLineProvider.DiscoverTestsOptionKey),
loggingState.CommandLineParseResult.IsOptionSet(PlatformCommandLineProvider.ServerOptionKey),
PlatformCommandLineProvider.GetMinimumExpectedTests(loggingState.CommandLineParseResult),
loggingState.FileLoggerProvider);
loggingState.FileLoggerProvider,
serviceProvider.GetClock());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.Testing.Platform.OutputDevice;

internal static class OutputFormatter
{
public static string FormatString(string? text)
{
if (text == null)
{
return "<null>";
}

if (text == string.Empty)
{
return "<empty>";
}

#pragma warning disable IDE0046 // Convert to conditional expression
if (RoslynString.IsNullOrWhiteSpace(text))
{
return text.Replace("\r", "\\r").Replace("\n", "\\n").Replace("\t", "\\t");
}
#pragma warning restore IDE0046 // Convert to conditional expression

return text;
Comment thread
nohwnd marked this conversation as resolved.
Outdated
}
}
144 changes: 144 additions & 0 deletions src/Platform/Microsoft.Testing.Platform/UI/AnsiCodes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.Testing.Platform.UI;
Comment thread
nohwnd marked this conversation as resolved.
Outdated

/// <summary>
/// A collection of standard ANSI/VT100 control codes.
/// </summary>
internal static class AnsiCodes
{
/// <summary>
/// Escape character.
/// </summary>
public const string Esc = "\x1b";

/// <summary>
/// The control sequence introducer.
/// </summary>
public const string CSI = "\x1b[";

/// <summary>
/// Select graphic rendition.
/// </summary>
/// <remarks>
/// Print <see cref="CSI"/>color-code<see cref="SetColor"/> to change text color.
/// </remarks>
public const string SetColor = ";1m";

/// <summary>
/// Select graphic rendition - set bold mode.
/// </summary>
/// <remarks>
/// Print <see cref="CSI"/><see cref="SetBold"/> to change text to bold.
/// </remarks>
public const string SetBold = "1m";

/// <summary>
/// A shortcut to reset color back to normal.
/// </summary>
public const string SetDefaultColor = CSI + "m";

/// <summary>
/// Non-xterm extension to render a hyperlink.
/// </summary>
/// <remarks>
/// Print <see cref="LinkPrefix"/>url<see cref="LinkInfix"/>text<see cref="LinkSuffix"/> to render a hyperlink.
/// </remarks>
public const string LinkPrefix = "\x1b]8;;";

/// <summary>
/// <see cref="LinkPrefix"/>.
/// </summary>
public const string LinkInfix = "\x1b\\";

/// <summary>
/// <see cref="LinkPrefix"/>.
/// </summary>
public const string LinkSuffix = "\x1b]8;;\x1b\\";

/// <summary>
/// Moves up the specified number of lines and puts cursor at the beginning of the line.
/// </summary>
/// <remarks>
/// Print <see cref="CSI"/>N<see cref="MoveUpToLineStart"/> to move N lines up.
/// </remarks>
public const string MoveUpToLineStart = "F";

/// <summary>
/// Moves forward (to the right) the specified number of characters.
/// </summary>
/// <remarks>
/// Print <see cref="CSI"/>N<see cref="MoveForward"/> to move N characters forward.
/// </remarks>
public const string MoveForward = "C";

/// <summary>
/// Moves backward (to the left) the specified number of characters.
/// </summary>
/// <remarks>
/// Print <see cref="CSI"/>N<see cref="MoveBackward"/> to move N characters backward.
/// </remarks>
public const string MoveBackward = "D";

/// <summary>
/// Clears everything from cursor to end of screen.
/// </summary>
/// <remarks>
/// Print <see cref="CSI"/><see cref="EraseInDisplay"/> to clear.
/// </remarks>
public const string EraseInDisplay = "J";

/// <summary>
/// Clears everything from cursor to the end of the current line.
/// </summary>
/// <remarks>
/// Print <see cref="CSI"/><see cref="EraseInLine"/> to clear.
/// </remarks>
public const string EraseInLine = "K";

/// <summary>
/// Hides the cursor.
/// </summary>
public const string HideCursor = "\x1b[?25l";

/// <summary>
/// Shows/restores the cursor.
/// </summary>
public const string ShowCursor = "\x1b[?25h";

/// <summary>
/// Set progress state to a busy spinner. <br/>
/// Note: this code works only on ConEmu terminals, and conflicts with push a notification code on iTerm2.
/// </summary>
/// <remarks>
/// <see href="https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC">ConEmu specific OSC codes.</see><br/>
/// <see href="https://iterm2.com/documentation-escape-codes.html">iTerm2 proprietary escape codes.</see>
/// </remarks>
public const string SetProgressIndeterminate = "\x1b]9;4;3;\x1b\\";

/// <summary>
/// Remove progress state, restoring taskbar status to normal. <br/>
/// Note: this code works only on ConEmu terminals, and conflicts with push a notification code on iTerm2.
/// </summary>
/// <remarks>
/// <see href="https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC">ConEmu specific OSC codes.</see><br/>
/// <see href="https://iterm2.com/documentation-escape-codes.html">iTerm2 proprietary escape codes.</see>
/// </remarks>
public const string RemoveProgress = "\x1b]9;4;0;\x1b\\";

public static string Colorize(string? s, TerminalColor color)
=> RoslynString.IsNullOrWhiteSpace(s) ? s ?? string.Empty : $"{CSI}{(int)color}{SetColor}{s}{SetDefaultColor}";

public static string MakeBold(string? s)
=> RoslynString.IsNullOrWhiteSpace(s) ? s ?? string.Empty : $"{CSI}{SetBold}{s}{SetDefaultColor}";

public static string MoveCursorBackward(int count) => $"{CSI}{count}{MoveBackward}";

/// <summary>
/// Moves cursor to the specified column, or the rightmost column if <paramref name="column"/> is greater than the width of the terminal.
/// </summary>
/// <param name="column">Column index.</param>
/// <returns>Control codes to set the desired position.</returns>
public static string SetCursorHorizontal(int column) => $"{CSI}{column}G";
}
37 changes: 37 additions & 0 deletions src/Platform/Microsoft.Testing.Platform/UI/AnsiDetector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

// Portions of the code in this file were ported from the spectre.console by Patrik Svensson, Phil Scott, Nils Andresen
// https://github.com/spectreconsole/spectre.console/blob/main/src/Spectre.Console/Internal/Backends/Ansi/AnsiDetector.cs
// and from the supports-ansi project by Qingrong Ke
// https://github.com/keqingrong/supports-ansi/blob/master/index.js
using System.Text.RegularExpressions;

namespace Microsoft.Testing.Platform.UI;

internal class AnsiDetector
{
private static readonly Regex[] TerminalsRegexes =
{
new("^xterm"), // xterm, PuTTY, Mintty
new("^rxvt"), // RXVT
new("^(?!eterm-color).*eterm.*"), // Accepts eterm, but not eterm-color, which does not support moving the cursor, see #9950.
new("^screen"), // GNU screen, tmux
new("tmux"), // tmux
new("^vt100"), // DEC VT series
new("^vt102"), // DEC VT series
new("^vt220"), // DEC VT series
new("^vt320"), // DEC VT series
new("ansi"), // ANSI
new("scoansi"), // SCO ANSI
new("cygwin"), // Cygwin, MinGW
new("linux"), // Linux console
new("konsole"), // Konsole
new("bvterm"), // Bitvise SSH Client
new("^st-256color"), // Suckless Simple Terminal, st
new("alacritty"), // Alacritty
};

internal static bool IsAnsiSupported(string termType)
=> !RoslynString.IsNullOrEmpty(termType) && TerminalsRegexes.Any(regex => regex.IsMatch(termType));
}
36 changes: 36 additions & 0 deletions src/Platform/Microsoft.Testing.Platform/UI/AssemblyRun.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.Testing.Platform.UI;

internal sealed class AssemblyRun
Comment thread
nohwnd marked this conversation as resolved.
Outdated
{
public AssemblyRun(int slotIndex, AssemblyRunStartedUpdate assemblyRunStartedUpdate, StopwatchAbstraction stopwatch)
{
SlotIndex = slotIndex;
AssemblyRunStartedUpdate = assemblyRunStartedUpdate;
Stopwatch = stopwatch;
}

public int SlotIndex { get; }

public AssemblyRunStartedUpdate AssemblyRunStartedUpdate { get; }

public StopwatchAbstraction Stopwatch { get; }

public List<string> Attachments { get; } = new();

public List<IMessage> Messages { get; } = new();

public int FailedTests { get; internal set; }

public int PassedTests { get; internal set; }

public int SkippedTests { get; internal set; }

public int TotalTests { get; internal set; }

public int TimedOutTests { get; internal set; }

public int CancelledTests { get; internal set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.Testing.Platform.UI;

internal sealed class AssemblyRunCompletedUpdate(string assembly, string? targetFramework, string? architecture)
{
public string Assembly { get; } = assembly;

public string? TargetFramework { get; } = targetFramework;

public string? Architecture { get; } = architecture;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

internal sealed class AssemblyRunStartedUpdate(string assembly, int tests, string? targetFramework, string? architecture)
{
public string Assembly { get; } = assembly;

public int Tests { get; } = tests;

public string? TargetFramework { get; } = targetFramework;

public string? Architecture { get; } = architecture;
}
Loading