1313* limitations under the License.
1414*/
1515
16+ using System ;
1617using System . Collections . Generic ;
1718using System . Linq ;
1819using FluentAssertions ;
@@ -391,6 +392,112 @@ public void Average_with_nullable_longs_selector_should_work(
391392 results . Should ( ) . Equal ( null , null , 4.0 ) ;
392393 }
393394
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+
394501 public class C
395502 {
396503 public int Id { get ; set ; }
@@ -404,6 +511,8 @@ public class C
404511 public float ? [ ] NullableFloats { get ; set ; }
405512 public int ? [ ] NullableInts { get ; set ; }
406513 public long ? [ ] NullableLongs { get ; set ; }
514+ [ BsonRepresentation ( BsonType . Decimal128 ) ] public decimal [ ] EmptyDecimals { get ; set ; }
515+ [ BsonRepresentation ( BsonType . Decimal128 ) ] public decimal ? [ ] EmptyNullableDecimals { get ; set ; }
407516 }
408517
409518 public sealed class ClassFixture : MongoCollectionFixture < C >
@@ -422,7 +531,9 @@ public sealed class ClassFixture : MongoCollectionFixture<C>
422531 NullableDoubles = new double ? [ 0 ] { } ,
423532 NullableFloats = new float ? [ 0 ] { } ,
424533 NullableInts = new int ? [ 0 ] { } ,
425- NullableLongs = new long ? [ 0 ] { }
534+ NullableLongs = new long ? [ 0 ] { } ,
535+ EmptyDecimals = [ ] ,
536+ EmptyNullableDecimals = [ ]
426537 } ,
427538 new C
428539 {
@@ -436,7 +547,9 @@ public sealed class ClassFixture : MongoCollectionFixture<C>
436547 NullableDoubles = new double ? [ ] { null } ,
437548 NullableFloats = new float ? [ ] { null } ,
438549 NullableInts = new int ? [ ] { null } ,
439- NullableLongs = new long ? [ ] { null }
550+ NullableLongs = new long ? [ ] { null } ,
551+ EmptyDecimals = [ ] ,
552+ EmptyNullableDecimals = [ ]
440553 } ,
441554 new C
442555 {
@@ -450,7 +563,9 @@ public sealed class ClassFixture : MongoCollectionFixture<C>
450563 NullableDoubles = new double ? [ ] { null , 1.0 , 2.0 , 3.0 } ,
451564 NullableFloats = new float ? [ ] { null , 1.0F , 2.0F , 3.0F } ,
452565 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 = [ ]
454569 }
455570 ] ;
456571 }
0 commit comments