Skip to content

Commit 7c190e5

Browse files
feat(primitive-collections): including literal types for non-navigation/simple members.
AutoMapper/AutoMapper.Extensions.OData#196
1 parent c23c79c commit 7c190e5

File tree

2 files changed

+62
-9
lines changed

2 files changed

+62
-9
lines changed

LogicBuilder.Expressions.Utils.Tests/TypeExtensionsTests.cs

+48-8
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Reflection;
5-
using System.Text;
6-
using System.Threading.Tasks;
75
using Xunit;
86

97
namespace LogicBuilder.Expressions.Utils.Tests
@@ -13,6 +11,7 @@ public class TypeExtensionsTests
1311
[Theory]
1412
[InlineData(nameof(DerivedThing.Id), typeof(DerivedThing))]
1513
[InlineData(nameof(DerivedThing.Name), typeof(BaseThing))]
14+
[InlineData(nameof(DerivedThing.DataInBytes), typeof(BaseThing))]
1615
[InlineData(nameof(DerivedThing.Description), typeof(DerivedThing))]
1716
public void MemberInfoReflectedTypeMustMatchTheDeclaringType(string propertyName, Type reflectedType)
1817
{
@@ -26,30 +25,71 @@ public void MemberInfoReflectedTypeMustMatchTheDeclaringType(string propertyName
2625
[Theory]
2726
[InlineData(nameof(DerivedThing.Id), typeof(DerivedThing))]
2827
[InlineData(nameof(DerivedThing.Name), typeof(BaseThing))]
28+
[InlineData(nameof(DerivedThing.DataInBytes), typeof(BaseThing))]
2929
[InlineData(nameof(DerivedThing.Description), typeof(DerivedThing))]
30-
public void MemberInfoReflectedTypeMustMatchTheDeclaringTypeForGetSelectedMembers(string propertyName, Type reflectedType)
30+
public void MemberInfoReflectedTypeMustMatchTheDeclaringTypeForGetSelectedMembers(string propertyName,
31+
Type reflectedType)
3132
{
3233
//act
33-
MemberInfo memberInfo = typeof(DerivedThing).GetSelectedMembers(new List<string>()).FirstOrDefault(m => m.Name == propertyName);
34+
MemberInfo memberInfo = typeof(DerivedThing).GetSelectedMembers(new List<string>())
35+
.FirstOrDefault(m => m.Name == propertyName);
3436

3537
//assert
3638
Assert.Equal(reflectedType.FullName, memberInfo.ReflectedType.FullName);
3739
}
3840

39-
public abstract class BaseThing
41+
[Theory]
42+
[InlineData(typeof(DerivedThing))]
43+
[InlineData(typeof(BaseThing))]
44+
public void GetSelectedMembers_WhenSelectIsEmpty_MustReturnAllLiteralMembers(Type reflectedType)
45+
{
46+
// Act
47+
var memberInfos = reflectedType.GetSelectedMembers(Enumerable.Empty<string>().ToList());
48+
49+
// Assert
50+
Assert.Multiple(() =>
51+
{
52+
var names = memberInfos.Select(mi => mi.Name);
53+
54+
Assert.DoesNotContain(memberInfos, name => name.Name == nameof(BaseThing.Objects));
55+
56+
Assert.Contains(names, name => name == nameof(BaseThing.ParametersArray));
57+
Assert.Contains(memberInfos, name => name.Name == nameof(BaseThing.ParametersList));
58+
Assert.Contains(memberInfos, name => name.Name == nameof(BaseThing.Ints));
59+
Assert.Contains(memberInfos, name => name.Name == nameof(BaseThing.Strings));
60+
Assert.Contains(memberInfos, name => name.Name == nameof(BaseThing.Booleans));
61+
Assert.Contains(memberInfos, name => name.Name == nameof(BaseThing.DateTimes));
62+
Assert.Contains(memberInfos, name => name.Name == nameof(BaseThing.Dates));
63+
Assert.Contains(memberInfos, name => name.Name == nameof(BaseThing.Guides));
64+
Assert.Contains(memberInfos, name => name.Name == nameof(BaseThing.UnsignedInts));
65+
});
66+
}
67+
68+
private abstract class BaseThing
4069
{
4170
public string Name { get; set; }
71+
public byte[] DataInBytes { get; set; }
72+
public string[] ParametersArray { get; set; }
73+
public ICollection<string> Strings { get; set; }
74+
public List<string> ParametersList { get; set; }
75+
public List<bool> Booleans { get; set; }
76+
public ISet<DateTime> DateTimes { get; set; }
77+
public ISet<DateOnly> Dates { get; set; }
78+
public HashSet<Guid> Guides { get; set; }
79+
public uint[] UnsignedInts { get; set; }
80+
public IEnumerable<int> Ints { get; set; }
81+
public List<object> Objects { get; set; }
4282
}
4383

44-
public class DerivedThing : BaseThing, IDerivedThing
84+
private class DerivedThing : BaseThing, IDerivedThing
4585
{
4686
public Guid Id { get; set; }
4787
public string Description { get; set; }
4888
}
4989

50-
public interface IDerivedThing
90+
private interface IDerivedThing
5191
{
5292
public string Description { get; set; }
5393
}
5494
}
55-
}
95+
}

LogicBuilder.Expressions.Utils/TypeExtensions.cs

+14-1
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,22 @@ private static MemberInfo[] GetValueTypeMembers(this Type parentType)
204204
return parentType.GetMemberInfos().Where
205205
(
206206
info => (info.MemberType == MemberTypes.Field || info.MemberType == MemberTypes.Property)
207-
&& (info.GetMemberType().IsLiteralType() || info.GetMemberType() == typeof(byte[]))//Need typeof(byte[]) for SQL Server timestamp column
207+
&& (info.GetMemberType().IsLiteralType() || info.GetMemberType().IsLiteralList())
208208
).ToArray();
209209
}
210+
211+
private static bool IsLiteralList(this Type type)
212+
{
213+
// Check if type is a List
214+
if (!type.IsList()) return false;
215+
216+
// If not generic, check if it's a literal type (i.e. string[])
217+
if (!type.IsGenericType) return type.GetElementType().IsLiteralType();
218+
219+
// Extract the type T from List<T> and check if it's a literal type
220+
var firstGenericArgument = type.GetGenericArguments().First();
221+
return firstGenericArgument.IsLiteralType();
222+
}
210223

211224
private static MemberInfo[] GetMemberInfos(this Type parentType)
212225
=> parentType.GetMembers(instanceBindingFlags).Select

0 commit comments

Comments
 (0)