Skip to content

Commit

Permalink
Enable Nullable Reference Types, and revert source otherwise back to …
Browse files Browse the repository at this point in the history
…C# 6
  • Loading branch information
bradwilson committed Jul 9, 2020
1 parent b90aad7 commit 726e482
Show file tree
Hide file tree
Showing 54 changed files with 1,177 additions and 355 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ root = true
indent_style = tab
indent_size = 4
insert_final_newline = true
end_of_line = lf

# Visual Studio demands 2-spaced project files
# Tabs are not legal whitespace for YAML files
Expand Down
6 changes: 5 additions & 1 deletion Assert.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System;
#if XUNIT_NULLABLE
#nullable enable
#endif

using System;
using System.ComponentModel;

namespace Xunit
Expand Down
150 changes: 106 additions & 44 deletions CollectionAsserts.cs

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions Comparers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System;
#if XUNIT_NULLABLE
#nullable enable
#endif

using System;
using System.Collections;
using System.Collections.Generic;
using Xunit.Sdk;
Expand All @@ -12,12 +16,17 @@ namespace Xunit
#endif
partial class Assert
{
static IComparer<T> GetComparer<T>() where T : IComparable
static IComparer<T> GetComparer<T>()
where T : IComparable
{
return new AssertComparer<T>();
}

#if XUNIT_NULLABLE
static IEqualityComparer<T> GetEqualityComparer<T>(IEqualityComparer? innerComparer = null)
#else
static IEqualityComparer<T> GetEqualityComparer<T>(IEqualityComparer innerComparer = null)
#endif
{
return new AssertEqualityComparer<T>(innerComparer);
}
Expand Down
18 changes: 11 additions & 7 deletions EqualityAsserts.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System;
#if XUNIT_NULLABLE
#nullable enable
#endif

using System;
using System.Collections.Generic;
using System.Globalization;
using Xunit.Sdk;
Expand Down Expand Up @@ -34,7 +38,7 @@ public static void Equal<T>(T expected, T actual)
/// <exception cref="EqualException">Thrown when the objects are not equal</exception>
public static void Equal<T>(T expected, T actual, IEqualityComparer<T> comparer)
{
Assert.GuardArgumentNotNull("comparer", comparer);
GuardArgumentNotNull(nameof(comparer), comparer);

if (!comparer.Equals(expected, actual))
throw new EqualException(expected, actual);
Expand All @@ -53,7 +57,7 @@ public static void Equal(double expected, double actual, int precision)
var expectedRounded = Math.Round(expected, precision);
var actualRounded = Math.Round(actual, precision);

if (!GetEqualityComparer<double>().Equals(expectedRounded, actualRounded))
if (expectedRounded != actualRounded)

This comment has been minimized.

Copy link
@drewnoakes

drewnoakes Jul 14, 2020

Contributor

Looks like this breaks behaviour if expected is NaN. Should probably be !Equals(expectedRounded, actualRounded).

throw new EqualException(
string.Format(CultureInfo.CurrentCulture, "{0} (rounded from {1})", expectedRounded, expected),
string.Format(CultureInfo.CurrentCulture, "{0} (rounded from {1})", actualRounded, actual)
Expand All @@ -73,7 +77,7 @@ public static void Equal(decimal expected, decimal actual, int precision)
var expectedRounded = Math.Round(expected, precision);
var actualRounded = Math.Round(actual, precision);

if (!GetEqualityComparer<decimal>().Equals(expectedRounded, actualRounded))
if (expectedRounded != actualRounded)
throw new EqualException(
string.Format(CultureInfo.CurrentCulture, "{0} (rounded from {1})", expectedRounded, expected),
string.Format(CultureInfo.CurrentCulture, "{0} (rounded from {1})", actualRounded, actual)
Expand Down Expand Up @@ -137,7 +141,7 @@ public static void NotEqual<T>(T expected, T actual)
/// <exception cref="NotEqualException">Thrown when the objects are equal</exception>
public static void NotEqual<T>(T expected, T actual, IEqualityComparer<T> comparer)
{
Assert.GuardArgumentNotNull("comparer", comparer);
GuardArgumentNotNull(nameof(comparer), comparer);

if (comparer.Equals(expected, actual))
throw new NotEqualException(ArgumentFormatter.Format(expected), ArgumentFormatter.Format(actual));
Expand All @@ -156,7 +160,7 @@ public static void NotEqual(double expected, double actual, int precision)
var expectedRounded = Math.Round(expected, precision);
var actualRounded = Math.Round(actual, precision);

if (GetEqualityComparer<double>().Equals(expectedRounded, actualRounded))
if (expectedRounded == actualRounded)

This comment has been minimized.

Copy link
@drewnoakes

drewnoakes Jul 14, 2020

Contributor

Ditto.

throw new NotEqualException(
string.Format(CultureInfo.CurrentCulture, "{0} (rounded from {1})", expectedRounded, expected),
string.Format(CultureInfo.CurrentCulture, "{0} (rounded from {1})", actualRounded, actual)
Expand All @@ -176,7 +180,7 @@ public static void NotEqual(decimal expected, decimal actual, int precision)
var expectedRounded = Math.Round(expected, precision);
var actualRounded = Math.Round(actual, precision);

if (GetEqualityComparer<decimal>().Equals(expectedRounded, actualRounded))
if (expectedRounded == actualRounded)
throw new NotEqualException(
string.Format(CultureInfo.CurrentCulture, "{0} (rounded from {1})", expectedRounded, expected),
string.Format(CultureInfo.CurrentCulture, "{0} (rounded from {1})", actualRounded, actual)
Expand Down
40 changes: 39 additions & 1 deletion EventAsserts.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System;
#if XUNIT_NULLABLE
#nullable enable
#endif

using System;
using System.Threading.Tasks;
using Xunit.Sdk;

Expand Down Expand Up @@ -97,22 +101,48 @@ public static async Task<RaisedEvent<T>> RaisesAnyAsync<T>(Action<EventHandler<T
return raisedEvent;
}

#if XUNIT_NULLABLE
static RaisedEvent<T>? RaisesInternal<T>(Action<EventHandler<T>> attach, Action<EventHandler<T>> detach, Action testCode)
#else
static RaisedEvent<T> RaisesInternal<T>(Action<EventHandler<T>> attach, Action<EventHandler<T>> detach, Action testCode)
#endif
where T : EventArgs
{
GuardArgumentNotNull(nameof(attach), attach);
GuardArgumentNotNull(nameof(detach), detach);
GuardArgumentNotNull(nameof(testCode), testCode);

#if XUNIT_NULLABLE
RaisedEvent<T>? raisedEvent = null;
void handler(object? s, T args) => raisedEvent = new RaisedEvent<T>(s, args);
#else
RaisedEvent<T> raisedEvent = null;
EventHandler<T> handler = (object s, T args) => raisedEvent = new RaisedEvent<T>(s, args);
#endif
attach(handler);
testCode();
detach(handler);
return raisedEvent;
}

#if XUNIT_NULLABLE
static async Task<RaisedEvent<T>?> RaisesAsyncInternal<T>(Action<EventHandler<T>> attach, Action<EventHandler<T>> detach, Func<Task> testCode)
#else
static async Task<RaisedEvent<T>> RaisesAsyncInternal<T>(Action<EventHandler<T>> attach, Action<EventHandler<T>> detach, Func<Task> testCode)
#endif
where T : EventArgs
{
GuardArgumentNotNull(nameof(attach), attach);
GuardArgumentNotNull(nameof(detach), detach);
GuardArgumentNotNull(nameof(testCode), testCode);

#if XUNIT_NULLABLE
RaisedEvent<T>? raisedEvent = null;
void handler(object? s, T args) => raisedEvent = new RaisedEvent<T>(s, args);
#else
RaisedEvent<T> raisedEvent = null;
EventHandler<T> handler = (object s, T args) => raisedEvent = new RaisedEvent<T>(s, args);
#endif
attach(handler);
await testCode();
detach(handler);
Expand All @@ -129,7 +159,11 @@ public class RaisedEvent<T>
/// <summary>
/// The sender of the event.
/// </summary>
#if XUNIT_NULLABLE
public object? Sender { get; }
#else
public object Sender { get; }
#endif

/// <summary>
/// The event arguments.
Expand All @@ -141,7 +175,11 @@ public class RaisedEvent<T>
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="args">The event arguments</param>
#if XUNIT_NULLABLE
public RaisedEvent(object? sender, T args)
#else
public RaisedEvent(object sender, T args)
#endif
{
Sender = sender;
Arguments = args;
Expand Down
34 changes: 25 additions & 9 deletions ExceptionAsserts.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System;
#if XUNIT_NULLABLE
#nullable enable
#endif

using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
Expand Down Expand Up @@ -137,9 +141,13 @@ public static async Task<Exception> ThrowsAsync(Type exceptionType, Func<Task> t
return Throws(exceptionType, await RecordExceptionAsync(testCode));
}

#if XUNIT_NULLABLE
static Exception Throws(Type exceptionType, Exception? exception)
#else
static Exception Throws(Type exceptionType, Exception exception)
#endif
{
Assert.GuardArgumentNotNull("exceptionType", exceptionType);
GuardArgumentNotNull(nameof(exceptionType), exceptionType);

if (exception == null)
throw new ThrowsException(exceptionType);
Expand All @@ -150,9 +158,13 @@ static Exception Throws(Type exceptionType, Exception exception)
return exception;
}

#if XUNIT_NULLABLE
static Exception ThrowsAny(Type exceptionType, Exception? exception)
#else
static Exception ThrowsAny(Type exceptionType, Exception exception)
#endif
{
Assert.GuardArgumentNotNull("exceptionType", exceptionType);
GuardArgumentNotNull(nameof(exceptionType), exceptionType);

if (exception == null)
throw new ThrowsException(exceptionType);
Expand All @@ -174,8 +186,10 @@ static Exception ThrowsAny(Type exceptionType, Exception exception)
public static T Throws<T>(string paramName, Action testCode)
where T : ArgumentException
{
var ex = Assert.Throws<T>(testCode);
Assert.Equal(paramName, ex.ParamName);
GuardArgumentNotNull(nameof(paramName), paramName);

This comment has been minimized.

Copy link
@RussKie

RussKie Aug 26, 2022

❗ This is wrong, paramName can be null.

    [Fact]
    public void test()
    {
        Assert.Throws<ArgumentException>(null, () => new MyClass().ThrowArgumentException());
    }

    public class MyClass
    {
        public void ThrowArgumentException() => throw new ArgumentException("message");
    }

image


var ex = Throws<T>(testCode);
Equal(paramName, ex.ParamName);
return ex;
}

Expand All @@ -190,8 +204,10 @@ public static T Throws<T>(string paramName, Action testCode)
public static T Throws<T>(string paramName, Func<object> testCode)
where T : ArgumentException
{
var ex = Assert.Throws<T>(testCode);
Assert.Equal(paramName, ex.ParamName);
GuardArgumentNotNull(nameof(paramName), paramName);

var ex = Throws<T>(testCode);
Equal(paramName, ex.ParamName);
return ex;
}

Expand All @@ -212,8 +228,8 @@ public static T Throws<T>(string paramName, Func<object> testCode)
public static async Task<T> ThrowsAsync<T>(string paramName, Func<Task> testCode)
where T : ArgumentException
{
var ex = await Assert.ThrowsAsync<T>(testCode);
Assert.Equal(paramName, ex.ParamName);
var ex = await ThrowsAsync<T>(testCode);
Equal(paramName, ex.ParamName);
return ex;
}
}
Expand Down
11 changes: 10 additions & 1 deletion Guards.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
using System;
#if XUNIT_NULLABLE
#nullable enable
using System.Diagnostics.CodeAnalysis;
#endif

using System;

namespace Xunit
{
Expand All @@ -10,7 +15,11 @@ namespace Xunit
partial class Assert
{
/// <summary/>
#if XUNIT_NULLABLE
internal static void GuardArgumentNotNull(string argName, [NotNull] object? argValue)
#else
internal static void GuardArgumentNotNull(string argName, object argValue)
#endif
{
if (argValue == null)
throw new ArgumentNullException(argName);
Expand Down
14 changes: 13 additions & 1 deletion IdentityAsserts.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using Xunit.Sdk;
#if XUNIT_NULLABLE
#nullable enable
#endif

using Xunit.Sdk;

namespace Xunit
{
Expand All @@ -15,7 +19,11 @@ partial class Assert
/// <param name="expected">The expected object instance</param>
/// <param name="actual">The actual object instance</param>
/// <exception cref="NotSameException">Thrown when the objects are the same instance</exception>
#if XUNIT_NULLABLE
public static void NotSame(object? expected, object? actual)
#else
public static void NotSame(object expected, object actual)
#endif
{
if (object.ReferenceEquals(expected, actual))
throw new NotSameException();
Expand All @@ -27,7 +35,11 @@ public static void NotSame(object expected, object actual)
/// <param name="expected">The expected object instance</param>
/// <param name="actual">The actual object instance</param>
/// <exception cref="SameException">Thrown when the objects are not the same instance</exception>
#if XUNIT_NULLABLE
public static void Same(object? expected, object? actual)
#else
public static void Same(object expected, object actual)
#endif
{
if (!object.ReferenceEquals(expected, actual))
throw new SameException(expected, actual);
Expand Down
20 changes: 13 additions & 7 deletions PropertyAsserts.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System;
#if XUNIT_NULLABLE
#nullable enable
#endif

using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
Expand All @@ -23,10 +27,11 @@ partial class Assert
/// <exception cref="PropertyChangedException">Thrown when the notification is not raised</exception>
public static void PropertyChanged(INotifyPropertyChanged @object, string propertyName, Action testCode)
{
Assert.GuardArgumentNotNull("object", @object);
Assert.GuardArgumentNotNull("testCode", testCode);
GuardArgumentNotNull(nameof(@object), @object);
GuardArgumentNotNull(nameof(propertyName), propertyName);
GuardArgumentNotNull(nameof(testCode), testCode);

bool propertyChangeHappened = false;
var propertyChangeHappened = false;

PropertyChangedEventHandler handler = (sender, args) => propertyChangeHappened |= string.IsNullOrEmpty(args.PropertyName) || propertyName.Equals(args.PropertyName, StringComparison.OrdinalIgnoreCase);

Expand Down Expand Up @@ -60,10 +65,11 @@ public static void PropertyChanged(INotifyPropertyChanged @object, string proper
/// <exception cref="PropertyChangedException">Thrown when the notification is not raised</exception>
public static async Task PropertyChangedAsync(INotifyPropertyChanged @object, string propertyName, Func<Task> testCode)
{
Assert.GuardArgumentNotNull("object", @object);
Assert.GuardArgumentNotNull("testCode", testCode);
GuardArgumentNotNull(nameof(@object), @object);
GuardArgumentNotNull(nameof(propertyName), propertyName);
GuardArgumentNotNull(nameof(testCode), testCode);

bool propertyChangeHappened = false;
var propertyChangeHappened = false;

PropertyChangedEventHandler handler = (sender, args) => propertyChangeHappened |= string.IsNullOrEmpty(args.PropertyName) || propertyName.Equals(args.PropertyName, StringComparison.OrdinalIgnoreCase);

Expand Down
Loading

0 comments on commit 726e482

Please sign in to comment.