Skip to content
Merged
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
38 changes: 27 additions & 11 deletions src/Nest/Resolvers/PropertyNameResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace Nest.Resolvers
{
Expand Down Expand Up @@ -130,9 +132,12 @@ protected override Expression VisitMethodCall(MethodCallExpression m, Stack<stri
{
if (m.Method.Name == "Suffix" && m.Arguments.Any())
{
var constantExpression = m.Arguments.Last() as ConstantExpression;
if (constantExpression != null)
stack.Push(constantExpression.Value as string);
VisitConstantOrVariable(m, stack);
var callingMember = new ReadOnlyCollection<Expression>(
new List<Expression> {{m.Arguments.First()}}
);
base.VisitExpressionList(callingMember, stack, properties);
return m;
}
else if (m.Method.Name == "FullyQualified" && m.Arguments.Any())
{
Expand All @@ -142,20 +147,21 @@ protected override Expression VisitMethodCall(MethodCallExpression m, Stack<stri
}
else if (m.Method.Name == "get_Item" && m.Arguments.Any())
{
if (!typeof(IDictionary).IsAssignableFrom(m.Object.Type))
var t = m.Object.Type;
var isDict =
typeof(IDictionary).IsAssignableFrom(t)
|| typeof(IDictionary<,>).IsAssignableFrom(t)
|| (t.IsGenericType && t.GetGenericTypeDefinition() == typeof (IDictionary<,>));

if (!isDict)
{
return base.VisitMethodCall(m, stack, properties);
}
var lastArg = m.Arguments.Last();
var constantExpression = lastArg as ConstantExpression;
var value = constantExpression != null
? constantExpression.Value.ToString()
: Expression.Lambda(lastArg).Compile().DynamicInvoke().ToString();
stack.Push(value);
VisitConstantOrVariable(m, stack);
Visit(m.Object, stack, properties);
return m;
}
if (IsLinqOperator(m.Method))
else if (IsLinqOperator(m.Method))
{
for (int i = 1; i < m.Arguments.Count; i++)
{
Expand All @@ -166,6 +172,16 @@ protected override Expression VisitMethodCall(MethodCallExpression m, Stack<stri
}
return base.VisitMethodCall(m, stack, properties);
}

private static void VisitConstantOrVariable(MethodCallExpression m, Stack<string> stack)
{
var lastArg = m.Arguments.Last();
var constantExpression = lastArg as ConstantExpression;
var value = constantExpression != null
? constantExpression.Value.ToString()
: Expression.Lambda(lastArg).Compile().DynamicInvoke().ToString();
stack.Push(value);
}

private static bool IsLinqOperator(MethodInfo method)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using FluentAssertions;
using Nest.Resolvers;
using NUnit.Framework;
using Nest.Tests.MockData.Domain;

namespace Nest.Tests.Unit.Internals.Inferno
{
[TestFixture]
public class PropertyPathResolverTests
{
private class CustomDict : Dictionary<string, ElasticsearchProject> { }

private class DomainObject
{
public string Name { get; set; }
public IDictionary<string, ElasticsearchProject> Dictionary { get; set; }
public CustomDict CustomDict { get; set; }
public IList<ElasticsearchProject> Collection { get; set; }

}

private readonly ElasticInferrer _infer;
private readonly string _variable = "vari";

public PropertyPathResolverTests()
{
_infer = TestElasticClient.Client.Infer;
}

private string P(Expression<Func<DomainObject, object>> path)
{
return this._infer.PropertyPath(Property.Path(path));
}

[Test]
public void SimpleProperty()
{
P(p => p.Name).Should().Be("name");
}

[Test]
public void SuffixOnPropery()
{
P(p => p.Name.Suffix("sort")).Should().Be("name.sort");
}

[Test]
public void IndexOnCollection()
{
P(p => p.Collection[0]).Should().Be("collection");
}

[Test]
public void IndexOnCollectionProperty()
{
P(p => p.Collection[0].Name).Should().Be("collection.name");
}

[Test]
public void FirstOnCollection()
{
P(p => p.Collection.First()).Should().Be("collection");
}

[Test]
public void FirstOnCollectionProperty()
{
P(p => p.Collection.First().Name).Should().Be("collection.name");
}

[Test]
public void Dictionary()
{
P(p => p.Dictionary["hardcoded"]).Should().Be("dictionary.hardcoded");
}

[Test]
public void DictionaryPropery()
{
P(p => p.Dictionary["hardcoded"].Name).Should().Be("dictionary.hardcoded.name");
}

//Test variables
[Test]
public void DictionaryVariableKey()
{
P(p => p.Dictionary[_variable]).Should().Be("dictionary.vari");
}

[Test]
public void DictionaryVariableKeyProperty()
{
P(p => p.Dictionary[_variable].Name).Should().Be("dictionary.vari.name");
}

[Test]
public void CustomDictionary()
{
P(p => p.CustomDict["hardcoded"]).Should().Be("customDict.hardcoded");
}

[Test]
public void CustomDictionaryPropery()
{
P(p => p.CustomDict["hardcoded"].Name).Should().Be("customDict.hardcoded.name");
}

//Test variables

[Test]
public void CustomDictionaryVariableKey()
{
P(p => p.CustomDict[_variable]).Should().Be("customDict.vari");
}

[Test]
public void CustomDictionaryVariableKeyProperty()
{
P(p => p.CustomDict[_variable].Name).Should().Be("customDict.vari.name");
}

//Test suffixes
[Test]
public void PropertySuffix()
{
P(p => p.Name.Suffix("suffix")).Should().Be("name.suffix");
}

[Test]
public void DictionarySuffix()
{
P(p => p.Dictionary["hardcoded"].Suffix("suffix")).Should().Be("dictionary.hardcoded.suffix");
}

[Test]
public void FirstOnCollectionSuffix()
{
P(p => p.Collection.First().Suffix("suffix")).Should().Be("collection.suffix");
}

[Test]
public void IndexOnCollectionSuffix()
{
P(p => p.Collection[0].Suffix("suffix")).Should().Be("collection.suffix");
}

[Test]
public void CollectionSuffix()
{
P(p => p.Collection.Suffix("suffix")).Should().Be("collection.suffix");
}

[Test]
public void PropertySuffixVariable()
{
P(p => p.Name.Suffix(_variable)).Should().Be("name.vari");
}

[Test]
public void PropertySuffixLocalVariable()
{
var prop = "propXY12";
P(p => p.Name.Suffix(prop)).Should().Be("name." + prop);
}

//Fully qualified tests
//TODO remove in 2.0 as type.properties are gonna be removed in elasticsearch 2.0

[Test]
public void PropertySuffixVariableFullyQualified()
{
P(p => p.FullyQualified().Name.Suffix(_variable)).Should().Be("domainobject.name.vari");
}
}
}

This file was deleted.

2 changes: 1 addition & 1 deletion src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@
<Compile Include="Core\AttributeBasedMap\BaseAttributeMappingTests.cs" />
<Compile Include="Core\AttributeBasedMap\DeepObjectMappingTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Internals\Inferno\PropertyVisitorTests.cs" />
<Compile Include="Internals\Inferno\PropertyPathResolverTests.cs" />
<Compile Include="Search\Highlight\HighlightTests.cs" />
<Compile Include="Search\Query\ConditionLess\ConditionLessTests.cs" />
<Compile Include="Search\Query\ConditionlessBool\ConditionLessBooleanTests.cs" />
Expand Down