Skip to content
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
35 changes: 31 additions & 4 deletions Gigya.ServiceContract/HttpService/ServiceSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public ServiceSchema(Type[] interfaces)
SetHashCode();
}

// TODO: Why?
public string Hash { get; set; }

private void SetHashCode()
Expand Down Expand Up @@ -192,10 +193,36 @@ public TypeSchema(Type type, IEnumerable<Attribute> attributes) : base(type, att

private IEnumerable<FieldSchema> 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<string, FieldSchema>();

while (type != null)
{
void add(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 addRange(IEnumerable<FieldSchema> fss)
{
foreach (var fs in fss)
add(fs);
}

addRange(type
.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.Select(x => new FieldSchema(x)));

addRange(type
.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.Select(x => new FieldSchema(x)));

type = type.BaseType;
}

return fields.Values;
}

private bool IsCompositeType(Type type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -60,6 +64,35 @@ internal interface ITestInterface
Task<ResponseData> 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
{
Expand Down Expand Up @@ -93,18 +126,26 @@ 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));
Assert.IsTrue(schema.Interfaces[0].Methods[0].Response.Fields[1].Name == nameof(ResponseData.b));
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()
Expand Down