public void Parse_ComplexSegment_PLP()
        {
            // Arrange
            var template = "{p1}-cool-{p2}";

            var expected = new RouteTemplate(template, new List <TemplateSegment>());

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[0].Parts.Add(TemplatePart.CreateParameter("p1",
                                                                        false,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));
            expected.Parameters.Add(expected.Segments[0].Parts[0]);
            expected.Segments[0].Parts.Add(TemplatePart.CreateLiteral("cool-"));
            expected.Segments[0].Parts.Add(TemplatePart.CreateParameter("p2",
                                                                        false,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));
            expected.Parameters.Add(expected.Segments[0].Parts[2]);

            // Act
            var actual = TemplateParser.Parse(template);

            // Assert
            Assert.Equal <RouteTemplate>(expected, actual, new TemplateEqualityComparer());
        }
        public void Parse_ComplexSegment_OptionalParameterFollowingPeriod_PeriodAfterSlash()
        {
            // Arrange
            var template = "{p2}/.{p3?}";

            var expected = new RouteTemplate(template, new List <TemplateSegment>());

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[0].Parts.Add(TemplatePart.CreateParameter("p2",
                                                                        false,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[1].Parts.Add(TemplatePart.CreateLiteral("."));
            expected.Segments[1].Parts.Add(TemplatePart.CreateParameter("p3",
                                                                        false,
                                                                        true,
                                                                        null,
                                                                        null));
            expected.Parameters.Add(expected.Segments[0].Parts[0]);
            expected.Parameters.Add(expected.Segments[1].Parts[1]);

            // Act
            var actual = TemplateParser.Parse(template);

            // Assert
            Assert.Equal <RouteTemplate>(expected, actual, new TemplateEqualityComparer());
        }
Beispiel #3
0
        public static TemplatePart ParseRouteParameter([NotNull] string routeParameter)
        {
            var isCatchAll = routeParameter.StartsWith("*", StringComparison.Ordinal);
            var isOptional = routeParameter.EndsWith("?", StringComparison.Ordinal);

            routeParameter = isCatchAll ? routeParameter.Substring(1) : routeParameter;
            routeParameter = isOptional ? routeParameter.Substring(0, routeParameter.Length - 1) : routeParameter;

            var parameterMatch = _parameterRegex.Match(routeParameter);

            if (!parameterMatch.Success)
            {
                return(TemplatePart.CreateParameter(name: string.Empty,
                                                    isCatchAll: isCatchAll,
                                                    isOptional: isOptional,
                                                    defaultValue: null,
                                                    inlineConstraints: null));
            }

            var parameterName = parameterMatch.Groups["parameterName"].Value;

            // Add the default value if present
            var defaultValueGroup = parameterMatch.Groups["defaultValue"];
            var defaultValue      = GetDefaultValue(defaultValueGroup);

            // Register inline constraints if present
            var constraintGroup   = parameterMatch.Groups["constraint"];
            var inlineConstraints = GetInlineConstraints(constraintGroup);

            return(TemplatePart.CreateParameter(parameterName,
                                                isCatchAll,
                                                isOptional,
                                                defaultValue,
                                                inlineConstraints));
        }
        public void ParameterPart_ParameterNameAndDefaultAndParameterKindAndEnumerableOfParameterPolicies_ShouldMakeCopyOfParameterPolicies()
        {
            // Arrange (going through hoops to get an enumerable of RoutePatternParameterPolicyReference)
            const string name         = "Id";
            var          defaults     = new { a = "13", };
            var          x            = new InlineConstraint("x");
            var          y            = new InlineConstraint("y");
            var          z            = new InlineConstraint("z");
            var          constraints  = new[] { x, y, z };
            var          templatePart = TemplatePart.CreateParameter("t", false, false, null, constraints);
            var          routePatternParameterPart = (RoutePatternParameterPart)templatePart.ToRoutePatternPart();
            var          policies = routePatternParameterPart.ParameterPolicies.ToList();

            // Act
            var parameterPart = RoutePatternFactory.ParameterPart(name, defaults, RoutePatternParameterKind.Standard, policies);

            policies[0] = null;
            policies.RemoveAt(1);

            // Assert
            Assert.NotNull(parameterPart.ParameterPolicies);
            Assert.Equal(3, parameterPart.ParameterPolicies.Count);
            Assert.NotNull(parameterPart.ParameterPolicies[0]);
            Assert.NotNull(parameterPart.ParameterPolicies[1]);
            Assert.NotNull(parameterPart.ParameterPolicies[2]);
        }
        public void Formats_template_parameters_correctly(string expected, string template, bool isCatchAll, bool isOptional)
        {
            var templatePart = TemplatePart.CreateParameter(template, isCatchAll, isOptional, defaultValue: null, inlineConstraints: null);

            var result = templatePart.ToTemplatePartString();

            result.Should().Be(expected);
        }
        public void Can_format_template_segements()
        {
            var expected = "{p}";
            var segments = new List <TemplateSegment> {
                new TemplateSegment()
            };

            segments[0].Parts.Add(TemplatePart.CreateParameter("p", false, false, defaultValue: null, inlineConstraints: null));

            var result = segments[0].ToTemplateSegmentString();

            result.Should().Be(expected);
        }
Beispiel #7
0
        public void Configure(IApplicationBuilder app)
        {
            //We are building a url template from scratch, segment by segemtn, oldskool
            var segment = new TemplateSegment();

            segment.Parts.Add(TemplatePart.CreateLiteral("page"));

            var segment2 = new TemplateSegment();

            segment2.Parts.Add(
                TemplatePart.CreateParameter("title",
                                             isCatchAll: true,
                                             isOptional: true,
                                             defaultValue: null,
                                             inlineConstraints: new InlineConstraint[] {})
                );

            var segments = new TemplateSegment [] {
                segment,
                segment2
            };

            var template        = new RouteTemplate("page", segments.ToList());
            var templateMatcher = new TemplateMatcher(template, new RouteValueDictionary());

            app.Use(async(context, next) => {
                await context.Response.WriteAsync("We are using two segments, one with Literal Template Part ('page') and the other with Parameter Template Part ('title')");
                await context.Response.WriteAsync("\n\n");
                await next.Invoke();
            });
            app.Use(async(context, next) => {
                var path1     = "/page/what";
                var routeData = new RouteValueDictionary();//This dictionary will be populated by the parameter template part (in this case "title")
                var isMatch1  = templateMatcher.TryMatch(path1, routeData);
                await context.Response.WriteAsync($"{path1} is match? {isMatch1} => route data value for 'title' is {routeData["title"]} \n");
                await next.Invoke();
            });

            app.Use(async(context, next) => {
                var path1     = "/page/the/old/man/and/the/sea";
                var routeData = new RouteValueDictionary();//This dictionary will be populated by the parameter template part (in this case "title")
                var isMatch1  = templateMatcher.TryMatch(path1, routeData);
                await context.Response.WriteAsync($"{path1} is match? {isMatch1} => route data value for 'title' is {routeData["title"]} \n");
                await next.Invoke();
            });

            app.Run(async context =>
            {
                await context.Response.WriteAsync("");
            });
        }
        public void Configure(IApplicationBuilder app)
        {
            //We are building a url template from scratch, segment by segemtn, oldskool
            var segment = new TemplateSegment();

            segment.Parts.Add(TemplatePart.CreateLiteral("page"));

            var segment2 = new TemplateSegment();

            segment2.Parts.Add(TemplatePart.CreateParameter("id",
                                                            isCatchAll: false,
                                                            isOptional: false,
                                                            defaultValue: null,
                                                            inlineConstraints: new InlineConstraint[] { new InlineConstraint("int") }));

            var segments = new TemplateSegment[] {
                segment,
                segment2
            };

            var template        = new RouteTemplate("page", segments.ToList());
            var templateMatcher = new TemplateMatcher(template, new RouteValueDictionary());

            app.Use(async(context, next) =>
            {
                await context.Response.WriteAsync("We are using one segment with two parts, one Literal Template Part ('page') and the other with Parameter Template Part ('id').");
                await context.Response.WriteAsync("It is the equivalent of /page/{id:int}");
                await context.Response.WriteAsync("\n\n");
                await next.Invoke();
            });

            app.Use(async(context, next) =>
            {
                var path1     = "/page/10";
                var routeData = new RouteValueDictionary();//This dictionary will be populated by the parameter template part (in this case "title")
                var isMatch1  = templateMatcher.TryMatch(path1, routeData);
                await context.Response.WriteAsync($"{path1} is match? {isMatch1} => route data value for 'id' is {routeData["id"]} \n");
                await next.Invoke();
            });

            app.Use(async(context, next) =>
            {
                var path      = "/page/a";
                var routeData = new RouteValueDictionary();//This dictionary will be populated by the parameter template part (in this case "title")
                var isMatch1  = templateMatcher.TryMatch(path, routeData);
                await context.Response.WriteAsync($"{path} is match? {isMatch1} - as you can see TemplateMatcher does not give a damn about InlineConstraint. It is by design. \n");
            });
        }
Beispiel #9
0
        public void Parse_OptionalParameter()
        {
            // Arrange
            var template = "{p?}";

            var expected = new RouteTemplate(new List <TemplateSegment>());

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[0].Parts.Add(TemplatePart.CreateParameter("p", false, true, defaultValue: null, inlineConstraint: null));
            expected.Parameters.Add(expected.Segments[0].Parts[0]);

            // Act
            var actual = TemplateParser.Parse(template, _inlineConstraintResolver);

            // Assert
            Assert.Equal <RouteTemplate>(expected, actual, new TemplateEqualityComparer());
        }
Beispiel #10
0
        public void Configure(IApplicationBuilder app)
        {
            var apiSegment = new TemplateSegment();

            apiSegment.Parts.Add(TemplatePart.CreateLiteral("api"));

            var serviceNameSegment = new TemplateSegment();

            serviceNameSegment.Parts.Add(
                TemplatePart.CreateParameter("serviceName",
                                             isCatchAll: false,
                                             isOptional: true,
                                             defaultValue: null,
                                             inlineConstraints: new InlineConstraint[] { })
                );

            var segments = new TemplateSegment[] {
                apiSegment,
                serviceNameSegment
            };

            var routeTemplate   = new RouteTemplate("default", segments.ToList());
            var templateMatcher = new TemplateMatcher(routeTemplate, new RouteValueDictionary());

            app.Use(async(context, next) =>
            {
                context.Response.Headers.Add("Content-type", "text/html");
                var requestPath = context.Request.Path;
                var routeData   = new RouteValueDictionary();
                var isMatch     = templateMatcher.TryMatch(requestPath, routeData);
                await context.Response.WriteAsync($"Request Path is <i>{requestPath}</i><br/>Match state is <b>{isMatch}</b><br/>Requested service name is {routeData["serviceName"]}");
                await next.Invoke();
            });

            app.Run(async context =>
            {
                await context.Response.WriteAsync("");
            });
        }
        public void Parse_MultipleParameters()
        {
            // Arrange
            var template = "{p1}/{p2}/{*p3}";

            var expected = new RouteTemplate(template, new List <TemplateSegment>());

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[0].Parts.Add(TemplatePart.CreateParameter("p1",
                                                                        false,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));
            expected.Parameters.Add(expected.Segments[0].Parts[0]);

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[1].Parts.Add(TemplatePart.CreateParameter("p2",
                                                                        false,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));
            expected.Parameters.Add(expected.Segments[1].Parts[0]);

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[2].Parts.Add(TemplatePart.CreateParameter("p3",
                                                                        true,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));
            expected.Parameters.Add(expected.Segments[2].Parts[0]);

            // Act
            var actual = TemplateParser.Parse(template);

            // Assert
            Assert.Equal <RouteTemplate>(expected, actual, new TemplateEqualityComparer());
        }
        [InlineData(@"{p1:regex(([{{(])\w+)}", @"regex(([{(])\w+)")]                                      // Not balanced {
        public void Parse_RegularExpressions(string template, string constraint)
        {
            // Arrange
            var expected = new RouteTemplate(template, new List <TemplateSegment>());

            expected.Segments.Add(new TemplateSegment());
            var c = new InlineConstraint(constraint);

            expected.Segments[0].Parts.Add(
                TemplatePart.CreateParameter("p1",
                                             false,
                                             false,
                                             defaultValue: null,
                                             inlineConstraints: new List <InlineConstraint> {
                c
            }));
            expected.Parameters.Add(expected.Segments[0].Parts[0]);

            // Act
            var actual = TemplateParser.Parse(template);

            // Assert
            Assert.Equal <RouteTemplate>(expected, actual, new TemplateEqualityComparer());
        }
        public static TemplatePart ParseRouteParameter([NotNull] string routeParameter)
        {
            if (routeParameter.Length == 0)
            {
                return(TemplatePart.CreateParameter(
                           name: string.Empty,
                           isCatchAll: false,
                           isOptional: false,
                           defaultValue: null,
                           inlineConstraints: null));
            }

            var startIndex = 0;
            var endIndex   = routeParameter.Length - 1;

            var isCatchAll = false;
            var isOptional = false;

            if (routeParameter[0] == '*')
            {
                isCatchAll = true;
                startIndex++;
            }

            if (routeParameter[endIndex] == '?')
            {
                isOptional = true;
                endIndex--;
            }

            var currentIndex = startIndex;

            // Parse parameter name
            var parameterName = string.Empty;

            while (currentIndex <= endIndex)
            {
                var currentChar = routeParameter[currentIndex];

                if ((currentChar == ':' || currentChar == '=') && startIndex != currentIndex)
                {
                    // Parameter names are allowed to start with delimiters used to denote constraints or default values.
                    // i.e. "=foo" or ":bar" would be treated as parameter names rather than default value or constraint
                    // specifications.
                    parameterName = routeParameter.Substring(startIndex, currentIndex - startIndex);

                    // Roll the index back and move to the constraint parsing stage.
                    currentIndex--;
                    break;
                }
                else if (currentIndex == endIndex)
                {
                    parameterName = routeParameter.Substring(startIndex, currentIndex - startIndex + 1);
                }

                currentIndex++;
            }

            var parseResults = ParseConstraints(routeParameter, currentIndex, endIndex);

            currentIndex = parseResults.CurrentIndex;

            string defaultValue = null;

            if (currentIndex <= endIndex &&
                routeParameter[currentIndex] == '=')
            {
                defaultValue = routeParameter.Substring(currentIndex + 1, endIndex - currentIndex);
            }

            return(TemplatePart.CreateParameter(parameterName,
                                                isCatchAll,
                                                isOptional,
                                                defaultValue,
                                                parseResults.Constraints));
        }