diff --git a/TUnit.Assertions.Tests/AsyncEnumerableAssertionTests.cs b/TUnit.Assertions.Tests/AsyncEnumerableAssertionTests.cs index b65f2ed237..2541b0b334 100644 --- a/TUnit.Assertions.Tests/AsyncEnumerableAssertionTests.cs +++ b/TUnit.Assertions.Tests/AsyncEnumerableAssertionTests.cs @@ -149,6 +149,21 @@ await Assert.That(items) .Or.Contains(99); // First passes, so overall passes } + [Test] + public async Task Test_AsyncEnumerable_NullAssertions_Preserve_Chaining() + { + var items = AsyncRange(1, 5); + + await Assert.That(items) + .IsNotNull() + .And.Contains(3); + + IAsyncEnumerable? nullItems = null; + await Assert.That(nullItems!) + .IsNull() + .Or.Contains(3); + } + // Null handling [Test] public async Task Test_AsyncEnumerable_Null_Fails() diff --git a/TUnit.Assertions.Tests/CollectionAssertionTests.cs b/TUnit.Assertions.Tests/CollectionAssertionTests.cs index 0ba70fb5c0..24c21cfb10 100644 --- a/TUnit.Assertions.Tests/CollectionAssertionTests.cs +++ b/TUnit.Assertions.Tests/CollectionAssertionTests.cs @@ -108,6 +108,49 @@ public async Task Count_WithInnerAssertion_AllMatch() await Assert.That(items).Count(item => item.IsGreaterThan(0)).IsEqualTo(5); } + [Test] + public async Task NullAssertions_Preserve_List_Chaining() + { + var items = new List { 1 }; + + await Assert.That(items).IsNotNull().And.ItemAt(0).IsEqualTo(1); + + List? nullItems = null; + await Assert.That(nullItems).IsNull().Or.ItemAt(0).IsEqualTo(1); + } + + [Test] + public async Task NullAssertions_Preserve_Dictionary_And_Set_Chaining() + { + IDictionary dictionary = new Dictionary { ["one"] = 1 }; + ISet set = new HashSet { 1 }; + + await Assert.That(dictionary).IsNotNull().And.ContainsKey("one"); + await Assert.That(set).IsNotNull().And.IsSubsetOf([1, 2]); + } + + [Test] + public async Task NullAssertions_IsNotNull_Fails_When_Null_Through_Chain() + { + List? nullItems = null; + + await Assert.That(async () => + await Assert.That(nullItems).IsNotNull().And.Contains(1) + ).Throws() + .WithMessageContaining("to not be null"); + } + + [Test] + public async Task NullAssertions_IsNull_Fails_When_NotNull_Through_Chain() + { + var items = new List { 1 }; + + await Assert.That(async () => + await Assert.That(items).IsNull().Or.Contains(99) + ).Throws() + .WithMessageContaining("to be null"); + } + [Test] public async Task Count_WithInnerAssertion_Lambda_Collection() { diff --git a/TUnit.Assertions/Conditions/AsyncEnumerableAssertions.cs b/TUnit.Assertions/Conditions/AsyncEnumerableAssertions.cs index 4767edbd14..423b66af0b 100644 --- a/TUnit.Assertions/Conditions/AsyncEnumerableAssertions.cs +++ b/TUnit.Assertions/Conditions/AsyncEnumerableAssertions.cs @@ -43,6 +43,15 @@ private static async Task> MaterializeAsync(IAsyncEnumerable protected abstract AssertionResult CheckMaterialized(List items); } +internal class AsyncEnumerableNullAssertion(AssertionContext> context, bool expectNull) + : AsyncEnumerableAssertionBase(context) +{ + protected override Task CheckAsync(EvaluationMetadata> metadata) + => NullCheck.Check(metadata, expectNull); + + protected override string GetExpectation() => NullCheck.Expectation(expectNull); +} + /// /// Asserts that the async enumerable is empty or not empty. /// diff --git a/TUnit.Assertions/Conditions/CollectionNullAssertion.cs b/TUnit.Assertions/Conditions/CollectionNullAssertion.cs index 94b09acee7..38530ef317 100644 --- a/TUnit.Assertions/Conditions/CollectionNullAssertion.cs +++ b/TUnit.Assertions/Conditions/CollectionNullAssertion.cs @@ -1,32 +1,99 @@ using System.Collections; +using TUnit.Assertions.Abstractions; using TUnit.Assertions.Core; using TUnit.Assertions.Sources; namespace TUnit.Assertions.Conditions; /// -/// Asserts that a collection is not null, preserving collection type information. +/// Asserts that a collection is null (or not null), preserving collection type information. /// Extends CollectionAssertionBase to ensure .And and .Or return collection-specific continuations. /// -public class CollectionNotNullAssertion : CollectionAssertionBase +internal class CollectionNullAssertion(AssertionContext context, bool expectNull) + : CollectionAssertionBase(context) where TCollection : IEnumerable { - public CollectionNotNullAssertion(AssertionContext context) - : base(context) - { - } - protected override Task CheckAsync(EvaluationMetadata metadata) + => NullCheck.Check(metadata, expectNull); + + protected override string GetExpectation() => NullCheck.Expectation(expectNull); +} + +internal class ListNullAssertion(AssertionContext context, bool expectNull) + : ListAssertionBase(context) + where TList : IList +{ + protected override Task CheckAsync(EvaluationMetadata metadata) + => NullCheck.Check(metadata, expectNull); + + protected override string GetExpectation() => NullCheck.Expectation(expectNull); +} + +internal class ReadOnlyListNullAssertion(AssertionContext context, bool expectNull) + : ReadOnlyListAssertionBase(context) + where TList : IReadOnlyList +{ + protected override Task CheckAsync(EvaluationMetadata metadata) + => NullCheck.Check(metadata, expectNull); + + protected override string GetExpectation() => NullCheck.Expectation(expectNull); +} + +internal class DictionaryNullAssertion(AssertionContext context, bool expectNull) + : DictionaryAssertionBase(context) + where TDictionary : IReadOnlyDictionary + where TKey : notnull +{ + protected override Task CheckAsync(EvaluationMetadata metadata) + => NullCheck.Check(metadata, expectNull); + + protected override string GetExpectation() => NullCheck.Expectation(expectNull); +} + +internal class MutableDictionaryNullAssertion(AssertionContext context, bool expectNull) + : MutableDictionaryAssertionBase(context) + where TDictionary : IDictionary + where TKey : notnull +{ + protected override Task CheckAsync(EvaluationMetadata metadata) + => NullCheck.Check(metadata, expectNull); + + protected override string GetExpectation() => NullCheck.Expectation(expectNull); +} + +internal class SetNullAssertion( + AssertionContext context, + Func> adapterFactory, + bool expectNull) + : SetAssertionBase(context) + where TSet : IEnumerable +{ + // adapterFactory is never invoked on the null-check path (the set is never materialized), + // but SetAssertionBase requires CreateSetAdapter, so it must be supplied. + protected override ISetAdapter CreateSetAdapter(TSet value) => adapterFactory(value); + + protected override Task CheckAsync(EvaluationMetadata metadata) + => NullCheck.Check(metadata, expectNull); + + protected override string GetExpectation() => NullCheck.Expectation(expectNull); +} + +internal static class NullCheck +{ + public static Task Check(EvaluationMetadata metadata, bool expectNull) { - var value = metadata.Value; + if (metadata.Exception != null) + { + return Task.FromResult(AssertionResult.Failed($"threw {metadata.Exception.GetType().Name}", metadata.Exception)); + } - if (value != null) + if (expectNull ? metadata.Value is null : metadata.Value is not null) { return AssertionResult._passedTask; } - return Task.FromResult(AssertionResult.Failed("value is null")); + return Task.FromResult(AssertionResult.Failed(expectNull ? "value is not null" : "value is null")); } - protected override string GetExpectation() => "to not be null"; + public static string Expectation(bool expectNull) => expectNull ? "to be null" : "to not be null"; } diff --git a/TUnit.Assertions/Conditions/NullAssertion.cs b/TUnit.Assertions/Conditions/NullAssertion.cs index 2a6c15a742..251a11077e 100644 --- a/TUnit.Assertions/Conditions/NullAssertion.cs +++ b/TUnit.Assertions/Conditions/NullAssertion.cs @@ -20,7 +20,7 @@ protected override Task CheckAsync(EvaluationMetadata m { if (metadata.Exception != null) { - return Task.FromResult(AssertionResult.Failed("received null")); + return Task.FromResult(AssertionResult.Failed($"threw {metadata.Exception.GetType().Name}", metadata.Exception)); } var value = metadata.Value; diff --git a/TUnit.Assertions/Extensions/AssertionExtensions.cs b/TUnit.Assertions/Extensions/AssertionExtensions.cs index d80570af2c..212a334294 100644 --- a/TUnit.Assertions/Extensions/AssertionExtensions.cs +++ b/TUnit.Assertions/Extensions/AssertionExtensions.cs @@ -46,22 +46,6 @@ public static NotNullAssertion IsNotNull( return new NotNullAssertion(mappedContext); } - /// - /// Asserts that a collection is not null, preserving collection type information. - /// Returns a collection-aware assertion that maintains TItem type for proper chaining. - /// This overload enables: Assert.That(collection).IsNotNull().And.Contains(x => predicate). - /// - public static CollectionNotNullAssertion IsNotNull( - this CollectionAssertionBase source) - where TCollection : class, IEnumerable - { - var assertionSource = (IAssertionSource)source; - assertionSource.Context.ExpressionBuilder.Append(".IsNotNull()"); - // Map from TCollection? to TCollection (nullable to non-nullable) - var mappedContext = assertionSource.Context.Map((TCollection? v) => v!); - return new CollectionNotNullAssertion(mappedContext); - } - /// /// Alias for IsEqualTo - asserts that the value is equal to the expected value. /// Works with assertions, And, and Or continuations! diff --git a/TUnit.Assertions/Sources/AsyncEnumerableAssertionBase.cs b/TUnit.Assertions/Sources/AsyncEnumerableAssertionBase.cs index 7ae256b726..91c8c9e13e 100644 --- a/TUnit.Assertions/Sources/AsyncEnumerableAssertionBase.cs +++ b/TUnit.Assertions/Sources/AsyncEnumerableAssertionBase.cs @@ -39,6 +39,24 @@ private protected AsyncEnumerableAssertionBase( protected override string GetExpectation() => "async enumerable assertion"; + /// + /// Asserts that the async enumerable is null while preserving async-enumerable-specific chaining. + /// + public AsyncEnumerableAssertionBase IsNull() + { + Context.ExpressionBuilder.Append(".IsNull()"); + return new AsyncEnumerableNullAssertion(Context, expectNull: true); + } + + /// + /// Asserts that the async enumerable is not null while preserving async-enumerable-specific chaining. + /// + public AsyncEnumerableAssertionBase IsNotNull() + { + Context.ExpressionBuilder.Append(".IsNotNull()"); + return new AsyncEnumerableNullAssertion(Context, expectNull: false); + } + /// /// Asserts that the async enumerable is empty. /// Example: await Assert.That(asyncEnumerable).IsEmpty(); diff --git a/TUnit.Assertions/Sources/CollectionAssertionBase.cs b/TUnit.Assertions/Sources/CollectionAssertionBase.cs index c5d7c24454..4490a521af 100644 --- a/TUnit.Assertions/Sources/CollectionAssertionBase.cs +++ b/TUnit.Assertions/Sources/CollectionAssertionBase.cs @@ -44,6 +44,29 @@ private protected CollectionAssertionBase( protected override string GetExpectation() => "collection assertion"; + // Subclasses hide IsNull/IsNotNull with `public new` to narrow the return type to their own + // base (e.g. ListAssertionBase). This is the same idiom used by And/Or below; virtual+override + // with covariant returns is avoided because covariant returns are not honored at runtime on the + // netstandard2.0 target consumed by .NET Framework. + + /// + /// Asserts that the collection is null while preserving collection-specific chaining. + /// + public CollectionAssertionBase IsNull() + { + Context.ExpressionBuilder.Append(".IsNull()"); + return new CollectionNullAssertion(Context, expectNull: true); + } + + /// + /// Asserts that the collection is not null while preserving collection-specific chaining. + /// + public CollectionAssertionBase IsNotNull() + { + Context.ExpressionBuilder.Append(".IsNotNull()"); + return new CollectionNullAssertion(Context, expectNull: false); + } + /// /// Asserts that the collection is of the specified type and returns an assertion on the casted value. /// This allows chaining additional assertions on the typed value. diff --git a/TUnit.Assertions/Sources/DictionaryAssertionBase.cs b/TUnit.Assertions/Sources/DictionaryAssertionBase.cs index 4be375439b..aea85145de 100644 --- a/TUnit.Assertions/Sources/DictionaryAssertionBase.cs +++ b/TUnit.Assertions/Sources/DictionaryAssertionBase.cs @@ -40,6 +40,24 @@ private protected DictionaryAssertionBase( protected override string GetExpectation() => "dictionary assertion"; + /// + /// Asserts that the dictionary is null while preserving dictionary-specific chaining. + /// + public new DictionaryAssertionBase IsNull() + { + Context.ExpressionBuilder.Append(".IsNull()"); + return new DictionaryNullAssertion(Context, expectNull: true); + } + + /// + /// Asserts that the dictionary is not null while preserving dictionary-specific chaining. + /// + public new DictionaryAssertionBase IsNotNull() + { + Context.ExpressionBuilder.Append(".IsNotNull()"); + return new DictionaryNullAssertion(Context, expectNull: false); + } + /// /// Asserts that the dictionary contains the specified key. /// This instance method enables calling ContainsKey with proper type inference. diff --git a/TUnit.Assertions/Sources/ListAssertionBase.cs b/TUnit.Assertions/Sources/ListAssertionBase.cs index 12365631b9..18218dc430 100644 --- a/TUnit.Assertions/Sources/ListAssertionBase.cs +++ b/TUnit.Assertions/Sources/ListAssertionBase.cs @@ -31,6 +31,24 @@ private protected ListAssertionBase( { } + /// + /// Asserts that the list is null while preserving list-specific chaining. + /// + public new ListAssertionBase IsNull() + { + Context.ExpressionBuilder.Append(".IsNull()"); + return new ListNullAssertion(Context, expectNull: true); + } + + /// + /// Asserts that the list is not null while preserving list-specific chaining. + /// + public new ListAssertionBase IsNotNull() + { + Context.ExpressionBuilder.Append(".IsNotNull()"); + return new ListNullAssertion(Context, expectNull: false); + } + /// /// Asserts that the item at the specified index equals the expected value. /// Example: await Assert.That(list).HasItemAt(0, "expected"); diff --git a/TUnit.Assertions/Sources/MutableDictionaryAssertionBase.cs b/TUnit.Assertions/Sources/MutableDictionaryAssertionBase.cs index 4b35035413..c94d8a73ba 100644 --- a/TUnit.Assertions/Sources/MutableDictionaryAssertionBase.cs +++ b/TUnit.Assertions/Sources/MutableDictionaryAssertionBase.cs @@ -38,6 +38,24 @@ private protected MutableDictionaryAssertionBase( protected override string GetExpectation() => "dictionary assertion"; + /// + /// Asserts that the dictionary is null while preserving mutable-dictionary-specific chaining. + /// + public new MutableDictionaryAssertionBase IsNull() + { + Context.ExpressionBuilder.Append(".IsNull()"); + return new MutableDictionaryNullAssertion(Context, expectNull: true); + } + + /// + /// Asserts that the dictionary is not null while preserving mutable-dictionary-specific chaining. + /// + public new MutableDictionaryAssertionBase IsNotNull() + { + Context.ExpressionBuilder.Append(".IsNotNull()"); + return new MutableDictionaryNullAssertion(Context, expectNull: false); + } + /// /// Asserts that the dictionary contains the specified key. /// Example: await Assert.That(dictionary).ContainsKey("key1"); diff --git a/TUnit.Assertions/Sources/ReadOnlyListAssertionBase.cs b/TUnit.Assertions/Sources/ReadOnlyListAssertionBase.cs index 3d7c8db6ca..d4cd240574 100644 --- a/TUnit.Assertions/Sources/ReadOnlyListAssertionBase.cs +++ b/TUnit.Assertions/Sources/ReadOnlyListAssertionBase.cs @@ -33,6 +33,24 @@ private protected ReadOnlyListAssertionBase( context.SetPendingLink(previousAssertion, combinerType); } + /// + /// Asserts that the list is null while preserving read-only-list-specific chaining. + /// + public new ReadOnlyListAssertionBase IsNull() + { + Context.ExpressionBuilder.Append(".IsNull()"); + return new ReadOnlyListNullAssertion(Context, expectNull: true); + } + + /// + /// Asserts that the list is not null while preserving read-only-list-specific chaining. + /// + public new ReadOnlyListAssertionBase IsNotNull() + { + Context.ExpressionBuilder.Append(".IsNotNull()"); + return new ReadOnlyListNullAssertion(Context, expectNull: false); + } + /// /// Asserts that the list has an item at the specified index that equals the expected value. /// Example: await Assert.That(list).HasItemAt(0, "first"); diff --git a/TUnit.Assertions/Sources/SetAssertionBase.cs b/TUnit.Assertions/Sources/SetAssertionBase.cs index 62576cbff1..a482818907 100644 --- a/TUnit.Assertions/Sources/SetAssertionBase.cs +++ b/TUnit.Assertions/Sources/SetAssertionBase.cs @@ -43,6 +43,24 @@ private protected SetAssertionBase( protected override string GetExpectation() => "set assertion"; + /// + /// Asserts that the set is null while preserving set-specific chaining. + /// + public new SetAssertionBase IsNull() + { + Context.ExpressionBuilder.Append(".IsNull()"); + return new SetNullAssertion(Context, CreateSetAdapter, expectNull: true); + } + + /// + /// Asserts that the set is not null while preserving set-specific chaining. + /// + public new SetAssertionBase IsNotNull() + { + Context.ExpressionBuilder.Append(".IsNotNull()"); + return new SetNullAssertion(Context, CreateSetAdapter, expectNull: false); + } + // ======================================== // Set-specific methods // ======================================== diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt index fc2d114091..3fd6de6860 100644 --- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt @@ -915,13 +915,6 @@ namespace .Conditions } public class CollectionMemberAssertionAdapter : . where TCollection : . { } - public class CollectionNotNullAssertion : . - where TCollection : . - { - public CollectionNotNullAssertion(. context) { } - protected override .<.> CheckAsync(. metadata) { } - protected override string GetExpectation() { } - } public abstract class ComparerBasedAssertion : . { protected ComparerBasedAssertion(. context) { } @@ -2724,8 +2717,6 @@ namespace .Extensions where TValue : class { } public static . IsNotNull(this . source) where TValue : struct { } - public static . IsNotNull(this . source) - where TCollection : class, . { } public static ..IsNotParsableIntoAssertion IsNotParsableInto<[.(..None | ..PublicMethods | ..Interfaces)] T>(this . source) { } public static . IsOfType(this . source, expectedType, [.("expectedType")] string? expression = null) { } public static ..IsParsableIntoAssertion IsParsableInto<[.(..None | ..PublicMethods | ..Interfaces)] T>(this . source) { } @@ -6187,7 +6178,9 @@ namespace .Sources public .> IsNotAssignableFrom() { } public .> IsNotAssignableTo() { } public . IsNotEmpty() { } + public . IsNotNull() { } public .<., TExpected> IsNotTypeOf() { } + public . IsNull() { } public .<., TExpected> IsTypeOf() { } } public class AsyncEnumerableAssertion : . @@ -6258,7 +6251,9 @@ namespace .Sources public . IsNotAssignableFrom() { } public . IsNotAssignableTo() { } public . IsNotEmpty() { } + public . IsNotNull() { } public . IsNotTypeOf() { } + public . IsNull() { } public . IsOrderedBy( keySelector, [.("keySelector")] string? expression = null) { } public . IsOrderedBy( keySelector, .? comparer, [.("keySelector")] string? selectorExpression = null, [.("comparer")] string? comparerExpression = null) { } public . IsOrderedByDescending( keySelector, [.("keySelector")] string? expression = null) { } @@ -6303,6 +6298,8 @@ namespace .Sources public . DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { } public . DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } } public class DictionaryAssertion : .<., TKey, TValue>, .<., .> where TKey : notnull @@ -6347,6 +6344,8 @@ namespace .Sources public new . Or { get; } public . FirstItem() { } public . HasItemAt(int index, TItem expected, [.("index")] string? indexExpression = null, [.("expected")] string? expectedExpression = null) { } + public new . IsNotNull() { } + public new . IsNull() { } public . ItemAt(int index, [.("index")] string? expression = null) { } public . LastItem() { } } @@ -6418,6 +6417,8 @@ namespace .Sources public . DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { } public . DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } } public class MutableDictionaryAssertion : .<., TKey, TValue>, .<., .>, .<., .> where TKey : notnull @@ -6434,6 +6435,8 @@ namespace .Sources public new . Or { get; } public . FirstItem() { } public . HasItemAt(int index, TItem expected, .? comparer = null, [.("index")] string? indexExpression = null, [.("expected")] string? expectedExpression = null) { } + public new . IsNotNull() { } + public new . IsNull() { } public . ItemAt(int index, [.("index")] string? indexExpression = null) { } public . LastItem() { } } @@ -6467,6 +6470,8 @@ namespace .Sources protected abstract . CreateSetAdapter(TSet value); public . DoesNotOverlap(. other, [.("other")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } public . IsProperSubsetOf(. other, [.("other")] string? expression = null) { } public . IsProperSupersetOf(. other, [.("other")] string? expression = null) { } public . IsSubsetOf(. other, [.("other")] string? expression = null) { } diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt index 8783b78802..abbcb81286 100644 --- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt @@ -898,13 +898,6 @@ namespace .Conditions } public class CollectionMemberAssertionAdapter : . where TCollection : . { } - public class CollectionNotNullAssertion : . - where TCollection : . - { - public CollectionNotNullAssertion(. context) { } - protected override .<.> CheckAsync(. metadata) { } - protected override string GetExpectation() { } - } public abstract class ComparerBasedAssertion : . { protected ComparerBasedAssertion(. context) { } @@ -2703,8 +2696,6 @@ namespace .Extensions where TValue : class { } public static . IsNotNull(this . source) where TValue : struct { } - public static . IsNotNull(this . source) - where TCollection : class, . { } public static ..IsNotParsableIntoAssertion IsNotParsableInto<[.(..None | ..PublicMethods | ..Interfaces)] T>(this . source) { } public static . IsOfType(this . source, expectedType, [.("expectedType")] string? expression = null) { } public static ..IsParsableIntoAssertion IsParsableInto<[.(..None | ..PublicMethods | ..Interfaces)] T>(this . source) { } @@ -6110,7 +6101,9 @@ namespace .Sources public .> IsNotAssignableFrom() { } public .> IsNotAssignableTo() { } public . IsNotEmpty() { } + public . IsNotNull() { } public .<., TExpected> IsNotTypeOf() { } + public . IsNull() { } public .<., TExpected> IsTypeOf() { } } public class AsyncEnumerableAssertion : . @@ -6180,7 +6173,9 @@ namespace .Sources public . IsNotAssignableFrom() { } public . IsNotAssignableTo() { } public . IsNotEmpty() { } + public . IsNotNull() { } public . IsNotTypeOf() { } + public . IsNull() { } public . IsOrderedBy( keySelector, [.("keySelector")] string? expression = null) { } public . IsOrderedBy( keySelector, .? comparer, [.("keySelector")] string? selectorExpression = null, [.("comparer")] string? comparerExpression = null) { } public . IsOrderedByDescending( keySelector, [.("keySelector")] string? expression = null) { } @@ -6225,6 +6220,8 @@ namespace .Sources public . DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { } public . DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } } public class DictionaryAssertion : .<., TKey, TValue>, .<., .> where TKey : notnull @@ -6269,6 +6266,8 @@ namespace .Sources public new . Or { get; } public . FirstItem() { } public . HasItemAt(int index, TItem expected, [.("index")] string? indexExpression = null, [.("expected")] string? expectedExpression = null) { } + public new . IsNotNull() { } + public new . IsNull() { } public . ItemAt(int index, [.("index")] string? expression = null) { } public . LastItem() { } } @@ -6340,6 +6339,8 @@ namespace .Sources public . DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { } public . DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } } public class MutableDictionaryAssertion : .<., TKey, TValue>, .<., .>, .<., .> where TKey : notnull @@ -6356,6 +6357,8 @@ namespace .Sources public new . Or { get; } public . FirstItem() { } public . HasItemAt(int index, TItem expected, .? comparer = null, [.("index")] string? indexExpression = null, [.("expected")] string? expectedExpression = null) { } + public new . IsNotNull() { } + public new . IsNull() { } public . ItemAt(int index, [.("index")] string? indexExpression = null) { } public . LastItem() { } } @@ -6389,6 +6392,8 @@ namespace .Sources protected abstract . CreateSetAdapter(TSet value); public . DoesNotOverlap(. other, [.("other")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } public . IsProperSubsetOf(. other, [.("other")] string? expression = null) { } public . IsProperSupersetOf(. other, [.("other")] string? expression = null) { } public . IsSubsetOf(. other, [.("other")] string? expression = null) { } diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt index ed5f733562..adb56dfc3a 100644 --- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt @@ -915,13 +915,6 @@ namespace .Conditions } public class CollectionMemberAssertionAdapter : . where TCollection : . { } - public class CollectionNotNullAssertion : . - where TCollection : . - { - public CollectionNotNullAssertion(. context) { } - protected override .<.> CheckAsync(. metadata) { } - protected override string GetExpectation() { } - } public abstract class ComparerBasedAssertion : . { protected ComparerBasedAssertion(. context) { } @@ -2724,8 +2717,6 @@ namespace .Extensions where TValue : class { } public static . IsNotNull(this . source) where TValue : struct { } - public static . IsNotNull(this . source) - where TCollection : class, . { } public static ..IsNotParsableIntoAssertion IsNotParsableInto<[.(..None | ..PublicMethods | ..Interfaces)] T>(this . source) { } public static . IsOfType(this . source, expectedType, [.("expectedType")] string? expression = null) { } public static ..IsParsableIntoAssertion IsParsableInto<[.(..None | ..PublicMethods | ..Interfaces)] T>(this . source) { } @@ -6187,7 +6178,9 @@ namespace .Sources public .> IsNotAssignableFrom() { } public .> IsNotAssignableTo() { } public . IsNotEmpty() { } + public . IsNotNull() { } public .<., TExpected> IsNotTypeOf() { } + public . IsNull() { } public .<., TExpected> IsTypeOf() { } } public class AsyncEnumerableAssertion : . @@ -6258,7 +6251,9 @@ namespace .Sources public . IsNotAssignableFrom() { } public . IsNotAssignableTo() { } public . IsNotEmpty() { } + public . IsNotNull() { } public . IsNotTypeOf() { } + public . IsNull() { } public . IsOrderedBy( keySelector, [.("keySelector")] string? expression = null) { } public . IsOrderedBy( keySelector, .? comparer, [.("keySelector")] string? selectorExpression = null, [.("comparer")] string? comparerExpression = null) { } public . IsOrderedByDescending( keySelector, [.("keySelector")] string? expression = null) { } @@ -6303,6 +6298,8 @@ namespace .Sources public . DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { } public . DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } } public class DictionaryAssertion : .<., TKey, TValue>, .<., .> where TKey : notnull @@ -6347,6 +6344,8 @@ namespace .Sources public new . Or { get; } public . FirstItem() { } public . HasItemAt(int index, TItem expected, [.("index")] string? indexExpression = null, [.("expected")] string? expectedExpression = null) { } + public new . IsNotNull() { } + public new . IsNull() { } public . ItemAt(int index, [.("index")] string? expression = null) { } public . LastItem() { } } @@ -6418,6 +6417,8 @@ namespace .Sources public . DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { } public . DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } } public class MutableDictionaryAssertion : .<., TKey, TValue>, .<., .>, .<., .> where TKey : notnull @@ -6434,6 +6435,8 @@ namespace .Sources public new . Or { get; } public . FirstItem() { } public . HasItemAt(int index, TItem expected, .? comparer = null, [.("index")] string? indexExpression = null, [.("expected")] string? expectedExpression = null) { } + public new . IsNotNull() { } + public new . IsNull() { } public . ItemAt(int index, [.("index")] string? indexExpression = null) { } public . LastItem() { } } @@ -6467,6 +6470,8 @@ namespace .Sources protected abstract . CreateSetAdapter(TSet value); public . DoesNotOverlap(. other, [.("other")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } public . IsProperSubsetOf(. other, [.("other")] string? expression = null) { } public . IsProperSupersetOf(. other, [.("other")] string? expression = null) { } public . IsSubsetOf(. other, [.("other")] string? expression = null) { } diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt index b29afe65f8..3db6f0c9ae 100644 --- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt +++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt @@ -755,13 +755,6 @@ namespace .Conditions } public class CollectionMemberAssertionAdapter : . where TCollection : . { } - public class CollectionNotNullAssertion : . - where TCollection : . - { - public CollectionNotNullAssertion(. context) { } - protected override .<.> CheckAsync(. metadata) { } - protected override string GetExpectation() { } - } public abstract class ComparerBasedAssertion : . { protected ComparerBasedAssertion(. context) { } @@ -2429,8 +2422,6 @@ namespace .Extensions where TValue : class { } public static . IsNotNull(this . source) where TValue : struct { } - public static . IsNotNull(this . source) - where TCollection : class, . { } public static ..IsNotParsableIntoAssertion IsNotParsableInto(this . source) { } public static . IsOfType(this . source, expectedType, [.("expectedType")] string? expression = null) { } public static ..IsParsableIntoAssertion IsParsableInto(this . source) { } @@ -5305,7 +5296,9 @@ namespace .Sources public .> IsNotAssignableFrom() { } public .> IsNotAssignableTo() { } public . IsNotEmpty() { } + public . IsNotNull() { } public .<., TExpected> IsNotTypeOf() { } + public . IsNull() { } public .<., TExpected> IsTypeOf() { } } public class AsyncEnumerableAssertion : . @@ -5375,7 +5368,9 @@ namespace .Sources public . IsNotAssignableFrom() { } public . IsNotAssignableTo() { } public . IsNotEmpty() { } + public . IsNotNull() { } public . IsNotTypeOf() { } + public . IsNull() { } public . IsOrderedBy( keySelector, [.("keySelector")] string? expression = null) { } public . IsOrderedBy( keySelector, .? comparer, [.("keySelector")] string? selectorExpression = null, [.("comparer")] string? comparerExpression = null) { } public . IsOrderedByDescending( keySelector, [.("keySelector")] string? expression = null) { } @@ -5419,6 +5414,8 @@ namespace .Sources public . DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { } public . DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } } public class DictionaryAssertion : .<., TKey, TValue> where TKey : notnull @@ -5461,6 +5458,8 @@ namespace .Sources public new . Or { get; } public . FirstItem() { } public . HasItemAt(int index, TItem expected, [.("index")] string? indexExpression = null, [.("expected")] string? expectedExpression = null) { } + public new . IsNotNull() { } + public new . IsNull() { } public . ItemAt(int index, [.("index")] string? expression = null) { } public . LastItem() { } } @@ -5486,6 +5485,8 @@ namespace .Sources public . DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { } public . DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } } public class MutableDictionaryAssertion : .<., TKey, TValue> where TKey : notnull @@ -5500,6 +5501,8 @@ namespace .Sources public new . Or { get; } public . FirstItem() { } public . HasItemAt(int index, TItem expected, .? comparer = null, [.("index")] string? indexExpression = null, [.("expected")] string? expectedExpression = null) { } + public new . IsNotNull() { } + public new . IsNull() { } public . ItemAt(int index, [.("index")] string? indexExpression = null) { } public . LastItem() { } } @@ -5521,6 +5524,8 @@ namespace .Sources protected abstract . CreateSetAdapter(TSet value); public . DoesNotOverlap(. other, [.("other")] string? expression = null) { } protected override string GetExpectation() { } + public new . IsNotNull() { } + public new . IsNull() { } public . IsProperSubsetOf(. other, [.("other")] string? expression = null) { } public . IsProperSupersetOf(. other, [.("other")] string? expression = null) { } public . IsSubsetOf(. other, [.("other")] string? expression = null) { }