Skip to content
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

Improve the formatting of descriptions of Types #1895

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 30 additions & 0 deletions Src/FluentAssertions/Common/TypeDescriptionUtility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;

namespace FluentAssertions.Common
{
internal static class TypeDescriptionUtility
{
public static string GetDescriptionOfObjectType(object obj)
{
return (obj is null) ? "<null>" : GetTypeDescription(obj.GetType(), describeValue: true);
}

public static string GetTypeDescription(Type type)
=> GetTypeDescription(type, describeValue: false);

private static string GetTypeDescription(Type type, bool describeValue)
{
if ((type.Namespace == "System.Linq") && type.IsGenericType)
{
return "an anonymous iterator from a LINQ expression with element type " + type.GetGenericArguments()[0].FullName;
}
else
{
return
describeValue
? (type.IsValueType ? "a value of type " : "an instance of ") + type.FullName
: type.FullName;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public static class DataColumnCollectionAssertionExtensions
.BecauseOf(because, becauseArgs)
.FailWith(
"Invalid expectation: Expected {context:column collection} to refer to an instance of " +
"DataColumnCollection{reason}, but found {0}.",
assertion.Subject);
"DataColumnCollection{reason}, but found " +
TypeDescriptionUtility.GetDescriptionOfObjectType(assertion.Subject) + ".");
}

return new AndConstraint<GenericCollectionAssertions<DataColumn>>(assertion);
Expand Down Expand Up @@ -89,8 +89,8 @@ public static class DataColumnCollectionAssertionExtensions
.BecauseOf(because, becauseArgs)
.FailWith(
"Invalid expectation: Expected {context:column collection} to refer to a different instance of " +
"DataColumnCollection{reason}, but found {0}.",
assertion.Subject);
"DataColumnCollection{reason}, but found " +
TypeDescriptionUtility.GetDescriptionOfObjectType(assertion.Subject) + ".");
}

return new AndConstraint<GenericCollectionAssertions<DataColumn>>(assertion);
Expand Down
8 changes: 4 additions & 4 deletions Src/FluentAssertions/DataRowCollectionAssertionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public static class DataRowCollectionAssertionExtensions
.BecauseOf(because, becauseArgs)
.FailWith(
"Invalid expectation: Expected {context:column collection} to refer to an instance of " +
"DataRowCollection{reason}, but found {0}.",
assertion.Subject);
"DataRowCollection{reason}, but found " +
TypeDescriptionUtility.GetDescriptionOfObjectType(assertion.Subject) + ".");
}

return new AndConstraint<GenericCollectionAssertions<DataRow>>(assertion);
Expand Down Expand Up @@ -84,8 +84,8 @@ public static class DataRowCollectionAssertionExtensions
.BecauseOf(because, becauseArgs)
.FailWith(
"Invalid expectation: Expected {context:column collection} to refer to a different instance of " +
"DataRowCollection{reason}, but found {0}.",
assertion.Subject);
"DataRowCollection{reason}, but found " +
TypeDescriptionUtility.GetDescriptionOfObjectType(assertion.Subject) + ".");
}

return new AndConstraint<GenericCollectionAssertions<DataRow>>(assertion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ public static class DataTableCollectionAssertionExtensions
.BecauseOf(because, becauseArgs)
.FailWith(
"Invalid expectation: Expected {context:column collection} to refer to an instance of " +
"DataTableCollection{reason}, but found {0}.",
assertion.Subject);
"DataTableCollection{reason}, but found " +
TypeDescriptionUtility.GetDescriptionOfObjectType(assertion.Subject) + ".");
}

return new AndConstraint<GenericCollectionAssertions<DataTable>>(assertion);
Expand Down Expand Up @@ -81,8 +81,8 @@ public static class DataTableCollectionAssertionExtensions
.BecauseOf(because, becauseArgs)
.FailWith(
"Invalid expectation: Expected {context:column collection} to refer to a different instance of " +
"DataTableCollection{reason}, but found {0}.",
assertion.Subject);
"DataTableCollection{reason}, but found " +
TypeDescriptionUtility.GetDescriptionOfObjectType(assertion.Subject) + ".");
}

