Skip to content

Switch to AwesomeAssertions #113425

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@
<NewtonsoftJsonBsonVersion>1.0.2</NewtonsoftJsonBsonVersion>
<SQLitePCLRawbundle_greenVersion>2.0.4</SQLitePCLRawbundle_greenVersion>
<MoqVersion>4.18.4</MoqVersion>
<FluentAssertionsVersion>6.7.0</FluentAssertionsVersion>
<AwesomeAssertionsVersion>8.0.2</AwesomeAssertionsVersion>
<FsCheckVersion>2.14.3</FsCheckVersion>
<CommandLineParserVersion>2.9.1</CommandLineParserVersion>
<!-- Android gRPC client tests -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ public static class DependencyResolutionCommandResultExtensions
public static AndConstraint<CommandResultAssertions> HaveRuntimePropertyContaining(this CommandResultAssertions assertion, string propertyName, params string[] values)
{
string propertyValue = GetAppMockPropertyValue(assertion, propertyName);
AssertionChain assertionChain = AssertionChain.GetOrCreate();

foreach (string value in values)
{
Execute.Assertion.ForCondition(propertyValue != null && propertyValue.Contains(value))
assertionChain.ForCondition(propertyValue != null && propertyValue.Contains(value))
.FailWith($"The property {propertyName} doesn't contain expected value: '{value}'{Environment.NewLine}" +
$"{propertyName}='{propertyValue}'" +
$"{assertion.GetDiagnosticsInfo()}");
Expand All @@ -33,10 +34,11 @@ public static AndConstraint<CommandResultAssertions> HaveRuntimePropertyContaini
public static AndConstraint<CommandResultAssertions> NotHaveRuntimePropertyContaining(this CommandResultAssertions assertion, string propertyName, params string[] values)
{
string propertyValue = GetAppMockPropertyValue(assertion, propertyName);
AssertionChain assertionChain = AssertionChain.GetOrCreate();

foreach (string value in values)
{
Execute.Assertion.ForCondition(propertyValue != null && !propertyValue.Contains(value))
assertionChain.ForCondition(propertyValue != null && !propertyValue.Contains(value))
.FailWith($"The property {propertyName} contains unexpected value: '{value}'{Environment.NewLine}" +
$"{propertyName}='{propertyValue}'" +
$"{assertion.GetDiagnosticsInfo()}");
Expand Down Expand Up @@ -80,10 +82,11 @@ public static AndConstraint<CommandResultAssertions> HaveResolvedComponentDepend
params string[] values)
{
string propertyValue = GetComponentMockPropertyValue(assertion, propertyName);
AssertionChain assertionChain = AssertionChain.GetOrCreate();

foreach (string value in values)
{
Execute.Assertion.ForCondition(propertyValue != null && propertyValue.Contains(value))
assertionChain.ForCondition(propertyValue != null && propertyValue.Contains(value))
.FailWith($"The resolved {propertyName} doesn't contain expected value: '{value}'{Environment.NewLine}" +
$"{propertyName}='{propertyValue}'" +
$"{assertion.GetDiagnosticsInfo()}");
Expand All @@ -98,10 +101,11 @@ public static AndConstraint<CommandResultAssertions> NotHaveResolvedComponentDep
params string[] values)
{
string propertyValue = GetComponentMockPropertyValue(assertion, propertyName);
AssertionChain assertionChain = AssertionChain.GetOrCreate();

foreach (string value in values)
{
Execute.Assertion.ForCondition(propertyValue != null && !propertyValue.Contains(value))
assertionChain.ForCondition(propertyValue != null && !propertyValue.Contains(value))
.FailWith($"The resolved {propertyName} contains unexpected value: '{value}'{Environment.NewLine}" +
$"{propertyName}='{propertyValue}'" +
$"{assertion.GetDiagnosticsInfo()}");
Expand Down
41 changes: 22 additions & 19 deletions src/installer/tests/TestUtils/Assertions/CommandResultAssertions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ public class CommandResultAssertions
{
public CommandResult Result { get; }

public CommandResultAssertions(CommandResult commandResult)
public AssertionChain CurrentAssertionChain { get; }

public CommandResultAssertions(CommandResult commandResult, AssertionChain assertionChain)
{
Result = commandResult;
CurrentAssertionChain = assertionChain;
}

public AndConstraint<CommandResultAssertions> ExitWith(int expectedExitCode)
Expand All @@ -25,128 +28,128 @@ public AndConstraint<CommandResultAssertions> ExitWith(int expectedExitCode)
if (!OperatingSystem.IsWindows())
expectedExitCode = expectedExitCode & 0xFF;

Execute.Assertion.ForCondition(Result.ExitCode == expectedExitCode)
CurrentAssertionChain.ForCondition(Result.ExitCode == expectedExitCode)
.FailWith($"Expected command to exit with {expectedExitCode} but it did not.{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> Pass()
{
Execute.Assertion.ForCondition(Result.ExitCode == 0)
CurrentAssertionChain.ForCondition(Result.ExitCode == 0)
.FailWith($"Expected command to pass but it did not.{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> Fail()
{
Execute.Assertion.ForCondition(Result.ExitCode != 0)
CurrentAssertionChain.ForCondition(Result.ExitCode != 0)
.FailWith($"Expected command to fail but it did not.{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> HaveStdOut()
{
Execute.Assertion.ForCondition(!string.IsNullOrEmpty(Result.StdOut))
CurrentAssertionChain.ForCondition(!string.IsNullOrEmpty(Result.StdOut))
.FailWith($"Command did not output anything to stdout{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> HaveStdOut(string expectedOutput)
{
Execute.Assertion.ForCondition(Result.StdOut.Equals(expectedOutput, StringComparison.Ordinal))
CurrentAssertionChain.ForCondition(Result.StdOut.Equals(expectedOutput, StringComparison.Ordinal))
.FailWith($"Command did not output with Expected Output. Expected: '{expectedOutput}'{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> HaveStdOutContaining(string pattern)
{
Execute.Assertion.ForCondition(Result.StdOut.Contains(pattern))
CurrentAssertionChain.ForCondition(Result.StdOut.Contains(pattern))
.FailWith($"The command output did not contain expected result: '{pattern}'{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> NotHaveStdOutContaining(string pattern)
{
Execute.Assertion.ForCondition(!Result.StdOut.Contains(pattern))
CurrentAssertionChain.ForCondition(!Result.StdOut.Contains(pattern))
.FailWith($"The command output contained a result it should not have contained: '{pattern}'{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> HaveStdOutMatching(string pattern, RegexOptions options = RegexOptions.None)
{
Execute.Assertion.ForCondition(Regex.IsMatch(Result.StdOut, pattern, options))
CurrentAssertionChain.ForCondition(Regex.IsMatch(Result.StdOut, pattern, options))
.FailWith($"Matching the command output failed. Pattern: '{pattern}'{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> NotHaveStdOutMatching(string pattern, RegexOptions options = RegexOptions.None)
{
Execute.Assertion.ForCondition(!Regex.IsMatch(Result.StdOut, pattern, options))
CurrentAssertionChain.ForCondition(!Regex.IsMatch(Result.StdOut, pattern, options))
.FailWith($"The command output matched a pattern is should not have matched. Pattern: '{pattern}'{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> HaveStdErr()
{
Execute.Assertion.ForCondition(!string.IsNullOrEmpty(Result.StdErr))
CurrentAssertionChain.ForCondition(!string.IsNullOrEmpty(Result.StdErr))
.FailWith($"Command did not output anything to stderr.{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> HaveStdErrContaining(string pattern)
{
Execute.Assertion.ForCondition(Result.StdErr.Contains(pattern))
CurrentAssertionChain.ForCondition(Result.StdErr.Contains(pattern))
.FailWith($"The command error output did not contain expected result: '{pattern}'{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> NotHaveStdErrContaining(string pattern)
{
Execute.Assertion.ForCondition(!Result.StdErr.Contains(pattern))
CurrentAssertionChain.ForCondition(!Result.StdErr.Contains(pattern))
.FailWith($"The command error output contained a result it should not have contained: '{pattern}'{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> HaveStdErrMatching(string pattern, RegexOptions options = RegexOptions.None)
{
Execute.Assertion.ForCondition(Regex.IsMatch(Result.StdErr, pattern, options))
CurrentAssertionChain.ForCondition(Regex.IsMatch(Result.StdErr, pattern, options))
.FailWith($"Matching the command error output failed. Pattern: '{pattern}'{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> NotHaveStdOut()
{
Execute.Assertion.ForCondition(string.IsNullOrEmpty(Result.StdOut))
CurrentAssertionChain.ForCondition(string.IsNullOrEmpty(Result.StdOut))
.FailWith($"Expected command to not output to stdout but it did:{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> NotHaveStdErr()
{
Execute.Assertion.ForCondition(string.IsNullOrEmpty(Result.StdErr))
CurrentAssertionChain.ForCondition(string.IsNullOrEmpty(Result.StdErr))
.FailWith($"Expected command to not output to stderr but it did:{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> FileExists(string path)
{
Execute.Assertion.ForCondition(System.IO.File.Exists(path))
CurrentAssertionChain.ForCondition(System.IO.File.Exists(path))
.FailWith($"The command did not write the expected file: '{path}'{GetDiagnosticsInfo()}");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> FileContains(string path, string pattern)
{
string fileContent = System.IO.File.ReadAllText(path);
Execute.Assertion.ForCondition(fileContent.Contains(pattern))
CurrentAssertionChain.ForCondition(fileContent.Contains(pattern))
.FailWith($"The command did not write the expected result '{pattern}' to the file: '{path}'{GetDiagnosticsInfo()}{Environment.NewLine}file content: >>{fileContent}<<");
return new AndConstraint<CommandResultAssertions>(this);
}

public AndConstraint<CommandResultAssertions> NotFileContains(string path, string pattern)
{
string fileContent = System.IO.File.ReadAllText(path);
Execute.Assertion.ForCondition(!fileContent.Contains(pattern))
CurrentAssertionChain.ForCondition(!fileContent.Contains(pattern))
.FailWith($"The command did not write the expected result '{pattern}' to the file: '{path}'{GetDiagnosticsInfo()}{Environment.NewLine}file content: >>{fileContent}<<");
return new AndConstraint<CommandResultAssertions>(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using FluentAssertions;
using FluentAssertions.Execution;
using Microsoft.DotNet.Cli.Build.Framework;
using System;

Expand All @@ -11,13 +12,13 @@ public static class CommandResultExtensions
{
public static CommandResultAssertions Should(this CommandResult commandResult)
{
return new CommandResultAssertions(commandResult);
return new CommandResultAssertions(commandResult, AssertionChain.GetOrCreate());
}

public static CommandResult StdErrAfter(this CommandResult commandResult, string pattern)
{
int i = commandResult.StdErr.IndexOf(pattern);
i.Should().BeGreaterOrEqualTo(
i.Should().BeGreaterThanOrEqualTo(
0,
"Trying to filter StdErr after '{0}', but such string can't be found in the StdErr.{1}{2}",
pattern,
Expand Down
24 changes: 13 additions & 11 deletions src/installer/tests/TestUtils/Assertions/DirectoryInfoAssertions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,35 @@ namespace Microsoft.DotNet.CoreSetup.Test
public class DirectoryInfoAssertions
{
private DirectoryInfo _dirInfo;
private AssertionChain _assertionChain;

public DirectoryInfoAssertions(DirectoryInfo dir)
public DirectoryInfoAssertions(DirectoryInfo dir, AssertionChain assertionChain)
{
_dirInfo = dir;
_assertionChain = assertionChain;
}

public DirectoryInfo DirectoryInfo => _dirInfo;

public AndConstraint<DirectoryInfoAssertions> Exist()
{
Execute.Assertion.ForCondition(_dirInfo.Exists)
_assertionChain.ForCondition(_dirInfo.Exists)
.FailWith($"Expected directory '{_dirInfo.FullName}' does not exist.");
return new AndConstraint<DirectoryInfoAssertions>(this);
}

public AndConstraint<DirectoryInfoAssertions> HaveFile(string expectedFile)
{
var file = _dirInfo.EnumerateFiles(expectedFile, SearchOption.TopDirectoryOnly).SingleOrDefault();
Execute.Assertion.ForCondition(file != null)
_assertionChain.ForCondition(file != null)
.FailWith($"Expected File '{expectedFile}' cannot be found in directory '{_dirInfo.FullName}.");
return new AndConstraint<DirectoryInfoAssertions>(this);
}

public AndConstraint<DirectoryInfoAssertions> NotHaveFile(string expectedFile)
{
var file = _dirInfo.EnumerateFiles(expectedFile, SearchOption.TopDirectoryOnly).SingleOrDefault();
Execute.Assertion.ForCondition(file == null)
_assertionChain.ForCondition(file == null)
.FailWith($"File '{expectedFile}' should not be found in directory '{_dirInfo.FullName}'.");
return new AndConstraint<DirectoryInfoAssertions>(this);
}
Expand Down Expand Up @@ -67,19 +69,19 @@ public AndConstraint<DirectoryInfoAssertions> NotHaveFiles(IEnumerable<string> e
public AndConstraint<DirectoryInfoAssertions> HaveDirectory(string expectedDir)
{
var dir = _dirInfo.EnumerateDirectories(expectedDir, SearchOption.TopDirectoryOnly).SingleOrDefault();
Execute.Assertion.ForCondition(dir != null)
_assertionChain.ForCondition(dir != null)
.FailWith($"Expected directory '{expectedDir}' cannot be found inside directory '{_dirInfo.FullName}'.");

return new AndConstraint<DirectoryInfoAssertions>(new DirectoryInfoAssertions(dir));
return new AndConstraint<DirectoryInfoAssertions>(new DirectoryInfoAssertions(dir, _assertionChain));
}

public AndConstraint<DirectoryInfoAssertions> NotHaveDirectory(string expectedDir)
{
var dir = _dirInfo.EnumerateDirectories(expectedDir, SearchOption.TopDirectoryOnly).SingleOrDefault();
Execute.Assertion.ForCondition(dir == null)
_assertionChain.ForCondition(dir == null)
.FailWith($"Directory '{expectedDir}' should not be found in found inside directory '{_dirInfo.FullName}'.");

return new AndConstraint<DirectoryInfoAssertions>(new DirectoryInfoAssertions(dir));
return new AndConstraint<DirectoryInfoAssertions>(new DirectoryInfoAssertions(dir, _assertionChain));
}

public AndConstraint<DirectoryInfoAssertions> OnlyHaveFiles(IEnumerable<string> expectedFiles)
Expand All @@ -89,10 +91,10 @@ public AndConstraint<DirectoryInfoAssertions> OnlyHaveFiles(IEnumerable<string>
var extraFiles = Enumerable.Except(actualFiles, expectedFiles);
var nl = Environment.NewLine;

Execute.Assertion.ForCondition(!missingFiles.Any())
_assertionChain.ForCondition(!missingFiles.Any())
.FailWith($"Following files cannot be found inside directory {_dirInfo.FullName} {nl} {string.Join(nl, missingFiles)}");

Execute.Assertion.ForCondition(!extraFiles.Any())
_assertionChain.ForCondition(!extraFiles.Any())
.FailWith($"Following extra files are found inside directory {_dirInfo.FullName} {nl} {string.Join(nl, extraFiles)}");

return new AndConstraint<DirectoryInfoAssertions>(this);
Expand All @@ -103,7 +105,7 @@ public AndConstraint<DirectoryInfoAssertions> NotBeModifiedAfter(DateTime timeUt
_dirInfo.Refresh();
DateTime writeTime = _dirInfo.LastWriteTimeUtc;

Execute.Assertion.ForCondition(writeTime <= timeUtc)
_assertionChain.ForCondition(writeTime <= timeUtc)
.FailWith($"Directory '{_dirInfo.FullName}' should not be modified after {timeUtc}, but is modified at {writeTime}.");

return new AndConstraint<DirectoryInfoAssertions>(this);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using FluentAssertions.Execution;
using System.IO;

namespace Microsoft.DotNet.CoreSetup.Test
Expand All @@ -9,7 +10,7 @@ public static class DirectoryInfoExtensions
{
public static DirectoryInfoAssertions Should(this DirectoryInfo dir)
{
return new DirectoryInfoAssertions(dir);
return new DirectoryInfoAssertions(dir, AssertionChain.GetOrCreate());
}
}
}
2 changes: 1 addition & 1 deletion src/installer/tests/TestUtils/TestUtils.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="$(FluentAssertionsVersion)" />
<PackageReference Include="AwesomeAssertions" Version="$(AwesomeAssertionsVersion)" />
<PackageReference Include="Microsoft.DotNet.XUnitExtensions" Version="$(MicrosoftDotNetXUnitExtensionsVersion)" />
<PackageReference Include="xunit.core" Version="$(XUnitVersion)" ExcludeAssets="build" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="$(MicrosoftExtensionsDependencyModelVersion)" />
Expand Down
Loading
Loading