Skip to content

Commit 7a07b18

Browse files
authored
Re-enable Tables converter tests (Azure#25932)
1 parent 6b3884d commit 7a07b18

File tree

7 files changed

+259
-362
lines changed

7 files changed

+259
-362
lines changed

sdk/tables/Microsoft.Azure.WebJobs.Extensions.Tables/src/PocoToTableEntityConverter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public PocoToTableEntityConverter()
2020
ConvertsPartitionKey = HasGetter<string>("PartitionKey");
2121
ConvertsRowKey = HasGetter<string>("RowKey");
2222
ConvertsETag = HasGetter<string>("ETag");
23+
HasGetter<DateTimeOffset>("Timestamp");
2324
}
2425

2526
public bool ConvertsPartitionKey { get; }

sdk/tables/Microsoft.Azure.WebJobs.Extensions.Tables/src/PocoTypeBinder.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Globalization;
6+
using System.Reflection;
67
using Azure;
78
using Azure.Data.Tables;
89
using Azure.Monitor.Query;
@@ -15,12 +16,28 @@ internal class PocoTypeBinder: TypeBinder<TableEntity>
1516
public static PocoTypeBinder Shared { get; } = new();
1617
protected override void Set<T>(TableEntity destination, T value, BoundMemberInfo memberInfo)
1718
{
18-
// Remove the ETag and Timestamp properties, as they do not need to be serialized
19-
if (memberInfo.Name == TableConstants.PropertyNames.ETag || memberInfo.Name == TableConstants.PropertyNames.Timestamp)
19+
// TODO: this is not the best place for this check
20+
if (memberInfo.MemberInfo is PropertyInfo { GetMethod: { IsPrivate: true } })
2021
{
2122
return;
2223
}
2324

25+
switch (memberInfo.Name)
26+
{
27+
case TableConstants.PropertyNames.ETag:
28+
destination.ETag = new ETag((string)(object)value);
29+
return;
30+
case TableConstants.PropertyNames.Timestamp:
31+
destination.Timestamp = (DateTimeOffset)(object)value;
32+
return;
33+
case TableConstants.PropertyNames.RowKey:
34+
destination.RowKey = (string)(object)value;
35+
return;
36+
case TableConstants.PropertyNames.PartitionKey:
37+
destination.PartitionKey = (string)(object)value;
38+
return;
39+
}
40+
2441
if (typeof(T) == typeof(bool) ||
2542
typeof(T) == typeof(bool?) ||
2643
typeof(T) == typeof(byte[]) ||
@@ -56,6 +73,12 @@ protected override bool TryGet<T>(BoundMemberInfo memberInfo, TableEntity source
5673
{
5774
value = default;
5875

76+
// TODO: this is not the best place for this check
77+
if (memberInfo.MemberInfo is PropertyInfo { SetMethod: { IsPrivate: true } })
78+
{
79+
return false;
80+
}
81+
5982
var key = memberInfo.Name switch
6083
{
6184
nameof(TableConstants.PropertyNames.ETag) => TableConstants.PropertyNames.EtagOdata,
@@ -167,7 +190,7 @@ protected override bool TryGet<T>(BoundMemberInfo memberInfo, TableEntity source
167190
else if (typeof(T) == typeof(TimeSpan))
168191
{
169192
// TODO: this is new. Who handled this before?
170-
value = (T)JsonConvert.DeserializeObject<T>(source.GetString(key));
193+
value = JsonConvert.DeserializeObject<T>(source.GetString(key));
171194
}
172195

173196
return true;

sdk/tables/Microsoft.Azure.WebJobs.Extensions.Tables/src/TableEntityToPocoConverter.cs

Lines changed: 33 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -2,84 +2,25 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System;
5-
using System.Collections.Generic;
6-
using System.Diagnostics;
75
using System.Globalization;
86
using System.Reflection;
97
using Azure.Data.Tables;
10-
using Microsoft.Azure.WebJobs.Host;
11-
using ITableEntity = Azure.Data.Tables.ITableEntity;
128

139
namespace Microsoft.Azure.WebJobs.Extensions.Tables
1410
{
1511
internal class TableEntityToPocoConverter<TOutput> : IConverter<TableEntity, TOutput> where TOutput : new()
1612
{
17-
// private readonly IPropertySetter<TOutput, string> _partitionKeySetter;
18-
// private readonly IPropertySetter<TOutput, string> _rowKeySetter;
19-
// private readonly IPropertySetter<TOutput, DateTimeOffset> _timestampSetter;
20-
// private readonly IPropertySetter<TOutput, string> _eTagSetter;
21-
// private readonly IReadOnlyDictionary<string, IPropertySetter<TOutput, EntityProperty>> _otherPropertySetters;
22-
23-
// private TableEntityToPocoConverter(
24-
// IPropertySetter<TOutput, string> partitionKeySetter,
25-
// IPropertySetter<TOutput, string> rowKeySetter,
26-
// IPropertySetter<TOutput, DateTimeOffset> timestampSetter,
27-
// IPropertySetter<TOutput, string> eTagSetter,
28-
// IReadOnlyDictionary<string, IPropertySetter<TOutput, EntityProperty>> otherPropertySetters)
29-
// {
30-
// Debug.Assert(otherPropertySetters != null);
31-
// _partitionKeySetter = partitionKeySetter;
32-
// _rowKeySetter = rowKeySetter;
33-
// _timestampSetter = timestampSetter;
34-
// _eTagSetter = eTagSetter;
35-
// _otherPropertySetters = otherPropertySetters;
36-
// }
13+
public TableEntityToPocoConverter()
14+
{
15+
CheckSetter<string>("PartitionKey");
16+
CheckSetter<string>("RowKey");
17+
CheckSetter<DateTimeOffset>("Timestamp");
18+
CheckSetter<string>("ETag");
19+
}
3720

3821
public TOutput Convert(TableEntity input)
3922
{
40-
if (input == null)
41-
{
42-
return default(TOutput);
43-
}
44-
45-
TOutput result = new TOutput();
46-
// if (_partitionKeySetter != null)
47-
// {
48-
// _partitionKeySetter.SetValue(ref result, input.PartitionKey);
49-
// }
50-
//
51-
// if (_rowKeySetter != null)
52-
// {
53-
// _rowKeySetter.SetValue(ref result, input.RowKey);
54-
// }
55-
//
56-
// if (_timestampSetter != null)
57-
// {
58-
// _timestampSetter.SetValue(ref result, input.Timestamp);
59-
// }
60-
//
61-
// IDictionary<string, EntityProperty> properties = input.WriteEntity(operationContext: null);
62-
// if (properties != null)
63-
// {
64-
// foreach (KeyValuePair<string, IPropertySetter<TOutput, EntityProperty>> pair in _otherPropertySetters)
65-
// {
66-
// string propertyName = pair.Key;
67-
// if (properties.ContainsKey(propertyName))
68-
// {
69-
// IPropertySetter<TOutput, EntityProperty> setter = pair.Value;
70-
// Debug.Assert(setter != null);
71-
// EntityProperty propertyValue = properties[propertyName];
72-
// setter.SetValue(ref result, propertyValue);
73-
// }
74-
// }
75-
// }
76-
//
77-
// if (_eTagSetter != null)
78-
// {
79-
// _eTagSetter.SetValue(ref result, input.ETag);
80-
// }
81-
82-
return PocoTypeBinder.Shared.Deserialize<TOutput>(input);
23+
return input == null ? default : PocoTypeBinder.Shared.Deserialize<TOutput>(input);
8324
}
8425
//
8526
// public static TableEntityToPocoConverter<TOutput> Create()
@@ -109,49 +50,30 @@ public TOutput Convert(TableEntity input)
10950
// eTagSetter, otherPropertySetters);
11051
// }
11152
//
112-
// private static IPropertySetter<TOutput, TProperty> GetSetter<TProperty>(string propertyName)
113-
// {
114-
// PropertyInfo property = typeof(TOutput).GetProperty(propertyName,
115-
// BindingFlags.Instance | BindingFlags.Public);
116-
// if (property == null || !property.CanWrite || !property.HasPublicSetMethod())
117-
// {
118-
// return null;
119-
// }
120-
//
121-
// if (property.PropertyType != typeof(TProperty))
122-
// {
123-
// string message = String.Format(CultureInfo.InvariantCulture,
124-
// "If the {0} property is present, it must be a {1}.", propertyName, typeof(TProperty).Name);
125-
// throw new InvalidOperationException(message);
126-
// }
127-
//
128-
// if (property.GetIndexParameters().Length != 0)
129-
// {
130-
// string message = String.Format(CultureInfo.InvariantCulture,
131-
// "If the {0} property is present, it must not be an indexer.", propertyName);
132-
// throw new InvalidOperationException(message);
133-
// }
134-
//
135-
// return PropertyAccessorFactory<TOutput>.CreateSetter<TProperty>(property);
136-
// }
137-
//
138-
// private static IPropertySetter<TOutput, EntityProperty> GetOtherSetter(PropertyInfo property)
139-
// {
140-
// MethodInfo genericMethodTemplate = typeof(TableEntityToPocoConverter<TOutput>).GetMethod(
141-
// "GetOtherSetterGeneric", BindingFlags.Static | BindingFlags.NonPublic);
142-
// MethodInfo genericMethod = genericMethodTemplate.MakeGenericMethod(property.PropertyType);
143-
// Func<PropertyInfo, IPropertySetter<TOutput, EntityProperty>> invoker =
144-
// (Func<PropertyInfo, IPropertySetter<TOutput, EntityProperty>>)genericMethod.CreateDelegate(
145-
// typeof(Func<PropertyInfo, IPropertySetter<TOutput, EntityProperty>>));
146-
// return invoker.Invoke(property);
147-
// }
148-
//
149-
// private static IPropertySetter<TOutput, EntityProperty> GetOtherSetterGeneric<TProperty>(PropertyInfo property)
150-
// {
151-
// IConverter<EntityProperty, TProperty> converter = EntityPropertyToTConverterFactory.Create<TProperty>();
152-
// IPropertySetter<TOutput, TProperty> propertySetter =
153-
// PropertyAccessorFactory<TOutput>.CreateSetter<TProperty>(property);
154-
// return new ConverterPropertySetter<TOutput, TProperty, EntityProperty>(converter, propertySetter);
155-
// }
53+
private static bool CheckSetter<TProperty>(string propertyName)
54+
{
55+
PropertyInfo property = typeof(TOutput).GetProperty(propertyName,
56+
BindingFlags.Instance | BindingFlags.Public);
57+
if (property == null || !property.CanWrite || !property.HasPublicSetMethod())
58+
{
59+
return false;
60+
}
61+
62+
if (property.PropertyType != typeof(TProperty))
63+
{
64+
string message = String.Format(CultureInfo.InvariantCulture,
65+
"If the {0} property is present, it must be a {1}.", propertyName, typeof(TProperty).Name);
66+
throw new InvalidOperationException(message);
67+
}
68+
69+
if (property.GetIndexParameters().Length != 0)
70+
{
71+
string message = String.Format(CultureInfo.InvariantCulture,
72+
"If the {0} property is present, it must not be an indexer.", propertyName);
73+
throw new InvalidOperationException(message);
74+
}
75+
76+
return true;
77+
}
15678
}
15779
}

sdk/tables/Microsoft.Azure.WebJobs.Extensions.Tables/tests/Microsoft.Azure.WebJobs.Extensions.Tables.Tests.csproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,9 @@
1919
</ItemGroup>
2020

2121
<ItemGroup>
22-
<Compile Remove="TableEntityToPocoConverterTests.cs" />
2322
<Compile Remove="TableEntityValueBinderTests.cs" />
24-
<Compile Remove="PocoToTableEntityConverterTests.cs" />
2523
<Compile Remove="EntityPropertyToTConverterFactoryTests.cs" />
2624
<Compile Remove="TToEntityPropertyConverterFactoryTests.cs" />
2725
</ItemGroup>
2826

29-
3027
</Project>

0 commit comments

Comments
 (0)