From a7a34aa6eb392b7da2694d696adbca6028d1da77 Mon Sep 17 00:00:00 2001 From: aikixd Date: Sun, 26 Jan 2020 16:51:39 +0200 Subject: [PATCH 1/2] Fixed duplicate entries in schema --- .../HttpService/ServiceSchema.cs | 35 +++++++++++-- .../ServiceSchemaTests.cs | 51 +++++++++++++++++-- 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/Gigya.ServiceContract/HttpService/ServiceSchema.cs b/Gigya.ServiceContract/HttpService/ServiceSchema.cs index d033934f..55562756 100644 --- a/Gigya.ServiceContract/HttpService/ServiceSchema.cs +++ b/Gigya.ServiceContract/HttpService/ServiceSchema.cs @@ -52,6 +52,7 @@ public ServiceSchema(Type[] interfaces) SetHashCode(); } + // TODO: Why? public string Hash { get; set; } private void SetHashCode() @@ -192,10 +193,36 @@ public TypeSchema(Type type, IEnumerable attributes) : base(type, att private IEnumerable GetFields(Type type) { - var baseFields = type.BaseType != typeof(object) && type.BaseType != null ? GetFields(type.BaseType) : new FieldSchema[0]; - var properties = type.GetProperties().Select(_ => new FieldSchema(_)); - var fields = type.GetFields().Select(_ => new FieldSchema(_)); - return baseFields.Concat(properties).Concat(fields); + var fields = new Dictionary(); + + while (type != null) + { + void with(FieldSchema fs) + { + if (fields.TryGetValue(fs.Name, out var s)) + s.Attributes = s.Attributes.Union(fs.Attributes).ToArray(); + else + fields.Add(fs.Name, fs); + } + + void add(IEnumerable fss) + { + foreach (var fs in fss) + with(fs); + } + + add(type + .GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) + .Select(x => new FieldSchema(x))); + + add(type + .GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) + .Select(x => new FieldSchema(x))); + + type = type.BaseType; + } + + return fields.Values; } private bool IsCompositeType(Type type) diff --git a/tests/Gigya.Microdot.ServiceContract.UnitTests/ServiceSchemaTests.cs b/tests/Gigya.Microdot.ServiceContract.UnitTests/ServiceSchemaTests.cs index 2b0c5fc5..3ed329bf 100644 --- a/tests/Gigya.Microdot.ServiceContract.UnitTests/ServiceSchemaTests.cs +++ b/tests/Gigya.Microdot.ServiceContract.UnitTests/ServiceSchemaTests.cs @@ -33,11 +33,15 @@ class DataParamBase { [Sensitive] public int BaseField; + + public virtual int VirtProp { get; set; } } class Data: DataParamBase { public string s; public Nested n; + + public override int VirtProp { get => base.VirtProp; set => base.VirtProp = value; } } class Nested @@ -60,6 +64,35 @@ internal interface ITestInterface Task DoSomething(int i, double? nd, string s, [Sensitive] Data data); } + abstract class AbctractClass + { + public abstract int PropAbstractVirtual { get; set; } + public abstract int PropAbstract { get; set; } + } + + class VirtClass : AbctractClass + { + public int fldHidden; + public override int PropAbstractVirtual { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public override int PropAbstract { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public virtual int PropVirtual { get; set; } + } + + class SpecificClass : VirtClass + { + // TODO: UB + public new int fldHidden; + public override int PropAbstractVirtual { get => base.PropAbstractVirtual; set => base.PropAbstractVirtual = value; } + public override int PropVirtual { get => base.PropVirtual; set => base.PropVirtual = value; } + } + + internal interface IDoublesTest + { + [PublicEndpoint("test")] + Task Test(SpecificClass obj); + } + [TestFixture,Parallelizable(ParallelScope.Fixtures)] public class ServiceSchemaTests { @@ -93,11 +126,11 @@ public void TestSerialization() Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[2].Name == "s"); Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Attributes.Length == 1); Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Attributes[0].Attribute is SensitiveAttribute); - Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Fields[0].Name == nameof(DataParamBase.BaseField)); - Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Fields[0].Attributes[0].Attribute is SensitiveAttribute); - Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Fields[0].Type == typeof(int)); - Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Fields[1].Name == nameof(Data.s)); - Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Fields[1].Type == typeof(string)); + Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Fields[3].Name == nameof(DataParamBase.BaseField)); + Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Fields[3].Attributes[0].Attribute is SensitiveAttribute); + Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Fields[3].Type == typeof(int)); + Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Fields[0].Name == nameof(Data.s)); + Assert.IsTrue(schema.Interfaces[0].Methods[0].Parameters[3].Fields[0].Type == typeof(string)); Assert.IsTrue(schema.Interfaces[0].Methods[0].Response.Type == typeof(ResponseData)); Assert.IsTrue(schema.Interfaces[0].Methods[0].Response.Fields[0].Name == nameof(ResponseData.a)); Assert.IsTrue(schema.Interfaces[0].Methods[0].Response.Fields[0].Type == typeof(string)); @@ -105,6 +138,14 @@ public void TestSerialization() Assert.IsTrue(schema.Interfaces[0].Methods[0].Response.Fields[1].Type == typeof(int)); } + [Test] + public void ServiceSchema_DoesntContainDuplicates() + { + ServiceSchema schema = new ServiceSchema(new[] { typeof(IDoublesTest) }); + + Assert.AreEqual(4, schema.Interfaces[0].Methods[0].Parameters[0].Fields.Length); + } + [Test] public void TestUnknownAttribute() From 7dd06d7533cff9516597a53a73df40d82a4922d4 Mon Sep 17 00:00:00 2001 From: aikixd Date: Sun, 2 Feb 2020 12:18:47 +0200 Subject: [PATCH 2/2] Rename function --- Gigya.ServiceContract/HttpService/ServiceSchema.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Gigya.ServiceContract/HttpService/ServiceSchema.cs b/Gigya.ServiceContract/HttpService/ServiceSchema.cs index 55562756..0500eee7 100644 --- a/Gigya.ServiceContract/HttpService/ServiceSchema.cs +++ b/Gigya.ServiceContract/HttpService/ServiceSchema.cs @@ -197,7 +197,7 @@ private IEnumerable GetFields(Type type) while (type != null) { - void with(FieldSchema fs) + void add(FieldSchema fs) { if (fields.TryGetValue(fs.Name, out var s)) s.Attributes = s.Attributes.Union(fs.Attributes).ToArray(); @@ -205,17 +205,17 @@ void with(FieldSchema fs) fields.Add(fs.Name, fs); } - void add(IEnumerable fss) + void addRange(IEnumerable fss) { foreach (var fs in fss) - with(fs); + add(fs); } - add(type + addRange(type .GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Select(x => new FieldSchema(x))); - add(type + addRange(type .GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Select(x => new FieldSchema(x)));