@@ -23,6 +23,8 @@ public void AssertIs(AssertNode node) {
23
23
24
24
_logger ? . Write ( $ "{ node . MemberName } : { node . TargetType ? . GetFriendlyName ( ) ?? "(null)" } = ") ;
25
25
try {
26
+ if ( TryPredicateAssertIs ( targetType , actual , expected , node ) ) { return ; }
27
+
26
28
// null 比較
27
29
if ( targetType is null ) {
28
30
if ( ! ( actual is null ) ) { throw new PrimitiveAssertFailedException ( node , "ターゲット型は null ですが、actual は非 null です。" , _message ) ; }
@@ -79,6 +81,30 @@ private void WriteLog(AssertNode node, string additionalMessage) {
79
81
_logger . WriteLine ( ) ;
80
82
}
81
83
84
+ private bool TryPredicateAssertIs ( Type ? targetType , object ? actual , object ? expected , AssertNode node ) {
85
+ if ( expected is null ) { return false ; }
86
+
87
+ if ( expected is AssertPredicate predicate ) {
88
+ if ( ! predicate ( actual ) ) { throw new PrimitiveAssertFailedException ( node , "actual はカスタム条件に一致しませんでした。" , _message ) ; }
89
+
90
+ WriteLog ( node , "actual はカスタム条件に一致しました。" ) ;
91
+ return true ;
92
+ }
93
+
94
+ Type expectedType = expected . GetType ( ) ;
95
+ if ( expectedType . IsGenericType && expectedType . GetGenericTypeDefinition ( ) == typeof ( AssertPredicate < > ) ) {
96
+ Type genericType = expectedType . GetGenericArguments ( ) [ 0 ] ;
97
+
98
+ if ( ! genericType . IsAssignableFrom ( actual ? . GetType ( ) ) ) { throw new PrimitiveAssertFailedException ( node , "actual はカスタム条件の型引数にキャストできませんでした。" , _message ) ; }
99
+ if ( ! ( bool ) expectedType . GetMethod ( "Invoke" ) . Invoke ( expected , new [ ] { actual } ) ) { throw new PrimitiveAssertFailedException ( node , "actual はカスタム条件に一致しませんでした。" , _message ) ; }
100
+
101
+ WriteLog ( node , "actual はカスタム条件に一致しました。" ) ;
102
+ return true ;
103
+ }
104
+
105
+ return false ;
106
+ }
107
+
82
108
private bool TryNumericAssertIs ( Type targetType , object actual , object expected , AssertNode node ) {
83
109
if ( ! Numeric . IsNumeric ( targetType ) ) { return false ; }
84
110
0 commit comments