diff --git a/src/TestFramework/TestFramework/Assertions/Assert.cs b/src/TestFramework/TestFramework/Assertions/Assert.cs index b345210c39..6fa6f41ca7 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.cs @@ -20,10 +20,41 @@ private Assert() /// /// /// Users can use this to plug-in custom assertions through C# extension methods. - /// For instance, the signature of a custom assertion provider could be "public static void IsOfType<T>(this Assert assert, object obj)" - /// Users could then use a syntax similar to the default assertions which in this case is "Assert.That.IsOfType<Dog>(animal);" - /// More documentation is at "https://github.com/Microsoft/testfx/docs/README.md". + /// For instance, the signature of a custom assertion provider could be public static void IsOfType<T>(this Assert assert, object obj) + /// and the call-site would be Assert.That.IsOfType<Dog>(animal);. + /// For more information, see Create custom assertions with Assert.That. /// + /// + /// The following example defines a custom IsPrime assertion as an extension method on + /// and invokes it through Assert.That: + /// + /// using System; + /// using System.Linq; + /// using Microsoft.VisualStudio.TestTools.UnitTesting; + /// + /// public static class CustomAssertExtensions + /// { + /// public static void IsPrime(this Assert assert, int value) + /// { + /// if (value < 2 || Enumerable.Range(2, (int)Math.Sqrt(value) - 1).Any(i => value % i == 0)) + /// { + /// throw new AssertFailedException($"Assert.That.IsPrime failed. Value <{value}> is not a prime number."); + /// } + /// } + /// } + /// + /// [TestClass] + /// public class CalculatorTests + /// { + /// [TestMethod] + /// public void NextPrime_ReturnsPrime() + /// { + /// int result = new Calculator().NextPrime(10); + /// Assert.That.IsPrime(result); + /// } + /// } + /// + /// public static Assert That { get; } = new(); /// diff --git a/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs b/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs index 30a2558bb4..2393ac17d0 100644 --- a/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs +++ b/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs @@ -21,11 +21,46 @@ private CollectionAssert() /// Gets the singleton instance of the CollectionAssert functionality. /// /// + /// /// Users can use this to plug-in custom assertions through C# extension methods. - /// For instance, the signature of a custom assertion provider could be "public static void AreEqualUnordered(this CollectionAssert customAssert, ICollection expected, ICollection actual)" - /// Users could then use a syntax similar to the default assertions which in this case is "CollectionAssert.That.AreEqualUnordered(list1, list2);" - /// More documentation is at "https://github.com/Microsoft/testfx/docs/README.md". + /// For instance, the signature of a custom assertion provider could be public static void AreEqualUnordered(this CollectionAssert customAssert, ICollection expected, ICollection actual) + /// and the call-site would be CollectionAssert.That.AreEqualUnordered(list1, list2);. + /// + /// + /// For new custom assertions, prefer extending instead, because is likely to be deprecated in a future release. + /// For more information, see Extension hooks on StringAssert and CollectionAssert. + /// /// + /// + /// The following example defines a custom AreEqualUnordered assertion as an extension method + /// on and invokes it through CollectionAssert.That: + /// + /// using System.Collections.Generic; + /// using System.Linq; + /// using Microsoft.VisualStudio.TestTools.UnitTesting; + /// + /// public static class CustomCollectionAssertExtensions + /// { + /// public static void AreEqualUnordered<T>(this CollectionAssert collectionAssert, IEnumerable<T> expected, IEnumerable<T> actual) + /// { + /// if (!expected.OrderBy(x => x).SequenceEqual(actual.OrderBy(x => x))) + /// { + /// throw new AssertFailedException("CollectionAssert.That.AreEqualUnordered failed. Collections do not contain the same elements."); + /// } + /// } + /// } + /// + /// [TestClass] + /// public class SetTests + /// { + /// [TestMethod] + /// public void Items_MatchRegardlessOfOrder() + /// { + /// CollectionAssert.That.AreEqualUnordered(new[] { 1, 2, 3 }, new[] { 3, 1, 2 }); + /// } + /// } + /// + /// public static CollectionAssert That { get; } = new(); #endregion diff --git a/src/TestFramework/TestFramework/Assertions/StringAssert.cs b/src/TestFramework/TestFramework/Assertions/StringAssert.cs index 08106d7e22..f7ab02bc93 100644 --- a/src/TestFramework/TestFramework/Assertions/StringAssert.cs +++ b/src/TestFramework/TestFramework/Assertions/StringAssert.cs @@ -19,11 +19,48 @@ private StringAssert() /// Gets the singleton instance of the StringAssert functionality. /// /// + /// /// Users can use this to plug-in custom assertions through C# extension methods. - /// For instance, the signature of a custom assertion provider could be "public static void ContainsWords(this StringAssert customAssert, string value, ICollection substrings)" - /// Users could then use a syntax similar to the default assertions which in this case is "StringAssert.That.ContainsWords(value, substrings);" - /// More documentation is at "https://github.com/Microsoft/testfx/docs/README.md". + /// For instance, the signature of a custom assertion provider could be public static void ContainsWords(this StringAssert customAssert, string value, ICollection substrings) + /// and the call-site would be StringAssert.That.ContainsWords(value, substrings);. + /// + /// + /// For new custom assertions, prefer extending instead, because is likely to be deprecated in a future release. + /// For more information, see Extension hooks on StringAssert and CollectionAssert. + /// /// + /// + /// The following example defines a custom ContainsWords assertion as an extension method + /// on and invokes it through StringAssert.That: + /// + /// using System.Collections.Generic; + /// using Microsoft.VisualStudio.TestTools.UnitTesting; + /// + /// public static class CustomStringAssertExtensions + /// { + /// public static void ContainsWords(this StringAssert stringAssert, string value, IEnumerable<string> words) + /// { + /// foreach (string word in words) + /// { + /// if (value == null || !value.Contains(word)) + /// { + /// throw new AssertFailedException($"StringAssert.That.ContainsWords failed. Word <{word}> not found in <{value}>."); + /// } + /// } + /// } + /// } + /// + /// [TestClass] + /// public class MessageTests + /// { + /// [TestMethod] + /// public void Greeting_ContainsExpectedWords() + /// { + /// StringAssert.That.ContainsWords("Hello, world!", new[] { "Hello", "world" }); + /// } + /// } + /// + /// public static StringAssert That { get; } = new(); #endregion