Skip to content

Commit

Permalink
Assert.AreEqual/AreNotEqual overloads with IEquatable (#1433)
Browse files Browse the repository at this point in the history
  • Loading branch information
Evangelink authored Dec 5, 2022
1 parent 73f02b4 commit c5120fd
Show file tree
Hide file tree
Showing 5 changed files with 312 additions and 32 deletions.
245 changes: 214 additions & 31 deletions src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Globalization;

namespace Microsoft.VisualStudio.TestTools.UnitTesting;
Expand Down Expand Up @@ -31,9 +32,31 @@ public sealed partial class Assert
/// Thrown if <paramref name="expected"/> is not equal to <paramref name="actual"/>.
/// </exception>
public static void AreEqual<T>(T? expected, T? actual)
{
AreEqual(expected, actual, string.Empty, null);
}
=> AreEqual(expected, actual, null, string.Empty, null);

/// <summary>
/// Tests whether the specified values are equal and throws an exception
/// if the two values are not equal. Different numeric types are treated
/// as unequal even if the logical values are equal. 42L is not equal to 42.
/// </summary>
/// <typeparam name="T">
/// The type of values to compare.
/// </typeparam>
/// <param name="expected">
/// The first value to compare. This is the value the tests expects.
/// </param>
/// <param name="actual">
/// The second value to compare. This is the value produced by the code under test.
/// </param>
/// <param name="comparer">
/// The <see cref="System.Collections.Generic.IEqualityComparer{T}"/> implementation to use when comparing keys,
/// or null to use the default <see cref="System.Collections.Generic.EqualityComparer{T}"/>.
/// </param>
/// <exception cref="AssertFailedException">
/// Thrown if <paramref name="expected"/> is not equal to <paramref name="actual"/>.
/// </exception>
public static void AreEqual<T>(T? expected, T? actual, IEqualityComparer<T>? comparer)
=> AreEqual(expected, actual, comparer, string.Empty, null);

/// <summary>
/// Tests whether the specified values are equal and throws an exception
Expand All @@ -59,9 +82,37 @@ public static void AreEqual<T>(T? expected, T? actual)
/// <paramref name="actual"/>.
/// </exception>
public static void AreEqual<T>(T? expected, T? actual, string? message)
{
AreEqual(expected, actual, message, null);
}
=> AreEqual(expected, actual, null, message, null);

/// <summary>
/// Tests whether the specified values are equal and throws an exception
/// if the two values are not equal. Different numeric types are treated
/// as unequal even if the logical values are equal. 42L is not equal to 42.
/// </summary>
/// <typeparam name="T">
/// The type of values to compare.
/// </typeparam>
/// <param name="expected">
/// The first value to compare. This is the value the tests expects.
/// </param>
/// <param name="actual">
/// The second value to compare. This is the value produced by the code under test.
/// </param>
/// <param name="comparer">
/// The <see cref="System.Collections.Generic.IEqualityComparer{T}"/> implementation to use when comparing keys,
/// or null to use the default <see cref="System.Collections.Generic.EqualityComparer{T}"/>.
/// </param>
/// <param name="message">
/// The message to include in the exception when <paramref name="actual"/>
/// is not equal to <paramref name="expected"/>. The message is shown in
/// test results.
/// </param>
/// <exception cref="AssertFailedException">
/// Thrown if <paramref name="expected"/> is not equal to
/// <paramref name="actual"/>.
/// </exception>
public static void AreEqual<T>(T? expected, T? actual, IEqualityComparer<T>? comparer, string? message)
=> AreEqual(expected, actual, comparer, message, null);

/// <summary>
/// Tests whether the specified values are equal and throws an exception
Expand Down Expand Up @@ -90,19 +141,64 @@ public static void AreEqual<T>(T? expected, T? actual, string? message)
/// <paramref name="actual"/>.
/// </exception>
public static void AreEqual<T>(T? expected, T? actual, string? message, params object?[]? parameters)
=> AreEqual(expected, actual, null, message, parameters);

/// <summary>
/// Tests whether the specified values are equal and throws an exception
/// if the two values are not equal. Different numeric types are treated
/// as unequal even if the logical values are equal. 42L is not equal to 42.
/// </summary>
/// <typeparam name="T">
/// The type of values to compare.
/// </typeparam>
/// <param name="expected">
/// The first value to compare. This is the value the tests expects.
/// </param>
/// <param name="actual">
/// The second value to compare. This is the value produced by the code under test.
/// </param>
/// <param name="comparer">
/// The <see cref="System.Collections.Generic.IEqualityComparer{T}"/> implementation to use when comparing keys,
/// or null to use the default <see cref="System.Collections.Generic.EqualityComparer{T}"/>.
/// </param>
/// <param name="message">
/// The message to include in the exception when <paramref name="actual"/>
/// is not equal to <paramref name="expected"/>. The message is shown in
/// test results.
/// </param>
/// <param name="parameters">
/// An array of parameters to use when formatting <paramref name="message"/>.
/// </param>
/// <exception cref="AssertFailedException">
/// Thrown if <paramref name="expected"/> is not equal to
/// <paramref name="actual"/>.
/// </exception>
public static void AreEqual<T>(T? expected, T? actual, IEqualityComparer<T>? comparer, string? message, params object?[]? parameters)
{
if (!object.Equals(expected, actual))
var localComparer = comparer ?? EqualityComparer<T>.Default;
if (localComparer.Equals(expected!, actual!))
{
string userMessage = BuildUserMessage(message, parameters);
string finalMessage = string.Format(
CultureInfo.CurrentCulture,
FrameworkMessages.AreEqualFailMsg,
userMessage,
ReplaceNulls(expected),
ReplaceNulls(actual));

ThrowAssertFailed("Assert.AreEqual", finalMessage);
return;
}

string userMessage = BuildUserMessage(message, parameters);
string finalMessage = actual != null && expected != null && !actual.GetType().Equals(expected.GetType())
? string.Format(
CultureInfo.CurrentCulture,
FrameworkMessages.AreEqualDifferentTypesFailMsg,
userMessage,
ReplaceNulls(expected),
expected.GetType().FullName,
ReplaceNulls(actual),
actual.GetType().FullName)
: string.Format(
CultureInfo.CurrentCulture,
FrameworkMessages.AreEqualFailMsg,
userMessage,
ReplaceNulls(expected),
ReplaceNulls(actual));

ThrowAssertFailed("Assert.AreEqual", finalMessage);
}

/// <summary>
Expand All @@ -124,9 +220,32 @@ public static void AreEqual<T>(T? expected, T? actual, string? message, params o
/// Thrown if <paramref name="notExpected"/> is equal to <paramref name="actual"/>.
/// </exception>
public static void AreNotEqual<T>(T? notExpected, T? actual)
{
AreNotEqual(notExpected, actual, string.Empty, null);
}
=> AreNotEqual(notExpected, actual, null, string.Empty, null);

/// <summary>
/// Tests whether the specified values are unequal and throws an exception
/// if the two values are equal. Different numeric types are treated
/// as unequal even if the logical values are equal. 42L is not equal to 42.
/// </summary>
/// <typeparam name="T">
/// The type of values to compare.
/// </typeparam>
/// <param name="notExpected">
/// The first value to compare. This is the value the test expects not
/// to match <paramref name="actual"/>.
/// </param>
/// <param name="actual">
/// The second value to compare. This is the value produced by the code under test.
/// </param>
/// <param name="comparer">
/// The <see cref="System.Collections.Generic.IEqualityComparer{T}"/> implementation to use when comparing keys,
/// or null to use the default <see cref="System.Collections.Generic.EqualityComparer{T}"/>.
/// </param>
/// <exception cref="AssertFailedException">
/// Thrown if <paramref name="notExpected"/> is equal to <paramref name="actual"/>.
/// </exception>
public static void AreNotEqual<T>(T? notExpected, T? actual, IEqualityComparer<T>? comparer)
=> AreNotEqual(notExpected, actual, comparer, string.Empty, null);

/// <summary>
/// Tests whether the specified values are unequal and throws an exception
Expand All @@ -152,9 +271,37 @@ public static void AreNotEqual<T>(T? notExpected, T? actual)
/// Thrown if <paramref name="notExpected"/> is equal to <paramref name="actual"/>.
/// </exception>
public static void AreNotEqual<T>(T? notExpected, T? actual, string? message)
{
AreNotEqual(notExpected, actual, message, null);
}
=> AreNotEqual(notExpected, actual, null, message, null);

/// <summary>
/// Tests whether the specified values are unequal and throws an exception
/// if the two values are equal. Different numeric types are treated
/// as unequal even if the logical values are equal. 42L is not equal to 42.
/// </summary>
/// <typeparam name="T">
/// The type of values to compare.
/// </typeparam>
/// <param name="notExpected">
/// The first value to compare. This is the value the test expects not
/// to match <paramref name="actual"/>.
/// </param>
/// <param name="actual">
/// The second value to compare. This is the value produced by the code under test.
/// </param>
/// <param name="comparer">
/// The <see cref="System.Collections.Generic.IEqualityComparer{T}"/> implementation to use when comparing keys,
/// or null to use the default <see cref="System.Collections.Generic.EqualityComparer{T}"/>.
/// </param>
/// <param name="message">
/// The message to include in the exception when <paramref name="actual"/>
/// is equal to <paramref name="notExpected"/>. The message is shown in
/// test results.
/// </param>
/// <exception cref="AssertFailedException">
/// Thrown if <paramref name="notExpected"/> is equal to <paramref name="actual"/>.
/// </exception>
public static void AreNotEqual<T>(T? notExpected, T? actual, IEqualityComparer<T>? comparer, string? message)
=> AreNotEqual(notExpected, actual, comparer, message, null);

/// <summary>
/// Tests whether the specified values are unequal and throws an exception
Expand Down Expand Up @@ -183,18 +330,54 @@ public static void AreNotEqual<T>(T? notExpected, T? actual, string? message)
/// Thrown if <paramref name="notExpected"/> is equal to <paramref name="actual"/>.
/// </exception>
public static void AreNotEqual<T>(T? notExpected, T? actual, string? message, params object?[]? parameters)
=> AreNotEqual(notExpected, actual, null, message, parameters);

/// <summary>
/// Tests whether the specified values are unequal and throws an exception
/// if the two values are equal. Different numeric types are treated
/// as unequal even if the logical values are equal. 42L is not equal to 42.
/// </summary>
/// <typeparam name="T">
/// The type of values to compare.
/// </typeparam>
/// <param name="notExpected">
/// The first value to compare. This is the value the test expects not
/// to match <paramref name="actual"/>.
/// </param>
/// <param name="actual">
/// The second value to compare. This is the value produced by the code under test.
/// </param>
/// <param name="comparer">
/// The <see cref="System.Collections.Generic.IEqualityComparer{T}"/> implementation to use when comparing keys,
/// or null to use the default <see cref="System.Collections.Generic.EqualityComparer{T}"/>.
/// </param>
/// <param name="message">
/// The message to include in the exception when <paramref name="actual"/>
/// is equal to <paramref name="notExpected"/>. The message is shown in
/// test results.
/// </param>
/// <param name="parameters">
/// An array of parameters to use when formatting <paramref name="message"/>.
/// </param>
/// <exception cref="AssertFailedException">
/// Thrown if <paramref name="notExpected"/> is equal to <paramref name="actual"/>.
/// </exception>
public static void AreNotEqual<T>(T? notExpected, T? actual, IEqualityComparer<T>? comparer, string? message, params object?[]? parameters)
{
if (object.Equals(notExpected, actual))
var localComparer = comparer ?? EqualityComparer<T>.Default;
if (!localComparer.Equals(notExpected!, actual!))
{
string userMessage = BuildUserMessage(message, parameters);
string finalMessage = string.Format(
CultureInfo.CurrentCulture,
FrameworkMessages.AreNotEqualFailMsg,
userMessage,
ReplaceNulls(notExpected),
ReplaceNulls(actual));
ThrowAssertFailed("Assert.AreNotEqual", finalMessage);
return;
}

string userMessage = BuildUserMessage(message, parameters);
string finalMessage = string.Format(
CultureInfo.CurrentCulture,
FrameworkMessages.AreNotEqualFailMsg,
userMessage,
ReplaceNulls(notExpected),
ReplaceNulls(actual));
ThrowAssertFailed("Assert.AreNotEqual", finalMessage);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
virtual Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.GetDisplayName(System.Reflection.MethodInfo! methodInfo, object?[]? data) -> string?
static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual<T>(T? expected, T? actual, System.Collections.Generic.IEqualityComparer<T>? comparer) -> void
static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual<T>(T? expected, T? actual, System.Collections.Generic.IEqualityComparer<T>? comparer, string? message) -> void
static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual<T>(T? expected, T? actual, System.Collections.Generic.IEqualityComparer<T>? comparer, string? message, params object?[]? parameters) -> void
static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual<T>(T? notExpected, T? actual, System.Collections.Generic.IEqualityComparer<T>? comparer) -> void
static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual<T>(T? notExpected, T? actual, System.Collections.Generic.IEqualityComparer<T>? comparer, string? message) -> void
static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual<T>(T? notExpected, T? actual, System.Collections.Generic.IEqualityComparer<T>? comparer, string? message, params object?[]? parameters) -> void
virtual Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.GetDisplayName(System.Reflection.MethodInfo! methodInfo, object?[]? data) -> string?
static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreSame<T>(T? expected, T? actual) -> void
static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreSame<T>(T? expected, T? actual, string? message) -> void
static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreSame<T>(T? expected, T? actual, string? message, params object?[]? parameters) -> void
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@
<data name="AreEqualCaseFailMsg" xml:space="preserve">
<value>Expected:&lt;{1}&gt;. Case is different for actual value:&lt;{2}&gt;. {0}</value>
</data>
<data name="AreEqualDifferentTypesFailMsg" xml:space="preserve">
<value>Expected:&lt;{1} ({2})&gt;. Actual:&lt;{3} ({4})&gt;. {0}</value>
</data>
<data name="AreNotEqualFailMsg" xml:space="preserve">
<value>Expected any value except:&lt;{1}&gt;. Actual:&lt;{2}&gt;. {0}</value>
</data>
Expand Down
Loading

0 comments on commit c5120fd

Please sign in to comment.