Skip to content

Commit 1e795f3

Browse files
committed
Add unit tests to cover primitive methods on QueryExpression types
1 parent cd8ae40 commit 1e795f3

File tree

1 file changed

+335
-0
lines changed

1 file changed

+335
-0
lines changed
Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,335 @@
1+
using System.Collections.Immutable;
2+
using FluentAssertions;
3+
using JetBrains.Annotations;
4+
using JsonApiDotNetCore.Configuration;
5+
using JsonApiDotNetCore.Queries.Expressions;
6+
using JsonApiDotNetCore.Resources;
7+
using JsonApiDotNetCore.Resources.Annotations;
8+
using Microsoft.Extensions.Logging.Abstractions;
9+
using Microsoft.Extensions.Primitives;
10+
using Xunit;
11+
12+
namespace JsonApiDotNetCoreTests.UnitTests.Queries;
13+
14+
public sealed class QueryExpressionTests
15+
{
16+
public static IEnumerable<object[]> ExpressionTestData =>
17+
new QueryExpression[][]
18+
{
19+
[
20+
TestExpressionFactory.Instance.Any(),
21+
TestExpressionFactory.Instance.Any()
22+
],
23+
[
24+
TestExpressionFactory.Instance.Comparison(),
25+
TestExpressionFactory.Instance.Comparison()
26+
],
27+
[
28+
TestExpressionFactory.Instance.Count(),
29+
TestExpressionFactory.Instance.Count()
30+
],
31+
[
32+
TestExpressionFactory.Instance.Has(),
33+
TestExpressionFactory.Instance.Has()
34+
],
35+
[
36+
TestExpressionFactory.Instance.IncludeElementForParent(),
37+
TestExpressionFactory.Instance.IncludeElementForParent()
38+
],
39+
[
40+
TestExpressionFactory.Instance.IncludeElementForChildren(),
41+
TestExpressionFactory.Instance.IncludeElementForChildren()
42+
],
43+
[
44+
TestExpressionFactory.Instance.Include(),
45+
TestExpressionFactory.Instance.Include()
46+
],
47+
[
48+
TestExpressionFactory.Instance.IsType(),
49+
TestExpressionFactory.Instance.IsType()
50+
],
51+
[
52+
TestExpressionFactory.Instance.LiteralConstant(),
53+
TestExpressionFactory.Instance.LiteralConstant()
54+
],
55+
[
56+
TestExpressionFactory.Instance.Logical(),
57+
TestExpressionFactory.Instance.Logical()
58+
],
59+
[
60+
TestExpressionFactory.Instance.MatchText(),
61+
TestExpressionFactory.Instance.MatchText()
62+
],
63+
[
64+
TestExpressionFactory.Instance.Not(),
65+
TestExpressionFactory.Instance.Not()
66+
],
67+
[
68+
TestExpressionFactory.Instance.NullConstant(),
69+
TestExpressionFactory.Instance.NullConstant()
70+
],
71+
[
72+
TestExpressionFactory.Instance.PaginationElementQueryStringValue(),
73+
TestExpressionFactory.Instance.PaginationElementQueryStringValue()
74+
],
75+
[
76+
TestExpressionFactory.Instance.Pagination(),
77+
TestExpressionFactory.Instance.Pagination()
78+
],
79+
[
80+
TestExpressionFactory.Instance.PaginationQueryStringValue(),
81+
TestExpressionFactory.Instance.PaginationQueryStringValue()
82+
],
83+
[
84+
TestExpressionFactory.Instance.QueryableHandler(),
85+
TestExpressionFactory.Instance.QueryableHandler()
86+
],
87+
[
88+
TestExpressionFactory.Instance.QueryStringParameterScope(),
89+
TestExpressionFactory.Instance.QueryStringParameterScope()
90+
],
91+
[
92+
TestExpressionFactory.Instance.ResourceFieldChainForText(),
93+
TestExpressionFactory.Instance.ResourceFieldChainForText()
94+
],
95+
[
96+
TestExpressionFactory.Instance.ResourceFieldChainForParent(),
97+
TestExpressionFactory.Instance.ResourceFieldChainForParent()
98+
],
99+
[
100+
TestExpressionFactory.Instance.ResourceFieldChainForChildren(),
101+
TestExpressionFactory.Instance.ResourceFieldChainForChildren()
102+
],
103+
[
104+
TestExpressionFactory.Instance.SortElement(),
105+
TestExpressionFactory.Instance.SortElement()
106+
],
107+
[
108+
TestExpressionFactory.Instance.Sort(),
109+
TestExpressionFactory.Instance.Sort()
110+
],
111+
[
112+
TestExpressionFactory.Instance.SparseFieldSet(),
113+
TestExpressionFactory.Instance.SparseFieldSet()
114+
],
115+
[
116+
TestExpressionFactory.Instance.SparseFieldTable(),
117+
TestExpressionFactory.Instance.SparseFieldTable()
118+
]
119+
};
120+
121+
[Theory]
122+
[MemberData(nameof(ExpressionTestData))]
123+
public void Expressions_are_equal(QueryExpression left, QueryExpression right)
124+
{
125+
// Assert
126+
left.Equals(right).Should().BeTrue();
127+
right.Equals(left).Should().BeTrue();
128+
}
129+
130+
[Theory]
131+
[MemberData(nameof(ExpressionTestData))]
132+
public void Expressions_have_same_hash_code(QueryExpression left, QueryExpression right)
133+
{
134+
// Assert
135+
left.GetHashCode().Should().Be(right.GetHashCode());
136+
}
137+
138+
[Theory]
139+
[MemberData(nameof(ExpressionTestData))]
140+
public void Expressions_convert_to_same_string(QueryExpression left, QueryExpression right)
141+
{
142+
// Assert
143+
left.ToString().Should().Be(right.ToString());
144+
}
145+
146+
[Theory]
147+
[MemberData(nameof(ExpressionTestData))]
148+
public void Expressions_convert_to_same_full_string(QueryExpression left, QueryExpression right)
149+
{
150+
// Assert
151+
left.ToFullString().Should().Be(right.ToFullString());
152+
}
153+
154+
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]
155+
private class BaseTestResource : Identifiable<Guid>
156+
{
157+
[Attr]
158+
public string? Text { get; set; }
159+
160+
[HasOne]
161+
public BaseTestResource? Parent { get; set; }
162+
163+
[HasMany]
164+
public ISet<BaseTestResource> Children { get; set; } = new HashSet<BaseTestResource>();
165+
}
166+
167+
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]
168+
private sealed class DerivedTestResource : BaseTestResource;
169+
170+
private sealed class TestExpressionFactory
171+
{
172+
private readonly ResourceType _baseTestResourceType;
173+
private readonly ResourceType _derivedTestResourceType;
174+
private readonly AttrAttribute _textAttribute;
175+
private readonly RelationshipAttribute _parentRelationship;
176+
private readonly RelationshipAttribute _childrenRelationship;
177+
public static TestExpressionFactory Instance { get; } = new();
178+
179+
private TestExpressionFactory()
180+
{
181+
var options = new JsonApiOptions();
182+
183+
var builder = new ResourceGraphBuilder(options, NullLoggerFactory.Instance);
184+
builder.Add<BaseTestResource, Guid>();
185+
builder.Add<DerivedTestResource, Guid>();
186+
IResourceGraph resourceGraph = builder.Build();
187+
188+
_baseTestResourceType = resourceGraph.GetResourceType<BaseTestResource>();
189+
_derivedTestResourceType = resourceGraph.GetResourceType<DerivedTestResource>();
190+
_textAttribute = _baseTestResourceType.GetAttributeByPropertyName(nameof(BaseTestResource.Text));
191+
_parentRelationship = _baseTestResourceType.GetRelationshipByPropertyName(nameof(BaseTestResource.Parent));
192+
_childrenRelationship = _baseTestResourceType.GetRelationshipByPropertyName(nameof(BaseTestResource.Children));
193+
}
194+
195+
public AnyExpression Any()
196+
{
197+
return new AnyExpression(ResourceFieldChainForText(), [LiteralConstant()]);
198+
}
199+
200+
public ComparisonExpression Comparison()
201+
{
202+
return new ComparisonExpression(ComparisonOperator.Equals, ResourceFieldChainForText(), LiteralConstant());
203+
}
204+
205+
public CountExpression Count()
206+
{
207+
return new CountExpression(ResourceFieldChainForChildren());
208+
}
209+
210+
public HasExpression Has()
211+
{
212+
return new HasExpression(ResourceFieldChainForChildren(), Comparison());
213+
}
214+
215+
public IncludeElementExpression IncludeElementForParent()
216+
{
217+
return new IncludeElementExpression(_parentRelationship);
218+
}
219+
220+
public IncludeElementExpression IncludeElementForChildren()
221+
{
222+
return new IncludeElementExpression(_childrenRelationship);
223+
}
224+
225+
public IncludeExpression Include()
226+
{
227+
return new IncludeExpression([
228+
IncludeElementForParent(),
229+
IncludeElementForChildren()
230+
]);
231+
}
232+
233+
public IsTypeExpression IsType()
234+
{
235+
return new IsTypeExpression(ResourceFieldChainForParent(), _derivedTestResourceType, Has());
236+
}
237+
238+
public LiteralConstantExpression LiteralConstant()
239+
{
240+
return new LiteralConstantExpression(typeof(string), "example");
241+
}
242+
243+
public LogicalExpression Logical()
244+
{
245+
return new LogicalExpression(LogicalOperator.Or, Comparison(), MatchText());
246+
}
247+
248+
public MatchTextExpression MatchText()
249+
{
250+
return new MatchTextExpression(ResourceFieldChainForText(), LiteralConstant(), TextMatchKind.Contains);
251+
}
252+
253+
public NotExpression Not()
254+
{
255+
return new NotExpression(Comparison());
256+
}
257+
258+
public NullConstantExpression NullConstant()
259+
{
260+
return NullConstantExpression.Instance;
261+
}
262+
263+
public PaginationElementQueryStringValueExpression PaginationElementQueryStringValue()
264+
{
265+
return new PaginationElementQueryStringValueExpression(ResourceFieldChainForChildren(), 5, 8);
266+
}
267+
268+
public PaginationExpression Pagination()
269+
{
270+
return new PaginationExpression(new PageNumber(2), new PageSize(5));
271+
}
272+
273+
public PaginationQueryStringValueExpression PaginationQueryStringValue()
274+
{
275+
return new PaginationQueryStringValueExpression([PaginationElementQueryStringValue()]);
276+
}
277+
278+
public QueryableHandlerExpression QueryableHandler()
279+
{
280+
#pragma warning disable CS8974 // Converting method group to non-delegate type
281+
object handler = TestQueryableHandler;
282+
#pragma warning restore CS8974 // Converting method group to non-delegate type
283+
return new QueryableHandlerExpression(handler, "disableCache");
284+
}
285+
286+
public QueryStringParameterScopeExpression QueryStringParameterScope()
287+
{
288+
return new QueryStringParameterScopeExpression(LiteralConstant(), ResourceFieldChainForChildren());
289+
}
290+
291+
public ResourceFieldChainExpression ResourceFieldChainForText()
292+
{
293+
return new ResourceFieldChainExpression([_textAttribute]);
294+
}
295+
296+
public ResourceFieldChainExpression ResourceFieldChainForParent()
297+
{
298+
return new ResourceFieldChainExpression([_parentRelationship]);
299+
}
300+
301+
public ResourceFieldChainExpression ResourceFieldChainForChildren()
302+
{
303+
return new ResourceFieldChainExpression([_childrenRelationship]);
304+
}
305+
306+
public SortElementExpression SortElement()
307+
{
308+
return new SortElementExpression(Count(), false);
309+
}
310+
311+
public SortExpression Sort()
312+
{
313+
return new SortExpression([SortElement()]);
314+
}
315+
316+
public SparseFieldSetExpression SparseFieldSet()
317+
{
318+
return new SparseFieldSetExpression([
319+
_textAttribute,
320+
_childrenRelationship
321+
]);
322+
}
323+
324+
public SparseFieldTableExpression SparseFieldTable()
325+
{
326+
return new SparseFieldTableExpression(ImmutableDictionary.Create<ResourceType, SparseFieldSetExpression>()
327+
.Add(_baseTestResourceType, SparseFieldSet()));
328+
}
329+
330+
private static IQueryable<BaseTestResource> TestQueryableHandler(IQueryable<BaseTestResource> source, StringValues parameterValue)
331+
{
332+
throw new NotImplementedException();
333+
}
334+
}
335+
}

0 commit comments

Comments
 (0)