File tree 6 files changed +73
-7
lines changed
tests/NSubstitute.Acceptance.Specs
6 files changed +73
-7
lines changed Original file line number Diff line number Diff line change
1
+ using System . Diagnostics . CodeAnalysis ;
1
2
using NSubstitute . Exceptions ;
2
3
3
4
namespace NSubstitute . Core . Arguments ;
@@ -43,6 +44,9 @@ public GenericToNonGenericMatcherProxy(IArgumentMatcher<T> matcher)
43
44
}
44
45
45
46
public bool IsSatisfiedBy ( object ? argument ) => _matcher . IsSatisfiedBy ( ( T ? ) argument ! ) ;
47
+
48
+ public override string ToString ( ) =>
49
+ ( _matcher as IDescribeSpecification ) ? . DescribeSpecification ( ) ?? _matcher . ToString ( ) ?? "" ;
46
50
}
47
51
48
52
private class GenericToNonGenericMatcherProxyWithDescribe < T > : GenericToNonGenericMatcherProxy < T > , IDescribeNonMatches
@@ -53,6 +57,9 @@ public GenericToNonGenericMatcherProxyWithDescribe(IArgumentMatcher<T> matcher)
53
57
}
54
58
55
59
public string DescribeFor ( object ? argument ) => ( ( IDescribeNonMatches ) _matcher ) . DescribeFor ( argument ) ;
60
+
61
+ public override string ToString ( ) =>
62
+ ( _matcher as IDescribeSpecification ) ? . DescribeSpecification ( ) ?? _matcher . ToString ( ) ?? "" ;
56
63
}
57
64
58
65
private class DefaultValueContainer < T >
Original file line number Diff line number Diff line change 1
1
namespace NSubstitute . Core . Arguments ;
2
2
3
3
/// <summary>
4
- /// Provides a specification for arguments for use with <see ctype="Arg.Matches (IArgumentMatcher)" />.
5
- /// Can additionally implement <see cref="IDescribeNonMatches" /> to give descriptions when arguments do not match.
4
+ /// Provides a specification for arguments.
5
+ /// Can implement <see cref="IDescribeNonMatches" /> to give descriptions when arguments do not match.
6
+ /// Can implement <see cref="IDescribeSpecification"/> to give descriptions of expected arguments (otherwise
7
+ /// `ToString()` will be used for descriptions).
6
8
/// </summary>
7
9
public interface IArgumentMatcher
8
10
{
@@ -14,8 +16,10 @@ public interface IArgumentMatcher
14
16
}
15
17
16
18
/// <summary>
17
- /// Provides a specification for arguments for use with <see ctype="Arg.Matches < T >(IArgumentMatcher)" />.
18
- /// Can additionally implement <see ctype="IDescribeNonMatches" /> to give descriptions when arguments do not match.
19
+ /// Provides a specification for arguments.
20
+ /// Can implement <see cref="IDescribeNonMatches" /> to give descriptions when arguments do not match.
21
+ /// Can implement <see cref="IDescribeSpecification"/> to give descriptions of expected arguments (otherwise
22
+ /// `ToString()` will be used for descriptions).
19
23
/// </summary>
20
24
/// <typeparam name="T">Matches arguments of type <typeparamref name="T"/> or compatible type.</typeparam>
21
25
public interface IArgumentMatcher < T >
Original file line number Diff line number Diff line change @@ -123,7 +123,9 @@ public IEnumerable<ArgumentMatchInfo> NonMatchingArguments(ICall call)
123
123
124
124
public override string ToString ( )
125
125
{
126
- var argSpecsAsStrings = _argumentSpecifications . Select ( x => x . ToString ( ) ?? string . Empty ) . ToArray ( ) ;
126
+ var argSpecsAsStrings = _argumentSpecifications . Select ( x =>
127
+ ( x as IDescribeSpecification ) ? . DescribeSpecification ( ) ?? x . ToString ( ) ?? string . Empty
128
+ ) . ToArray ( ) ;
127
129
return CallFormatter . Default . Format ( GetMethodInfo ( ) , argSpecsAsStrings ) ;
128
130
}
129
131
Original file line number Diff line number Diff line change 1
1
namespace NSubstitute . Core ;
2
2
3
+ /// <summary>
4
+ /// A type that can describe how an argument does not match a required condition.
5
+ /// Use in conjunction with <see cref="NSubstitute.Core.Arguments.IArgumentMatcher"/> to provide information about
6
+ /// non-matches.
7
+ /// </summary>
3
8
public interface IDescribeNonMatches
4
9
{
5
10
/// <summary>
@@ -9,4 +14,4 @@ public interface IDescribeNonMatches
9
14
/// <param name="argument"></param>
10
15
/// <returns>Description of the non-match, or <see cref="string.Empty" /> if no description can be provided.</returns>
11
16
string DescribeFor ( object ? argument ) ;
12
- }
17
+ }
Original file line number Diff line number Diff line change
1
+ namespace NSubstitute . Core ;
2
+
3
+ /// <summary>
4
+ /// A type that can describe the required conditions to meet a specification.
5
+ /// Use in conjunction with <see cref="NSubstitute.Core.Arguments.IArgumentMatcher"/> to provide information about
6
+ /// what it requires to match an argument.
7
+ /// </summary>
8
+ public interface IDescribeSpecification {
9
+
10
+ /// <summary>
11
+ /// A concise description of the conditions required to match this specification.
12
+ /// </summary>
13
+ /// <returns></returns>
14
+ string DescribeSpecification ( ) ;
15
+ }
Original file line number Diff line number Diff line change @@ -745,4 +745,37 @@ public void SetUp()
745
745
{
746
746
_something = Substitute . For < ISomething > ( ) ;
747
747
}
748
- }
748
+
749
+ [ Test ]
750
+ public void Should_use_ToString_to_describe_custom_arg_matcher_without_DescribesSpec ( )
751
+ {
752
+ var ex = Assert . Throws < ReceivedCallsException > ( ( ) =>
753
+ {
754
+ _something . Received ( ) . Add ( 23 , ArgumentMatcher . Enqueue ( new CustomMatcher ( ) ) ) ;
755
+ } ) ;
756
+ Assert . That ( ex . Message , Contains . Substring ( "Add(23, Custom match)" ) ) ;
757
+ }
758
+
759
+ [ Test ]
760
+ public void Should_describe_spec_for_custom_arg_matcher_when_implemented ( )
761
+ {
762
+ var ex = Assert . Throws < ReceivedCallsException > ( ( ) =>
763
+ {
764
+ _something . Received ( ) . Add ( 23 , ArgumentMatcher . Enqueue ( new CustomDescribeSpecMatcher ( ) ) ) ;
765
+ } ) ;
766
+ Assert . That ( ex . Message , Contains . Substring ( "Add(23, DescribeSpec)" ) ) ;
767
+ }
768
+
769
+ class CustomMatcher : IArgumentMatcher , IDescribeNonMatches , IArgumentMatcher < int >
770
+ {
771
+ public string DescribeFor ( object argument ) => "failed" ;
772
+ public bool IsSatisfiedBy ( object argument ) => false ;
773
+ public bool IsSatisfiedBy ( int argument ) => false ;
774
+ public override string ToString ( ) => "Custom match" ;
775
+ }
776
+
777
+ class CustomDescribeSpecMatcher : CustomMatcher , IDescribeSpecification
778
+ {
779
+ public string DescribeSpecification ( ) => "DescribeSpec" ;
780
+ }
781
+ }
You can’t perform that action at this time.
0 commit comments