mirror of
https://github.com/Biarity/Sieve.git
synced 2024-11-22 05:22:57 +01:00
Added case-insensitive operators and started unit tests project
This commit is contained in:
parent
aa6a836cfb
commit
2796197cc9
12
Sieve.sln
12
Sieve.sln
@ -1,11 +1,13 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.27130.2010
|
VisualStudioVersion = 15.0.27130.2027
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sieve", "Sieve\Sieve.csproj", "{B32B8B33-94B0-40E3-8FE5-D54602222717}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sieve", "Sieve\Sieve.csproj", "{B32B8B33-94B0-40E3-8FE5-D54602222717}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SieveTests", "SieveTests\SieveTests.csproj", "{8043D264-42A0-4275-97A1-46400C02E37E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SieveTests", "SieveTests\SieveTests.csproj", "{8043D264-42A0-4275-97A1-46400C02E37E}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SieveUnitTests", "SieveUnitTests\SieveUnitTests.csproj", "{21C3082D-F40E-457F-BE2E-AA099E19E199}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@ -21,6 +23,10 @@ Global
|
|||||||
{8043D264-42A0-4275-97A1-46400C02E37E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{8043D264-42A0-4275-97A1-46400C02E37E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{8043D264-42A0-4275-97A1-46400C02E37E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{8043D264-42A0-4275-97A1-46400C02E37E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{8043D264-42A0-4275-97A1-46400C02E37E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{8043D264-42A0-4275-97A1-46400C02E37E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{21C3082D-F40E-457F-BE2E-AA099E19E199}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{21C3082D-F40E-457F-BE2E-AA099E19E199}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{21C3082D-F40E-457F-BE2E-AA099E19E199}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{21C3082D-F40E-457F-BE2E-AA099E19E199}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -13,6 +13,6 @@ namespace Sieve.Models
|
|||||||
GreaterThanOrEqualTo,
|
GreaterThanOrEqualTo,
|
||||||
LessThanOrEqualTo,
|
LessThanOrEqualTo,
|
||||||
Contains,
|
Contains,
|
||||||
StartsWith
|
StartsWith,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,9 @@ namespace Sieve.Models
|
|||||||
{
|
{
|
||||||
private string _filter;
|
private string _filter;
|
||||||
private string[] operators = new string[] {
|
private string[] operators = new string[] {
|
||||||
|
"==*",
|
||||||
|
"@=*",
|
||||||
|
"_=*",
|
||||||
"==",
|
"==",
|
||||||
"!=",
|
"!=",
|
||||||
">",
|
">",
|
||||||
@ -16,7 +19,8 @@ namespace Sieve.Models
|
|||||||
">=",
|
">=",
|
||||||
"<=",
|
"<=",
|
||||||
"@=",
|
"@=",
|
||||||
"_=" };
|
"_="
|
||||||
|
};
|
||||||
|
|
||||||
public FilterTerm(string filter)
|
public FilterTerm(string filter)
|
||||||
{
|
{
|
||||||
@ -67,6 +71,7 @@ namespace Sieve.Models
|
|||||||
switch (Operator.Trim().ToLower())
|
switch (Operator.Trim().ToLower())
|
||||||
{
|
{
|
||||||
case "==":
|
case "==":
|
||||||
|
case "==*":
|
||||||
return FilterOperator.Equals;
|
return FilterOperator.Equals;
|
||||||
case "!=":
|
case "!=":
|
||||||
return FilterOperator.NotEquals;
|
return FilterOperator.NotEquals;
|
||||||
@ -79,8 +84,10 @@ namespace Sieve.Models
|
|||||||
case "<=":
|
case "<=":
|
||||||
return FilterOperator.LessThanOrEqualTo;
|
return FilterOperator.LessThanOrEqualTo;
|
||||||
case "@=":
|
case "@=":
|
||||||
|
case "@=*":
|
||||||
return FilterOperator.Contains;
|
return FilterOperator.Contains;
|
||||||
case "_=":
|
case "_=":
|
||||||
|
case "_=*":
|
||||||
return FilterOperator.StartsWith;
|
return FilterOperator.StartsWith;
|
||||||
default:
|
default:
|
||||||
return FilterOperator.Equals;
|
return FilterOperator.Equals;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Microsoft.Extensions.Options;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
@ -49,6 +49,14 @@ namespace Sieve.Services
|
|||||||
_options = options;
|
_options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply filtering, sorting, and pagination parameters found in `model` to `source`
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEntity"></typeparam>
|
||||||
|
/// <param name="model">An instance of ISieveModel</param>
|
||||||
|
/// <param name="source">Data source</param>
|
||||||
|
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
||||||
|
/// <returns>Returns a transformed version of `source`</returns>
|
||||||
public IQueryable<TEntity> ApplyAll<TEntity>(ISieveModel model, IQueryable<TEntity> source, object[] dataForCustomMethods = null)
|
public IQueryable<TEntity> ApplyAll<TEntity>(ISieveModel model, IQueryable<TEntity> source, object[] dataForCustomMethods = null)
|
||||||
{
|
{
|
||||||
var result = source;
|
var result = source;
|
||||||
@ -67,7 +75,112 @@ namespace Sieve.Services
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply filtering parameters found in `model` to `source`
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEntity"></typeparam>
|
||||||
|
/// <param name="model">An instance of ISieveModel</param>
|
||||||
|
/// <param name="source">Data source</param>
|
||||||
|
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
||||||
|
/// <returns>Returns a transformed version of `source`</returns>
|
||||||
|
public IQueryable<TEntity> ApplyFiltering<TEntity>(ISieveModel model, IQueryable<TEntity> result, object[] dataForCustomMethods = null)
|
||||||
|
{
|
||||||
|
if (model?.FiltersParsed == null)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
foreach (var filterTerm in model.FiltersParsed)
|
||||||
|
{
|
||||||
|
var property = GetSieveProperty<TEntity>(false, true, filterTerm.Name);
|
||||||
|
|
||||||
|
if (property != null)
|
||||||
|
{
|
||||||
|
var converter = TypeDescriptor.GetConverter(property.PropertyType);
|
||||||
|
var parameter = Expression.Parameter(typeof(TEntity), "e");
|
||||||
|
|
||||||
|
dynamic filterValue = Expression.Constant(
|
||||||
|
converter.CanConvertFrom(typeof(string)) ?
|
||||||
|
converter.ConvertFrom(filterTerm.Value) :
|
||||||
|
Convert.ChangeType(filterTerm.Value, property.PropertyType));
|
||||||
|
|
||||||
|
|
||||||
|
dynamic propertyValue = Expression.PropertyOrField(parameter, property.Name);
|
||||||
|
|
||||||
|
if (filterTerm.Operator.Contains("*"))
|
||||||
|
{
|
||||||
|
propertyValue = Expression.Call(propertyValue,
|
||||||
|
typeof(string).GetMethods()
|
||||||
|
.First(m => m.Name == "ToUpper" && m.GetParameters().Length == 0));
|
||||||
|
|
||||||
|
filterValue = Expression.Call(filterValue,
|
||||||
|
typeof(string).GetMethods()
|
||||||
|
.First(m => m.Name == "ToUpper" && m.GetParameters().Length == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression comparison;
|
||||||
|
|
||||||
|
switch (filterTerm.OperatorParsed)
|
||||||
|
{
|
||||||
|
case FilterOperator.Equals:
|
||||||
|
comparison = Expression.Equal(propertyValue, filterValue);
|
||||||
|
break;
|
||||||
|
case FilterOperator.NotEquals:
|
||||||
|
comparison = Expression.NotEqual(propertyValue, filterValue);
|
||||||
|
break;
|
||||||
|
case FilterOperator.GreaterThan:
|
||||||
|
comparison = Expression.GreaterThan(propertyValue, filterValue);
|
||||||
|
break;
|
||||||
|
case FilterOperator.LessThan:
|
||||||
|
comparison = Expression.LessThan(propertyValue, filterValue);
|
||||||
|
break;
|
||||||
|
case FilterOperator.GreaterThanOrEqualTo:
|
||||||
|
comparison = Expression.GreaterThanOrEqual(propertyValue, filterValue);
|
||||||
|
break;
|
||||||
|
case FilterOperator.LessThanOrEqualTo:
|
||||||
|
comparison = Expression.LessThanOrEqual(propertyValue, filterValue);
|
||||||
|
break;
|
||||||
|
case FilterOperator.Contains:
|
||||||
|
comparison = Expression.Call(propertyValue,
|
||||||
|
typeof(string).GetMethods()
|
||||||
|
.First(m => m.Name == "Contains" && m.GetParameters().Length == 1),
|
||||||
|
filterValue);
|
||||||
|
break;
|
||||||
|
case FilterOperator.StartsWith:
|
||||||
|
comparison = Expression.Call(propertyValue,
|
||||||
|
typeof(string).GetMethods()
|
||||||
|
.First(m => m.Name == "StartsWith" && m.GetParameters().Length == 1),
|
||||||
|
filterValue); break;
|
||||||
|
default:
|
||||||
|
comparison = Expression.Equal(propertyValue, filterValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = result.Where(Expression.Lambda<Func<TEntity, bool>>(
|
||||||
|
comparison,
|
||||||
|
parameter));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = ApplyCustomMethod(result, filterTerm.Name, _customFilterMethods,
|
||||||
|
new object[] {
|
||||||
|
result,
|
||||||
|
filterTerm.Operator,
|
||||||
|
filterTerm.Value
|
||||||
|
}, dataForCustomMethods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply sorting parameters found in `model` to `source`
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEntity"></typeparam>
|
||||||
|
/// <param name="model">An instance of ISieveModel</param>
|
||||||
|
/// <param name="source">Data source</param>
|
||||||
|
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
||||||
|
/// <returns>Returns a transformed version of `source`</returns>
|
||||||
public IQueryable<TEntity> ApplySorting<TEntity>(ISieveModel model, IQueryable<TEntity> result, object[] dataForCustomMethods = null)
|
public IQueryable<TEntity> ApplySorting<TEntity>(ISieveModel model, IQueryable<TEntity> result, object[] dataForCustomMethods = null)
|
||||||
{
|
{
|
||||||
if (model?.SortsParsed == null)
|
if (model?.SortsParsed == null)
|
||||||
@ -97,84 +210,15 @@ namespace Sieve.Services
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQueryable<TEntity> ApplyFiltering<TEntity>(ISieveModel model, IQueryable<TEntity> result, object[] dataForCustomMethods = null)
|
|
||||||
{
|
|
||||||
if (model?.FiltersParsed == null)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
foreach (var filterTerm in model.FiltersParsed)
|
|
||||||
{
|
|
||||||
var property = GetSieveProperty<TEntity>(false, true, filterTerm.Name);
|
|
||||||
|
|
||||||
if (property != null)
|
|
||||||
{
|
|
||||||
var converter = TypeDescriptor.GetConverter(property.PropertyType);
|
|
||||||
var parameter = Expression.Parameter(typeof(TEntity), "e");
|
|
||||||
|
|
||||||
var filterValue = Expression.Constant(
|
|
||||||
converter.CanConvertFrom(typeof(string)) ?
|
|
||||||
converter.ConvertFrom(filterTerm.Value) :
|
|
||||||
Convert.ChangeType(filterTerm.Value, property.PropertyType));
|
|
||||||
|
|
||||||
var propertyValue = Expression.PropertyOrField(parameter, property.Name);
|
|
||||||
|
|
||||||
Expression comparison;
|
|
||||||
|
|
||||||
switch (filterTerm.OperatorParsed)
|
|
||||||
{
|
|
||||||
case FilterOperator.Equals:
|
|
||||||
comparison = Expression.Equal(propertyValue, filterValue);
|
|
||||||
break;
|
|
||||||
case FilterOperator.NotEquals:
|
|
||||||
comparison = Expression.NotEqual(propertyValue, filterValue);
|
|
||||||
break;
|
|
||||||
case FilterOperator.GreaterThan:
|
|
||||||
comparison = Expression.GreaterThan(propertyValue, filterValue);
|
|
||||||
break;
|
|
||||||
case FilterOperator.LessThan:
|
|
||||||
comparison = Expression.LessThan(propertyValue, filterValue);
|
|
||||||
break;
|
|
||||||
case FilterOperator.GreaterThanOrEqualTo:
|
|
||||||
comparison = Expression.GreaterThanOrEqual(propertyValue, filterValue);
|
|
||||||
break;
|
|
||||||
case FilterOperator.LessThanOrEqualTo:
|
|
||||||
comparison = Expression.LessThanOrEqual(propertyValue, filterValue);
|
|
||||||
break;
|
|
||||||
case FilterOperator.Contains:
|
|
||||||
comparison = Expression.Call(propertyValue,
|
|
||||||
typeof(string).GetMethods()
|
|
||||||
.First(m => m.Name == "Contains" && m.GetParameters().Length == 1),
|
|
||||||
filterValue);
|
|
||||||
break;
|
|
||||||
case FilterOperator.StartsWith:
|
|
||||||
comparison = Expression.Call(propertyValue,
|
|
||||||
typeof(string).GetMethods()
|
|
||||||
.First(m => m.Name == "StartsWith" && m.GetParameters().Length == 1),
|
|
||||||
filterValue); break;
|
|
||||||
default:
|
|
||||||
comparison = Expression.Equal(propertyValue, filterValue);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = result.Where(Expression.Lambda<Func<TEntity, bool>>(
|
|
||||||
comparison,
|
|
||||||
parameter));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = ApplyCustomMethod(result, filterTerm.Name, _customFilterMethods,
|
|
||||||
new object[] {
|
|
||||||
result,
|
|
||||||
filterTerm.Operator,
|
|
||||||
filterTerm.Value
|
|
||||||
}, dataForCustomMethods);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply pagination parameters found in `model` to `source`
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEntity"></typeparam>
|
||||||
|
/// <param name="model">An instance of ISieveModel</param>
|
||||||
|
/// <param name="source">Data source</param>
|
||||||
|
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
||||||
|
/// <returns>Returns a transformed version of `source`</returns>
|
||||||
public IQueryable<TEntity> ApplyPagination<TEntity>(ISieveModel model, IQueryable<TEntity> result)
|
public IQueryable<TEntity> ApplyPagination<TEntity>(ISieveModel model, IQueryable<TEntity> result)
|
||||||
{
|
{
|
||||||
var page = model?.Page ?? 1;
|
var page = model?.Page ?? 1;
|
||||||
@ -188,7 +232,7 @@ namespace Sieve.Services
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyInfo GetSieveProperty<TEntity>(bool canSortRequired, bool canFilterRequired, string name)
|
private PropertyInfo GetSieveProperty<TEntity>(bool canSortRequired, bool canFilterRequired, string name)
|
||||||
{
|
{
|
||||||
return typeof(TEntity).GetProperties().FirstOrDefault(p =>
|
return typeof(TEntity).GetProperties().FirstOrDefault(p =>
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Sieve</id>
|
<id>Sieve</id>
|
||||||
<version>1.3.7</version>
|
<version>1.3.8</version>
|
||||||
<title>Sieve</title>
|
<title>Sieve</title>
|
||||||
<authors>Biarity</authors>
|
<authors>Biarity</authors>
|
||||||
<owners>Biarity</owners>
|
<owners>Biarity</owners>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<description>
|
<description>
|
||||||
Sieve is a simple, clean, and extensible framework for .NET Core that adds sorting, filtering, and pagination functionality out of the box. Most common use case would be for serving ASP.NET Core GET queries. Documentation available on GitHub: https://github.com/Biarity/Sieve/
|
Sieve is a simple, clean, and extensible framework for .NET Core that adds sorting, filtering, and pagination functionality out of the box. Most common use case would be for serving ASP.NET Core GET queries. Documentation available on GitHub: https://github.com/Biarity/Sieve/
|
||||||
</description>
|
</description>
|
||||||
<releaseNotes>Custom operators no longer supported for simplicity</releaseNotes>
|
<releaseNotes>Filter before sort</releaseNotes>
|
||||||
<copyright>Copyright 2018</copyright>
|
<copyright>Copyright 2018</copyright>
|
||||||
<tags>aspnetcore filter sort page paginate sieve search</tags>
|
<tags>aspnetcore filter sort page paginate sieve search</tags>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
25
SieveUnitTests/Entities/Post.cs
Normal file
25
SieveUnitTests/Entities/Post.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Sieve.Attributes;
|
||||||
|
|
||||||
|
namespace SieveUnitTests.Entities
|
||||||
|
{
|
||||||
|
public class Post
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
|
public string Title { get; set; } = Guid.NewGuid().ToString().Replace("-", string.Empty).Substring(0, 8);
|
||||||
|
|
||||||
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
|
public int LikeCount { get; set; } = new Random().Next(0, 1000);
|
||||||
|
|
||||||
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
|
public int CommentCount { get; set; } = new Random().Next(0, 1000);
|
||||||
|
|
||||||
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
|
public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow;
|
||||||
|
}
|
||||||
|
}
|
97
SieveUnitTests/General.cs
Normal file
97
SieveUnitTests/General.cs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Sieve.Models;
|
||||||
|
using Sieve.Services;
|
||||||
|
using SieveUnitTests.Entities;
|
||||||
|
using SieveUnitTests.Services;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SieveUnitTests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class General
|
||||||
|
{
|
||||||
|
private SieveProcessor _processor;
|
||||||
|
private IQueryable<Post> _posts;
|
||||||
|
|
||||||
|
public General()
|
||||||
|
{
|
||||||
|
_processor = new SieveProcessor(new SieveOptionsAccessor(),
|
||||||
|
new SieveCustomSortMethods(),
|
||||||
|
new SieveCustomFilterMethods());
|
||||||
|
|
||||||
|
_posts = new List<Post>
|
||||||
|
{
|
||||||
|
new Post() {
|
||||||
|
Id = 0,
|
||||||
|
Title = "A",
|
||||||
|
LikeCount = 100
|
||||||
|
},
|
||||||
|
new Post() {
|
||||||
|
Id = 1,
|
||||||
|
Title = "B",
|
||||||
|
LikeCount = 50
|
||||||
|
},
|
||||||
|
new Post() {
|
||||||
|
Id = 2,
|
||||||
|
Title = "C",
|
||||||
|
LikeCount = 0
|
||||||
|
},
|
||||||
|
}.AsQueryable();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ContainsCanBeCaseInsensitive()
|
||||||
|
{
|
||||||
|
var model = new SieveModel()
|
||||||
|
{
|
||||||
|
Filters = "Title@=*a"
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = _processor.ApplyFiltering(model, _posts);
|
||||||
|
|
||||||
|
Assert.AreEqual(result.First().Id, 0);
|
||||||
|
Assert.IsTrue(result.Count() == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ContainsIsCaseSensitive()
|
||||||
|
{
|
||||||
|
var model = new SieveModel()
|
||||||
|
{
|
||||||
|
Filters = "Title@=a",
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = _processor.ApplyFiltering(model, _posts);
|
||||||
|
|
||||||
|
Assert.IsTrue(result.Count() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void EqualsDoesntFailWithNonStringTypes()
|
||||||
|
{
|
||||||
|
var model = new SieveModel()
|
||||||
|
{
|
||||||
|
Filters = "LikeCount==50",
|
||||||
|
};
|
||||||
|
|
||||||
|
Console.WriteLine(model.FiltersParsed.First().Value);
|
||||||
|
Console.WriteLine(model.FiltersParsed.First().Operator);
|
||||||
|
Console.WriteLine(model.FiltersParsed.First().OperatorParsed);
|
||||||
|
|
||||||
|
var result = _processor.ApplyFiltering(model, _posts);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Assert.AreEqual(result.First().Id, 1);
|
||||||
|
Assert.IsTrue(result.Count() == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//Sorts = "LikeCount",
|
||||||
|
//Page = 1,
|
||||||
|
//PageSize = 10
|
||||||
|
//
|
20
SieveUnitTests/Services/SieveCustomFilterMethods.cs
Normal file
20
SieveUnitTests/Services/SieveCustomFilterMethods.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using Sieve.Services;
|
||||||
|
using SieveUnitTests.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SieveUnitTests.Services
|
||||||
|
{
|
||||||
|
public class SieveCustomFilterMethods : ISieveCustomFilterMethods
|
||||||
|
{
|
||||||
|
public IQueryable<Post> IsNew(IQueryable<Post> source, string op, string value)
|
||||||
|
{
|
||||||
|
var result = source.Where(p => p.LikeCount < 100 &&
|
||||||
|
p.CommentCount < 5);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
SieveUnitTests/Services/SieveCustomSortMethods.cs
Normal file
23
SieveUnitTests/Services/SieveCustomSortMethods.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using Sieve.Services;
|
||||||
|
using SieveUnitTests.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SieveUnitTests.Services
|
||||||
|
{
|
||||||
|
public class SieveCustomSortMethods : ISieveCustomSortMethods
|
||||||
|
{
|
||||||
|
public IQueryable<Post> Popularity(IQueryable<Post> source, bool useThenBy, bool desc)
|
||||||
|
{
|
||||||
|
var result = useThenBy ?
|
||||||
|
((IOrderedQueryable<Post>)source).ThenBy(p => p.LikeCount) :
|
||||||
|
source.OrderBy(p => p.LikeCount)
|
||||||
|
.ThenBy(p => p.CommentCount)
|
||||||
|
.ThenBy(p => p.DateCreated);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
SieveUnitTests/Services/SieveOptionsAccessor.cs
Normal file
26
SieveUnitTests/Services/SieveOptionsAccessor.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Sieve.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SieveUnitTests
|
||||||
|
{
|
||||||
|
public class SieveOptionsAccessor : IOptions<SieveOptions>
|
||||||
|
{
|
||||||
|
private SieveOptions _value;
|
||||||
|
|
||||||
|
public SieveOptions Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SieveOptionsAccessor()
|
||||||
|
{
|
||||||
|
_value = new SieveOptions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
SieveUnitTests/SieveUnitTests.csproj
Normal file
19
SieveUnitTests/SieveUnitTests.csproj
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" Version="1.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Sieve\Sieve.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -1,6 +1,6 @@
|
|||||||
### 1. Pack:
|
### 1. Pack:
|
||||||
```
|
```
|
||||||
dotnet pack Sieve.csproj -c Release -o . /p:PackageVersion=1.3.4
|
dotnet pack Sieve.csproj -c Release -o . /p:PackageVersion=1.3.8
|
||||||
```
|
```
|
||||||
Don't forget to change version since nuget packages are immutable (add one to the nuget current).
|
Don't forget to change version since nuget packages are immutable (add one to the nuget current).
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ Also don't forget updaing `releaseNotes` in nuspec.
|
|||||||
|
|
||||||
### 3. Publish:
|
### 3. Publish:
|
||||||
```
|
```
|
||||||
nuget push Sieve.1.2.0.nupkg API_KEY -Source https://api.nuget.org/v3/index.json
|
nuget push Sieve.1.3.8.nupkg API_KEY -Source https://api.nuget.org/v3/index.json
|
||||||
```
|
```
|
||||||
Replace API_KEY with one you get from nuget's website.
|
Replace API_KEY with one you get from nuget's website.
|
||||||
Also don't forget to replace corresponding version.
|
Also don't forget to replace corresponding version.
|
||||||
|
Loading…
Reference in New Issue
Block a user