Add [NotNull] attribute on the Should() method for object assertions by 0xced · Pull Request #2987 · fluentassertions/fluentassertions · GitHub
Skip to content
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
93 changes: 47 additions & 46 deletions Src/FluentAssertions/AssertionExtensions.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Src/FluentAssertions/DataRowAssertionExtensions.cs
2 changes: 1 addition & 1 deletion Src/FluentAssertions/DataSetAssertionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static class DataSetAssertionExtensions
/// current <see cref="DataSet"/>.
/// </summary>
[Pure]
public static DataSetAssertions<TDataSet> Should<TDataSet>(this TDataSet actualValue)
public static DataSetAssertions<TDataSet> Should<TDataSet>([System.Diagnostics.CodeAnalysis.NotNullAttribute] this TDataSet actualValue)
where TDataSet : DataSet
{
return new DataSetAssertions<TDataSet>(actualValue);
Expand Down
2 changes: 1 addition & 1 deletion Src/FluentAssertions/DataTableAssertionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static class DataTableAssertionExtensions
/// current <see cref="DataTable"/>.
/// </summary>
[Pure]
public static DataTableAssertions<TDataTable> Should<TDataTable>(this TDataTable actualValue)
public static DataTableAssertions<TDataTable> Should<TDataTable>([System.Diagnostics.CodeAnalysis.NotNullAttribute] this TDataTable actualValue)
where TDataTable : DataTable
{
return new DataTableAssertions<TDataTable>(actualValue);
Expand Down
3 changes: 2 additions & 1 deletion Src/FluentAssertions/EnumAssertionsExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using FluentAssertions.Primitives;

Expand Down Expand Up @@ -27,7 +28,7 @@ public static EnumAssertions<TEnum> Should<TEnum>(this TEnum @enum)
/// current <typeparamref name="TEnum"/>.
/// </summary>
[Pure]
public static NullableEnumAssertions<TEnum> Should<TEnum>(this TEnum? @enum)
public static NullableEnumAssertions<TEnum> Should<TEnum>([NotNull] this TEnum? @enum)
where TEnum : struct, Enum
{
return new NullableEnumAssertions<TEnum>(@enum);
Expand Down
5 changes: 3 additions & 2 deletions Src/FluentAssertions/Xml/XmlAssertionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Xml;
using FluentAssertions.Xml;

Expand All @@ -7,12 +8,12 @@ namespace FluentAssertions;
[DebuggerNonUserCode]
public static class XmlAssertionExtensions
{
public static XmlNodeAssertions Should(this XmlNode actualValue)
public static XmlNodeAssertions Should([NotNull] this XmlNode actualValue)
{
return new XmlNodeAssertions(actualValue);
}

public static XmlElementAssertions Should(this XmlElement actualValue)
public static XmlElementAssertions Should([NotNull] this XmlElement actualValue)
{
return new XmlElementAssertions(actualValue);
}
Expand Down

Large diffs are not rendered by default.

102 changes: 51 additions & 51 deletions Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

42 changes: 41 additions & 1 deletion Tests/FluentAssertions.Specs/AssertionExtensionsSpecs.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using FluentAssertions.Common;
Expand Down Expand Up @@ -157,6 +158,45 @@ public void Should_methods_have_a_matching_overload_to_guard_against_chaining_an
"AssertionExtensions.cs should have a guard overload of Should calling InvalidShouldCall()");
}

[Theory]
[MemberData(nameof(GetShouldMethods), true)]
public void Should_methods_returning_reference_or_nullable_type_assertions_are_annotated_with_not_null_attribute(MethodInfo method)
{
var notNullAttribute = method.GetParameters().Single().GetCustomAttribute<NotNullAttribute>();
notNullAttribute.Should().NotBeNull();
}

[Theory]
[MemberData(nameof(GetShouldMethods), false)]
public void Should_methods_not_returning_reference_or_nullable_type_assertions_are_not_annotated_with_not_null_attribute(MethodInfo method)
{
var notNullAttribute = method.GetParameters().Single().GetCustomAttribute<NotNullAttribute>();
notNullAttribute.Should().BeNull();
}

public static IEnumerable<object[]> GetShouldMethods(bool referenceOrNullableTypes)
{
return AllTypes.From(typeof(FluentAssertions.AssertionExtensions).Assembly)
.ThatAreClasses()
.ThatAreStatic()
.Where(t => t.IsPublic)
.SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public))
.Where(m => m.Name == "Should"
&& !IsGuardOverload(m)
&& m.GetParameters().Length == 1
&& (referenceOrNullableTypes ? IsReferenceOrNullableTypeAssertion(m) : !IsReferenceOrNullableTypeAssertion(m)))
.Select(m => new object[] { m });
}

private static bool ReturnsReferenceTypeAssertions(MethodInfo m) =>
m.ReturnType.IsAssignableToOpenGeneric(typeof(ReferenceTypeAssertions<,>));

private static bool IsNullableTypeAssertion(MethodInfo m) =>
m.GetParameters()[0].ParameterType.IsAssignableToOpenGeneric(typeof(Nullable<>));

private static bool IsReferenceOrNullableTypeAssertion(MethodInfo m) =>
ReturnsReferenceTypeAssertions(m) || IsNullableTypeAssertion(m);

private static bool IsGuardOverload(MethodInfo m) =>
m.ReturnType == typeof(void) && m.IsDefined(typeof(ObsoleteAttribute));

Expand Down
5 changes: 5 additions & 0 deletions docs/_pages/releases.md