Skip to content

Commit 1923b43

Browse files
committed
OrderBy Tests
1 parent 2b9c052 commit 1923b43

File tree

10 files changed

+226
-27
lines changed

10 files changed

+226
-27
lines changed

src/AutSoft.Linq/Queryable/OrderByExtensions.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public static IOrderedQueryable<TSource> ThenBy<TSource, TKey>(
8080
public static IOrderedQueryable<TSource> OrderBy<TSource>(
8181
this IQueryable<TSource> source,
8282
PageRequest pageRequest,
83-
Expression<Func<TSource, object>> defaultOrderingSelector)
83+
Expression<Func<TSource, object?>> defaultOrderingSelector)
8484
{
8585
return source.OrderBy(
8686
string.IsNullOrEmpty(pageRequest.OrderBy)
@@ -103,7 +103,7 @@ public static IOrderedQueryable<TSource> OrderBy<TSource>(
103103
public static IOrderedQueryable<TSource> OrderBy<TSource, TDto>(
104104
this IQueryable<TSource> source,
105105
PageRequest pageRequest,
106-
Expression<Func<TSource, object>> defaultOrderingSelector,
106+
Expression<Func<TSource, object?>> defaultOrderingSelector,
107107
IConfigurationProvider mappings)
108108
{
109109
var orderKeySelector = GetOrderKeySelector<TSource, TDto>(pageRequest, defaultOrderingSelector, mappings);
@@ -126,7 +126,7 @@ public static IOrderedQueryable<TSource> OrderBy<TSource, TDto>(
126126
public static IOrderedQueryable<TSource> OrderBy<TSource, TDto>(
127127
this IQueryable<TSource> source,
128128
PageRequest pageRequest,
129-
Expression<Func<TSource, object>> defaultOrderingSelector,
129+
Expression<Func<TSource, object?>> defaultOrderingSelector,
130130
OrderDirection defaultOrderDirection,
131131
IConfigurationProvider mappings)
132132
{
@@ -138,9 +138,9 @@ public static IOrderedQueryable<TSource> OrderBy<TSource, TDto>(
138138
return source.OrderBy(orderKeySelector, pageRequest.OrderDirection);
139139
}
140140

141-
private static Expression<Func<TSource, object>> GetOrderKeySelector<TSource, TDto>(
141+
private static Expression<Func<TSource, object?>> GetOrderKeySelector<TSource, TDto>(
142142
PageRequest pageRequest,
143-
Expression<Func<TSource, object>> defaultOrderingSelector,
143+
Expression<Func<TSource, object?>> defaultOrderingSelector,
144144
IConfigurationProvider mappings)
145145
{
146146
if (!string.IsNullOrEmpty(pageRequest.OrderBy))
@@ -161,7 +161,7 @@ private static Expression<Func<TSource, object>> GetOrderKeySelector<TSource, TD
161161
?.CustomMapExpression;
162162

163163
orderKeySelector = expression != null
164-
? Expression.Lambda<Func<TSource, object>>(Expression.Convert(expression.Body, typeof(object)), expression.Parameters)
164+
? Expression.Lambda<Func<TSource, object?>>(Expression.Convert(expression.Body, typeof(object)), expression.Parameters)
165165
: e => EF.Property<object>(e!, pageRequest.OrderBy);
166166
}
167167

test/AutSoft.Linq.Tests/AutSoft.Linq.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
1717
<PackageReference Include="Moq" Version="4.18.2" />
1818
<PackageReference Include="xunit" Version="2.4.1" />
19+
<PackageReference Include="Xunit.Combinatorial" Version="1.5.7-beta" />
1920
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
2021
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2122
<PrivateAssets>all</PrivateAssets>
Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
1-
namespace AutSoft.Linq.Tests.Queryable.OrderByExtensions;
1+
using AutSoft.Linq.Models;
2+
using AutSoft.Linq.Queryable;
3+
4+
using FluentAssertions;
5+
6+
namespace AutSoft.Linq.Tests.Queryable.OrderByExtensions;
27

38
public partial class OrderByFluent : OrderByExtensionsTests
49
{
10+
[Theory]
11+
[InlineData(OrderDirection.Ascending)]
12+
[InlineData(OrderDirection.Descending)]
13+
public void Should_ReturnOrdered(OrderDirection orderDirection)
14+
{
15+
// Act
16+
var ordered = Subject.OrderBy(x => x.Name, orderDirection).ToList();
17+
18+
// Assert
19+
ordered.Should().HaveCount(Subject.Count());
20+
_ = orderDirection switch
21+
{
22+
OrderDirection.Ascending => ordered.Should().BeInAscendingOrder(p => p.Name),
23+
OrderDirection.Descending => ordered.Should().BeInDescendingOrder(p => p.Name),
24+
_ => throw new NotSupportedException(),
25+
};
26+
}
527
}
Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,46 @@
1-
namespace AutSoft.Linq.Tests.Queryable.OrderByExtensions;
1+
using AutSoft.Linq.Models;
2+
using AutSoft.Linq.Queryable;
3+
4+
using FluentAssertions;
5+
6+
using System.Linq.Expressions;
7+
8+
namespace AutSoft.Linq.Tests.Queryable.OrderByExtensions;
29

310
public partial class OrderByFromEFModel : OrderByExtensionsTests
411
{
12+
public static List<(string orderColumn, Expression<Func<Person, object?>> expectedOrderExpression)> DefaultOrderExpression() => new()
13+
{
14+
(nameof(Person.Id), p => p.Id),
15+
(nameof(Person.Name), p => p.Name),
16+
(nameof(Person.Address), p => p.Address),
17+
(nameof(Person.DateOfBirth), p => p.DateOfBirth),
18+
};
19+
20+
[Theory]
21+
[CombinatorialData]
22+
public void Should_ReturnOrdered(
23+
[CombinatorialMemberData(nameof(DefaultOrderExpression))] (string orderColumn, Expression<Func<Person, object?>> expectedOrderExpression) ordering,
24+
OrderDirection orderDirection)
25+
{
26+
// Act
27+
var ordered = Subject
28+
.OrderBy(new PageRequest { OrderBy = ordering.orderColumn, OrderDirection = orderDirection }, p => p.Id)
29+
.ToList();
30+
31+
// Assert
32+
ordered.Should().HaveCount(Subject.Count());
33+
if (orderDirection is OrderDirection.Ascending)
34+
{
35+
ordered.Should().BeInAscendingOrder(ordering.expectedOrderExpression);
36+
}
37+
else if (orderDirection is OrderDirection.Descending)
38+
{
39+
ordered.Should().BeInDescendingOrder(ordering.expectedOrderExpression);
40+
}
41+
else
42+
{
43+
throw new NotSupportedException("Not valid test case input");
44+
}
45+
}
546
}
Lines changed: 113 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using AutoMapper.QueryableExtensions;
22

3+
using AutSoft.Common.Exceptions;
34
using AutSoft.Linq.Models;
45
using AutSoft.Linq.Queryable;
56

@@ -11,26 +12,125 @@ namespace AutSoft.Linq.Tests.Queryable.OrderByExtensions;
1112

1213
public partial class OrderByFromMappings : OrderByExtensionsTests
1314
{
15+
public static List<(string orderColumn, Expression<Func<PersonDto, object?>> expectedOrderExpression)> OrderExpression() => new()
16+
{
17+
(nameof(PersonDto.Id), p => p.Id),
18+
(nameof(PersonDto.Name), p => p.Name),
19+
(nameof(PersonDto.Age), p => p.Age),
20+
};
21+
1422
[Theory]
15-
[InlineData(nameof(PersonDto.Id))]
16-
[InlineData(nameof(PersonDto.Name))]
17-
[InlineData(nameof(PersonDto.Age))]
18-
public void Should_ReturnOrdered(string orderBy)
23+
[CombinatorialData]
24+
public void Should_ReturnOrdered(
25+
[CombinatorialMemberData(nameof(OrderExpression))] (string orderColumn, Expression<Func<PersonDto, object?>> expectedOrderExpression) ordering,
26+
OrderDirection orderDirection)
1927
{
2028
// Act
2129
var ordered = Subject
22-
.OrderBy<Person, PersonDto>(new PageRequest { OrderBy = orderBy }, p => p.Id, Mapper.ConfigurationProvider)
30+
.OrderBy<Person, PersonDto>(new PageRequest { OrderBy = ordering.orderColumn, OrderDirection = orderDirection }, p => p.Id, Mapper.ConfigurationProvider)
2331
.ProjectTo<PersonDto>(Mapper.ConfigurationProvider)
2432
.ToList();
2533

2634
// Assert
27-
ordered.Should().HaveCount(Subject.Count());
28-
ordered.Should().BeInAscendingOrder(orderBy switch
29-
{
30-
nameof(PersonDto.Id) => (Expression<Func<PersonDto, object?>>)(p => p.Id),
31-
nameof(PersonDto.Name) => p => p.Name,
32-
nameof(PersonDto.Age) => p => p.Age,
33-
_ => throw new NotSupportedException("Not valid test case input"),
34-
});
35+
ordered.Should().HaveCount(Subject.Count()).And.HaveCountGreaterThan(0);
36+
if (orderDirection is OrderDirection.Ascending)
37+
{
38+
ordered.Should().BeInAscendingOrder(ordering.expectedOrderExpression);
39+
}
40+
else if (orderDirection is OrderDirection.Descending)
41+
{
42+
ordered.Should().BeInDescendingOrder(ordering.expectedOrderExpression);
43+
}
44+
else
45+
{
46+
throw new NotSupportedException("Not valid test case input");
47+
}
48+
}
49+
50+
public static List<(Expression<Func<Person, object?>> defaultOrderExpression, Expression<Func<PersonDto, object?>> expectedOrderExpression)> DefaultOrderExpression() => new()
51+
{
52+
(p => p.Id, p => p.Id),
53+
(p => p.Name, p => p.Name),
54+
(p => p.Address, p => p.Address),
55+
};
56+
57+
[Theory]
58+
[CombinatorialData]
59+
public void Should_ReturnDefaultOrdered_WithoutOrderingInfo(
60+
[CombinatorialMemberData(nameof(DefaultOrderExpression))]
61+
(Expression<Func<Person, object?>> defaultOrderExpression, Expression<Func<PersonDto, object?>> expectedOrderExpression) expressions,
62+
OrderDirection orderDirection)
63+
{
64+
// Act
65+
var ordered = Subject
66+
.OrderBy<Person, PersonDto>(new PageRequest() { OrderDirection = orderDirection }, expressions.defaultOrderExpression, Mapper.ConfigurationProvider)
67+
.ProjectTo<PersonDto>(Mapper.ConfigurationProvider)
68+
.ToList();
69+
70+
// Assert
71+
ordered.Should().HaveCount(Subject.Count()).And.HaveCountGreaterThan(0);
72+
if (orderDirection is OrderDirection.Ascending)
73+
{
74+
ordered.Should().BeInAscendingOrder(expressions.expectedOrderExpression);
75+
}
76+
else if (orderDirection is OrderDirection.Descending)
77+
{
78+
ordered.Should().BeInDescendingOrder(expressions.expectedOrderExpression);
79+
}
80+
else
81+
{
82+
throw new NotSupportedException("Not valid test case input");
83+
}
84+
}
85+
86+
[Theory]
87+
[CombinatorialData]
88+
public void Should_ReturnDefaultOrdered_WithDefaultOrderDirection(
89+
[CombinatorialMemberData(nameof(DefaultOrderExpression))]
90+
(Expression<Func<Person, object?>> defaultOrderExpression, Expression<Func<PersonDto, object?>> expectedOrderExpression) expressions,
91+
OrderDirection defaultOrderDirection)
92+
{
93+
// Act
94+
var ordered = Subject
95+
.OrderBy<Person, PersonDto>(new PageRequest(), expressions.defaultOrderExpression, defaultOrderDirection, Mapper.ConfigurationProvider)
96+
.ProjectTo<PersonDto>(Mapper.ConfigurationProvider)
97+
.ToList();
98+
99+
// Assert
100+
ordered.Should().HaveCount(Subject.Count()).And.HaveCountGreaterThan(0);
101+
if (defaultOrderDirection is OrderDirection.Ascending)
102+
{
103+
ordered.Should().BeInAscendingOrder(expressions.expectedOrderExpression);
104+
}
105+
else if (defaultOrderDirection is OrderDirection.Descending)
106+
{
107+
ordered.Should().BeInDescendingOrder(expressions.expectedOrderExpression);
108+
}
109+
else
110+
{
111+
throw new NotSupportedException("Not valid test case input");
112+
}
113+
}
114+
115+
[Fact]
116+
public void Should_ThrowOnNotSortableColumn()
117+
{
118+
// Act
119+
var func = () => Subject
120+
.OrderBy<Person, PersonDto>(new PageRequest { OrderBy = nameof(PersonDto.Address) }, p => p.Id, Mapper.ConfigurationProvider);
121+
122+
// Assert
123+
func.Should().Throw<ValidationException>();
124+
}
125+
126+
[Fact]
127+
public void Should_ThrowOnNotExistedColumn()
128+
{
129+
// Act
130+
var func = () => Subject
131+
.OrderBy<Person, PersonDto>(new PageRequest { OrderBy = "TEST" }, p => p.Id, Mapper.ConfigurationProvider);
132+
133+
// Assert
134+
func.Should().Throw<ValidationException>();
35135
}
36136
}
Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,38 @@
1-
namespace AutSoft.Linq.Tests.Queryable.OrderByExtensions;
1+
using AutSoft.Linq.Models;
2+
using AutSoft.Linq.Queryable;
3+
4+
using FluentAssertions;
5+
6+
namespace AutSoft.Linq.Tests.Queryable.OrderByExtensions;
27

38
public partial class ThenByFluent : OrderByExtensionsTests
49
{
10+
[Theory]
11+
[InlineData(OrderDirection.Ascending)]
12+
[InlineData(OrderDirection.Descending)]
13+
public void Should_ReturnOrdered(OrderDirection thenByDirection)
14+
{
15+
// Act
16+
var ordered = Subject.OrderBy(x => x.Name, OrderDirection.Ascending)
17+
.ThenBy(x => x.DateOfBirth, thenByDirection)
18+
.ToList();
19+
20+
// Assert
21+
ordered.Should().HaveCount(Subject.Count());
22+
23+
if (thenByDirection is OrderDirection.Ascending)
24+
{
25+
var expected = Subject.OrderBy(x => x.Name).ThenBy(x => x.DateOfBirth).ToList();
26+
ordered.Should().ContainInOrder(expected);
27+
}
28+
else if (thenByDirection is OrderDirection.Descending)
29+
{
30+
var expected = Subject.OrderBy(x => x.Name).ThenByDescending(x => x.DateOfBirth).ToList();
31+
ordered.Should().ContainInOrder(expected);
32+
}
33+
else
34+
{
35+
throw new NotSupportedException();
36+
}
37+
}
538
}

test/AutSoft.Linq.Tests/Queryable/OrderByExtensions/OrderByExtensionsTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ protected virtual void Dispose(bool disposing)
4040
{
4141
if (disposing)
4242
{
43+
DbContext.Database.EnsureDeleted();
4344
DbContext.Dispose();
4445
}
4546

test/AutSoft.Linq.Tests/Queryable/OrderByExtensions/Person.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace AutSoft.Linq.Tests.Queryable.OrderByExtensions;
22

3-
internal class Person
3+
public class Person
44
{
55
public int Id { get; set; }
66
public string? Name { get; set; }

test/AutSoft.Linq.Tests/Queryable/OrderByExtensions/PersonDbContext.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Microsoft.EntityFrameworkCore;
1+
using Microsoft.EntityFrameworkCore;
22

33
namespace AutSoft.Linq.Tests.Queryable.OrderByExtensions;
44

@@ -8,7 +8,8 @@ internal class PersonDbContext : DbContext
88

99
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
1010
{
11-
optionsBuilder.UseInMemoryDatabase("test");
11+
// Every DbContext instance works on a different in-memory db
12+
optionsBuilder.UseInMemoryDatabase(Guid.NewGuid().ToString());
1213

1314
base.OnConfiguring(optionsBuilder);
1415
}

test/AutSoft.Linq.Tests/Queryable/OrderByExtensions/PersonDto.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
using AutSoft.Linq.Queryable;
1+
using AutSoft.Linq.Queryable;
22

33
namespace AutSoft.Linq.Tests.Queryable.OrderByExtensions;
44

5-
internal class PersonDto
5+
public class PersonDto
66
{
77
public int Id { get; set; }
88
public string? Name { get; set; }

0 commit comments

Comments
 (0)