From 8b59ddfd41db1d34f44d0414eb8c5609a038c576 Mon Sep 17 00:00:00 2001
From: Frank Ray <52075808+FrankRay78@users.noreply.github.com>
Date: Wed, 23 Jul 2025 22:11:07 +0100
Subject: [PATCH] Separate Spectre.Console.Cli from Spectre.Console (#1850)
---
src/Directory.Packages.props | 40 ++++++------
src/Spectre.Console.Cli.sln | 51 +++++++++++++++
.../Spectre.Console.Cli.csproj | 9 +--
.../Extensions/ShouldlyExtensions.cs | 17 ++++-
.../TestConsoleExtensions.Exceptions.cs | 59 +++++++++++++++++
.../{ => Extensions}/TestConsoleExtensions.cs | 2 +-
.../Properties/Usings.cs | 1 +
.../Spectre.Console.Testing.csproj | 13 ++--
src/Spectre.Console.sln | 64 ++++---------------
.../{Prompts => }/ValidationResult.cs | 2 +-
.../Spectre.Console.Cli.Tests.csproj | 19 +++---
.../Spectre.Console.Tests.csproj | 3 +-
.../Utilities/TestConsoleExtensions.cs | 38 -----------
13 files changed, 179 insertions(+), 139 deletions(-)
create mode 100644 src/Spectre.Console.Cli.sln
create mode 100644 src/Spectre.Console.Testing/Extensions/TestConsoleExtensions.Exceptions.cs
rename src/Spectre.Console.Testing/{ => Extensions}/TestConsoleExtensions.cs (98%)
rename src/Spectre.Console/{Prompts => }/ValidationResult.cs (96%)
delete mode 100644 src/Tests/Spectre.Console.Tests/Utilities/TestConsoleExtensions.cs
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index 0bdd1483..b40c4ffa 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -1,27 +1,27 @@
-
true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
\ No newline at end of file
diff --git a/src/Spectre.Console.Cli.sln b/src/Spectre.Console.Cli.sln
new file mode 100644
index 00000000..4dc2b9a9
--- /dev/null
+++ b/src/Spectre.Console.Cli.sln
@@ -0,0 +1,51 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32414.318
+MinimumVisualStudioVersion = 15.0.26124.0
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Cli", "Spectre.Console.Cli\Spectre.Console.Cli.csproj", "{1B67B74F-1243-4381-9A2B-86EA66D135C5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Cli.Tests", "Tests\Spectre.Console.Cli.Tests\Spectre.Console.Cli.Tests.csproj", "{E07C46D2-714F-4116-BADD-FEE09617A9C4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|x64.Build.0 = Debug|Any CPU
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|x86.Build.0 = Debug|Any CPU
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|x64.ActiveCfg = Release|Any CPU
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|x64.Build.0 = Release|Any CPU
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|x86.ActiveCfg = Release|Any CPU
+ {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|x86.Build.0 = Release|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|x64.Build.0 = Debug|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|x86.Build.0 = Debug|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|x64.ActiveCfg = Release|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|x64.Build.0 = Release|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|x86.ActiveCfg = Release|Any CPU
+ {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {5729B071-67A0-48FB-8B1B-275E6822086C}
+ EndGlobalSection
+EndGlobal
diff --git a/src/Spectre.Console.Cli/Spectre.Console.Cli.csproj b/src/Spectre.Console.Cli/Spectre.Console.Cli.csproj
index 17c2a24b..880da88e 100644
--- a/src/Spectre.Console.Cli/Spectre.Console.Cli.csproj
+++ b/src/Spectre.Console.Cli/Spectre.Console.Cli.csproj
@@ -1,21 +1,17 @@
-
+
net9.0;net8.0;netstandard2.0
true
- false
+ false
false
-
-
-
-
3.0.0
False
@@ -26,6 +22,7 @@
all
runtime; build; native; contentfiles; analyzers
+
diff --git a/src/Spectre.Console.Testing/Extensions/ShouldlyExtensions.cs b/src/Spectre.Console.Testing/Extensions/ShouldlyExtensions.cs
index 112cd185..fbdb2e0a 100644
--- a/src/Spectre.Console.Testing/Extensions/ShouldlyExtensions.cs
+++ b/src/Spectre.Console.Testing/Extensions/ShouldlyExtensions.cs
@@ -1,7 +1,20 @@
-namespace Spectre.Console;
+namespace Spectre.Console.Testing;
-internal static class ShouldlyExtensions
+///
+/// Provides extensions for testing using the Shouldly-style fluent assertions.
+///
+public static class ShouldlyExtensions
{
+ ///
+ /// Performs the specified action on the given object and then returns the object.
+ /// Useful for fluent testing patterns where additional assertions or operations
+ /// are chained together in a readable manner.
+ ///
+ /// The type of the object.
+ /// The object to operate on.
+ /// An action to perform on the object.
+ /// The original object, to allow further chaining.
+ /// Thrown if is null.
[DebuggerStepThrough]
public static T And(this T item, Action action)
{
diff --git a/src/Spectre.Console.Testing/Extensions/TestConsoleExtensions.Exceptions.cs b/src/Spectre.Console.Testing/Extensions/TestConsoleExtensions.Exceptions.cs
new file mode 100644
index 00000000..582ddf18
--- /dev/null
+++ b/src/Spectre.Console.Testing/Extensions/TestConsoleExtensions.Exceptions.cs
@@ -0,0 +1,59 @@
+namespace Spectre.Console.Testing;
+
+///
+/// Provides extension methods for working with in a testing context,
+/// including stack trace normalization for consistent and deterministic test output.
+///
+public static partial class TestConsoleExtensions
+{
+ private static readonly Regex _lineNumberRegex = new Regex(":\\d+", RegexOptions.Singleline);
+ private static readonly Regex _filenameRegex = new Regex("\\sin\\s.*cs:nn", RegexOptions.Multiline);
+
+ ///
+ /// Writes the given exception to the and returns a normalized string
+ /// representation of the exception, with file paths and line numbers sanitized.
+ ///
+ /// The to write to.
+ /// The exception to write and normalize.
+ /// Optional formatting options for exception output.
+ /// A normalized string of the exception's output, safe for snapshot testing.
+ ///
+ /// Thrown if the console's output buffer is not empty before writing the exception.
+ ///
+ public static string WriteNormalizedException(this TestConsole console, Exception ex, ExceptionFormats formats = ExceptionFormats.Default)
+ {
+ if (!string.IsNullOrWhiteSpace(console.Output))
+ {
+ throw new InvalidOperationException("Output buffer is not empty.");
+ }
+
+ console.WriteException(ex, formats);
+ return string.Join("\n", NormalizeStackTrace(console.Output)
+ .NormalizeLineEndings()
+ .Split(new char[] { '\n' })
+ .Select(line => line.TrimEnd()));
+ }
+
+ ///
+ /// Normalizes a stack trace string by replacing line numbers with ":nn"
+ /// and converting full file paths to a fixed placeholder path ("/xyz/filename.cs").
+ ///
+ /// The stack trace text to normalize.
+ /// A sanitized stack trace suitable for stable testing output.
+ public static string NormalizeStackTrace(string text)
+ {
+ text = _lineNumberRegex.Replace(text, match =>
+ {
+ return ":nn";
+ });
+
+ return _filenameRegex.Replace(text, match =>
+ {
+ var value = match.Value;
+ var index = value.LastIndexOfAny(new[] { '\\', '/' });
+ var filename = value.Substring(index + 1, value.Length - index - 1);
+
+ return $" in /xyz/{filename}";
+ });
+ }
+}
diff --git a/src/Spectre.Console.Testing/TestConsoleExtensions.cs b/src/Spectre.Console.Testing/Extensions/TestConsoleExtensions.cs
similarity index 98%
rename from src/Spectre.Console.Testing/TestConsoleExtensions.cs
rename to src/Spectre.Console.Testing/Extensions/TestConsoleExtensions.cs
index 545414c9..ffe6a8b1 100644
--- a/src/Spectre.Console.Testing/TestConsoleExtensions.cs
+++ b/src/Spectre.Console.Testing/Extensions/TestConsoleExtensions.cs
@@ -3,7 +3,7 @@ namespace Spectre.Console.Testing;
///
/// Contains extensions for .
///
-public static class TestConsoleExtensions
+public static partial class TestConsoleExtensions
{
///
/// Sets the console's color system.
diff --git a/src/Spectre.Console.Testing/Properties/Usings.cs b/src/Spectre.Console.Testing/Properties/Usings.cs
index 030cad02..4f5f1e95 100644
--- a/src/Spectre.Console.Testing/Properties/Usings.cs
+++ b/src/Spectre.Console.Testing/Properties/Usings.cs
@@ -3,6 +3,7 @@ global using System.Collections.Generic;
global using System.Diagnostics;
global using System.IO;
global using System.Linq;
+global using System.Text.RegularExpressions;
global using System.Threading;
global using System.Threading.Tasks;
global using Spectre.Console.Cli;
diff --git a/src/Spectre.Console.Testing/Spectre.Console.Testing.csproj b/src/Spectre.Console.Testing/Spectre.Console.Testing.csproj
index 182a63d0..71d9c078 100644
--- a/src/Spectre.Console.Testing/Spectre.Console.Testing.csproj
+++ b/src/Spectre.Console.Testing/Spectre.Console.Testing.csproj
@@ -1,4 +1,4 @@
-
+
net9.0;net8.0;netstandard2.0
@@ -7,14 +7,9 @@
Contains testing utilities for Spectre.Console.
-
-
-
-
-
-
-
-
+
+
+
diff --git a/src/Spectre.Console.sln b/src/Spectre.Console.sln
index 756d7c13..07a1b580 100644
--- a/src/Spectre.Console.sln
+++ b/src/Spectre.Console.sln
@@ -10,10 +10,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{20595AD4
.editorconfig = .editorconfig
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
+ Directory.Packages.props = Directory.Packages.props
..\dotnet-tools.json = ..\dotnet-tools.json
..\global.json = ..\global.json
stylecop.json = stylecop.json
- Directory.Packages.props = Directory.Packages.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{C3E2CB5C-1517-4C75-B59A-93D4E22BEC8D}"
@@ -24,23 +24,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{C3E2CB
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.ImageSharp", "Extensions\Spectre.Console.ImageSharp\Spectre.Console.ImageSharp.csproj", "{0EFE694D-0770-4E71-BF4E-EC2B41362F79}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Testing", "Spectre.Console.Testing\Spectre.Console.Testing.csproj", "{7D5F6704-8249-46DD-906C-9E66419F215F}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{E0E45070-123C-4A4D-AA98-2A780308876C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Tests", "Tests\Spectre.Console.Tests\Spectre.Console.Tests.csproj", "{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Cli", "Spectre.Console.Cli\Spectre.Console.Cli.csproj", "{1B67B74F-1243-4381-9A2B-86EA66D135C5}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Cli.Tests", "Tests\Spectre.Console.Cli.Tests\Spectre.Console.Cli.Tests.csproj", "{E07C46D2-714F-4116-BADD-FEE09617A9C4}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Json", "Extensions\Spectre.Console.Json\Spectre.Console.Json.csproj", "{579E6E31-1E2F-4FE1-8F8C-9770878993E9}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{F34EFD87-6CEA-453F-858B-094EA413578C}"
- ProjectSection(SolutionItems) = preProject
- Tests\Directory.Build.props = Tests\Directory.Build.props
- Tests\.editorconfig = Tests\.editorconfig
- EndProjectSection
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spectre.Console.Testing", "Spectre.Console.Testing\Spectre.Console.Testing.csproj", "{6C0416D5-44E6-D04B-B767-8772A7E7C08B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -76,18 +66,6 @@ Global
{0EFE694D-0770-4E71-BF4E-EC2B41362F79}.Release|x64.Build.0 = Release|Any CPU
{0EFE694D-0770-4E71-BF4E-EC2B41362F79}.Release|x86.ActiveCfg = Release|Any CPU
{0EFE694D-0770-4E71-BF4E-EC2B41362F79}.Release|x86.Build.0 = Release|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Debug|x64.ActiveCfg = Debug|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Debug|x64.Build.0 = Debug|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Debug|x86.ActiveCfg = Debug|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Debug|x86.Build.0 = Debug|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Release|Any CPU.Build.0 = Release|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Release|x64.ActiveCfg = Release|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Release|x64.Build.0 = Release|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Release|x86.ActiveCfg = Release|Any CPU
- {7D5F6704-8249-46DD-906C-9E66419F215F}.Release|x86.Build.0 = Release|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -100,30 +78,6 @@ Global
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Release|x64.Build.0 = Release|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Release|x86.ActiveCfg = Release|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Release|x86.Build.0 = Release|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|x64.ActiveCfg = Debug|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|x64.Build.0 = Debug|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|x86.ActiveCfg = Debug|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Debug|x86.Build.0 = Debug|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|Any CPU.Build.0 = Release|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|x64.ActiveCfg = Release|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|x64.Build.0 = Release|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|x86.ActiveCfg = Release|Any CPU
- {1B67B74F-1243-4381-9A2B-86EA66D135C5}.Release|x86.Build.0 = Release|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|x64.ActiveCfg = Debug|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|x64.Build.0 = Debug|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|x86.ActiveCfg = Debug|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Debug|x86.Build.0 = Debug|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|Any CPU.Build.0 = Release|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|x64.ActiveCfg = Release|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|x64.Build.0 = Release|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|x86.ActiveCfg = Release|Any CPU
- {E07C46D2-714F-4116-BADD-FEE09617A9C4}.Release|x86.Build.0 = Release|Any CPU
{579E6E31-1E2F-4FE1-8F8C-9770878993E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{579E6E31-1E2F-4FE1-8F8C-9770878993E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{579E6E31-1E2F-4FE1-8F8C-9770878993E9}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -136,6 +90,18 @@ Global
{579E6E31-1E2F-4FE1-8F8C-9770878993E9}.Release|x64.Build.0 = Release|Any CPU
{579E6E31-1E2F-4FE1-8F8C-9770878993E9}.Release|x86.ActiveCfg = Release|Any CPU
{579E6E31-1E2F-4FE1-8F8C-9770878993E9}.Release|x86.Build.0 = Release|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Debug|x64.Build.0 = Debug|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Debug|x86.Build.0 = Debug|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Release|x64.ActiveCfg = Release|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Release|x64.Build.0 = Release|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Release|x86.ActiveCfg = Release|Any CPU
+ {6C0416D5-44E6-D04B-B767-8772A7E7C08B}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -144,8 +110,6 @@ Global
{C3E2CB5C-1517-4C75-B59A-93D4E22BEC8D} = {20595AD4-8D75-4AF8-B6BC-9C38C160423F}
{0EFE694D-0770-4E71-BF4E-EC2B41362F79} = {E0E45070-123C-4A4D-AA98-2A780308876C}
{579E6E31-1E2F-4FE1-8F8C-9770878993E9} = {E0E45070-123C-4A4D-AA98-2A780308876C}
- {60A4CADD-2B3D-48ED-89C0-1637A1F111AE} = {F34EFD87-6CEA-453F-858B-094EA413578C}
- {E07C46D2-714F-4116-BADD-FEE09617A9C4} = {F34EFD87-6CEA-453F-858B-094EA413578C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5729B071-67A0-48FB-8B1B-275E6822086C}
diff --git a/src/Spectre.Console/Prompts/ValidationResult.cs b/src/Spectre.Console/ValidationResult.cs
similarity index 96%
rename from src/Spectre.Console/Prompts/ValidationResult.cs
rename to src/Spectre.Console/ValidationResult.cs
index 8bff32bb..cdda2a97 100644
--- a/src/Spectre.Console/Prompts/ValidationResult.cs
+++ b/src/Spectre.Console/ValidationResult.cs
@@ -1,7 +1,7 @@
namespace Spectre.Console;
///
-/// Represents a prompt validation result.
+/// Represents a validation result.
///
public sealed class ValidationResult
{
diff --git a/src/Tests/Spectre.Console.Cli.Tests/Spectre.Console.Cli.Tests.csproj b/src/Tests/Spectre.Console.Cli.Tests/Spectre.Console.Cli.Tests.csproj
index 1d95708b..fbe125b7 100644
--- a/src/Tests/Spectre.Console.Cli.Tests/Spectre.Console.Cli.Tests.csproj
+++ b/src/Tests/Spectre.Console.Cli.Tests/Spectre.Console.Cli.Tests.csproj
@@ -5,13 +5,14 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -19,9 +20,7 @@
-
-
-
+
diff --git a/src/Tests/Spectre.Console.Tests/Spectre.Console.Tests.csproj b/src/Tests/Spectre.Console.Tests/Spectre.Console.Tests.csproj
index 352f29d9..d93410e1 100644
--- a/src/Tests/Spectre.Console.Tests/Spectre.Console.Tests.csproj
+++ b/src/Tests/Spectre.Console.Tests/Spectre.Console.Tests.csproj
@@ -1,4 +1,4 @@
-
+
net9.0;net8.0
@@ -26,7 +26,6 @@
-
diff --git a/src/Tests/Spectre.Console.Tests/Utilities/TestConsoleExtensions.cs b/src/Tests/Spectre.Console.Tests/Utilities/TestConsoleExtensions.cs
deleted file mode 100644
index 29711a7d..00000000
--- a/src/Tests/Spectre.Console.Tests/Utilities/TestConsoleExtensions.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-namespace Spectre.Console.Tests;
-
-public static class TestConsoleExtensions
-{
- private static readonly Regex _lineNumberRegex = new Regex(":\\d+", RegexOptions.Singleline);
- private static readonly Regex _filenameRegex = new Regex("\\sin\\s.*cs:nn", RegexOptions.Multiline);
-
- public static string WriteNormalizedException(this TestConsole console, Exception ex, ExceptionFormats formats = ExceptionFormats.Default)
- {
- if (!string.IsNullOrWhiteSpace(console.Output))
- {
- throw new InvalidOperationException("Output buffer is not empty.");
- }
-
- console.WriteException(ex, formats);
- return string.Join("\n", NormalizeStackTrace(console.Output)
- .NormalizeLineEndings()
- .Split(new char[] { '\n' })
- .Select(line => line.TrimEnd()));
- }
-
- public static string NormalizeStackTrace(string text)
- {
- text = _lineNumberRegex.Replace(text, match =>
- {
- return ":nn";
- });
-
- return _filenameRegex.Replace(text, match =>
- {
- var value = match.Value;
- var index = value.LastIndexOfAny(new[] { '\\', '/' });
- var filename = value.Substring(index + 1, value.Length - index - 1);
-
- return $" in /xyz/{filename}";
- });
- }
-}