Permalink
Browse files

Adding support and tests for virtual property count.

  • Loading branch information...
athoscouto authored and robward-ms committed Feb 7, 2017
1 parent 2ef3fc9 commit c0c6006a5a8683507c38623144a145de128851c6
@@ -1602,6 +1602,9 @@
<Compile Include="..\UriParser\SemanticAst\CollectionResourceNode.cs">
<Link>Microsoft\OData\Core\UriParser\SemanticAst\CollectionResourceNode.cs</Link>
</Compile>
<Compile Include="..\UriParser\SemanticAst\CountVirtualPropertyNode.cs">
<Link>Microsoft\OData\Core\UriParser\SemanticAst\CountVirtualPropertyNode.cs</Link>
</Compile>
<Compile Include="..\UriParser\SemanticAst\NonResourceRangeVariable.cs">
<Link>Microsoft\OData\Core\UriParser\SemanticAst\NonResourceRangeVariable.cs</Link>
</Compile>
@@ -68,6 +68,7 @@
<Compile Include="BindingPathHelper.cs" />
<Compile Include="UriParser\ODataPathInfo.cs" />
<Compile Include="UriParser\SemanticAst\CollectionComplexNode.cs" />
<Compile Include="UriParser\SemanticAst\CountVirtualPropertyNode.cs" />
<Compile Include="UriParser\SemanticAst\SingleComplexNode.cs" />
<Compile Include="UriParser\SemanticAst\SingleResourceNode.cs" />
<Compile Include="UriParser\TypeFacetsPromotionRules.cs" />
@@ -34,6 +34,12 @@ public enum AggregationMethod
/// <summary>
/// The aggregation method CountDistinct.
/// </summary>
CountDistinct
CountDistinct,
/// <summary>
/// The aggregation method Count.
/// Used only internally to represent the virtual property $count.
/// </summary>
VirtualPropertyCount,
}
}
@@ -116,6 +116,7 @@ private IEdmTypeReference CreateAggregateExpressionTypeReference(SingleValueNode
expressionPrimitiveKind));
}
case AggregationMethod.VirtualPropertyCount:
case AggregationMethod.CountDistinct:
return EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int64, false);
case AggregationMethod.Max:
@@ -172,6 +172,11 @@ internal QueryNode BindEndPath(EndPathToken endPathToken)
return GeneratePropertyAccessQueryNode(singleValueParent as SingleResourceNode, property, state);
}
if (endPathToken.Identifier == ExpressionConstants.QueryOptionCount)
{
return new CountVirtualPropertyNode();
}
if (functionCallBinder.TryBindEndPathAsFunctionCall(endPathToken, singleValueParent, state, out boundFunction))
{
return boundFunction;
@@ -284,9 +284,19 @@ internal AggregateExpressionToken ParseAggregateExpression()
{
// expression
var expression = this.ParseExpression();
var endPathExpression = expression as EndPathToken;
AggregationMethod verb;
// "with" verb
var verb = this.ParseAggregateWith();
if (endPathExpression != null && endPathExpression.Identifier == ExpressionConstants.QueryOptionCount)
{
expression = new EndPathToken("$count", endPathExpression.NextToken);
verb = AggregationMethod.VirtualPropertyCount;
}
else
{
// "with" verb
verb = this.ParseAggregateWith();
}
// "as" alias
var alias = this.ParseAggregateAs();
@@ -0,0 +1,27 @@
using Microsoft.OData.Edm;
namespace Microsoft.OData.UriParser
{
/// <summary>
/// Dummy class that allows virtual property $count
/// to work like any other aggregation method.
/// </summary>
public sealed class CountVirtualPropertyNode : SingleValueNode
{
public CountVirtualPropertyNode() { }
public override QueryNodeKind Kind
{
get
{
return QueryNodeKind.None;
}
}
public override IEdmTypeReference TypeReference {
get {
return EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int64, false);
}
}
}
}
@@ -65,6 +65,32 @@ public void BindApplyWithAggregateShouldReturnApplyClause()
statement.Alias.Should().Be("TotalPrice");
}
[Fact]
public void BindApplyWithCountInAggregateShouldReturnApplyClause()
{
var tokens = _parser.ParseApply("aggregate($count as TotalCount)");
var binder = new ApplyBinder(FakeBindMethods.BindSingleComplexProperty, _bindingState);
var actual = binder.BindApply(tokens);
actual.Should().NotBeNull();
actual.Transformations.Should().HaveCount(1);
var transformations = actual.Transformations.ToList();
var aggregate = transformations[0] as AggregateTransformationNode;
aggregate.Should().NotBeNull();
aggregate.Kind.Should().Be(TransformationNodeKind.Aggregate);
aggregate.Expressions.Should().NotBeNull();
aggregate.Expressions.Should().HaveCount(1);
var statements = aggregate.Expressions.ToList();
var statement = statements[0];
statement.Method.Should().Be(AggregationMethod.VirtualPropertyCount);
statement.Alias.Should().Be("TotalCount");
}
[Fact]
public void BindApplyWithAggregateAndFilterShouldReturnApplyClause()
{
@@ -164,6 +164,41 @@ public void ParseApplyWithMultipleAggregateExpressionsShouldReturnAggregateToken
VerifyAggregateExpressionToken("SharePrice", AggregationMethod.CountDistinct, "SharePriceDistinctCount", statements[1]);
}
[Fact]
public void ParseApplyWithSingleCountExpressionShouldReturnAggregateToken()
{
var apply = "aggregate($count as Count)";
var actual = this.testSubject.ParseApply(apply);
actual.Should().NotBeNull();
actual.Should().HaveCount(1);
var aggregate = actual.First() as AggregateToken;
aggregate.Should().NotBeNull();
aggregate.Expressions.Should().HaveCount(1);
VerifyAggregateExpressionToken("$count", AggregationMethod.VirtualPropertyCount, "Count", aggregate.Expressions.First());
}
[Fact]
public void ParseApplyWithCountAndOtherAggregationExpressionShouldReturnAggregateToken()
{
var apply = "aggregate($count as Count, SharePrice with countdistinct as SharePriceDistinctCount)";
var actual = this.testSubject.ParseApply(apply);
actual.Should().NotBeNull();
actual.Should().HaveCount(1);
var aggregate = actual.First() as AggregateToken;
aggregate.Should().NotBeNull();
aggregate.Expressions.Should().HaveCount(2);
var statements = aggregate.Expressions.ToList();
VerifyAggregateExpressionToken("$count", AggregationMethod.VirtualPropertyCount, "Count", aggregate.Expressions.First());
VerifyAggregateExpressionToken("SharePrice", AggregationMethod.CountDistinct, "SharePriceDistinctCount", statements[1]);
}
[Fact]
public void ParseApplyWithAggregateMissingOpenParenShouldThrow()
{
@@ -5683,6 +5683,13 @@ public sealed class Microsoft.OData.UriParser.CountSegment : Microsoft.OData.Uri
public virtual T TranslateWith (PathSegmentTranslator`1 translator)
}
public sealed class Microsoft.OData.UriParser.CountVirtualPropertyNode : Microsoft.OData.UriParser.SingleValueNode {
public CountVirtualPropertyNode ()
Microsoft.OData.UriParser.QueryNodeKind Kind { public virtual get; }
Microsoft.OData.Edm.IEdmTypeReference TypeReference { public virtual get; }
}
public sealed class Microsoft.OData.UriParser.CustomUriLiteralParsers : IUriLiteralParser {
public static void AddCustomUriLiteralParser (Microsoft.OData.UriParser.IUriLiteralParser customUriLiteralParser)
public static void AddCustomUriLiteralParser (Microsoft.OData.Edm.IEdmTypeReference edmTypeReference, Microsoft.OData.UriParser.IUriLiteralParser customUriLiteralParser)
@@ -6154,6 +6161,7 @@ public enum Microsoft.OData.UriParser.Aggregation.AggregationMethod : int {
Max = 2
Min = 1
Sum = 0
VirtualPropertyCount = 5
}
public enum Microsoft.OData.UriParser.Aggregation.TransformationNodeKind : int {

0 comments on commit c0c6006

Please sign in to comment.