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, DefaultUriResolver, ref entityType, out firstNonTypeToken); followInvalidTypeSegment.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.SelectExpandPathBinder_FollowNonTypeSegment("Stuff")); }
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, DefaultUriResolver, ref entityType, out firstNonTypeToken); followLongChain.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.ExpandItemBinder_PathTooDeep); }
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, DefaultUriResolver, 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 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, DefaultUriResolver, 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"); }
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, 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); // next, create an ODataPath and add the segments to it. if (lastSegment != null) { 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 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, DefaultUriResolver, ref entityType, out firstNonTypeToken); var segment = Assert.Single(result); var caseSegment = Assert.IsType <TypeSegment>(segment); Assert.Same(HardCodedTestModel.GetEmployeeType(), caseSegment.EdmType); Assert.Same(HardCodedTestModel.GetEmployeeType(), entityType); firstNonTypeToken.ShouldBeNonSystemToken("WorkEmail"); }
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, DefaultUriResolver, ref entityType, out firstNonTypeToken); var castSegments = result.OfType <TypeSegment>(); Assert.Equal(2, castSegments.Count()); Assert.Contains(castSegments, x => x.EdmType == HardCodedTestModel.GetEmployeeType()); Assert.Contains(castSegments, x => x.EdmType == HardCodedTestModel.GetManagerType()); Assert.Same(HardCodedTestModel.GetManagerType(), entityType); firstNonTypeToken.ShouldBeNonSystemToken("NumberOfReports"); }
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); }