示例#1
0
        public async Task SelectAsync_MultipleValidCandidatesInGroup_ReportsAmbiguity()
        {
            // Arrange
            var endpoints    = new MatcherEndpoint[] { CreateEndpoint("/test1"), CreateEndpoint("/test2"), CreateEndpoint("/test3"), };
            var scores       = new int[] { 0, 1, 1 };
            var candidateSet = CreateCandidateSet(endpoints, scores);

            candidateSet[0].IsValidCandidate = false;
            candidateSet[1].IsValidCandidate = true;
            candidateSet[2].IsValidCandidate = true;

            var(httpContext, feature) = CreateContext();
            var selector = CreateSelector();

            // Act
            var ex = await Assert.ThrowsAsync <AmbiguousMatchException>(() => selector.SelectAsync(httpContext, feature, candidateSet));

            // Assert
            Assert.Equal(
                @"The request matched multiple endpoints. Matches: 

test: /test2
test: /test3", ex.Message);
            Assert.Null(feature.Endpoint);
        }
示例#2
0
            public InnerMatcher(string[] segments, MatcherEndpoint endpoint)
            {
                _segments = segments;
                Endpoint  = endpoint;

                _candidates = new Candidate[] { new Candidate(endpoint), };
            }
示例#3
0
        public async Task SelectAsync_RunsEndpointSelectorPolicies()
        {
            // Arrange
            var endpoints    = new MatcherEndpoint[] { CreateEndpoint("/test1"), CreateEndpoint("/test2"), CreateEndpoint("/test3"), };
            var scores       = new int[] { 0, 0, 1 };
            var candidateSet = CreateCandidateSet(endpoints, scores);

            var policy = new Mock <MatcherPolicy>();

            policy
            .As <IEndpointSelectorPolicy>()
            .Setup(p => p.Apply(It.IsAny <HttpContext>(), It.IsAny <CandidateSet>()))
            .Callback <HttpContext, CandidateSet>((c, cs) =>
            {
                cs[1].IsValidCandidate = false;
            });

            candidateSet[0].IsValidCandidate = false;
            candidateSet[1].IsValidCandidate = true;
            candidateSet[2].IsValidCandidate = true;

            var(httpContext, feature) = CreateContext();
            var selector = CreateSelector(policy.Object);

            // Act
            await selector.SelectAsync(httpContext, feature, candidateSet);

            // Assert
            Assert.Same(endpoints[2], feature.Endpoint);
        }
示例#4
0
        public async Task SelectAsync_ManyGroupsLastCandidate_ChoosesCandidate()
        {
            // Arrange
            var endpoints = new MatcherEndpoint[]
            {
                CreateEndpoint("/test1"),
                CreateEndpoint("/test2"),
                CreateEndpoint("/test3"),
                CreateEndpoint("/test4"),
                CreateEndpoint("/test5"),
            };
            var scores       = new int[] { 0, 1, 2, 3, 4 };
            var candidateSet = CreateCandidateSet(endpoints, scores);

            candidateSet[0].IsValidCandidate = false;
            candidateSet[1].IsValidCandidate = false;
            candidateSet[2].IsValidCandidate = false;
            candidateSet[3].IsValidCandidate = false;
            candidateSet[4].IsValidCandidate = true;

            var(httpContext, feature) = CreateContext();
            var selector = CreateSelector();

            // Act
            await selector.SelectAsync(httpContext, feature, candidateSet);

            // Assert
            Assert.Same(endpoints[4], feature.Endpoint);
        }
示例#5
0
        public void Create_CreatesCandidateSet(int count)
        {
            // Arrange
            var endpoints = new MatcherEndpoint[count];

            for (var i = 0; i < endpoints.Length; i++)
            {
                endpoints[i] = CreateEndpoint($"/{i}");
            }

            var builder    = CreateDfaMatcherBuilder();
            var candidates = builder.CreateCandidates(endpoints);

            // Act
            var candidateSet = new CandidateSet(candidates);

            // Assert
            for (var i = 0; i < candidateSet.Count; i++)
            {
                ref var state = ref candidateSet[i];
                Assert.True(state.IsValidCandidate);
                Assert.Same(endpoints[i], state.Endpoint);
                Assert.Equal(candidates[i].Score, state.Score);
                Assert.Null(state.Values);
            }
        public override Endpoint Build()
        {
            var matcherEndpoint = new MatcherEndpoint(
                Invoker,
                RoutePattern,
                Order,
                new EndpointMetadataCollection(Metadata),
                DisplayName);

            return(matcherEndpoint);
        }
示例#7
0
        public void Setup()
        {
            Endpoints    = new MatcherEndpoint[1];
            Endpoints[0] = CreateEndpoint("/plaintext");

            Requests    = new HttpContext[1];
            Requests[0] = new DefaultHttpContext();
            Requests[0].RequestServices = CreateServices();
            Requests[0].Request.Path    = "/plaintext";

            _baseline = (TrivialMatcher)SetupMatcher(new TrivialMatcherBuilder());
            _dfa      = (DfaMatcher)SetupMatcher(CreateDfaMatcherBuilder());
        }
 private void SetupEndpoints()
 {
     Endpoints    = new MatcherEndpoint[10];
     Endpoints[0] = CreateEndpoint("/another-really-cool-entry");
     Endpoints[1] = CreateEndpoint("/Some-Entry");
     Endpoints[2] = CreateEndpoint("/a/path/with/more/segments");
     Endpoints[3] = CreateEndpoint("/random/name");
     Endpoints[4] = CreateEndpoint("/random/name2");
     Endpoints[5] = CreateEndpoint("/random/name3");
     Endpoints[6] = CreateEndpoint("/random/name4");
     Endpoints[7] = CreateEndpoint("/plaintext1");
     Endpoints[8] = CreateEndpoint("/plaintext2");
     Endpoints[9] = CreateEndpoint("/plaintext");
 }
示例#9
0
        public async Task SelectAsync_NoCandidates_DoesNothing()
        {
            // Arrange
            var endpoints    = new MatcherEndpoint[] { };
            var scores       = new int[] { };
            var candidateSet = CreateCandidateSet(endpoints, scores);

            var(httpContext, feature) = CreateContext();
            var selector = CreateSelector();

            // Act
            await selector.SelectAsync(httpContext, feature, candidateSet);

            // Assert
            Assert.Null(feature.Endpoint);
        }
示例#10
0
        public override Task SelectAsync(
            HttpContext httpContext,
            IEndpointFeature feature,
            CandidateSet candidateSet)
        {
            for (var i = 0; i < _selectorPolicies.Length; i++)
            {
                _selectorPolicies[i].Apply(httpContext, candidateSet);
            }

            MatcherEndpoint      endpoint = null;
            RouteValueDictionary values   = null;
            int?foundScore = null;

            for (var i = 0; i < candidateSet.Count; i++)
            {
                ref var state = ref candidateSet[i];

                var isValid = state.IsValidCandidate;
                if (isValid && foundScore == null)
                {
                    // This is the first match we've seen - speculatively assign it.
                    endpoint   = state.Endpoint;
                    values     = state.Values;
                    foundScore = state.Score;
                }
                else if (isValid && foundScore < state.Score)
                {
                    // This candidate is lower priority than the one we've seen
                    // so far, we can stop.
                    //
                    // Don't worry about the 'null < state.Score' case, it returns false.
                    break;
                }
                else if (isValid && foundScore == state.Score)
                {
                    // This is the second match we've found of the same score, so there
                    // must be an ambiguity.
                    //
                    // Don't worry about the 'null == state.Score' case, it returns false.

                    ReportAmbiguity(candidateSet);

                    // Unreachable, ReportAmbiguity always throws.
                    throw new NotSupportedException();
                }
            }
        public void Setup()
        {
            Endpoints    = new MatcherEndpoint[1];
            Endpoints[0] = CreateEndpoint("/plaintext");

            Requests    = new HttpContext[1];
            Requests[0] = new DefaultHttpContext();
            Requests[0].RequestServices = CreateServices();
            Requests[0].Request.Path    = "/plaintext";

            _baseline = (BarebonesMatcher)SetupMatcher(new BarebonesMatcherBuilder());
            _dfa      = SetupMatcher(CreateDfaMatcherBuilder());
            _route    = SetupMatcher(new RouteMatcherBuilder());
            _tree     = SetupMatcher(new TreeRouterMatcherBuilder());

            _feature = new EndpointFeature();
        }
示例#12
0
        public async Task SelectAsync_NoValidCandidates_DoesNothing()
        {
            // Arrange
            var endpoints    = new MatcherEndpoint[] { CreateEndpoint("/test"), };
            var scores       = new int[] { 0, };
            var candidateSet = CreateCandidateSet(endpoints, scores);

            candidateSet[0].Values           = new RouteValueDictionary();
            candidateSet[0].IsValidCandidate = false;

            var(httpContext, feature) = CreateContext();
            var selector = CreateSelector();

            // Act
            await selector.SelectAsync(httpContext, feature, candidateSet);

            // Assert
            Assert.Null(feature.Endpoint);
            Assert.Null(feature.Values);
        }
示例#13
0
        public async Task SelectAsync_SingleCandidate_ChoosesCandidate()
        {
            // Arrange
            var endpoints    = new MatcherEndpoint[] { CreateEndpoint("/test"), };
            var scores       = new int[] { 0, };
            var candidateSet = CreateCandidateSet(endpoints, scores);

            candidateSet[0].Values           = new RouteValueDictionary();
            candidateSet[0].IsValidCandidate = true;

            var(httpContext, feature) = CreateContext();
            var selector = CreateSelector();

            // Act
            await selector.SelectAsync(httpContext, feature, candidateSet);

            // Assert
            Assert.Same(endpoints[0], feature.Endpoint);
            Assert.Same(endpoints[0].Invoker, feature.Invoker);
            Assert.NotNull(feature.Values);
        }
示例#14
0
        public void Matcher_Reinitializes_WhenDataSourceChanges()
        {
            // Arrange
            var dataSource = new DynamicEndpointDataSource();
            var matcher    = new DataSourceDependentMatcher(dataSource, TestMatcherBuilder.Create);

            var endpoint = new MatcherEndpoint(
                MatcherEndpoint.EmptyInvoker,
                RoutePatternFactory.Parse("a/b/c"),
                0,
                EndpointMetadataCollection.Empty,
                "test");

            // Act
            dataSource.AddEndpoint(endpoint);

            // Assert
            var inner = Assert.IsType <TestMatcher>(matcher.CurrentMatcher);

            Assert.Collection(
                inner.Endpoints,
                e => Assert.Same(endpoint, e));
        }
示例#15
0
 public override void AddEndpoint(MatcherEndpoint endpoint)
 {
     _endpoints.Add(endpoint);
 }
示例#16
0
        public TrivialMatcher(MatcherEndpoint endpoint)
        {
            _endpoint = endpoint;

            _candidates = new Candidate[] { new Candidate(endpoint), };
        }