public void SingleExpandResultsInSingleExpandTree() { SelectExpandPathToStringVisitor visitor = new SelectExpandPathToStringVisitor(); NonSystemToken path = new NonSystemToken("NavProp", null, null); path.IsStructuralProperty = false; path.Accept(visitor).Should().Be("NavProp"); }
public void IsNamespaceOrContainerQualifiedIsCorrect() { NonSystemToken token1 = new NonSystemToken("Fully.Qualified.Namespace", null, null); token1.IsNamespaceOrContainerQualified().Should().BeTrue(); NonSystemToken token2 = new NonSystemToken("namespace", null, null); token2.IsNamespaceOrContainerQualified().Should().BeFalse(); }
public void MaxRecursiveDepthIsRespected() { NonSystemToken typeSegment = new NonSystemToken("Fully.Qualified.Namespace.Employee", null, new NonSystemToken("Fully.Qualified.Namespace.Manager", null, new NonSystemToken("NumberOfReports", null, null))); PathSegmentToken firstNonTypeToken; IEdmStructuredType entityType = HardCodedTestModel.GetPersonType(); Action followLongChain = () => SelectExpandPathBinder.FollowTypeSegments(typeSegment, HardCodedTestModel.TestModel, 1, ODataUriResolver.Default, ref entityType, out firstNonTypeToken); followLongChain.ShouldThrow<ODataException>().WithMessage(ODataErrorStrings.ExpandItemBinder_PathTooDeep); }
public void InvalidTypeSegmentThrowsException() { NonSystemToken typeSegment = new NonSystemToken("Stuff", null, new NonSystemToken("stuff", null, null)); PathSegmentToken firstNonTypeToken; IEdmStructuredType entityType = HardCodedTestModel.GetPersonType(); Action followInvalidTypeSegment = () => SelectExpandPathBinder.FollowTypeSegments(typeSegment, HardCodedTestModel.TestModel, 800, ODataUriResolver.Default, ref entityType, out firstNonTypeToken); followInvalidTypeSegment.ShouldThrow<ODataException>().WithMessage(ODataErrorStrings.SelectExpandPathBinder_FollowNonTypeSegment("Stuff")); }
public void PathWithoutWildcardIsInvariant() { RemoveWildcardVisitor visitor = new RemoveWildcardVisitor(); NonSystemToken token = new NonSystemToken("stuff", null, null); token.Accept(visitor); token.Identifier.Should().Be("stuff"); token.NextToken.Should().BeNull(); }
public void NamedValuesSetCorrectly() { List<NamedValue> namedValues = new List<NamedValue>(); namedValues.Add(new NamedValue("name", new LiteralToken("value"))); NonSystemToken token = new NonSystemToken("stuff", namedValues, null); token.NamedValues.Should().OnlyContain(x => x.Name == "name" && x.Value.Value.As<string>() == "value"); }
public void ReversePathWorksWithStarToken() { // $expand=1/* PathReverser pathReverser = new PathReverser(); PathSegmentToken nonReversedPath = new NonSystemToken("*", null, new NonSystemToken("1", null, null)); PathSegmentToken reversedPath = nonReversedPath.Accept(pathReverser); reversedPath.ShouldBeNonSystemToken("1").And.NextToken.ShouldBeNonSystemToken("*"); }
public void ExpandOnlyPathResultsInExpandOnlyTree() { SelectExpandPathToStringVisitor visitor = new SelectExpandPathToStringVisitor(); NonSystemToken path = new NonSystemToken("NavProp", null, new NonSystemToken("NavProp1", null, null)); path.IsStructuralProperty = false; path.NextToken.IsStructuralProperty = false; path.Accept(visitor).Should().Be("NavProp($expand=NavProp1)"); }
public void SelectAtTheEndOfPathResultsInSelectQueryOption() { SelectExpandPathToStringVisitor visitor = new SelectExpandPathToStringVisitor(); NonSystemToken path = new NonSystemToken("NavProp", null, new NonSystemToken("StructuralProp", null, null)); path.IsStructuralProperty = false; path.NextToken.IsStructuralProperty = true; path.Accept(visitor).Should().Be("NavProp($select=StructuralProp)"); }
public void ReversePathWorksWithSingleSegment() { // $expand=1 PathReverser pathReverser = new PathReverser(); PathSegmentToken nonReversedPath = new NonSystemToken("1", null, null); PathSegmentToken reversedPath = nonReversedPath.Accept(pathReverser); reversedPath.ShouldBeNonSystemToken("1").And.NextToken.Should().BeNull(); }
public void ReversePathWorksWithATypeToken() { // $expand=Fully.Qualified.Namespace/1 PathReverser pathReverser = new PathReverser(); PathSegmentToken nonReversedPath = new NonSystemToken("1", null, new NonSystemToken("Fully.Qualified.Namespace", null, null)); PathSegmentToken reversedPath = nonReversedPath.Accept(pathReverser); reversedPath.ShouldBeNonSystemToken("Fully.Qualified.Namespace").And.NextToken.ShouldBeNonSystemToken("1"); }
public void IfNewTokenIsNullInputIsInvariant() { AddNewEndingTokenVisitor visitor = new AddNewEndingTokenVisitor(null); NonSystemToken token = new NonSystemToken("stuff", null, null); token.Accept(visitor); token.Identifier.Should().Be("stuff"); token.NextToken.Should().BeNull(); }
public void WildcardIsRemoved() { RemoveWildcardVisitor visitor = new RemoveWildcardVisitor(); NonSystemToken token = new NonSystemToken("stuff", null, new NonSystemToken("*", null, null)); token.Accept(visitor); token.Identifier.Should().Be("stuff"); token.NextToken.Should().BeNull(); }
public void ExpandTermTokenPathIsSet() { PathSegmentToken pathToken = new NonSystemToken("SomeNavProp", null, null); ExpandOptionParser optionParser = new ExpandOptionParser(5); var termToken = optionParser.BuildExpandTermToken(pathToken, ""); termToken.PathToNavProp.Should().Be(pathToken); }
public void IfNewTokenIsPresentItIsAddedToEndOfPath() { AddNewEndingTokenVisitor visitor = new AddNewEndingTokenVisitor(new NonSystemToken("moreStuff", null, null)); NonSystemToken token = new NonSystemToken("stuff", null, null); token.Accept(visitor); token.Identifier.Should().Be("stuff"); token.NextToken.Identifier.Should().Be("moreStuff"); token.NextToken.NextToken.Should().BeNull(); }
public void BindingOnTreeWithWithMultipleNavPropPathsThrows() { NonSystemToken topLevelSegment = new NonSystemToken("MyDog", null, null); NonSystemToken navProp = new NonSystemToken("MyPeople", null, topLevelSegment); ExpandTermToken expandTerm = new ExpandTermToken(navProp); ExpandToken expandToken = new ExpandToken(new ExpandTermToken[] {expandTerm}); Action bindTreeWithMultipleNavPropPaths = () => this.binderForPerson.Bind(BuildUnifiedSelectExpandToken(expandToken)); bindTreeWithMultipleNavPropPaths.ShouldThrow<ODataException>() .WithMessage(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath); }
public void SingleLevelTypeSegmentWorks() { NonSystemToken typeSegment = new NonSystemToken("Fully.Qualified.Namespace.Employee", null, new NonSystemToken("WorkEmail", null, null)); PathSegmentToken firstNonTypeToken; IEdmStructuredType entityType = HardCodedTestModel.GetPersonType(); var result = SelectExpandPathBinder.FollowTypeSegments(typeSegment, HardCodedTestModel.TestModel, 800, ODataUriResolver.Default, ref entityType, out firstNonTypeToken); result.Should().OnlyContain(x => x.Equals(new TypeSegment(HardCodedTestModel.GetEmployeeType(), null))); entityType.Should().Be(HardCodedTestModel.GetEmployeeType()); firstNonTypeToken.ShouldBeNonSystemToken("WorkEmail"); }
public void ReversePathWorksWithDeepPath() { // $expand=1/2/3/4 PathReverser pathReverser = new PathReverser(); NonSystemToken endPath = new NonSystemToken("4", null, new NonSystemToken("3", null, new NonSystemToken("2", null, new NonSystemToken("1", null, null)))); PathSegmentToken reversedPath = endPath.Accept(pathReverser); reversedPath.ShouldBeNonSystemToken("1") .And.NextToken.ShouldBeNonSystemToken("2") .And.NextToken.ShouldBeNonSystemToken("3") .And.NextToken.ShouldBeNonSystemToken("4"); }
public void NormalizeTreeResultsInReversedPath() { // $select=1/2/3 NonSystemToken endPath = new NonSystemToken("3", null, new NonSystemToken("2", null, new NonSystemToken("1", null, null))); SelectToken selectToken = new SelectToken(new NonSystemToken[]{endPath}); SelectTreeNormalizer selectTreeNormalizer = new SelectTreeNormalizer(); SelectToken normalizedToken = selectTreeNormalizer.NormalizeSelectTree(selectToken); normalizedToken.Properties.Single().ShouldBeNonSystemToken("1") .And.NextToken.ShouldBeNonSystemToken("2") .And.NextToken.ShouldBeNonSystemToken("3"); }
public void DeepPath() { NonSystemToken typeSegment = new NonSystemToken("Fully.Qualified.Namespace.Employee", null, new NonSystemToken("Fully.Qualified.Namespace.Manager", null, new NonSystemToken("NumberOfReports", null, null))); PathSegmentToken firstNonTypeToken; IEdmStructuredType entityType = HardCodedTestModel.GetPersonType(); var result = SelectExpandPathBinder.FollowTypeSegments(typeSegment, HardCodedTestModel.TestModel, 800, ODataUriResolver.Default, ref entityType, out firstNonTypeToken); result.Should().Contain(x => x.As<TypeSegment>().EdmType == HardCodedTestModel.GetEmployeeType()) .And.Contain(x => x.As<TypeSegment>().EdmType == HardCodedTestModel.GetManagerType()); entityType.Should().Be(HardCodedTestModel.GetManagerType()); firstNonTypeToken.ShouldBeNonSystemToken("NumberOfReports"); }
/// <summary> /// Traverse a NonSystemToken. /// </summary> /// <param name="tokenIn">The NonSystemToken to traverse.</param> public void Visit(NonSystemToken tokenIn) { if (tokenIn.NextToken == null) { if (newTokenToAdd != null) { tokenIn.SetNextToken(newTokenToAdd); } } else { tokenIn.NextToken.Accept(this); } }
public void CombineTermsWorksForMultipleTerms() { // $expand=1($expand=2), 1($expand=3) List<ExpandTermToken> expandTerms = new List<ExpandTermToken>(); var token2 = new NonSystemToken("2", null, null); var token3 = new NonSystemToken("3", null, null); expandTerms.Add(new ExpandTermToken(new NonSystemToken("1", /*namedValues*/null, /*nextToken*/null), /*SelectToken*/null, new ExpandToken(new List<ExpandTermToken>() { new ExpandTermToken(token2) }))); expandTerms.Add(new ExpandTermToken(new NonSystemToken("1", /*namedValues*/null, /*nextToken*/null), /*SelectToken*/null, new ExpandToken(new List<ExpandTermToken>() { new ExpandTermToken(token3) }))); ExpandToken expand = new ExpandToken(expandTerms); ExpandTreeNormalizer expandTreeNormalizer = new ExpandTreeNormalizer(); ExpandToken combinedExpand = expandTreeNormalizer.CombineTerms(expand); combinedExpand.ExpandTerms.Single().ShouldBeExpandTermToken("1", true); combinedExpand.ExpandTerms.ElementAt(0).ExpandOption.ExpandTerms.Should().Contain(t => t.PathToNavProp == token2); combinedExpand.ExpandTerms.ElementAt(0).ExpandOption.ExpandTerms.Should().Contain(t => t.PathToNavProp == token3); }
/// <summary> /// Visit a NonSystemToken /// </summary> /// <param name="tokenIn">the non sytem token to visit</param> public override void Visit(NonSystemToken tokenIn) { ExceptionUtils.CheckArgumentNotNull(tokenIn, "tokenIn"); // before looking for type segments or paths, handle both of the wildcard cases. if (tokenIn.NextToken == null) { SelectItem newSelectItem; if (SelectPathSegmentTokenBinder.TryBindAsWildcard(tokenIn, this.model, out newSelectItem)) { this.expandClauseToDecorate.AddToSelectedItems(newSelectItem); return; } } this.ProcessTokenAsPath(tokenIn); }
public void NormalizeTreeWorksForMultipleTerms() { // $select=1/2/3,4/5/6 NonSystemToken endPath = new NonSystemToken("3", null, new NonSystemToken("2", null, new NonSystemToken("1", null, null))); NonSystemToken endPath1 = new NonSystemToken("6", null, new NonSystemToken("5", null, new NonSystemToken("4", null, null))); SelectToken selectToken = new SelectToken(new NonSystemToken[]{endPath, endPath1}); SelectTreeNormalizer selectTreeNormalizer = new SelectTreeNormalizer(); SelectToken normalizedToken = selectTreeNormalizer.NormalizeSelectTree(selectToken); List<PathSegmentToken> tokens = normalizedToken.Properties.ToList(); tokens.Should().HaveCount(2); tokens.ElementAt(0).ShouldBeNonSystemToken("1") .And.NextToken.ShouldBeNonSystemToken("2") .And.NextToken.ShouldBeNonSystemToken("3"); tokens.ElementAt(1).ShouldBeNonSystemToken("4") .And.NextToken.ShouldBeNonSystemToken("5") .And.NextToken.ShouldBeNonSystemToken("6"); }
/// <summary> /// Translate a NonSystemToken. /// </summary> /// <param name="tokenIn">The NonSystemToken to translate.</param> public void Visit(NonSystemToken tokenIn) { if (tokenIn.Identifier != UriHelper.ASTERISK.ToString()) { if (tokenIn.NextToken == null) { return; } previous = tokenIn; tokenIn.NextToken.Accept(this); } else { previous.SetNextToken(null); return; } }
public void NormalizeTreeWorksForMultipleTerms() { // $select=1/2/3,4/5/6 NonSystemToken endPath = new NonSystemToken("3", null, new NonSystemToken("2", null, new NonSystemToken("1", null, null))); NonSystemToken endPath1 = new NonSystemToken("6", null, new NonSystemToken("5", null, new NonSystemToken("4", null, null))); SelectToken selectToken = new SelectToken(new NonSystemToken[] { endPath, endPath1 }); SelectTreeNormalizer selectTreeNormalizer = new SelectTreeNormalizer(); SelectToken normalizedToken = selectTreeNormalizer.NormalizeSelectTree(selectToken); List <PathSegmentToken> tokens = normalizedToken.Properties.ToList(); tokens.Should().HaveCount(2); tokens.ElementAt(0).ShouldBeNonSystemToken("1") .And.NextToken.ShouldBeNonSystemToken("2") .And.NextToken.ShouldBeNonSystemToken("3"); tokens.ElementAt(1).ShouldBeNonSystemToken("4") .And.NextToken.ShouldBeNonSystemToken("5") .And.NextToken.ShouldBeNonSystemToken("6"); }
/// <summary> /// Appends a name of a property/link/type to the current expand path. /// </summary> /// <param name="name">name of the property/link/type which needs to be added to the expand path.</param> /// <param name="isStructural">is this a structural property.</param> private void AppendToExpandPath(string name, bool isStructural) { PathSegmentToken path = this.expandPaths.LastOrDefault(); NonSystemToken newToken = new NonSystemToken(name, /*namedValues*/ null, /*nextToken*/ null); newToken.IsStructuralProperty = isStructural; if (path != null) { expandPaths.Remove(path); AddNewEndingTokenVisitor addNewEndingTokenVisitor = new AddNewEndingTokenVisitor(newToken); path.Accept(addNewEndingTokenVisitor); expandPaths.Add(path); } else { expandPaths.Add(newToken); } }
/// <summary> /// Write out a PathSegmentToken /// </summary> /// <param name="segmentToken">the pathSegmentToken to write.</param> private void WritePathSegment(PathSegmentToken segmentToken) { NonSystemToken nonSystemToken = segmentToken as NonSystemToken; if (nonSystemToken != null) { // If this desriptor have no path, it is a service-document Url, so just quit if (string.IsNullOrEmpty(nonSystemToken.Identifier)) { return; } if (nonSystemToken.NextToken != null) { this.WritePathSegment(nonSystemToken.NextToken); this.builder.Append(ExpressionConstants.SymbolForwardSlash); } this.builder.Append(nonSystemToken.Identifier); if (nonSystemToken.NamedValues != null) { this.builder.Append(ExpressionConstants.SymbolOpenParen); bool needComma = false; foreach (NamedValue nv in nonSystemToken.NamedValues) { if (needComma) { this.builder.Append(ExpressionConstants.SymbolComma); } this.builder.Append(nv.Name); this.builder.Append(ExpressionConstants.SymbolEqual); this.WriteLiteral(nv.Value); needComma = true; } this.builder.Append(ExpressionConstants.SymbolClosedParen); } } }
public void NormalizeTreeWorksWhenPathsHaveArguments() { // Arrange: $expand=1(name=value) ExpandToken expand = new ExpandToken(new ExpandTermToken[] { new ExpandTermToken(new NonSystemToken("1", new NamedValue[] { new NamedValue("name", new LiteralToken("value")) }, null)) }); // Act ExpandToken normalizedExpand = ExpandTreeNormalizer.NormalizeExpandTree(expand); // Assert Assert.NotNull(normalizedExpand); ExpandTermToken term = Assert.Single(normalizedExpand.ExpandTerms).ShouldBeExpandTermToken("1", true); NonSystemToken token = Assert.IsType <NonSystemToken>(term.PathToNavigationProp); Assert.Single(token.NamedValues).ShouldBeNamedValue("name", "value"); Assert.Null(term.ExpandOption); }
public void CombineTermsWorksForMultipleTerms() { // $expand=1($expand=2), 1($expand=3) List <ExpandTermToken> expandTerms = new List <ExpandTermToken>(); var token2 = new NonSystemToken("2", null, null); var token3 = new NonSystemToken("3", null, null); expandTerms.Add(new ExpandTermToken(new NonSystemToken("1", /*namedValues*/ null, /*nextToken*/ null), /*SelectToken*/ null, new ExpandToken(new List <ExpandTermToken>() { new ExpandTermToken(token2) }))); expandTerms.Add(new ExpandTermToken(new NonSystemToken("1", /*namedValues*/ null, /*nextToken*/ null), /*SelectToken*/ null, new ExpandToken(new List <ExpandTermToken>() { new ExpandTermToken(token3) }))); ExpandToken expand = new ExpandToken(expandTerms); ExpandTreeNormalizer expandTreeNormalizer = new ExpandTreeNormalizer(); ExpandToken combinedExpand = expandTreeNormalizer.CombineTerms(expand); combinedExpand.ExpandTerms.Single().ShouldBeExpandTermToken("1", true); combinedExpand.ExpandTerms.ElementAt(0).ExpandOption.ExpandTerms.Should().Contain(t => t.PathToNavigationProp == token2); combinedExpand.ExpandTerms.ElementAt(0).ExpandOption.ExpandTerms.Should().Contain(t => t.PathToNavigationProp == token3); }
public void NullPathSegmentTokensAreNotEquivalentToAnyNonNullToken() { var token = new NonSystemToken("foo", null, null); this.testSubject.Equals(null, token).Should().BeFalse(); this.testSubject.Equals(token, null).Should().BeFalse(); }
/// <summary> /// Building off of a PathSegmentToken whose value is star, only nested level options is allowed. /// </summary> /// <param name="pathToken">The PathSegmentToken representing the parsed expand path whose options we are now parsing.</param> /// <returns>An expand term token based on the path token, and all available expand options.</returns> private List <ExpandTermToken> BuildStarExpandTermToken(PathSegmentToken pathToken) { List <ExpandTermToken> expandTermTokenList = new List <ExpandTermToken>(); long?levelsOption = null; bool isRefExpand = (pathToken.Identifier == UriQueryConstants.RefSegment); // Based on the specification, // For star in expand, this will be supported, // $expand=* // $expand=EntitySet($expand=* ) // $expand=*/$ref // $expand=*,EntitySet // $expand=EntitySet, * // $expand=*/$ref,EntitySet // Parenthesized set of expand options for star expand option supported are $level per specification. // And this will throw exception, // $expand= * /$count // Parenthesized set of expand options for star expand option which will also cause exception are $filter, $select, $orderby, $skip, $top, $count, $search, and $expand per specification. // And level is not supported with "*/$ref". // As 2016/1/8, the navigation property is only supported in entity type, and will support in ComplexType in future. if (this.lexer.CurrentToken.Kind == ExpressionTokenKind.OpenParen) { // advance past the '(' this.lexer.NextToken(); // Check for (), which is not allowed. if (this.lexer.CurrentToken.Kind == ExpressionTokenKind.CloseParen) { throw new ODataException(ODataErrorStrings.UriParser_MissingExpandOption(pathToken.Identifier)); } // Only level option is supported by expand. while (this.lexer.CurrentToken.Kind != ExpressionTokenKind.CloseParen) { string text = this.enableCaseInsensitiveBuiltinIdentifier ? this.lexer.CurrentToken.Text.ToLowerInvariant() : this.lexer.CurrentToken.Text; switch (text) { case ExpressionConstants.QueryOptionLevels: { if (!isRefExpand) { levelsOption = ResolveLevelOption(); } else { // no option is allowed when expand with star per specification throw new ODataException(ODataErrorStrings.UriExpandParser_TermIsNotValidForStarRef(this.lexer.ExpressionText)); } break; } default: { throw new ODataException(ODataErrorStrings.UriExpandParser_TermIsNotValidForStar(this.lexer.ExpressionText)); } } } // Move past the ')' this.lexer.NextToken(); } // Either there was no '(' at all or we just read past the ')' so we should be at the end if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.End) { throw new ODataException(ODataErrorStrings.UriSelectParser_TermIsNotValid(this.lexer.ExpressionText)); } // As 2016/1/8, the navigation property is only supported in entity type, and will support in ComplexType in future. var entityType = parentEntityType as IEdmEntityType; if (entityType == null) { throw new ODataException(ODataErrorStrings.UriExpandParser_ParentEntityIsNull(this.lexer.ExpressionText)); } foreach (var navigationProperty in entityType.NavigationProperties()) { var tmpPathToken = default(PathSegmentToken); // create path token for each navigation properties. if (pathToken.Identifier.Equals(UriQueryConstants.RefSegment)) { tmpPathToken = new NonSystemToken(navigationProperty.Name, null, pathToken.NextToken.NextToken); tmpPathToken = new NonSystemToken(UriQueryConstants.RefSegment, null, tmpPathToken); } else { tmpPathToken = new NonSystemToken(navigationProperty.Name, null, pathToken.NextToken); } ExpandTermToken currentToken = new ExpandTermToken(tmpPathToken, null, null, null, null, null, levelsOption, null, null, null); expandTermTokenList.Add(currentToken); } return(expandTermTokenList); }
public void IdentifierSetCorrectly() { NonSystemToken token = new NonSystemToken("stuff", null, null); Assert.Equal("stuff", token.Identifier); }
internal static bool TryBindAsOperation(PathSegmentToken pathToken, IEdmModel model, IEdmStructuredType entityType, out ODataPathSegment segment) { Debug.Assert(pathToken != null, "pathToken != null"); Debug.Assert(entityType != null, "bindingType != null"); List <IEdmOperation> possibleFunctions = new List <IEdmOperation>(); // Catch all catchable exceptions as FindDeclaredBoundOperations is implemented by anyone. // If an exception occurs it will be supressed and the possible functions will be empty and return false. try { int wildCardPos = pathToken.Identifier.IndexOf("*", StringComparison.Ordinal); if (wildCardPos > -1) { string namespaceName = pathToken.Identifier.Substring(0, wildCardPos - 1); possibleFunctions = model.FindBoundOperations(entityType).Where(o => o.Namespace == namespaceName).ToList(); } else { NonSystemToken nonSystemToken = pathToken as NonSystemToken; IList <string> parameterNames = new List <string>(); if (nonSystemToken != null && nonSystemToken.NamedValues != null) { parameterNames = nonSystemToken.NamedValues.Select(s => s.Name).ToList(); } if (parameterNames.Count > 0) { // Always force to use fully qualified name when select operation possibleFunctions = model.FindBoundOperations(entityType).FilterByName(true, pathToken.Identifier).FilterOperationsByParameterNames(parameterNames, false).ToList(); } else { possibleFunctions = model.FindBoundOperations(entityType).FilterByName(true, pathToken.Identifier).ToList(); } } } catch (Exception exc) { if (!ExceptionUtils.IsCatchableExceptionType(exc)) { throw; } } possibleFunctions = possibleFunctions.EnsureOperationsBoundWithBindingParameter().ToList(); // Only filter if there is more than one and its needed. if (possibleFunctions.Count > 1) { possibleFunctions = possibleFunctions.FilterBoundOperationsWithSameTypeHierarchyToTypeClosestToBindingType(entityType).ToList(); } if (possibleFunctions.Count <= 0) { segment = null; return(false); } segment = new OperationSegment(possibleFunctions, null /*entitySet*/); return(true); }
private void ProcessTokenAsPath(NonSystemToken tokenIn) { Debug.Assert(tokenIn != null, "tokenIn != null"); List <ODataPathSegment> pathSoFar = new List <ODataPathSegment>(); IEdmStructuredType currentLevelType = this.edmType; // first, walk through all type segments in a row, converting them from tokens into segments. if (tokenIn.IsNamespaceOrContainerQualified()) { PathSegmentToken firstNonTypeToken; pathSoFar.AddRange(SelectExpandPathBinder.FollowTypeSegments(tokenIn, this.model, this.maxDepth, this.resolver, ref currentLevelType, out firstNonTypeToken)); Debug.Assert(firstNonTypeToken != null, "Did not get last token."); tokenIn = firstNonTypeToken as NonSystemToken; if (tokenIn == null) { throw new ODataException(ODataErrorStrings.SelectPropertyVisitor_SystemTokenInSelect(firstNonTypeToken.Identifier)); } } // next, create a segment for the first non-type segment in the path. ODataPathSegment lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(tokenIn, this.model, currentLevelType, resolver); // next, create an ODataPath and add the segments to it. if (lastSegment != null) { pathSoFar.Add(lastSegment); // try create a complex type property path. while (true) { // no need to go on if the current property is not of complex type. currentLevelType = lastSegment.EdmType as IEdmStructuredType; if (currentLevelType == null || currentLevelType.TypeKind != EdmTypeKind.Complex) { break; } NonSystemToken nextToken = tokenIn.NextToken as NonSystemToken; if (nextToken == null) { break; } // first try bind the segment as property. lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(nextToken, this.model, currentLevelType, resolver); // then try bind the segment as type cast. if (lastSegment == null) { IEdmStructuredType typeFromNextToken = UriEdmHelpers.FindTypeFromModel(this.model, nextToken.Identifier, this.resolver) as IEdmStructuredType; if (typeFromNextToken.IsOrInheritsFrom(currentLevelType)) { lastSegment = new TypeSegment(typeFromNextToken, /*entitySet*/ null); } } // type cast failed too. if (lastSegment == null) { break; } // try move to and add next path segment. tokenIn = nextToken; pathSoFar.Add(lastSegment); } } ODataSelectPath selectedPath = new ODataSelectPath(pathSoFar); var selectionItem = new PathSelectItem(selectedPath); // non-navigation cases do not allow further segments in $select. if (tokenIn.NextToken != null) { throw new ODataException(ODataErrorStrings.SelectBinder_MultiLevelPathInSelect); } // if the selected item is a nav prop, then see if its already there before we add it. NavigationPropertySegment trailingNavPropSegment = selectionItem.SelectedPath.LastSegment as NavigationPropertySegment; if (trailingNavPropSegment != null) { if (this.expandClauseToDecorate.SelectedItems.Any(x => x is PathSelectItem && ((PathSelectItem)x).SelectedPath.Equals(selectedPath))) { return; } } this.expandClauseToDecorate.AddToSelectedItems(selectionItem); }
public void IdentifierSetCorrectly() { NonSystemToken token = new NonSystemToken("stuff", null, null); token.Identifier.Should().Be("stuff"); }
/// <summary> /// Visit an NonSystemToken /// </summary> /// <param name="tokenIn">The System token to visit</param> /// <returns>A user defined class</returns> public virtual T Visit(NonSystemToken tokenIn) { throw new NotImplementedException(); }
public void PathSegmentTokensAreNotEquivalentDueToLength() { var token1 = new NonSystemToken("foo", null, null); var token2 = new NonSystemToken("foo", null, new SystemToken("$batch", null)); this.testSubject.Equals(token1, token2).Should().BeFalse(); }
public void PathSegmentTokensAreNotEquivalentAtSecondPosition() { var token1 = new NonSystemToken("foo", null, new SystemToken("$metadata", null)); var token2 = new NonSystemToken("foo", null, new SystemToken("$batch", null)); this.testSubject.Equals(token1, token2).Should().BeFalse(); }
public void PathSegmentTokenHashCodesShouldBeDifferent() { var token1 = new NonSystemToken("foo", null, null); var token2 = new NonSystemToken("bar", null, null); this.testSubject.GetHashCode(token1).Should().NotBe(this.testSubject.GetHashCode(token2)); }
public void PathSegmentTokenHashCodesShouldBeTheSame() { var token1 = new NonSystemToken("foo", null, new SystemToken("$metadata", null)); var token2 = new NonSystemToken("foo", null, new SystemToken("$metadata", null)); this.testSubject.GetHashCode(token1).Should().Be(this.testSubject.GetHashCode(token2)); }
// TODO: Probably missing more simple test cases // TODO: Write interesting, complex parsing cases private ExpandTermToken ParseExpandOptions(string optionsText, int maxDepth = 100) { PathSegmentToken pathToken = new NonSystemToken("NavProp", null, null); ExpandOptionParser optionParser = new ExpandOptionParser(maxDepth) { MaxFilterDepth = 9, MaxSearchDepth = 9, MaxOrderByDepth = 9 }; return optionParser.BuildExpandTermToken(pathToken, optionsText); }