13
13
* limitations under the License.
14
14
*/
15
15
16
+ using System ;
16
17
using System . Collections . Generic ;
17
18
using System . Linq ;
18
19
using FluentAssertions ;
@@ -391,6 +392,112 @@ public void Average_with_nullable_longs_selector_should_work(
391
392
results . Should ( ) . Equal ( null , null , 4.0 ) ;
392
393
}
393
394
395
+ [ Theory ]
396
+ [ ParameterAttributeData ]
397
+ public void Average_over_empty_set_of_nullable_values_should_work (
398
+ [ Values ( false , true ) ] bool withNestedAsQueryable )
399
+ {
400
+ var collection = Fixture . Collection ;
401
+
402
+ var queryable = withNestedAsQueryable ?
403
+ collection . AsQueryable ( ) . Select ( x => x . EmptyNullableDecimals . AsQueryable ( ) . Average ( ) ) :
404
+ collection . AsQueryable ( ) . Select ( x => x . EmptyNullableDecimals . Average ( ) ) ;
405
+
406
+ var stages = Translate ( collection , queryable ) ;
407
+ AssertStages ( stages , "{ $project : { _v : { $avg : '$EmptyNullableDecimals' }, _id : 0 } }" ) ;
408
+
409
+ var results = queryable . ToList ( ) ;
410
+ results . Should ( ) . Equal ( null , null , null ) ;
411
+ }
412
+
413
+ [ Theory ]
414
+ [ ParameterAttributeData ]
415
+ public void Average_with_selector_over_empty_set_of_nullable_values_should_work (
416
+ [ Values ( false , true ) ] bool withNestedAsQueryable )
417
+ {
418
+ var collection = Fixture . Collection ;
419
+
420
+ var queryable = withNestedAsQueryable ?
421
+ collection . AsQueryable ( ) . Select ( x => x . EmptyNullableDecimals . AsQueryable ( ) . Average ( x => x * 2.0M ) ) :
422
+ collection . AsQueryable ( ) . Select ( x => x . EmptyNullableDecimals . Average ( x => x * 2.0M ) ) ;
423
+
424
+ var stages = Translate ( collection , queryable ) ;
425
+ AssertStages ( stages , "{ $project : { _v : { $avg : { $map : { input : '$EmptyNullableDecimals', as : 'x', in : { $multiply : ['$$x', NumberDecimal(2)] } } } }, _id : 0 } }" ) ;
426
+
427
+ var results = queryable . ToList ( ) ;
428
+ results . Should ( ) . Equal ( null , null , null ) ;
429
+ }
430
+
431
+ [ Theory ]
432
+ [ ParameterAttributeData ]
433
+ public void Average_over_empty_set_of_non_nullable_values_should_throw (
434
+ [ Values ( false , true ) ] bool withNestedAsQueryable )
435
+ {
436
+ var collection = Fixture . Collection ;
437
+
438
+ var queryable = withNestedAsQueryable ?
439
+ collection . AsQueryable ( ) . Select ( x => x . EmptyDecimals . AsQueryable ( ) . Average ( ) ) :
440
+ collection . AsQueryable ( ) . Select ( x => x . EmptyDecimals . Average ( ) ) ;
441
+
442
+ var stages = Translate ( collection , queryable ) ;
443
+ AssertStages ( stages , "{ $project : { _v : { $avg : '$EmptyDecimals' }, _id : 0 } }" ) ;
444
+
445
+ Assert . Throws < FormatException > ( ( ) => queryable . ToList ( ) ) ;
446
+ }
447
+
448
+ [ Theory ]
449
+ [ ParameterAttributeData ]
450
+ public void Average_with_selector_over_empty_set_of_non_nullable_values_should_throw (
451
+ [ Values ( false , true ) ] bool withNestedAsQueryable )
452
+ {
453
+ var collection = Fixture . Collection ;
454
+
455
+ var queryable = withNestedAsQueryable ?
456
+ collection . AsQueryable ( ) . Select ( x => x . EmptyDecimals . AsQueryable ( ) . Average ( x => x * 2.0M ) ) :
457
+ collection . AsQueryable ( ) . Select ( x => x . EmptyDecimals . Average ( x => x * 2.0M ) ) ;
458
+
459
+ var stages = Translate ( collection , queryable ) ;
460
+ AssertStages ( stages , "{ $project : { _v : { $avg : { $map : { input : '$EmptyDecimals', as : 'x', in : { $multiply : ['$$x', NumberDecimal(2)] } } } }, _id : 0 } }" ) ;
461
+
462
+ Assert . Throws < FormatException > ( ( ) => queryable . ToList ( ) ) ;
463
+ }
464
+
465
+ [ Theory ]
466
+ [ ParameterAttributeData ]
467
+ public void Average_over_empty_set_of_non_nullable_values_cast_to_nullable_should_work (
468
+ [ Values ( false , true ) ] bool withNestedAsQueryable )
469
+ {
470
+ var collection = Fixture . Collection ;
471
+
472
+ var queryable = withNestedAsQueryable ?
473
+ collection . AsQueryable ( ) . Select ( x => x . EmptyDecimals . Select ( e => ( decimal ? ) e ) . AsQueryable ( ) . Average ( ) ) :
474
+ collection . AsQueryable ( ) . Select ( x => x . EmptyDecimals . Select ( e => ( decimal ? ) e ) . Average ( ) ) ;
475
+
476
+ var stages = Translate ( collection , queryable ) ;
477
+ AssertStages ( stages , "{ $project : { _v : { $avg : { $map : { input : '$EmptyDecimals', as : 'e', in : '$$e' } } }, _id : 0 } }" ) ;
478
+
479
+ var results = queryable . ToList ( ) ;
480
+ results . Should ( ) . Equal ( null , null , null ) ;
481
+ }
482
+
483
+ [ Theory ]
484
+ [ ParameterAttributeData ]
485
+ public void Average_with_selector_over_empty_set_of_non_nullable_values_cast_to_nullable_should_work (
486
+ [ Values ( false , true ) ] bool withNestedAsQueryable )
487
+ {
488
+ var collection = Fixture . Collection ;
489
+
490
+ var queryable = withNestedAsQueryable ?
491
+ collection . AsQueryable ( ) . Select ( x => x . EmptyDecimals . Select ( e => ( decimal ? ) e ) . AsQueryable ( ) . Average ( x => x * 2.0M ) ) :
492
+ collection . AsQueryable ( ) . Select ( x => x . EmptyDecimals . Select ( e => ( decimal ? ) e ) . Average ( x => x * 2.0M ) ) ;
493
+
494
+ var stages = Translate ( collection , queryable ) ;
495
+ AssertStages ( stages , "{ $project : { _v : { $avg : { $map : { input : { $map : { input : '$EmptyDecimals', as : 'e', in : '$$e' } }, as : 'x', in : { $multiply : ['$$x', { '$numberDecimal' : '2.0' }] } } } }, _id : 0 } }" ) ;
496
+
497
+ var results = queryable . ToList ( ) ;
498
+ results . Should ( ) . Equal ( null , null , null ) ;
499
+ }
500
+
394
501
public class C
395
502
{
396
503
public int Id { get ; set ; }
@@ -404,6 +511,8 @@ public class C
404
511
public float ? [ ] NullableFloats { get ; set ; }
405
512
public int ? [ ] NullableInts { get ; set ; }
406
513
public long ? [ ] NullableLongs { get ; set ; }
514
+ [ BsonRepresentation ( BsonType . Decimal128 ) ] public decimal [ ] EmptyDecimals { get ; set ; }
515
+ [ BsonRepresentation ( BsonType . Decimal128 ) ] public decimal ? [ ] EmptyNullableDecimals { get ; set ; }
407
516
}
408
517
409
518
public sealed class ClassFixture : MongoCollectionFixture < C >
@@ -422,7 +531,9 @@ public sealed class ClassFixture : MongoCollectionFixture<C>
422
531
NullableDoubles = new double ? [ 0 ] { } ,
423
532
NullableFloats = new float ? [ 0 ] { } ,
424
533
NullableInts = new int ? [ 0 ] { } ,
425
- NullableLongs = new long ? [ 0 ] { }
534
+ NullableLongs = new long ? [ 0 ] { } ,
535
+ EmptyDecimals = [ ] ,
536
+ EmptyNullableDecimals = [ ]
426
537
} ,
427
538
new C
428
539
{
@@ -436,7 +547,9 @@ public sealed class ClassFixture : MongoCollectionFixture<C>
436
547
NullableDoubles = new double ? [ ] { null } ,
437
548
NullableFloats = new float ? [ ] { null } ,
438
549
NullableInts = new int ? [ ] { null } ,
439
- NullableLongs = new long ? [ ] { null }
550
+ NullableLongs = new long ? [ ] { null } ,
551
+ EmptyDecimals = [ ] ,
552
+ EmptyNullableDecimals = [ ]
440
553
} ,
441
554
new C
442
555
{
@@ -450,7 +563,9 @@ public sealed class ClassFixture : MongoCollectionFixture<C>
450
563
NullableDoubles = new double ? [ ] { null , 1.0 , 2.0 , 3.0 } ,
451
564
NullableFloats = new float ? [ ] { null , 1.0F , 2.0F , 3.0F } ,
452
565
NullableInts = new int ? [ ] { null , 1 , 2 , 3 } ,
453
- NullableLongs = new long ? [ ] { null , 1L , 2L , 3L }
566
+ NullableLongs = new long ? [ ] { null , 1L , 2L , 3L } ,
567
+ EmptyDecimals = [ ] ,
568
+ EmptyNullableDecimals = [ ]
454
569
}
455
570
] ;
456
571
}
0 commit comments