diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fa32748ac..f1bbfb69d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,11 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### Removed - Removed the `Features` API which is not supported by OpenSearch from the low-level client ([#331](https://github.com/opensearch-project/opensearch-net/pull/331)) + +### Fixed +- Fixed `IEnumerable` property mapping. ([#380](https://github.com/opensearch-project/opensearch-net/pull/375)) + + ### Dependencies - Bumps `Microsoft.CodeAnalysis.CSharp` from 4.2.0 to 4.6.0 - Bumps `NSwag.Core.Yaml` from 13.19.0 to 13.20.0 @@ -118,4 +123,4 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) [Unreleased]: https://github.com/opensearch-project/opensearch-net/compare/v1.5.0...main [1.5.0]: https://github.com/opensearch-project/opensearch-net/compare/v1.4.0...v1.5.0 [1.4.0]: https://github.com/opensearch-project/opensearch-net/compare/v1.3.0...v1.4.0 -[1.3.0]: https://github.com/opensearch-project/opensearch-net/compare/v1.2.0...v1.3.0 \ No newline at end of file +[1.3.0]: https://github.com/opensearch-project/opensearch-net/compare/v1.2.0...v1.3.0 diff --git a/src/OpenSearch.Client/Mapping/Visitor/PropertyWalker.cs b/src/OpenSearch.Client/Mapping/Visitor/PropertyWalker.cs index fcd72b7415..5734b2d21b 100644 --- a/src/OpenSearch.Client/Mapping/Visitor/PropertyWalker.cs +++ b/src/OpenSearch.Client/Mapping/Visitor/PropertyWalker.cs @@ -205,11 +205,25 @@ private static Type GetUnderlyingType(Type type) if (type.IsArray) return type.GetElementType(); - if (type.IsGenericType && type.GetGenericArguments().Length == 1 - && (type.GetInterfaces().HasAny(t => t == typeof(IEnumerable)) || Nullable.GetUnderlyingType(type) != null)) - return type.GetGenericArguments()[0]; + if (ShouldUnwrapType(type)) + { + var returnType = type.GetGenericArguments()[0]; + if (ShouldUnwrapType(returnType)) // This is needed for types like IEnumerable. + { + return returnType.GetGenericArguments()[0]; + } + return returnType; + } return type; } + + private static bool ShouldUnwrapType(Type ty) => + ty.IsGenericType && + ty.GetGenericArguments().Length == 1 && + ( + ty.GetInterfaces().HasAny(t => t == typeof(IEnumerable)) || + Nullable.GetUnderlyingType(ty) != null + ); } } diff --git a/tests/Tests/Mapping/PropertyWalkerTests .cs b/tests/Tests/Mapping/PropertyWalkerTests .cs new file mode 100644 index 0000000000..eaa5d91749 --- /dev/null +++ b/tests/Tests/Mapping/PropertyWalkerTests .cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using OpenSearch.Client; +using OpenSearch.OpenSearch.Xunit.XunitPlumbing; + +namespace Tests.Mapping +{ + public class PropertyWalkerTests + { + [U] + public void BoolGetsMappedCorrectly() + { + var result = TestPropertyType(); + result.Should().Be("boolean"); + } + + [U] + public void StringGetsMappedCorrectly() + { + var result = TestPropertyType(); + result.Should().Be("text"); + } + + + [U] + public void DateTimeGetsMappedCorrectly() + { + var result = TestPropertyType(); + result.Should().Be("date"); + } + + [U] + public void IEnumerableOfNullableGetsMappedCorrectly() + { + var result = TestPropertyType>(); + result.Should().Be("integer"); + } + + [U] + public void IListOfNullableGetsMappedCorrectly() + { + var result = TestPropertyType>(); + result.Should().Be("integer"); + } + + [U] + public void IEnumerableOfValueTypesGetsMappedCorrectly() + { + var result = TestPropertyType>(); + result.Should().Be("integer"); + } + + [U] + public void IListOfValueTypesGetsMappedCorrectly() + { + var result = TestPropertyType>(); + result.Should().Be("integer"); + } + + private static string TestPropertyType() + { + var walker = new PropertyWalker(typeof(Test), null, 0); + var properties = walker.GetProperties(); + var result = properties.SingleOrDefault(); + return result.Value?.Type; + } + + + private class Test + { + public T Values { get; set; } + } + + } +}