Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
35 changes: 30 additions & 5 deletions src/Microsoft.VisualStudio.Validation/Assumes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime;
using System.Runtime.CompilerServices;

Expand All @@ -24,7 +23,10 @@ public static partial class Assumes
public static void NotNull<T>([ValidatedNotNull, NotNull]T? value)
where T : class
{
True(value is object);
if (value is null)
{
FailNotNull<T>();
}
}

/// <summary>
Expand All @@ -36,7 +38,10 @@ public static void NotNull<T>([ValidatedNotNull, NotNull]T? value)
public static void NotNull<T>([ValidatedNotNull, NotNull]T? value)
where T : struct
{
True(value.HasValue);
if (!value.HasValue)
{
FailNotNull<T>();
}
}

/// <summary>
Expand Down Expand Up @@ -97,7 +102,10 @@ public static void NotNullOrEmpty<T>([ValidatedNotNull, NotNull]IEnumerable<T>?
public static void Null<T>(T? value)
where T : class
{
True(value is null);
if (value is not null)
{
FailNull<T>();
}
}

/// <summary>
Expand All @@ -109,7 +117,10 @@ public static void Null<T>(T? value)
public static void Null<T>(T? value)
where T : struct
{
False(value.HasValue);
if (value.HasValue)
{
FailNull<T>();
}
}

/// <summary>
Expand Down Expand Up @@ -356,6 +367,20 @@ public static Exception Fail([Localizable(false)] string? message, Exception? in
}
}

[DoesNotReturn]
[MethodImpl(MethodImplOptions.NoInlining)]
private static void FailNotNull<T>()
{
Fail(Strings.FormatUnexpectedNull(typeof(T).Name));
}

[DoesNotReturn]
[MethodImpl(MethodImplOptions.NoInlining)]
private static void FailNull<T>()
{
Fail(Strings.FormatUnexpectedNonNull(typeof(T).Name));
}

/// <summary>
/// Helper method that formats string arguments.
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions src/Microsoft.VisualStudio.Validation/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,10 @@
<data name="ServiceMissing" xml:space="preserve">
<value>Cannot find an instance of the {0} service.</value>
</data>
<data name="UnexpectedNull" xml:space="preserve">
<value>Unexpected null value of type '{0}'.</value>
</data>
<data name="UnexpectedNonNull" xml:space="preserve">
<value>Unexpected non-null value of type '{0}'.</value>
</data>
</root>
20 changes: 16 additions & 4 deletions test/Microsoft.VisualStudio.Validation.Tests/AssumesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,28 +79,40 @@ public void Fail()
[Fact]
public void NotNull()
{
Assert.ThrowsAny<Exception>(() => Assumes.NotNull((object?)null));
Exception ex = Assert.ThrowsAny<Exception>(() => Assumes.NotNull((string?)null));

Assert.Equal("Unexpected null value of type 'String'.", ex.Message);
Comment thread
AArnott marked this conversation as resolved.

Assumes.NotNull("success");
}

[Fact]
public void NotNull_NullableStruct()
{
Assert.ThrowsAny<Exception>(() => Assumes.NotNull((int?)null));
Exception ex = Assert.ThrowsAny<Exception>(() => Assumes.NotNull((int?)null));

Assert.Equal("Unexpected null value of type 'Int32'.", ex.Message);

Assumes.NotNull((int?)5);
}

[Fact]
public void Null()
{
Assert.ThrowsAny<Exception>(() => Assumes.Null("not null"));
Exception ex = Assert.ThrowsAny<Exception>(() => Assumes.Null("not null"));

Assert.Equal("Unexpected non-null value of type 'String'.", ex.Message);

Assumes.Null((object?)null);
}

[Fact]
public void Null_NullableStruct()
{
Assert.ThrowsAny<Exception>(() => Assumes.Null((int?)5));
Exception ex = Assert.ThrowsAny<Exception>(() => Assumes.Null((int?)5));

Assert.Equal("Unexpected non-null value of type 'Int32'.", ex.Message);

Assumes.Null((int?)null);
}

Expand Down