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 {
@@ -866,12 +874,6 @@ public void Does_support_out_method_with_base_override()
866874 Assert . That ( outArg , Is . EqualTo ( 4 ) ) ;
867875 }
868876
869- [ SetUp ]
870- public void SetUp ( )
871- {
872- _something = Substitute . For < ISomething > ( ) ;
873- }
874-
875877 public interface IMyService
876878 {
877879 void MyMethod < T > ( IMyArgument < T > argument ) ;
@@ -919,6 +921,21 @@ public void Should_use_empty_string_for_null_describe_spec_for_custom_arg_matche
919921 Assert . That ( ex . Message , Contains . Substring ( "Add(23, )" ) ) ;
920922 }
921923
924+ [ Test ]
925+ public void Custom_arg_matcher_support ( )
926+ {
927+ _something . Add ( 1 , 2 ) ;
928+
929+ _something . Received ( ) . Add ( 1 , Arg . Is ( GreaterThan ( 0 ) ) ) ;
930+
931+ var exception = Assert . Throws < ReceivedCallsException > ( ( ) =>
932+ _something . Received ( ) . Add ( 1 , Arg . Is ( GreaterThan ( 3 ) ) ) ) ;
933+
934+ Assert . That ( exception . Message , Contains . Substring ( "Add(1, >3)" ) ) ;
935+ Assert . That ( exception . Message , Contains . Substring ( "Add(1, *2*)" ) ) ;
936+ Assert . That ( exception . Message , Contains . Substring ( "arg[1]: 2 \u226f 3" ) ) ;
937+ }
938+
922939 class CustomMatcher : IArgumentMatcher , IDescribeNonMatches , IArgumentMatcher < int >
923940 {
924941 public string DescribeFor ( object argument ) => "failed" ;
@@ -956,4 +973,39 @@ public override int MethodWithOutParameter(int arg1, out int arg2)
956973 return 2 ;
957974 }
958975 }
976+
977+ #if NET6_0_OR_GREATER
978+ /// <summary>
979+ /// See https://github.com/nsubstitute/NSubstitute/issues/822.
980+ /// </summary>
981+ [ Test ]
982+ public void Predicate_match ( )
983+ {
984+ _something . Say ( "hello" ) ;
985+
986+ _something . Received ( ) . Say ( Arg . Is ( Matching < string > ( x => x ? . Length > 0 ) ) ) ;
987+
988+ var exception = Assert . Throws < ReceivedCallsException > ( ( ) =>
989+ _something . Received ( ) . Say ( Arg . Is ( Matching < string > ( x => x ? . Length > 10 ) ) ) ) ;
990+ Assert . That ( exception . Message , Contains . Substring ( "Say(x => x?.Length > 10)" ) ) ;
991+ Assert . That ( exception . Message , Contains . Substring ( "Say(*\" hello\" *)" ) ) ;
992+ }
993+ #endif
959994}
995+
996+ static class Extensions
997+ {
998+ public static IArgumentMatcher < T > GreaterThan < T > ( T value ) where T : IComparable < T > =>
999+ new GreaterThanMatcher < T > ( value ) ;
1000+
1001+ private class GreaterThanMatcher < T > ( T value ) :
1002+ IDescribeNonMatches , IDescribeSpecification , IArgumentMatcher < T >
1003+ where T : IComparable < T >
1004+ {
1005+ public string DescribeFor ( object argument ) => $ "{ argument } ≯ { value } ";
1006+
1007+ public string DescribeSpecification ( ) => $ ">{ value } ";
1008+
1009+ public bool IsSatisfiedBy ( T argument ) => argument . CompareTo ( value ) > 0 ;
1010+ }
1011+ }
0 commit comments