15
15
16
16
using System ;
17
17
using System . Collections . Generic ;
18
+ using System . Linq . Expressions ;
18
19
using FluentAssertions ;
19
20
using MongoDB . Bson ;
20
21
using MongoDB . Bson . Serialization ;
@@ -176,41 +177,66 @@ public void Compound_typed()
176
177
"{ compound: { must: [{ exists: { path: 'age' } }, { exists: { path: 'fn' } }, { exists: { path: 'ln' } }], mustNot: [{ exists: { path: 'ret' } }, { exists: { path: 'dob' } }] } }" ) ;
177
178
}
178
179
179
- [ Fact ]
180
- public void Equals ( )
180
+ [ Theory ]
181
+ [ MemberData ( nameof ( EqualsSupportedTypesTestData ) ) ]
182
+ public void Equals_should_render_supported_type < T > (
183
+ T value ,
184
+ string valueRendered ,
185
+ Expression < Func < Person , T > > fieldExpression ,
186
+ string fieldRendered )
187
+ where T : struct , IComparable < T >
181
188
{
182
189
var subject = CreateSubject < BsonDocument > ( ) ;
190
+ var subjectTyped = CreateSubject < Person > ( ) ;
183
191
184
192
AssertRendered (
185
- subject . Equals ( "x" , true ) ,
186
- "{ equals: { path: 'x', value: true } }" ) ;
187
- AssertRendered (
188
- subject . Equals ( "x" , ObjectId . Empty ) ,
189
- "{ equals: { path: 'x', value: { $oid: '000000000000000000000000' } } }" ) ;
193
+ subject . Equals ( "x" , value ) ,
194
+ $ "{{ equals: {{ path: 'x', value: { valueRendered } }} }}") ;
190
195
191
196
var scoreBuilder = new SearchScoreDefinitionBuilder < BsonDocument > ( ) ;
192
197
AssertRendered (
193
- subject . Equals ( "x" , true , scoreBuilder . Constant ( 1 ) ) ,
194
- "{ equals: { path: 'x', value: true, score: { constant: { value: 1 } } } }" ) ;
198
+ subject . Equals ( "x" , value , scoreBuilder . Constant ( 1 ) ) ,
199
+ $ "{{ equals: {{ path: 'x', value: { valueRendered } , score: {{ constant: {{ value: 1 }} }} }} }}") ;
200
+
201
+ AssertRendered (
202
+ subjectTyped . Equals ( fieldExpression , value ) ,
203
+ $ "{{ equals: {{ path: '{ fieldRendered } ', value: { valueRendered } }} }}") ;
195
204
}
196
205
197
- [ Fact ]
198
- public void Equals_typed ( )
206
+ public static object [ ] [ ] EqualsSupportedTypesTestData => new [ ]
199
207
{
200
- var subject = CreateSubject < Person > ( ) ;
208
+ new object [ ] { true , "true" , Exp ( p => p . Retired ) , "ret" } ,
209
+ new object [ ] { ( sbyte ) 1 , "1" , Exp ( p => p . Int8 ) , nameof ( Person . Int8 ) , } ,
210
+ new object [ ] { ( byte ) 1 , "1" , Exp ( p => p . UInt8 ) , nameof ( Person . UInt8 ) , } ,
211
+ new object [ ] { ( short ) 1 , "1" , Exp ( p => p . Int16 ) , nameof ( Person . Int16 ) } ,
212
+ new object [ ] { ( ushort ) 1 , "1" , Exp ( p => p . UInt16 ) , nameof ( Person . UInt16 ) } ,
213
+ new object [ ] { ( int ) 1 , "1" , Exp ( p => p . Int32 ) , nameof ( Person . Int32 ) } ,
214
+ new object [ ] { ( uint ) 1 , "1" , Exp ( p => p . UInt32 ) , nameof ( Person . UInt32 ) } ,
215
+ new object [ ] { long . MaxValue , "NumberLong(\" 9223372036854775807\" )" , Exp ( p => p . Int64 ) , nameof ( Person . Int64 ) } ,
216
+ new object [ ] { ( float ) 1 , "1" , Exp ( p => p . Float ) , nameof ( Person . Float ) } ,
217
+ new object [ ] { ( double ) 1 , "1" , Exp ( p => p . Double ) , nameof ( Person . Double ) } ,
218
+ new object [ ] { DateTime . MinValue , "ISODate(\" 0001-01-01T00:00:00Z\" )" , Exp ( p => p . Birthday ) , "dob" } ,
219
+ new object [ ] { DateTimeOffset . MaxValue , "ISODate(\" 9999-12-31T23:59:59.999Z\" )" , Exp ( p => p . DateTimeOffset ) , nameof ( Person . DateTimeOffset ) } ,
220
+ new object [ ] { ObjectId . Empty , "{ $oid: '000000000000000000000000' }" , Exp ( p => p . Id ) , "_id" }
221
+ } ;
201
222
202
- AssertRendered (
203
- subject . Equals ( x => x . Retired , true ) ,
204
- "{ equals: { path: 'ret', value: true } }" ) ;
205
- AssertRendered (
206
- subject . Equals ( "Retired" , true ) ,
207
- "{ equals: { path: 'ret' , value: true } }" ) ;
223
+ [ Theory ]
224
+ [ MemberData ( nameof ( EqualsUnsupporteddTypesTestData ) ) ]
225
+ public void Equals_should_throw_on_unsupported_type < T > ( T value , Expression < Func < Person , T > > fieldExpression ) where T : struct , IComparable < T >
226
+ {
227
+ var subject = CreateSubject < BsonDocument > ( ) ;
228
+ Record . Exception ( ( ) => subject . Equals ( "x" , value ) ) . Should ( ) . BeOfType < InvalidCastException > ( ) ;
208
229
209
- AssertRendered (
210
- subject . Equals ( x => x . Id , ObjectId . Empty ) ,
211
- "{ equals: { path: '_id', value: { $oid: '000000000000000000000000' } } }" ) ;
230
+ var subjectTyped = CreateSubject < Person > ( ) ;
231
+ Record . Exception ( ( ) => subjectTyped . Equals ( fieldExpression , value ) ) . Should ( ) . BeOfType < InvalidCastException > ( ) ;
212
232
}
213
233
234
+ public static object [ ] [ ] EqualsUnsupporteddTypesTestData => new [ ]
235
+ {
236
+ new object [ ] { ( ulong ) 1 , Exp ( p => p . UInt64 ) } ,
237
+ new object [ ] { TimeSpan . Zero , Exp ( p => p . TimeSpan ) } ,
238
+ } ;
239
+
214
240
[ Fact ]
215
241
public void Exists ( )
216
242
{
@@ -928,8 +954,24 @@ private void AssertRendered<TDocument>(SearchDefinition<TDocument> query, BsonDo
928
954
929
955
private SearchDefinitionBuilder < TDocument > CreateSubject < TDocument > ( ) => new SearchDefinitionBuilder < TDocument > ( ) ;
930
956
931
- private class Person : SimplePerson
957
+ private static Expression < Func < Person , T > > Exp < T > ( Expression < Func < Person , T > > expression ) => expression ;
958
+
959
+ public class Person : SimplePerson
932
960
{
961
+ public byte UInt8 { get ; set ; }
962
+ public sbyte Int8 { get ; set ; }
963
+ public short Int16 { get ; set ; }
964
+ public ushort UInt16 { get ; set ; }
965
+ public int Int32 { get ; set ; }
966
+ public uint UInt32 { get ; set ; }
967
+ public long Int64 { get ; set ; }
968
+ public ulong UInt64 { get ; set ; }
969
+ public float Float { get ; set ; }
970
+ public double Double { get ; set ; }
971
+
972
+ public DateTimeOffset DateTimeOffset { get ; set ; }
973
+ public TimeSpan TimeSpan { get ; set ; }
974
+
933
975
[ BsonElement ( "age" ) ]
934
976
public int Age { get ; set ; }
935
977
@@ -938,14 +980,15 @@ private class Person : SimplePerson
938
980
939
981
[ BsonId ]
940
982
public ObjectId Id { get ; set ; }
983
+
941
984
[ BsonElement ( "location" ) ]
942
985
public GeoJsonPoint < GeoJson2DGeographicCoordinates > Location { get ; set ; }
943
986
944
987
[ BsonElement ( "ret" ) ]
945
988
public bool Retired { get ; set ; }
946
989
}
947
990
948
- private class SimplePerson
991
+ public class SimplePerson
949
992
{
950
993
[ BsonElement ( "fn" ) ]
951
994
public string FirstName { get ; set ; }
@@ -954,7 +997,7 @@ private class SimplePerson
954
997
public string LastName { get ; set ; }
955
998
}
956
999
957
- private class SimplestPerson
1000
+ public class SimplestPerson
958
1001
{
959
1002
[ BsonElement ( "fn" ) ]
960
1003
public string FirstName { get ; set ; }
0 commit comments