44using NSubstitute . Exceptions ;
55using NSubstitute . Extensions ;
66using NUnit . Framework ;
7+ using static NSubstitute . Acceptance . Specs . Extensions ;
8+ using static NSubstitute . ArgMatchers ;
79
810namespace NSubstitute . Acceptance . Specs ;
911
@@ -12,6 +14,12 @@ public class ArgumentMatching
1214{
1315 private ISomething _something ;
1416
17+ [ SetUp ]
18+ public void SetUp ( )
19+ {
20+ _something = Substitute . For < ISomething > ( ) ;
21+ }
22+
1523 [ Test ]
1624 public void Return_result_for_any_argument ( )
1725 {
@@ -887,12 +895,6 @@ public interface IWithStructWithDefaultConstructor
887895 void MethodWithStruct ( StructWithDefaultConstructor arg ) ;
888896 }
889897
890- [ SetUp ]
891- public void SetUp ( )
892- {
893- _something = Substitute . For < ISomething > ( ) ;
894- }
895-
896898 public interface IMyService
897899 {
898900 void MyMethod < T > ( IMyArgument < T > argument ) ;
@@ -940,6 +942,21 @@ public void Should_use_empty_string_for_null_describe_spec_for_custom_arg_matche
940942 Assert . That ( ex . Message , Contains . Substring ( "Add(23, )" ) ) ;
941943 }
942944
945+ [ Test ]
946+ public void Custom_arg_matcher_support ( )
947+ {
948+ _something . Add ( 1 , 2 ) ;
949+
950+ _something . Received ( ) . Add ( 1 , Arg . Is ( GreaterThan ( 0 ) ) ) ;
951+
952+ var exception = Assert . Throws < ReceivedCallsException > ( ( ) =>
953+ _something . Received ( ) . Add ( 1 , Arg . Is ( GreaterThan ( 3 ) ) ) ) ;
954+
955+ Assert . That ( exception . Message , Contains . Substring ( "Add(1, >3)" ) ) ;
956+ Assert . That ( exception . Message , Contains . Substring ( "Add(1, *2*)" ) ) ;
957+ Assert . That ( exception . Message , Contains . Substring ( "arg[1]: 2 \u226f 3" ) ) ;
958+ }
959+
943960 class CustomMatcher : IArgumentMatcher , IDescribeNonMatches , IArgumentMatcher < int >
944961 {
945962 public string DescribeFor ( object argument ) => "failed" ;
@@ -977,4 +994,39 @@ public override int MethodWithOutParameter(int arg1, out int arg2)
977994 return 2 ;
978995 }
979996 }
997+
998+ #if NET6_0_OR_GREATER
999+ /// <summary>
1000+ /// See https://github.com/nsubstitute/NSubstitute/issues/822.
1001+ /// </summary>
1002+ [ Test ]
1003+ public void Predicate_match ( )
1004+ {
1005+ _something . Say ( "hello" ) ;
1006+
1007+ _something . Received ( ) . Say ( Arg . Is ( Matching < string > ( x => x ? . Length > 0 ) ) ) ;
1008+
1009+ var exception = Assert . Throws < ReceivedCallsException > ( ( ) =>
1010+ _something . Received ( ) . Say ( Arg . Is ( Matching < string > ( x => x ? . Length > 10 ) ) ) ) ;
1011+ Assert . That ( exception . Message , Contains . Substring ( "Say(x => x?.Length > 10)" ) ) ;
1012+ Assert . That ( exception . Message , Contains . Substring ( "Say(*\" hello\" *)" ) ) ;
1013+ }
1014+ #endif
9801015}
1016+
1017+ static class Extensions
1018+ {
1019+ public static IArgumentMatcher < T > GreaterThan < T > ( T value ) where T : IComparable < T > =>
1020+ new GreaterThanMatcher < T > ( value ) ;
1021+
1022+ private class GreaterThanMatcher < T > ( T value ) :
1023+ IDescribeNonMatches , IDescribeSpecification , IArgumentMatcher < T >
1024+ where T : IComparable < T >
1025+ {
1026+ public string DescribeFor ( object argument ) => $ "{ argument } ≯ { value } ";
1027+
1028+ public string DescribeSpecification ( ) => $ ">{ value } ";
1029+
1030+ public bool IsSatisfiedBy ( T argument ) => argument . CompareTo ( value ) > 0 ;
1031+ }
1032+ }
0 commit comments