From 3013699dc7e49ed968a0ed6cf4773efe12b0cd07 Mon Sep 17 00:00:00 2001 From: Michael Staib Date: Thu, 29 Nov 2018 12:24:41 +0100 Subject: [PATCH] Fixed: Ignore doesn't work with InputObjectTyp (#373) --- .../Descriptors/InputFieldDescriptorTests.cs | 4 +- .../InputObjectTypeDescriptorDescriptors.cs | 25 ++++ ...Tests.cs => ObjectFieldDescriptorTests.cs} | 2 +- src/Types.Tests/Types/InputObjectTypeTests.cs | 30 +++++ .../Descriptors/InputObjectTypeDescriptor.cs | 120 ++++++++++-------- .../Types/Descriptors/ObjectTypeDescriptor.cs | 34 ++--- src/Types/Types/InputObjectType.cs | 2 +- 7 files changed, 143 insertions(+), 74 deletions(-) create mode 100644 src/Types.Tests/Types/Descriptors/InputObjectTypeDescriptorDescriptors.cs rename src/Types.Tests/Types/Descriptors/{FieldDescriptorTests.cs => ObjectFieldDescriptorTests.cs} (99%) diff --git a/src/Types.Tests/Types/Descriptors/InputFieldDescriptorTests.cs b/src/Types.Tests/Types/Descriptors/InputFieldDescriptorTests.cs index 5072fc768e9..17c315a881a 100644 --- a/src/Types.Tests/Types/Descriptors/InputFieldDescriptorTests.cs +++ b/src/Types.Tests/Types/Descriptors/InputFieldDescriptorTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using HotChocolate.Configuration; using HotChocolate.Language; using Xunit; @@ -160,7 +161,8 @@ public void OverwriteNativeDefaultValueWithDefaultValueLiteral() // assert InputFieldDescription description = descriptor.CreateDescription(); Assert.IsType(description.DefaultValue); - Assert.Equal("123", ((StringValueNode)description.DefaultValue).Value); + Assert.Equal("123", + ((StringValueNode)description.DefaultValue).Value); Assert.Null(description.NativeDefaultValue); } diff --git a/src/Types.Tests/Types/Descriptors/InputObjectTypeDescriptorDescriptors.cs b/src/Types.Tests/Types/Descriptors/InputObjectTypeDescriptorDescriptors.cs new file mode 100644 index 00000000000..eb73dc73a38 --- /dev/null +++ b/src/Types.Tests/Types/Descriptors/InputObjectTypeDescriptorDescriptors.cs @@ -0,0 +1,25 @@ +using Xunit; + +namespace HotChocolate.Types +{ + public class InputObjectTypeDescriptorDescriptors + { + [Fact] + public void Field_Ignore_PropertyIsExcluded() + { + // arrange + var descriptor = new InputObjectTypeDescriptor(); + IInputObjectTypeDescriptor descriptorItf = descriptor; + + // act + descriptorItf.Field(t => t.Id).Ignore(); + + // assert + InputObjectTypeDescription description = + descriptor.CreateDescription(); + + Assert.Collection(description.Fields, + t => Assert.Equal("name", t.Name)); + } + } +} diff --git a/src/Types.Tests/Types/Descriptors/FieldDescriptorTests.cs b/src/Types.Tests/Types/Descriptors/ObjectFieldDescriptorTests.cs similarity index 99% rename from src/Types.Tests/Types/Descriptors/FieldDescriptorTests.cs rename to src/Types.Tests/Types/Descriptors/ObjectFieldDescriptorTests.cs index a9a8924e4c9..aa6bed817ce 100644 --- a/src/Types.Tests/Types/Descriptors/FieldDescriptorTests.cs +++ b/src/Types.Tests/Types/Descriptors/ObjectFieldDescriptorTests.cs @@ -9,7 +9,7 @@ namespace HotChocolate.Types { - public class FieldDescriptorTests + public class ObjectFieldDescriptorTests { [Fact] public void DotNetTypesDoNotOverwriteSchemaTypes() diff --git a/src/Types.Tests/Types/InputObjectTypeTests.cs b/src/Types.Tests/Types/InputObjectTypeTests.cs index c40ffaabe07..d717c39573d 100644 --- a/src/Types.Tests/Types/InputObjectTypeTests.cs +++ b/src/Types.Tests/Types/InputObjectTypeTests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using ChilliCream.Testing; +using HotChocolate.Configuration; using HotChocolate.Language; using HotChocolate.Utilities; using Xunit; @@ -8,6 +9,29 @@ namespace HotChocolate.Types { public class InputObjectTypeTests { + [Fact] + public void Initialize_IgnoreProperty_PropertyIsNotInSchemaType() + { + // arrange + var errors = new List(); + var schemaContext = new SchemaContext(); + + // act + var fooType = new InputObjectType( + d => d.Field(f => f.Id).Ignore()); + INeedsInitialization init = fooType; + + // assert + var initializationContext = new TypeInitializationContext( + schemaContext, a => errors.Add(a), fooType, false); + init.RegisterDependencies(initializationContext); + schemaContext.CompleteTypes(); + + Assert.Empty(errors); + Assert.Collection(fooType.Fields, + t => Assert.Equal("name", t.Name)); + } + [Fact] public void ParseLiteral() { @@ -123,6 +147,12 @@ public Schema Create() } } + public class SimpleInput + { + public int Id { get; set; } + public string Name { get; set; } + } + public class SerializationInputObject1 { public SerializationInputObject2 Foo { get; set; } diff --git a/src/Types/Types/Descriptors/InputObjectTypeDescriptor.cs b/src/Types/Types/Descriptors/InputObjectTypeDescriptor.cs index 89f6d3e2b9b..5e98a8cf384 100644 --- a/src/Types/Types/Descriptors/InputObjectTypeDescriptor.cs +++ b/src/Types/Types/Descriptors/InputObjectTypeDescriptor.cs @@ -25,13 +25,36 @@ public InputObjectTypeDescription CreateDescription() return ObjectDescription; } - protected virtual void CompleteFields() + private void CompleteFields() { + var fields = new Dictionary(); + var handledProperties = new HashSet(); + foreach (InputFieldDescriptor fieldDescriptor in Fields) { - ObjectDescription.Fields.Add( - fieldDescriptor.CreateDescription()); + InputFieldDescription fieldDescription = fieldDescriptor + .CreateDescription(); + + if (!fieldDescription.Ignored) + { + fields[fieldDescription.Name] = fieldDescription; + } + + if (fieldDescription.Property != null) + { + handledProperties.Add(fieldDescription.Property); + } } + + OnCompleteFields(fields, handledProperties); + + ObjectDescription.Fields.AddRange(fields.Values); + } + + protected virtual void OnCompleteFields( + IDictionary fields, + ISet handledProperties) + { } protected void SyntaxNode(InputObjectTypeDefinitionNode syntaxNode) @@ -92,10 +115,10 @@ internal class InputObjectTypeDescriptor : InputObjectTypeDescriptor , IInputObjectTypeDescriptor { - public InputObjectTypeDescriptor(Type clrType) + public InputObjectTypeDescriptor() { - ObjectDescription.ClrType = clrType - ?? throw new ArgumentNullException(nameof(clrType)); + Type clrType = typeof(T); + ObjectDescription.ClrType = clrType; ObjectDescription.Name = clrType.GetGraphQLName(); ObjectDescription.Description = clrType.GetGraphQLDescription(); @@ -109,24 +132,50 @@ public InputObjectTypeDescriptor(Type clrType) } } - protected override void CompleteFields() + protected override void OnCompleteFields( + IDictionary fields, + ISet handledProperties) { - base.CompleteFields(); - - var descriptions = new Dictionary(); + if (ObjectDescription.FieldBindingBehavior == + BindingBehavior.Implicit) + { + AddImplicitFields(fields, handledProperties); + } + } - foreach (InputFieldDescription description in - ObjectDescription.Fields) + private void AddImplicitFields( + IDictionary fields, + ISet handledProperties) + { + foreach (KeyValuePair property in + GetProperties(handledProperties)) { - descriptions[description.Name] = description; + if (!fields.ContainsKey(property.Value)) + { + var fieldDescriptor = + new InputFieldDescriptor(property.Key); + + fields[property.Value] = fieldDescriptor + .CreateDescription(); + } } + } - if (ObjectDescription.FieldBindingBehavior == - BindingBehavior.Implicit) + private Dictionary GetProperties( + ISet handledProperties) + { + var properties = new Dictionary(); + + foreach (KeyValuePair property in + ReflectionUtils.GetProperties(ObjectDescription.ClrType)) { - DeriveFieldsFromType(descriptions); - ObjectDescription.Fields = descriptions.Values.ToList(); + if (!handledProperties.Contains(property.Value)) + { + properties[property.Value] = property.Key; + } } + + return properties; } protected void BindFields(BindingBehavior bindingBehavior) @@ -149,43 +198,6 @@ protected InputFieldDescriptor Field( nameof(property)); } - private void DeriveFieldsFromType( - Dictionary descriptions) - { - Dictionary properties = - GetProperties(ObjectDescription.ClrType); - - foreach (InputFieldDescription description in descriptions.Values - .Where(t => t.Property != null)) - { - properties.Remove(description.Property); - } - - foreach (KeyValuePair property in properties) - { - if (!descriptions.ContainsKey(property.Value)) - { - var descriptor = new InputFieldDescriptor(property.Key); - descriptions[property.Value] = descriptor - .CreateDescription(); - } - } - } - - private static Dictionary GetProperties(Type type) - { - var properties = new Dictionary(); - - foreach (PropertyInfo property in type.GetProperties( - BindingFlags.Instance | BindingFlags.Public) - .Where(t => t.DeclaringType != typeof(object))) - { - properties[property] = property.GetGraphQLName(); - } - - return properties; - } - #region IInputObjectTypeDescriptor IInputObjectTypeDescriptor IInputObjectTypeDescriptor.SyntaxNode( diff --git a/src/Types/Types/Descriptors/ObjectTypeDescriptor.cs b/src/Types/Types/Descriptors/ObjectTypeDescriptor.cs index fd374a50933..58582f6d8ba 100644 --- a/src/Types/Types/Descriptors/ObjectTypeDescriptor.cs +++ b/src/Types/Types/Descriptors/ObjectTypeDescriptor.cs @@ -378,23 +378,6 @@ protected override void OnCompleteFields( AddResolverTypes(fields); } - private Dictionary GetAllMembers( - ISet handledMembers) - { - var members = new Dictionary(); - - foreach (KeyValuePair member in - ReflectionUtils.GetMembers(ObjectDescription.ClrType)) - { - if (!handledMembers.Contains(member.Value)) - { - members[member.Value] = member.Key; - } - } - - return members; - } - private void AddImplicitFields( IDictionary fields, ISet handledMembers) @@ -414,6 +397,23 @@ private void AddImplicitFields( } } + private Dictionary GetAllMembers( + ISet handledMembers) + { + var members = new Dictionary(); + + foreach (KeyValuePair member in + ReflectionUtils.GetMembers(ObjectDescription.ClrType)) + { + if (!handledMembers.Contains(member.Value)) + { + members[member.Value] = member.Key; + } + } + + return members; + } + #region IObjectTypeDescriptor IObjectTypeDescriptor IObjectTypeDescriptor.Name(NameString name) diff --git a/src/Types/Types/InputObjectType.cs b/src/Types/Types/InputObjectType.cs index cf0a03c4417..9cf8a933f5b 100644 --- a/src/Types/Types/InputObjectType.cs +++ b/src/Types/Types/InputObjectType.cs @@ -187,7 +187,7 @@ public InputObjectType(Action> configure) #region Configuration internal sealed override InputObjectTypeDescriptor CreateDescriptor() => - new InputObjectTypeDescriptor(typeof(T)); + new InputObjectTypeDescriptor(); protected sealed override void Configure(IInputObjectTypeDescriptor descriptor) {