added tests for the sumbyasync methods

This commit is contained in:
Alexandre SPIESER
2019-02-04 23:11:36 +00:00
parent eaa90d67f5
commit 4ac0ffe91c
8 changed files with 158 additions and 19 deletions
@@ -9,13 +9,16 @@
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="2.1.2" /> <PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="2.1.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
<PackageReference Include="MongoDB.Driver" Version="2.7.0" /> <PackageReference Include="MongoDB.Driver" Version="2.7.0" />
<PackageReference Include="MongoDbGenericRepository" Version="1.3.8" />
<PackageReference Include="xunit" Version="2.4.0" /> <PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.console" Version="2.4.0" /> <PackageReference Include="xunit.runner.console" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0-beta4-build3742" /> <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0-beta4-build3742" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MongoDbGenericRepository\MongoDbGenericRepository.csproj" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System.Configuration"> <Reference Include="System.Configuration">
<HintPath>..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Configuration.dll</HintPath> <HintPath>..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Configuration.dll</HintPath>
@@ -1075,6 +1075,33 @@ namespace CoreIntegrationTests.Infrastructure
#endregion Index Management #endregion Index Management
#region Math
[Fact]
public async Task SumByAsync()
{
// Arrange
var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}";
var documents = CreateTestDocuments(5);
var i = 1;
documents.ForEach(e =>
{
e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++);
e.Nested.SomeAmount = 5m;
e.SomeContent = criteria;
});
SUT.AddMany<T>(documents);
var expectedSum = documents.Sum(e => e.Nested.SomeAmount);
// Act
var result = await SUT.SumByAsync<T>(e => e.SomeContent == criteria, e => e.Nested.SomeAmount, PartitionKey);
// Assert
Assert.Equal(expectedSum, result);
}
#endregion Math
#region Test Utils #region Test Utils
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
@@ -1068,6 +1068,33 @@ namespace CoreIntegrationTests.Infrastructure
#endregion Index Management #endregion Index Management
#region Math
[Fact]
public async Task SumByAsync()
{
// Arrange
var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}";
var documents = CreateTestDocuments(5);
var i = 1;
documents.ForEach(e =>
{
e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++);
e.Nested.SomeAmount = 5m;
e.SomeContent = criteria;
});
SUT.AddMany<T, TKey>(documents);
var expectedSum = documents.Sum(e => e.Nested.SomeAmount);
// Act
var result = await SUT.SumByAsync<T, TKey>(e => e.SomeContent == criteria, e => e.Nested.SomeAmount, PartitionKey);
// Assert
Assert.Equal(expectedSum, result);
}
#endregion Math
#region Test Utils #region Test Utils
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
private string GetCurrentMethod() private string GetCurrentMethod()
@@ -1,4 +1,5 @@
using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models; using MongoDbGenericRepository.Models;
using MongoDbGenericRepository.Utils; using MongoDbGenericRepository.Utils;
using System; using System;
@@ -21,6 +22,8 @@ namespace CoreIntegrationTests.Infrastructure
public class Nested public class Nested
{ {
public DateTime SomeDate { get; set; } public DateTime SomeDate { get; set; }
[BsonRepresentation(BsonType.Decimal128)]
public decimal SomeAmount { get; set; }
} }
public class Child public class Child
@@ -425,6 +425,34 @@ namespace MongoDbGenericRepository
where TKey : IEquatable<TKey>; where TKey : IEquatable<TKey>;
#endregion #endregion
#region Sum
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
Task<decimal> SumByAsync<TDocument>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, decimal>> selector,
string partitionKey = null)
where TDocument : IDocument;
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
Task<decimal> SumByAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, decimal>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
#endregion Sum
} }
} }
@@ -1022,10 +1022,46 @@ namespace MongoDbGenericRepository
/// </summary> /// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam> /// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param> /// <param name="filter">A LINQ expression filter.</param>
/// <param name="sortSelector">The property selector.</param>
/// <param name="ascending">Order of the sorting.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param> /// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param> /// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param> /// <param name="partitionKey">An optional partition key.</param>
public virtual async Task<List<TDocument>> GetPaginatedAsync<TDocument>(Expression<Func<TDocument, bool>> filter, int skipNumber = 0, int takeNumber = 50, string partitionKey = null) public virtual async Task<List<TDocument>> GetSortedPaginatedAsync<TDocument>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, object>> sortSelector,
bool ascending = true,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null)
where TDocument : IDocument
{
var sorting = ascending
? Builders<TDocument>.Sort.Ascending(sortSelector)
: Builders<TDocument>.Sort.Descending(sortSelector);
return await HandlePartitioned<TDocument>(partitionKey)
.Find(filter)
.Sort(sorting)
.Skip(skipNumber)
.Limit(takeNumber)
.ToListAsync();
}
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual async Task<List<TDocument>> GetPaginatedAsync<TDocument>(
Expression<Func<TDocument, bool>> filter,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null)
where TDocument : IDocument where TDocument : IDocument
{ {
return await HandlePartitioned<TDocument>(partitionKey).Find(filter).Skip(skipNumber).Limit(takeNumber).ToListAsync(); return await HandlePartitioned<TDocument>(partitionKey).Find(filter).Skip(skipNumber).Limit(takeNumber).ToListAsync();
@@ -12,7 +12,7 @@ namespace MongoDbGenericRepository
/// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation. /// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation.
/// Its constructor must be given a connection string and a database name. /// Its constructor must be given a connection string and a database name.
/// </summary> /// </summary>
public abstract partial class BaseMongoRepository : ReadOnlyMongoRepository, IBaseMongoRepository public abstract partial class ReadOnlyMongoRepository
{ {
/// <summary> /// <summary>
/// Sums the values of a selected field for a given filtered collection of documents. /// Sums the values of a selected field for a given filtered collection of documents.
@@ -26,11 +26,26 @@ namespace MongoDbGenericRepository
string partitionKey = null) string partitionKey = null)
where TDocument : IDocument where TDocument : IDocument
{ {
var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection<TDocument>() : GetCollection<TDocument>(partitionKey); return await SumByAsync<TDocument, Guid>(filter, selector, partitionKey);
}
return await collection.AsQueryable() /// <summary>
.Where(filter) /// Sums the values of a selected field for a given filtered collection of documents.
.SumAsync(selector); /// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
public virtual async Task<decimal> SumByAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, decimal>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await GetCollection<TDocument, TKey>(partitionKey)
.AsQueryable()
.Where(filter)
.SumAsync(selector);
} }
} }
@@ -11,7 +11,7 @@ namespace MongoDbGenericRepository
/// <summary> /// <summary>
/// The ReadOnlyMongoRepository implements the readonly functionality of the IReadOnlyMongoRepository. /// The ReadOnlyMongoRepository implements the readonly functionality of the IReadOnlyMongoRepository.
/// </summary> /// </summary>
public class ReadOnlyMongoRepository : IReadOnlyMongoRepository public abstract partial class ReadOnlyMongoRepository : IReadOnlyMongoRepository
{ {
/// <summary> /// <summary>
/// The connection string. /// The connection string.
@@ -578,7 +578,7 @@ namespace MongoDbGenericRepository
/// <param name="filter">A LINQ expression filter.</param> /// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param> /// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param> /// <param name="partitionKey">An optional partition key.</param>
public async Task<TValue> GetMinValueAsync<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null) public virtual async Task<TValue> GetMinValueAsync<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument where TDocument : IDocument
{ {
return await GetMinValueAsync<TDocument, Guid, TValue>(filter, minValueSelector, partitionKey); return await GetMinValueAsync<TDocument, Guid, TValue>(filter, minValueSelector, partitionKey);
@@ -593,7 +593,7 @@ namespace MongoDbGenericRepository
/// <param name="filter">A LINQ expression filter.</param> /// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param> /// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param> /// <param name="partitionKey">An optional partition key.</param>
public async Task<TValue> GetMinValueAsync<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null) public virtual async Task<TValue> GetMinValueAsync<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey> where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey> where TKey : IEquatable<TKey>
{ {
@@ -608,7 +608,7 @@ namespace MongoDbGenericRepository
/// <param name="filter">A LINQ expression filter.</param> /// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param> /// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param> /// <param name="partitionKey">An optional partition key.</param>
public TValue GetMinValue<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null) public virtual TValue GetMinValue<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument where TDocument : IDocument
{ {
return GetMinValue<TDocument, Guid, TValue>(filter, minValueSelector, partitionKey); return GetMinValue<TDocument, Guid, TValue>(filter, minValueSelector, partitionKey);
@@ -623,7 +623,7 @@ namespace MongoDbGenericRepository
/// <param name="filter">A LINQ expression filter.</param> /// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param> /// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param> /// <param name="partitionKey">An optional partition key.</param>
public TValue GetMinValue<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null) public virtual TValue GetMinValue<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey> where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey> where TKey : IEquatable<TKey>
{ {
@@ -640,7 +640,7 @@ namespace MongoDbGenericRepository
/// <typeparam name="TDocument">The document type.</typeparam> /// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="partitionKey">An optional partition key.</param> /// <param name="partitionKey">An optional partition key.</param>
/// <returns>An <see cref="IMongoCollection{TDocument}"/></returns> /// <returns>An <see cref="IMongoCollection{TDocument}"/></returns>
protected IMongoCollection<TDocument> GetCollection<TDocument>(string partitionKey = null) where TDocument : IDocument protected virtual IMongoCollection<TDocument> GetCollection<TDocument>(string partitionKey = null) where TDocument : IDocument
{ {
return MongoDbContext.GetCollection<TDocument>(partitionKey); return MongoDbContext.GetCollection<TDocument>(partitionKey);
} }
@@ -651,7 +651,7 @@ namespace MongoDbGenericRepository
/// <typeparam name="TDocument">The document type.</typeparam> /// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="document">The document.</param> /// <param name="document">The document.</param>
/// <returns></returns> /// <returns></returns>
protected IMongoCollection<TDocument> HandlePartitioned<TDocument>(TDocument document) where TDocument : IDocument protected virtual IMongoCollection<TDocument> HandlePartitioned<TDocument>(TDocument document) where TDocument : IDocument
{ {
if (document is IPartitionedDocument) if (document is IPartitionedDocument)
{ {
@@ -667,7 +667,7 @@ namespace MongoDbGenericRepository
/// <typeparam name="TKey">The type of the primary key.</typeparam> /// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="document">The document.</param> /// <param name="document">The document.</param>
/// <returns></returns> /// <returns></returns>
protected IMongoCollection<TDocument> HandlePartitioned<TDocument, TKey>(TDocument document) protected virtual IMongoCollection<TDocument> HandlePartitioned<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey> where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey> where TKey : IEquatable<TKey>
{ {
@@ -684,7 +684,7 @@ namespace MongoDbGenericRepository
/// <typeparam name="TDocument">The document type.</typeparam> /// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="partitionKey">The collection partition key.</param> /// <param name="partitionKey">The collection partition key.</param>
/// <returns></returns> /// <returns></returns>
protected IMongoCollection<TDocument> HandlePartitioned<TDocument>(string partitionKey) where TDocument : IDocument protected virtual IMongoCollection<TDocument> HandlePartitioned<TDocument>(string partitionKey) where TDocument : IDocument
{ {
if (!string.IsNullOrEmpty(partitionKey)) if (!string.IsNullOrEmpty(partitionKey))
{ {
@@ -700,7 +700,7 @@ namespace MongoDbGenericRepository
/// <typeparam name="TKey">The type of the primary key.</typeparam> /// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="partitionKey">The collection partition key.</param> /// <param name="partitionKey">The collection partition key.</param>
/// <returns></returns> /// <returns></returns>
protected IMongoCollection<TDocument> GetCollection<TDocument, TKey>(string partitionKey = null) protected virtual IMongoCollection<TDocument> GetCollection<TDocument, TKey>(string partitionKey = null)
where TDocument : IDocument<TKey> where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey> where TKey : IEquatable<TKey>
{ {
@@ -714,7 +714,7 @@ namespace MongoDbGenericRepository
/// <typeparam name="TKey">The type of the primary key.</typeparam> /// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="partitionKey">The collection partition key.</param> /// <param name="partitionKey">The collection partition key.</param>
/// <returns></returns> /// <returns></returns>
protected IMongoCollection<TDocument> HandlePartitioned<TDocument, TKey>(string partitionKey) protected virtual IMongoCollection<TDocument> HandlePartitioned<TDocument, TKey>(string partitionKey)
where TDocument : IDocument<TKey> where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey> where TKey : IEquatable<TKey>
{ {