public static RoutePattern Parse(string pattern) { if (pattern == null) { throw new ArgumentNullException(nameof(pattern)); } var trimmedPattern = TrimPrefix(pattern); var context = new TemplateParserContext(trimmedPattern); var segments = new List <RoutePatternPathSegment>(); while (context.MoveNext()) { var i = context.Index; if (context.Current == Separator) { // If we get here is means that there's a consecutive '/' character. // Templates don't start with a '/' and parsing a segment consumes the separator. throw new RoutePatternException(pattern, Resources.TemplateRoute_CannotHaveConsecutiveSeparators); } if (!ParseSegment(context, segments)) { throw new RoutePatternException(pattern, context.Error); } // A successful parse should always result in us being at the end or at a separator. Debug.Assert(context.AtEnd() || context.Current == Separator); if (context.Index <= i) { throw new InvalidProgramException("Infinite loop in the parser. This is a bug."); } } if (IsAllValid(context, segments)) { var builder = RoutePatternBuilder.Create(pattern); for (var i = 0; i < segments.Count; i++) { builder.PathSegments.Add(segments[i]); } return(builder.Build()); } else { throw new RoutePatternException(pattern, context.Error); } }
public void Parse_OptionalParameter() { // Arrange var template = "{p?}"; var builder = RoutePatternBuilder.Create(template); builder.AddPathSegmentFromText("{p?}", RoutePatternPart.CreateParameterFromText("{p?}", "p", null, RoutePatternParameterKind.Optional)); var expected = builder.Build(); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
public void Parse_SingleLiteral() { // Arrange var template = "cool"; var builder = RoutePatternBuilder.Create(template); builder.AddPathSegmentFromText("cool", RoutePatternPart.CreateLiteralFromText("cool", "cool")); var expected = builder.Build(); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
public void Parse_MultipleParameters() { // Arrange var template = "{p1}/{p2}/{*p3}"; var builder = RoutePatternBuilder.Create(template); builder.AddPathSegmentFromText("{p1}", RoutePatternPart.CreateParameterFromText("{p1}", "p1")); builder.AddPathSegmentFromText("{p2}", RoutePatternPart.CreateParameterFromText("{p2}", "p2")); builder.AddPathSegmentFromText("{*p3}", RoutePatternPart.CreateParameterFromText("{*p3}", "p3", null, RoutePatternParameterKind.CatchAll)); var expected = builder.Build(); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
public void Parse_ComplexSegment_OptionalParameterFollowingPeriod_PeriodAfterSlash() { // Arrange var template = "{p2}/.{p3?}"; var builder = RoutePatternBuilder.Create(template); builder.AddPathSegmentFromText("{p2}", RoutePatternPart.CreateParameterFromText("{p2}", "p2")); builder.AddPathSegmentFromText(".{p3?}", RoutePatternPart.CreateSeparatorFromText(".", "."), RoutePatternPart.CreateParameterFromText("{p3?}", "p3", null, RoutePatternParameterKind.Optional)); var expected = builder.Build(); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
public void Parse_ComplexSegment_ParametersFollowingPeriod() { // Arrange var template = "{p1}.{p2}"; var builder = RoutePatternBuilder.Create(template); builder.AddPathSegmentFromText( "{p1}.{p2}", RoutePatternPart.CreateParameterFromText("{p1}", "p1"), RoutePatternPart.CreateLiteralFromText(".", "."), RoutePatternPart.CreateParameterFromText("{p2}", "p2")); var expected = builder.Build(); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
public void Parse_ComplexSegment_LPL() { // Arrange var template = "cool-{p1}-awesome"; var builder = RoutePatternBuilder.Create(template); builder.AddPathSegmentFromText( template, RoutePatternPart.CreateLiteralFromText("cool-", "cool-"), RoutePatternPart.CreateParameterFromText("{p1}", "p1"), RoutePatternPart.CreateLiteralFromText("-awesome", "-awesome")); var expected = builder.Build(); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
[InlineData(@"{p1:regex(([{{(])\w+)}", @"regex(([{(])\w+)")] // Not balanced { public void Parse_RegularExpressions(string template, string constraint) { // Arrange var builder = RoutePatternBuilder.Create(template); builder.AddPathSegmentFromText( template, RoutePatternPart.CreateParameterFromText( template, "p1", null, RoutePatternParameterKind.Standard, ConstraintReference.CreateFromText(constraint, constraint))); var expected = builder.Build(); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }