Skip to content

Filter- and SortInputType now honor the SortFieldsByName-setting #8515

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions src/HotChocolate/Core/src/Types/Internal/FieldInitHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,21 +91,6 @@ public static TField[] CompleteFields<TFieldDefinition, TField>(
maxFieldCount);
}

public static TField[] CompleteFields<TField>(
ITypeCompletionContext context,
ITypeSystemMember declaringMember,
TField[] fields)
where TField : class, IFieldDefinition
{
ArgumentNullException.ThrowIfNull(context);
ArgumentNullException.ThrowIfNull(declaringMember);
ArgumentNullException.ThrowIfNull(fields);

CompleteFieldsInternal(context, declaringMember, fields);

return fields;
}

public static TField[] CompleteFieldsInternal<TFieldDefinition, TField>(
ITypeCompletionContext context,
ITypeSystemMember declaringMember,
Expand Down
6 changes: 3 additions & 3 deletions src/HotChocolate/Data/src/Data/Filters/Fields/AndField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ public sealed class AndField
: FilterOperationField
, IAndField
{
internal AndField(IDescriptorContext context, int index, string? scope)
: base(CreateConfiguration(context, scope), index)
internal AndField(FilterOperationFieldConfiguration configuration, int index)
: base(configuration, index)
{
}

Expand All @@ -31,7 +31,7 @@ protected override void OnCompleteField(
base.OnCompleteField(context, declaringMember, definition);
}

private static FilterOperationFieldConfiguration CreateConfiguration(
internal static FilterOperationFieldConfiguration CreateConfiguration(
IDescriptorContext context,
string? scope) =>
FilterOperationFieldDescriptor
Expand Down
6 changes: 3 additions & 3 deletions src/HotChocolate/Data/src/Data/Filters/Fields/OrField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ public sealed class OrField
: FilterOperationField
, IOrField
{
internal OrField(IDescriptorContext context, int index, string? scope)
: base(CreateConfiguration(context, scope), index)
internal OrField(FilterOperationFieldConfiguration configuration, int index)
: base(configuration, index)
{
}

Expand All @@ -31,7 +31,7 @@ protected override void OnCompleteField(
base.OnCompleteField(context, declaringMember, definition);
}

private static FilterOperationFieldConfiguration CreateConfiguration(
internal static FilterOperationFieldConfiguration CreateConfiguration(
IDescriptorContext context,
string? scope) =>
FilterOperationFieldDescriptor
Expand Down
40 changes: 21 additions & 19 deletions src/HotChocolate/Data/src/Data/Filters/FilterInputType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,44 +79,46 @@ protected override InputFieldCollection OnCompleteFields(
ITypeCompletionContext context,
InputObjectTypeConfiguration definition)
{
var fields = new InputField[definition.Fields.Count + 2];
var index = 0;

var fieldConfigurations = new List<FieldConfiguration>(definition.Fields.Count + 2);
if (definition is FilterInputTypeConfiguration { UseAnd: true } def)
{
fields[index] = new AndField(context.DescriptorContext, index, def.Scope);
index++;
fieldConfigurations.Add(AndField.CreateConfiguration(context.DescriptorContext, def.Scope));
}

if (definition is FilterInputTypeConfiguration { UseOr: true } defOr)
{
fields[index] = new OrField(context.DescriptorContext, index, defOr.Scope);
index++;
fieldConfigurations.Add(OrField.CreateConfiguration(context.DescriptorContext, defOr.Scope));
}

foreach (var fieldDefinition in
definition.Fields.Where(t => !t.Ignore))
foreach (var fieldDefinition in definition.Fields.Where(t => !t.Ignore))
{
switch (fieldDefinition)
{
case FilterOperationFieldConfiguration operation:
fields[index] = new FilterOperationField(operation, index);
index++;
fieldConfigurations.Add(operation);
break;

case FilterFieldConfiguration field:
fields[index] = new FilterField(field, index);
index++;
fieldConfigurations.Add(field);
break;
}
}

if (fields.Length > index)
{
Array.Resize(ref fields, index);
}

return new InputFieldCollection(CompleteFields(context, this, fields));
return new InputFieldCollection(
CompleteFields(
context,
this,
fieldConfigurations,
CreateField));
static InputField CreateField(FieldConfiguration fieldDef, int index) =>
fieldDef switch
{
FilterOperationFieldConfiguration { Id: DefaultFilterOperations.And } op => new AndField(op, index),
FilterOperationFieldConfiguration { Id: DefaultFilterOperations.Or } op => new OrField(op, index),
FilterOperationFieldConfiguration op => new FilterOperationField(op, index),
FilterFieldConfiguration field => new FilterField(field, index),
_ => throw new ArgumentException("Unsupported field type", nameof(fieldDef))
};
}

// we are disabling the default configure method so
Expand Down
19 changes: 9 additions & 10 deletions src/HotChocolate/Data/src/Data/Sorting/SortInputType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,23 @@ protected override InputFieldCollection OnCompleteFields(
ITypeCompletionContext context,
InputObjectTypeConfiguration configuration)
{
var fields = new InputField[configuration.Fields.Count];
var index = 0;
var fieldConfigurations = new List<SortFieldConfiguration>(configuration.Fields.Count);

foreach (var fieldDefinition in configuration.Fields)
{
if (fieldDefinition is SortFieldConfiguration { Ignore: false } field)
{
fields[index] = new SortField(field, index);
index++;
fieldConfigurations.Add(field);
}
}

if (fields.Length < index)
{
Array.Resize(ref fields, index);
}

return new InputFieldCollection(CompleteFields(context, this, fields));
return new InputFieldCollection(
CompleteFields(
context,
this,
fieldConfigurations,
CreateField));
static InputField CreateField(SortFieldConfiguration fieldDef, int index) => new SortField(fieldDef, index);
}

// we are disabling the default configure method so
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,20 @@ public async Task Execute_CoerceWhereArgument_MatchesSnapshot()
result.MatchSnapshot();
}

[Fact]
public void FilterInputType_Honors_SortFieldsByName()
{
// arrange
// act
var schema = CreateSchema(
s => s
.AddType(new FilterInputType<FilterWithNonAlphabeticallyMembers>())
.ModifyOptions(x => x.SortFieldsByName = true));

// assert
schema.MatchSnapshot();
}

public class FooDirectiveType
: DirectiveType<FooDirective>
{
Expand Down Expand Up @@ -608,4 +622,6 @@ public class FilterWithStruct
}

public record struct ExampleValueType(string Foo, string Bar);

public record FilterWithNonAlphabeticallyMembers(int X, int A, int Y, int Z, int B);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
schema {
query: Query
}

type Query {
foo: String
}

input FilterWithNonAlphabeticallyMembersFilterInput {
a: IntOperationFilterInput
and: [FilterWithNonAlphabeticallyMembersFilterInput!]
b: IntOperationFilterInput
or: [FilterWithNonAlphabeticallyMembersFilterInput!]
x: IntOperationFilterInput
y: IntOperationFilterInput
z: IntOperationFilterInput
}

input IntOperationFilterInput {
eq: Int
gt: Int
gte: Int
in: [Int]
lt: Int
lte: Int
neq: Int
ngt: Int
ngte: Int
nin: [Int]
nlt: Int
nlte: Int
}
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,20 @@ public void SortInputType_Should_InfereType_When_ItIsAInterface()
schema.ToString().MatchSnapshot();
}

[Fact]
public void SortInputType_Honors_SortFieldsByName()
{
// arrange
// act
var schema = CreateSchema(
s => s
.AddType(new SortInputType<SortTypeWithNonAlphabeticallyMembers>())
.ModifyOptions(x => x.SortFieldsByName = true));

// assert
schema.MatchSnapshot();
}

public class IgnoreTest
{
public int Id { get; set; }
Expand Down Expand Up @@ -368,4 +382,6 @@ protected override void Configure(IObjectTypeDescriptor<TestObject<T>> descripto
descriptor.Field(x => x.Root).UseFiltering();
}
}

public record SortTypeWithNonAlphabeticallyMembers(int X, int A, int Y, int Z, int B);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
schema {
query: Query
}

type Query {
foo: String
}

input SortTypeWithNonAlphabeticallyMembersSortInput {
a: SortEnumType
b: SortEnumType
x: SortEnumType
y: SortEnumType
z: SortEnumType
}

enum SortEnumType {
ASC
DESC
}