public void ToRoutePatternPathSegment() { // Arrange var literalPartA = RoutePatternFactory.LiteralPart("A"); var paramPartB = RoutePatternFactory.ParameterPart("B"); var paramPartC = RoutePatternFactory.ParameterPart("C"); var paramPartD = RoutePatternFactory.ParameterPart("D"); var separatorPartE = RoutePatternFactory.SeparatorPart("E"); var templateSegment = new TemplateSegment(RoutePatternFactory.Segment(paramPartC, literalPartA, separatorPartE, paramPartB)); // Act var routePatternPathSegment = templateSegment.ToRoutePatternPathSegment(); templateSegment.Parts[1] = new TemplatePart(RoutePatternFactory.ParameterPart("D")); templateSegment.Parts.RemoveAt(0); // Assert Assert.Equal(4, routePatternPathSegment.Parts.Count); Assert.IsType <RoutePatternParameterPart>(routePatternPathSegment.Parts[0]); Assert.Equal(paramPartC.Name, ((RoutePatternParameterPart)routePatternPathSegment.Parts[0]).Name); Assert.IsType <RoutePatternLiteralPart>(routePatternPathSegment.Parts[1]); Assert.Equal(literalPartA.Content, ((RoutePatternLiteralPart)routePatternPathSegment.Parts[1]).Content); Assert.IsType <RoutePatternSeparatorPart>(routePatternPathSegment.Parts[2]); Assert.Equal(separatorPartE.Content, ((RoutePatternSeparatorPart)routePatternPathSegment.Parts[2]).Content); Assert.IsType <RoutePatternParameterPart>(routePatternPathSegment.Parts[3]); Assert.Equal(paramPartB.Name, ((RoutePatternParameterPart)routePatternPathSegment.Parts[3]).Name); }
public RoutePatternPart ToRoutePatternPart() { if (IsLiteral && IsOptionalSeperator) { return(RoutePatternFactory.SeparatorPart(Text)); } else if (IsLiteral) { return(RoutePatternFactory.LiteralPart(Text)); } else { var kind = IsCatchAll ? RoutePatternParameterKind.CatchAll : IsOptional ? RoutePatternParameterKind.Optional : RoutePatternParameterKind.Standard; var constraints = InlineConstraints.Select(c => new RoutePatternParameterPolicyReference(c.Constraint)); return(RoutePatternFactory.ParameterPart(Name, DefaultValue, kind, constraints)); } }
private static bool IsSegmentValid(Context context, List <RoutePatternPart> parts) { // If a segment has multiple parts, then it can't contain a catch all. for (var i = 0; i < parts.Count; i++) { var part = parts[i]; if (part is RoutePatternParameterPart parameter && parameter.IsCatchAll && parts.Count > 1) { context.Error = Resources.TemplateRoute_CannotHaveCatchAllInMultiSegment; return(false); } } // if a segment has multiple parts, then only the last one parameter can be optional // if it is following a optional separator. for (var i = 0; i < parts.Count; i++) { var part = parts[i]; if (part is RoutePatternParameterPart parameter && parameter.IsOptional && parts.Count > 1) { // This optional parameter is the last part in the segment if (i == parts.Count - 1) { var previousPart = parts[i - 1]; if (!previousPart.IsLiteral && !previousPart.IsSeparator) { // The optional parameter is preceded by something that is not a literal or separator // Example of error message: // "In the segment '{RouteValue}{param?}', the optional parameter 'param' is preceded // by an invalid segment '{RouteValue}'. Only a period (.) can precede an optional parameter. context.Error = Resources.FormatTemplateRoute_OptionalParameterCanbBePrecededByPeriod( RoutePatternPathSegment.DebuggerToString(parts), parameter.Name, parts[i - 1].DebuggerToString()); return(false); } else if (previousPart is RoutePatternLiteralPart literal && literal.Content != PeriodString) { // The optional parameter is preceded by a literal other than period. // Example of error message: // "In the segment '{RouteValue}-{param?}', the optional parameter 'param' is preceded // by an invalid segment '-'. Only a period (.) can precede an optional parameter. context.Error = Resources.FormatTemplateRoute_OptionalParameterCanbBePrecededByPeriod( RoutePatternPathSegment.DebuggerToString(parts), parameter.Name, parts[i - 1].DebuggerToString()); return(false); } parts[i - 1] = RoutePatternFactory.SeparatorPart(((RoutePatternLiteralPart)previousPart).Content); } else { // This optional parameter is not the last one in the segment // Example: // An optional parameter must be at the end of the segment. In the segment '{RouteValue?})', // optional parameter 'RouteValue' is followed by ')' context.Error = Resources.FormatTemplateRoute_OptionalParameterHasTobeTheLast( RoutePatternPathSegment.DebuggerToString(parts), parameter.Name, parts[i + 1].DebuggerToString()); return(false); } } } // A segment cannot contain two consecutive parameters var isLastSegmentParameter = false; for (var i = 0; i < parts.Count; i++) { var part = parts[i]; if (part.IsParameter && isLastSegmentParameter) { context.Error = Resources.TemplateRoute_CannotHaveConsecutiveParameters; return(false); } isLastSegmentParameter = part.IsParameter; } return(true); }