return new AndConstraint<GenericCollectionAssertions<DataTable>>(assertion);
Expand Down
7 changes: 1 addition & 6 deletions Src/FluentAssertions/Types/TypeSelectorAssertions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -466,15 +466,10 @@ public AndConstraint<TypeSelectorAssertions> NotBeUnderNamespace(string @namespa

private static string GetDescriptionsFor(IEnumerable<Type> types)
{
IEnumerable<string> descriptions = types.Select(type => GetDescriptionFor(type));
IEnumerable<string> descriptions = types.Select(type => TypeDescriptionUtility.GetTypeDescription(type));
return string.Join(Environment.NewLine, descriptions);
}

private static string GetDescriptionFor(Type type)
{
return type.ToString();
}

/// <inheritdoc/>
public override bool Equals(object obj) =>
throw new NotSupportedException("Calling Equals on Assertion classes is not supported.");
Expand Down
67 changes: 67 additions & 0 deletions Tests/FluentAssertions.Specs/Common/TypeDescriptionUtilitySpecs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System.Collections.Generic;
using System.Linq;

using FluentAssertions.Common;

using Xunit;

namespace FluentAssertions.Specs
{
public class TypeDescriptionUtilitySpecs
{
[Fact]
public void When_object_is_null_it_should_work()
{
// Act & Assert
TypeDescriptionUtility.GetDescriptionOfObjectType(null).Should().Be("<null>");
}

[Fact]
public void When_object_is_value_type_it_should_work()
{
// Act & Assert
TypeDescriptionUtility.GetDescriptionOfObjectType(37).Should().Be("a value of type System.Int32");
}

[Fact]
public void When_object_is_reference_type_it_should_work()
{
// Act & Assert
TypeDescriptionUtility.GetDescriptionOfObjectType(new object()).Should().Be("an instance of System.Object");
}

[Fact]
public void When_object_is_generic_value_type_it_should_work()
{
// Arrange
var box = new Box<int>() { Value = 37 };

// Act & Assert
TypeDescriptionUtility.GetDescriptionOfObjectType(box).Should()
.Match("a value of type *+Box`1[[System.Int32*]]");
}

[Fact]
public void When_object_is_generic_reference_type_it_should_work()
{
// Act & Assert
TypeDescriptionUtility.GetDescriptionOfObjectType(new List<int>()).Should()
.Match("an instance of System.Collections.Generic.List`1[[System.Int32*]]");
}

[Fact]
public void When_object_is_LINQ_anonymous_iterator_type_it_should_work()
{
// Arrange
var value = new[] { 1, 2, 3 }.Select(x => 2 * x);

TypeDescriptionUtility.GetDescriptionOfObjectType(value).Should().Be(
"an anonymous iterator from a LINQ expression with element type System.Int32");
}

private struct Box<T>
{
public T Value { get; set; }
}
}
}
1 change: 1 addition & 0 deletions docs/_pages/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ sidebar:
* Added `NotBe` for nullable boolean values - [#1865](https://github.com/fluentassertions/fluentassertions/pull/1865)
* Added a new overload to `MatchRegex()` to assert on the number of regex matches - [#1869](https://github.com/fluentassertions/fluentassertions/pull/1869)
* Added difference to numeric assertion failure messages - [#1859](https://github.com/fluentassertions/fluentassertions/pull/1859)
* Improved the formatting of data type names, especially with regard to LINQ results - [#1895](https://github.com/fluentassertions/fluentassertions/1895)

### Fixes
* `EnumAssertions.Be` did not determine the caller name - [#1835](https://github.com/fluentassertions/fluentassertions/pull/1835)
Expand Down