Rename EndpointFeature -> EndpointSelectorContext

This commit is contained in:
Ryan Nowak 2018-09-27 15:06:51 -07:00
parent 1223752517
commit 1f5eec1d55
35 changed files with 335 additions and 337 deletions

View File

@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.Routing
protected (HttpContext httpContext, RouteValueDictionary ambientValues) CreateCurrentRequestContext(
object ambientValues = null)
{
var feature = new EndpointFeature { RouteValues = new RouteValueDictionary(ambientValues) };
var feature = new EndpointSelectorContext { RouteValues = new RouteValueDictionary(ambientValues) };
var context = new DefaultHttpContext();
context.Features.Set<IEndpointFeature>(feature);
context.Features.Set<IRouteValuesFeature>(feature);

View File

@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
private Matcher _dfa;
private int[] _samples;
private EndpointFeature _feature;
private EndpointSelectorContext _feature;
[GlobalSetup]
public void Setup()
@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
_baseline = (BarebonesMatcher)SetupMatcher(new BarebonesMatcherBuilder());
_dfa = SetupMatcher(CreateDfaMatcherBuilder());
_feature = new EndpointFeature();
_feature = new EndpointSelectorContext();
}
[Benchmark(Baseline = true, OperationsPerInvoke = SampleCount)]

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
private TrivialMatcher _baseline;
private DfaMatcher _dfa;
private EndpointFeature _feature;
private EndpointSelectorContext _feature;
[GlobalSetup]
public void Setup()
@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
_baseline = (TrivialMatcher)SetupMatcher(new TrivialMatcherBuilder());
_dfa = (DfaMatcher)SetupMatcher(CreateDfaMatcherBuilder());
_feature = new EndpointFeature();
_feature = new EndpointSelectorContext();
}
private void SetupEndpoints()

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
private BarebonesMatcher _baseline;
private Matcher _dfa;
private EndpointFeature _feature;
private EndpointSelectorContext _feature;
[GlobalSetup]
public void Setup()
@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
_baseline = (BarebonesMatcher)SetupMatcher(new BarebonesMatcherBuilder());
_dfa = SetupMatcher(CreateDfaMatcherBuilder());
_feature = new EndpointFeature();
_feature = new EndpointSelectorContext();
}
[Benchmark(Baseline = true, OperationsPerInvoke = EndpointCount)]

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
private Matcher _route;
private Matcher _tree;
private EndpointFeature _feature;
private EndpointSelectorContext _feature;
[GlobalSetup]
public void Setup()
@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
_route = SetupMatcher(new RouteMatcherBuilder());
_tree = SetupMatcher(new TreeRouterMatcherBuilder());
_feature = new EndpointFeature();
_feature = new EndpointSelectorContext();
}
private Matcher SetupMatcher(MatcherBuilder builder)

View File

@ -23,23 +23,23 @@ namespace Microsoft.AspNetCore.Routing.Matching
_candidates = new Candidate[] { new Candidate(endpoint), };
}
public sealed override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
public sealed override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
{
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}
if (feature == null)
if (context == null)
{
throw new ArgumentNullException(nameof(feature));
throw new ArgumentNullException(nameof(context));
}
var path = httpContext.Request.Path.Value;
if (string.Equals(_endpoint.RoutePattern.RawText, path, StringComparison.OrdinalIgnoreCase))
{
feature.Endpoint = _endpoint;
feature.RouteValues = new RouteValueDictionary();
context.Endpoint = _endpoint;
context.RouteValues = new RouteValueDictionary();
}
return Task.CompletedTask;

View File

@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Routing
public async Task Invoke(HttpContext httpContext)
{
var feature = new EndpointFeature();
var feature = new EndpointSelectorContext();
// There's an inherent race condition between waiting for init and accessing the matcher
// this is OK because once `_matcher` is initialized, it will not be set to null again.
@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.Routing
{
// Set the endpoint feature only on success. This means we won't overwrite any
// existing state for related features unless we did something.
SetEndpointFeature(httpContext, feature);
SetFeatures(httpContext, feature);
Log.MatchSuccess(_logger, feature);
}
@ -78,13 +78,13 @@ namespace Microsoft.AspNetCore.Routing
await _next(httpContext);
}
private static void SetEndpointFeature(HttpContext httpContext, EndpointFeature feature)
private static void SetFeatures(HttpContext httpContext, EndpointSelectorContext context)
{
// For back-compat EndpointRouteValuesFeature implements IEndpointFeature,
// IRouteValuesFeature and IRoutingFeature
httpContext.Features.Set<IRoutingFeature>(feature);
httpContext.Features.Set<IRouteValuesFeature>(feature);
httpContext.Features.Set<IEndpointFeature>(feature);
httpContext.Features.Set<IRoutingFeature>(context);
httpContext.Features.Set<IRouteValuesFeature>(context);
httpContext.Features.Set<IEndpointFeature>(context);
}
// Initialization is async to avoid blocking threads while reflection and things
@ -126,9 +126,9 @@ namespace Microsoft.AspNetCore.Routing
new EventId(2, "MatchFailure"),
"Request did not match any endpoints.");
public static void MatchSuccess(ILogger logger, EndpointFeature feature)
public static void MatchSuccess(ILogger logger, EndpointSelectorContext context)
{
_matchSuccess(logger, feature.Endpoint.DisplayName, null);
_matchSuccess(logger, context.Endpoint.DisplayName, null);
}
public static void MatchFailure(ILogger logger)

View File

@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Routing
{
public sealed class EndpointFeature : IEndpointFeature, IRouteValuesFeature, IRoutingFeature
public sealed class EndpointSelectorContext : IEndpointFeature, IRouteValuesFeature, IRoutingFeature
{
private RouteData _routeData;
private RouteValueDictionary _routeValues;

View File

@ -27,9 +27,9 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Used in tests
internal Matcher CurrentMatcher => _cache.Value;
public override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
public override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
{
return CurrentMatcher.MatchAsync(httpContext, feature);
return CurrentMatcher.MatchAsync(httpContext, context);
}
private Matcher CreateMatcher(IReadOnlyList<Endpoint> endpoints)

View File

@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Routing.Matching
{
@ -26,26 +25,26 @@ namespace Microsoft.AspNetCore.Routing.Matching
public override async Task SelectAsync(
HttpContext httpContext,
EndpointFeature feature,
EndpointSelectorContext context,
CandidateSet candidateSet)
{
var selectorPolicies = _selectorPolicies;
for (var i = 0; i < _selectorPolicies.Length; i++)
{
await selectorPolicies[i].ApplyAsync(httpContext, feature, candidateSet);
if (feature.Endpoint != null)
await selectorPolicies[i].ApplyAsync(httpContext, context, candidateSet);
if (context.Endpoint != null)
{
// This is a short circuit, the selector chose an endpoint.
return;
}
}
ProcessFinalCandidates(httpContext, feature, candidateSet);
ProcessFinalCandidates(httpContext, context, candidateSet);
}
private static void ProcessFinalCandidates(
HttpContext httpContext,
EndpointFeature feature,
EndpointSelectorContext context,
CandidateSet candidateSet)
{
Endpoint endpoint = null;
@ -87,8 +86,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
if (endpoint != null)
{
feature.Endpoint = endpoint;
feature.RouteValues = values;
context.Endpoint = endpoint;
context.RouteValues = values;
}
}

View File

@ -23,16 +23,16 @@ namespace Microsoft.AspNetCore.Routing.Matching
_maxSegmentCount = maxSegmentCount;
}
public sealed override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
public sealed override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
{
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}
if (feature == null)
if (context == null)
{
throw new ArgumentNullException(nameof(feature));
throw new ArgumentNullException(nameof(context));
}
// The sequence of actions we take is optimized to avoid doing expensive work
@ -132,7 +132,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
state.IsValidCandidate = isMatch;
}
return _selector.SelectAsync(httpContext, feature, candidateSet);
return _selector.SelectAsync(httpContext, context, candidateSet);
}
internal Candidate[] FindCandidateSet(

View File

@ -18,16 +18,16 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// Asynchronously selects an <see cref="Endpoint"/> from the <see cref="CandidateSet"/>.
/// </summary>
/// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
/// <param name="feature">The <see cref="IEndpointFeature"/> associated with the current request.</param>
/// <param name="context">The <see cref="EndpointSelectorContext"/> associated with the current request.</param>
/// <param name="candidates">The <see cref="CandidateSet"/>.</param>
/// <returns>A <see cref="Task"/> that completes asynchronously once endpoint selection is complete.</returns>
/// <remarks>
/// An <see cref="EndpointSelector"/> should assign the <see cref="EndpointFeature.Endpoint"/>
/// and <see cref="EndpointFeature.RouteValues"/> properties once an endpoint is selected.
/// An <see cref="EndpointSelector"/> should assign the <see cref="EndpointSelectorContext.Endpoint"/>
/// and <see cref="EndpointSelectorContext.RouteValues"/> properties once an endpoint is selected.
/// </remarks>
public abstract Task SelectAsync(
HttpContext httpContext,
EndpointFeature feature,
EndpointSelectorContext context,
CandidateSet candidates);
}
}

View File

@ -20,8 +20,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// <param name="httpContext">
/// The <see cref="HttpContext"/> associated with the current request.
/// </param>
/// <param name="feature">
/// The <see cref="EndpointFeature"/> associated with the current request.
/// <param name="context">
/// The <see cref="EndpointSelectorContext"/> associated with the current request.
/// </param>
/// <param name="candidates">The <see cref="CandidateSet"/>.</param>
/// <remarks>
@ -31,10 +31,10 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// <see cref="CandidateState.IsValidCandidate"/> to <c>false</c> where desired.
/// </para>
/// <para>
/// To signal an error condition, set <see cref="EndpointFeature.Endpoint"/> to an
/// To signal an error condition, set <see cref="EndpointSelectorContext.Endpoint"/> to an
/// <see cref="Endpoint"/> value that will produce the desired error when executed.
/// </para>
/// </remarks>
Task ApplyAsync(HttpContext httpContext, EndpointFeature feature, CandidateSet candidates);
Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidates);
}
}

View File

@ -17,10 +17,10 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// Attempts to asynchronously select an <see cref="Endpoint"/> for the current request.
/// </summary>
/// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
/// <param name="feature">
/// <param name="context">
/// The <see cref="IEndpointFeature"/> associated with the current request. The
/// <see cref="EndpointFeature"/> will be mutated to contain the result of the operation.</param>
/// <see cref="EndpointSelectorContext"/> will be mutated to contain the result of the operation.</param>
/// <returns>A <see cref="Task"/> which represents the asynchronous completion of the operation.</returns>
public abstract Task MatchAsync(HttpContext httpContext, EndpointFeature feature);
public abstract Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context);
}
}

View File

@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Routing
var httpContext = new DefaultHttpContext();
httpContext.RequestServices = new ServiceProvider();
httpContext.Features.Set<IEndpointFeature>(new EndpointFeature()
httpContext.Features.Set<IEndpointFeature>(new EndpointSelectorContext()
{
Endpoint = null,
});
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Routing
return Task.CompletedTask;
};
httpContext.Features.Set<IEndpointFeature>(new EndpointFeature()
httpContext.Features.Set<IEndpointFeature>(new EndpointSelectorContext()
{
Endpoint = new Endpoint(endpointFunc, EndpointMetadataCollection.Empty, "Test"),
});

View File

@ -105,11 +105,11 @@ namespace Microsoft.AspNetCore.Routing
private HttpContext CreateHttpContext()
{
var feature = new EndpointFeature();
var context = new EndpointSelectorContext();
var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IEndpointFeature>(feature);
httpContext.Features.Set<IRouteValuesFeature>(feature);
httpContext.Features.Set<IEndpointFeature>(context);
httpContext.Features.Set<IRouteValuesFeature>(context);
httpContext.RequestServices = new TestServiceProvider();

View File

@ -9,7 +9,7 @@ using Xunit;
namespace Microsoft.AspNetCore.Routing
{
public class EndpointFeatureTest
public class EndpointSelectorContextTest
{
[Fact]
public void RouteData_CanIntializeDataTokens_WithMetadata()
@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Routing
// Arrange
var expected = new RouteValueDictionary(new { foo = 17, bar = "hello", });
var feature = new EndpointFeature()
var context = new EndpointSelectorContext()
{
Endpoint = new RouteEndpoint(
TestConstants.EmptyRequestDelegate,
@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Routing
};
// Act
var routeData = ((IRoutingFeature)feature).RouteData;
var routeData = ((IRoutingFeature)context).RouteData;
// Assert
Assert.NotSame(expected, routeData.DataTokens);
@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Routing
public void RouteData_DataTokensIsEmpty_WithoutMetadata()
{
// Arrange
var feature = new EndpointFeature()
var context = new EndpointSelectorContext()
{
Endpoint = new RouteEndpoint(
TestConstants.EmptyRequestDelegate,
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Routing
};
// Act
var routeData = ((IRoutingFeature)feature).RouteData;
var routeData = ((IRoutingFeature)context).RouteData;
// Assert
Assert.Empty(routeData.DataTokens);

View File

@ -26,12 +26,12 @@ namespace Microsoft.AspNetCore.Routing
var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2);
var feature = new EndpointFeature()
var context = new EndpointSelectorContext()
{
RouteValues = new RouteValueDictionary(new { p = "5", })
};
var httpContext = CreateHttpContext();
httpContext.Features.Set<IRouteValuesFeature>(feature);
httpContext.Features.Set<IRouteValuesFeature>(context);
httpContext.Request.PathBase = new PathString("/Foo/Bar?encodeme?");
var values = new { query = "some?query", };

View File

@ -32,12 +32,12 @@ namespace Microsoft.AspNetCore.Routing
var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2);
var feature = new EndpointFeature()
var context = new EndpointSelectorContext()
{
RouteValues = new RouteValueDictionary(new { action = "Index", })
};
var httpContext = CreateHttpContext();
httpContext.Features.Set<IRouteValuesFeature>(feature);
httpContext.Features.Set<IRouteValuesFeature>(context);
httpContext.Request.PathBase = new PathString("/Foo/Bar?encodeme?");
// Act

View File

@ -18,13 +18,13 @@ namespace Microsoft.AspNetCore.Routing
{
var httpContext = new DefaultHttpContext();
var feature = new EndpointFeature
var context = new EndpointSelectorContext
{
RouteValues = new RouteValueDictionary(ambientValues)
};
httpContext.Features.Set<IEndpointFeature>(feature);
httpContext.Features.Set<IRouteValuesFeature>(feature);
httpContext.Features.Set<IEndpointFeature>(context);
httpContext.Features.Set<IRouteValuesFeature>(context);
return httpContext;
}

View File

@ -20,16 +20,16 @@ namespace Microsoft.AspNetCore.Routing.Matching
Matchers = matchers;
}
public override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
public override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
{
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}
if (feature == null)
if (context == null)
{
throw new ArgumentNullException(nameof(feature));
throw new ArgumentNullException(nameof(context));
}
var path = httpContext.Request.Path.Value;
@ -37,8 +37,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
if (Matchers[i].TryMatch(path))
{
feature.Endpoint = Matchers[i].Endpoint;
feature.RouteValues = new RouteValueDictionary();
context.Endpoint = Matchers[i].Endpoint;
context.RouteValues = new RouteValueDictionary();
}
}
@ -121,12 +121,12 @@ namespace Microsoft.AspNetCore.Routing.Matching
return Array.Empty<Candidate>();
}
public override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
public override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
{
if (TryMatch(httpContext.Request.Path.Value))
{
feature.Endpoint = Endpoint;
feature.RouteValues = new RouteValueDictionary();
context.Endpoint = Endpoint;
context.RouteValues = new RouteValueDictionary();
}
return Task.CompletedTask;

View File

@ -134,7 +134,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
public IReadOnlyList<RouteEndpoint> Endpoints { get; set; }
public override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
public override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
{
throw new NotImplementedException();
}

View File

@ -21,14 +21,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var scores = new int[] { };
var candidateSet = CreateCandidateSet(endpoints, scores);
var (httpContext, feature) = CreateContext();
var (httpContext, context) = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, feature, candidateSet);
await selector.SelectAsync(httpContext, context, candidateSet);
// Assert
Assert.Null(feature.Endpoint);
Assert.Null(context.Endpoint);
}
[Fact]
@ -42,14 +42,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet[0].Values = new RouteValueDictionary();
candidateSet[0].IsValidCandidate = false;
var (httpContext, feature) = CreateContext();
var (httpContext, context) = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, feature, candidateSet);
await selector.SelectAsync(httpContext, context, candidateSet);
// Assert
Assert.Null(feature.Endpoint);
Assert.Null(context.Endpoint);
}
[Fact]
@ -63,14 +63,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet[0].Values = new RouteValueDictionary();
candidateSet[0].IsValidCandidate = true;
var (httpContext, feature) = CreateContext();
var (httpContext, context) = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, feature, candidateSet);
await selector.SelectAsync(httpContext, context, candidateSet);
// Assert
Assert.Same(endpoints[0], feature.Endpoint);
Assert.Same(endpoints[0], context.Endpoint);
}
[Fact]
@ -84,14 +84,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet[0].IsValidCandidate = false;
candidateSet[1].IsValidCandidate = true;
var (httpContext, feature) = CreateContext();
var (httpContext, context) = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, feature, candidateSet);
await selector.SelectAsync(httpContext, context, candidateSet);
// Assert
Assert.Same(endpoints[1], feature.Endpoint);
Assert.Same(endpoints[1], context.Endpoint);
}
[Fact]
@ -106,14 +106,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet[1].IsValidCandidate = true;
candidateSet[2].IsValidCandidate = true;
var (httpContext, feature) = CreateContext();
var (httpContext, context) = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, feature, candidateSet);
await selector.SelectAsync(httpContext, context, candidateSet);
// Assert
Assert.Same(endpoints[1], feature.Endpoint);
Assert.Same(endpoints[1], context.Endpoint);
}
[Fact]
@ -137,14 +137,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet[3].IsValidCandidate = false;
candidateSet[4].IsValidCandidate = true;
var (httpContext, feature) = CreateContext();
var (httpContext, context) = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, feature, candidateSet);
await selector.SelectAsync(httpContext, context, candidateSet);
// Assert
Assert.Same(endpoints[4], feature.Endpoint);
Assert.Same(endpoints[4], context.Endpoint);
}
[Fact]
@ -159,11 +159,11 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet[1].IsValidCandidate = true;
candidateSet[2].IsValidCandidate = true;
var (httpContext, feature) = CreateContext();
var (httpContext, context) = CreateContext();
var selector = CreateSelector();
// Act
var ex = await Assert.ThrowsAsync<AmbiguousMatchException>(() => selector.SelectAsync(httpContext, feature, candidateSet));
var ex = await Assert.ThrowsAsync<AmbiguousMatchException>(() => selector.SelectAsync(httpContext, context, candidateSet));
// Assert
Assert.Equal(
@ -171,7 +171,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
test: /test2
test: /test3", ex.Message);
Assert.Null(feature.Endpoint);
Assert.Null(context.Endpoint);
}
[Fact]
@ -185,8 +185,8 @@ test: /test3", ex.Message);
var policy = new Mock<MatcherPolicy>();
policy
.As<IEndpointSelectorPolicy>()
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointFeature>(), It.IsAny<CandidateSet>()))
.Returns<HttpContext, EndpointFeature, CandidateSet>((c, f, cs) =>
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointSelectorContext>(), It.IsAny<CandidateSet>()))
.Returns<HttpContext, EndpointSelectorContext, CandidateSet>((c, f, cs) =>
{
cs[1].IsValidCandidate = false;
return Task.CompletedTask;
@ -196,14 +196,14 @@ test: /test3", ex.Message);
candidateSet[1].IsValidCandidate = true;
candidateSet[2].IsValidCandidate = true;
var (httpContext, feature) = CreateContext();
var (httpContext, context) = CreateContext();
var selector = CreateSelector(policy.Object);
// Act
await selector.SelectAsync(httpContext, feature, candidateSet);
await selector.SelectAsync(httpContext, context, candidateSet);
// Assert
Assert.Same(endpoints[2], feature.Endpoint);
Assert.Same(endpoints[2], context.Endpoint);
}
[Fact]
@ -217,8 +217,8 @@ test: /test3", ex.Message);
var policy1 = new Mock<MatcherPolicy>();
policy1
.As<IEndpointSelectorPolicy>()
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointFeature>(), It.IsAny<CandidateSet>()))
.Returns<HttpContext, EndpointFeature, CandidateSet>((c, f, cs) =>
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointSelectorContext>(), It.IsAny<CandidateSet>()))
.Returns<HttpContext, EndpointSelectorContext, CandidateSet>((c, f, cs) =>
{
f.Endpoint = cs[0].Endpoint;
return Task.CompletedTask;
@ -231,31 +231,31 @@ test: /test3", ex.Message);
.Returns(1000);
policy2
.As<IEndpointSelectorPolicy>()
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointFeature>(), It.IsAny<CandidateSet>()))
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointSelectorContext>(), It.IsAny<CandidateSet>()))
.Throws(new InvalidOperationException());
candidateSet[0].IsValidCandidate = false;
candidateSet[1].IsValidCandidate = true;
candidateSet[2].IsValidCandidate = true;
var (httpContext, feature) = CreateContext();
var (httpContext, context) = CreateContext();
var selector = CreateSelector(policy1.Object, policy2.Object);
// Act
await selector.SelectAsync(httpContext, feature, candidateSet);
await selector.SelectAsync(httpContext, context, candidateSet);
// Assert
Assert.Same(endpoints[0], feature.Endpoint);
Assert.Same(endpoints[0], context.Endpoint);
}
private static (HttpContext httpContext, EndpointFeature feature) CreateContext()
private static (HttpContext httpContext, EndpointSelectorContext context) CreateContext()
{
var feature = new EndpointFeature();
var context = new EndpointSelectorContext();
var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IEndpointFeature>(feature);
httpContext.Features.Set<IRouteValuesFeature>(feature);
httpContext.Features.Set<IEndpointFeature>(context);
httpContext.Features.Set<IRouteValuesFeature>(context);
return (httpContext, feature);
return (httpContext, context);
}
private static RouteEndpoint CreateEndpoint(string template)

View File

@ -14,13 +14,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
}
internal override Matcher CreateMatcher(params RouteEndpoint[] endpoints)

View File

@ -55,14 +55,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(endpointDataSource);
var (httpContext, endpointFeature) = CreateHttpContext();
var (httpContext, context) = CreateContext();
httpContext.Request.Path = "/1";
// Act
await matcher.MatchAsync(httpContext, endpointFeature);
await matcher.MatchAsync(httpContext, context);
// Assert
Assert.NotNull(endpointFeature.Endpoint);
Assert.NotNull(context.Endpoint);
}
[Fact]
@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(endpointDataSource);
var (httpContext, endpointFeature) = CreateHttpContext();
var (httpContext, endpointFeature) = CreateContext();
httpContext.Request.Path = "/One";
// Act
@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(endpointDataSource);
var (httpContext, endpointFeature) = CreateHttpContext();
var (httpContext, endpointFeature) = CreateContext();
httpContext.Request.Path = "/Teams";
// Act
@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpointSelector = new Mock<EndpointSelector>();
endpointSelector
.Setup(s => s.SelectAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointFeature>(), It.IsAny<CandidateSet>()))
.Setup(s => s.SelectAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointSelectorContext>(), It.IsAny<CandidateSet>()))
.Callback<HttpContext, IEndpointFeature, CandidateSet>((c, f, cs) =>
{
Assert.Equal(2, cs.Count);
@ -147,7 +147,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(endpointDataSource, endpointSelector.Object);
var (httpContext, endpointFeature) = CreateHttpContext();
var (httpContext, endpointFeature) = CreateContext();
httpContext.Request.Path = "/Teams";
// Act
@ -157,15 +157,15 @@ namespace Microsoft.AspNetCore.Routing.Matching
Assert.Equal(endpoint2, endpointFeature.Endpoint);
}
private (HttpContext httpContext, EndpointFeature feature) CreateHttpContext()
private (HttpContext httpContext, EndpointSelectorContext context) CreateContext()
{
var feature = new EndpointFeature();
var context = new EndpointSelectorContext();
var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IEndpointFeature>(feature);
httpContext.Features.Set<IRouteValuesFeature>(feature);
httpContext.Features.Set<IEndpointFeature>(context);
httpContext.Features.Set<IRouteValuesFeature>(context);
return (httpContext, feature);
return (httpContext, context);
}
}
}

View File

@ -28,13 +28,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
}
[Fact]
@ -43,13 +43,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Arrange
var endpoint = CreateEndpoint("/a/{b}/{c}", new { b = "17", c = "18", });
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/a");
var (httpContext, context) = CreateContext("/a");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, new { b = "17", c = "18", });
MatcherAssert.AssertMatch(context, httpContext, endpoint, new { b = "17", c = "18", });
}
[Fact]
@ -58,13 +58,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Arrange
var endpoint = CreateEndpoint("/a/{b}/{c}", new { b = "17", c = "18", d = "19" });
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/a");
var (httpContext, context) = CreateContext("/a");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, new { b = "17", c = "18", d = "19" });
MatcherAssert.AssertMatch(context, httpContext, endpoint, new { b = "17", c = "18", d = "19" });
}
[Theory]
@ -83,13 +83,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertNotMatch(feature, httpContext);
MatcherAssert.AssertNotMatch(context, httpContext);
}
[Theory]
@ -115,13 +115,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
}
[Theory]
@ -138,13 +138,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertNotMatch(feature, httpContext);
MatcherAssert.AssertNotMatch(context, httpContext);
}
[Theory]
@ -162,13 +162,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
}
// Historically catchall segments don't match an empty segment, but only if it's
@ -182,13 +182,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertNotMatch(feature, httpContext);
MatcherAssert.AssertNotMatch(context, httpContext);
// Need to access these to prevent a warning from the xUnit analyzer.
// Some of these tests will match (and process the values) and some will not.
@ -217,13 +217,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
}
[Theory]
@ -237,13 +237,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertNotMatch(feature, httpContext);
MatcherAssert.AssertNotMatch(context, httpContext);
}
[Theory]
@ -266,13 +266,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
}
[Theory]
@ -292,13 +292,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertNotMatch(feature, httpContext);
MatcherAssert.AssertNotMatch(context, httpContext);
}
// Most of are copied from old routing tests that date back to the VS 2010 era. Enjoy!
@ -317,13 +317,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
}
[Theory]
@ -347,13 +347,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Arrange
var matcher = CreateMatcher(other, expected);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, expected, ignoreValues: true);
MatcherAssert.AssertMatch(context, httpContext, expected, ignoreValues: true);
}
[Theory]
@ -381,13 +381,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Arrange
var matcher = CreateMatcher(other, expected);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, expected, ignoreValues: true);
MatcherAssert.AssertMatch(context, httpContext, expected, ignoreValues: true);
}
[Theory]
@ -434,13 +434,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var expected = endpoints[Array.IndexOf(templates, expectedTemplate)];
var matcher = CreateMatcher(endpoints);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, expected, ignoreValues: true);
MatcherAssert.AssertMatch(context, httpContext, expected, ignoreValues: true);
}
}
}

View File

@ -23,13 +23,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GET", });
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/hello", "GET");
var (httpContext, context) = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Fact]
@ -39,13 +39,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GET", }, acceptCorsPreflight: true);
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/hello", "GET");
var (httpContext, context) = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Fact]
@ -55,13 +55,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GET", }, acceptCorsPreflight: true);
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/hello", "GET", corsPreflight: true);
var (httpContext, context) = CreateContext("/hello", "GET", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
@ -72,14 +72,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GET", }, acceptCorsPreflight: false);
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/hello", "GET", corsPreflight: true);
var (httpContext, context) = CreateContext("/hello", "GET", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
Assert.NotSame(endpoint, feature.Endpoint);
Assert.Same(HttpMethodMatcherPolicy.Http405EndpointDisplayName, feature.Endpoint.DisplayName);
Assert.NotSame(endpoint, context.Endpoint);
Assert.Same(HttpMethodMatcherPolicy.Http405EndpointDisplayName, context.Endpoint.DisplayName);
}
[Fact]
@ -89,13 +89,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GeT", });
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/hello", "GET");
var (httpContext, context) = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Fact]
@ -105,13 +105,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GeT", }, acceptCorsPreflight: true);
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/hello", "GET", corsPreflight: true);
var (httpContext, context) = CreateContext("/hello", "GET", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Fact]
@ -121,13 +121,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello");
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/hello", "GET");
var (httpContext, context) = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Fact]
@ -137,13 +137,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", acceptCorsPreflight: true);
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/hello", "GET", corsPreflight: true);
var (httpContext, context) = CreateContext("/hello", "GET", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Fact] // This matches because the endpoint accepts OPTIONS
@ -153,13 +153,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", acceptCorsPreflight: false);
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/hello", "GET", corsPreflight: true);
var (httpContext, context) = CreateContext("/hello", "GET", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Fact]
@ -169,13 +169,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { });
var matcher = CreateMatcher(endpoint);
var (httpContext, feature) = CreateContext("/hello", "GET");
var (httpContext, context) = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Fact] // When all of the candidates handles specific verbs, use a 405 endpoint
@ -186,19 +186,19 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/hello", httpMethods: new string[] { "DELETE" });
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, feature) = CreateContext("/hello", "POST");
var (httpContext, context) = CreateContext("/hello", "POST");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
Assert.NotSame(endpoint1, feature.Endpoint);
Assert.NotSame(endpoint2, feature.Endpoint);
Assert.NotSame(endpoint1, context.Endpoint);
Assert.NotSame(endpoint2, context.Endpoint);
Assert.Same(HttpMethodMatcherPolicy.Http405EndpointDisplayName, feature.Endpoint.DisplayName);
Assert.Same(HttpMethodMatcherPolicy.Http405EndpointDisplayName, context.Endpoint.DisplayName);
// Invoke the endpoint
await feature.Endpoint.RequestDelegate(httpContext);
await context.Endpoint.RequestDelegate(httpContext);
Assert.Equal(405, httpContext.Response.StatusCode);
Assert.Equal("DELETE, GET, PUT", httpContext.Response.Headers["Allow"]);
}
@ -211,13 +211,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/hello", httpMethods: new string[] { "DELETE" });
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, feature) = CreateContext("/hello", "POST", corsPreflight: true);
var (httpContext, context) = CreateContext("/hello", "POST", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertNotMatch(feature, httpContext);
MatcherAssert.AssertNotMatch(context, httpContext);
}
[Fact] // When one of the candidates handles all verbs, dont use a 405 endpoint
@ -228,13 +228,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/hello", httpMethods: new string[] { "DELETE" });
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, feature) = CreateContext("/hello", "POST");
var (httpContext, context) = CreateContext("/hello", "POST");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertNotMatch(feature, httpContext);
MatcherAssert.AssertNotMatch(context, httpContext);
}
[Fact]
@ -245,13 +245,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/bar");
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, feature) = CreateContext("/hello", "GET");
var (httpContext, context) = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint1);
MatcherAssert.AssertMatch(context, httpContext, endpoint1);
}
[Fact]
@ -262,13 +262,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/bar", httpMethods: new string[] { });
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, feature) = CreateContext("/hello", "GET");
var (httpContext, context) = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint1);
MatcherAssert.AssertMatch(context, httpContext, endpoint1);
}
[Fact] // The non-http-method-specific endpoint is part of the same candidate set
@ -279,13 +279,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/{x}", httpMethods: new string[] { });
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, feature) = CreateContext("/hello", "POST");
var (httpContext, context) = CreateContext("/hello", "POST");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint2, ignoreValues: true);
MatcherAssert.AssertMatch(context, httpContext, endpoint2, ignoreValues: true);
}
private static Matcher CreateMatcher(params RouteEndpoint[] endpoints)
@ -305,7 +305,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
return builder.Build();
}
internal static (HttpContext httpContext, EndpointFeature feature) CreateContext(
internal static (HttpContext httpContext, EndpointSelectorContext context) CreateContext(
string path,
string httpMethod,
bool corsPreflight = false)
@ -320,11 +320,11 @@ namespace Microsoft.AspNetCore.Routing.Matching
httpContext.Request.Headers[AccessControlRequestMethod] = httpMethod;
}
var feature = new EndpointFeature();
httpContext.Features.Set<IEndpointFeature>(feature);
httpContext.Features.Set<IRouteValuesFeature>(feature);
var context = new EndpointSelectorContext();
httpContext.Features.Set<IEndpointFeature>(context);
httpContext.Features.Set<IRouteValuesFeature>(context);
return (httpContext, feature);
return (httpContext, context);
}
internal static RouteEndpoint CreateEndpoint(
string template,

View File

@ -12,22 +12,22 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
internal static class MatcherAssert
{
public static void AssertMatch(EndpointFeature feature, HttpContext context, Endpoint expected)
public static void AssertMatch(EndpointSelectorContext context, HttpContext httpContext, Endpoint expected)
{
AssertMatch(feature, context, expected, new RouteValueDictionary());
AssertMatch(context, httpContext, expected, new RouteValueDictionary());
}
public static void AssertMatch(EndpointFeature feature, HttpContext context, Endpoint expected, bool ignoreValues)
public static void AssertMatch(EndpointSelectorContext context, HttpContext httpContext, Endpoint expected, bool ignoreValues)
{
AssertMatch(feature, context, expected, new RouteValueDictionary(), ignoreValues);
AssertMatch(context, httpContext, expected, new RouteValueDictionary(), ignoreValues);
}
public static void AssertMatch(EndpointFeature feature, HttpContext context, Endpoint expected, object values)
public static void AssertMatch(EndpointSelectorContext context, HttpContext httpContext, Endpoint expected, object values)
{
AssertMatch(feature, context, expected, new RouteValueDictionary(values));
AssertMatch(context, httpContext, expected, new RouteValueDictionary(values));
}
public static void AssertMatch(EndpointFeature feature, HttpContext context, Endpoint expected, string[] keys, string[] values)
public static void AssertMatch(EndpointSelectorContext context, HttpContext httpContext, Endpoint expected, string[] keys, string[] values)
{
keys = keys ?? Array.Empty<string>();
values = values ?? Array.Empty<string>();
@ -38,33 +38,33 @@ namespace Microsoft.AspNetCore.Routing.Matching
}
var zipped = keys.Zip(values, (k, v) => new KeyValuePair<string, object>(k, v));
AssertMatch(feature, context, expected, new RouteValueDictionary(zipped));
AssertMatch(context, httpContext, expected, new RouteValueDictionary(zipped));
}
public static void AssertMatch(
EndpointFeature feature,
HttpContext context,
EndpointSelectorContext context,
HttpContext httpContext,
Endpoint expected,
RouteValueDictionary values,
bool ignoreValues = false)
{
if (feature.Endpoint == null)
if (context.Endpoint == null)
{
throw new XunitException($"Was expected to match '{expected.DisplayName}' but did not match.");
}
var actualValues = context.Features.Get<IRouteValuesFeature>().RouteValues;
var actualValues = httpContext.Features.Get<IRouteValuesFeature>().RouteValues;
if (actualValues == null)
{
throw new XunitException("RouteValues is null.");
}
if (!object.ReferenceEquals(expected, feature.Endpoint))
if (!object.ReferenceEquals(expected, context.Endpoint))
{
throw new XunitException(
$"Was expected to match '{expected.DisplayName}' but matched " +
$"'{feature.Endpoint.DisplayName}' with values: {FormatRouteValues(actualValues)}.");
$"'{context.Endpoint.DisplayName}' with values: {FormatRouteValues(actualValues)}.");
}
if (!ignoreValues)
@ -81,13 +81,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
}
}
public static void AssertNotMatch(EndpointFeature feature, HttpContext context)
public static void AssertNotMatch(EndpointSelectorContext context, HttpContext httpContext)
{
if (feature.Endpoint != null)
if (context.Endpoint != null)
{
throw new XunitException(
$"Was expected not to match '{feature.Endpoint.DisplayName}' " +
$"but matched with values: {FormatRouteValues(context.Features.Get<IRouteValuesFeature>().RouteValues)}.");
$"Was expected not to match '{context.Endpoint.DisplayName}' " +
$"but matched with values: {FormatRouteValues(httpContext.Features.Get<IRouteValuesFeature>().RouteValues)}.");
}
}

View File

@ -13,13 +13,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/");
var (httpContext, feature) = CreateContext("/");
var (httpContext, context) = CreateContext("/");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Fact]
@ -27,13 +27,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/simple");
var (httpContext, feature) = CreateContext("/simple");
var (httpContext, context) = CreateContext("/simple");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Fact]
@ -41,13 +41,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/simple");
var (httpContext, feature) = CreateContext("/simple/");
var (httpContext, context) = CreateContext("/simple/");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Theory]
@ -58,13 +58,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/Simple");
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
// Some matchers will optimize for the ASCII case
@ -75,13 +75,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
// Matchers should operate on the decoded representation - a matcher that calls
@ -93,13 +93,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
[Theory]
@ -113,13 +113,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/simple");
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertNotMatch(feature, httpContext);
MatcherAssert.AssertNotMatch(context, httpContext);
}
[Theory]
@ -130,13 +130,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext("/simple");
var (httpContext, context) = CreateContext("/simple");
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
// Matchers do their own 'splitting' of the path into segments, so including
@ -153,13 +153,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint);
MatcherAssert.AssertMatch(context, httpContext, endpoint);
}
// Matchers do their own 'splitting' of the path into segments, so including
@ -184,13 +184,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertNotMatch(feature, httpContext);
MatcherAssert.AssertNotMatch(context, httpContext);
}
[Fact]
@ -198,14 +198,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/{p}");
var (httpContext, feature) = CreateContext("/14");
var (httpContext, context) = CreateContext("/14");
var values = new RouteValueDictionary(new { p = "14", });
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, values);
}
[Fact]
@ -213,14 +213,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/{p:int}");
var (httpContext, feature) = CreateContext("/14");
var (httpContext, context) = CreateContext("/14");
var values = new RouteValueDictionary(new { p = "14", });
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, values);
}
[Fact]
@ -228,14 +228,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/{p}");
var (httpContext, feature) = CreateContext("/14/");
var (httpContext, context) = CreateContext("/14/");
var values = new RouteValueDictionary(new { p = "14", });
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, values);
}
[Fact]
@ -243,7 +243,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/foo/{ }/{.!$%}/{dynamic.data}");
var (httpContext, feature) = CreateContext("/foo/space/weirdmatch/matcherid");
var (httpContext, context) = CreateContext("/foo/space/weirdmatch/matcherid");
var values = new RouteValueDictionary()
{
{ " ", "space" },
@ -252,10 +252,10 @@ namespace Microsoft.AspNetCore.Routing.Matching
};
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, values);
}
[Theory]
@ -267,13 +267,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/{p}");
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertNotMatch(feature, httpContext);
MatcherAssert.AssertNotMatch(context, httpContext);
}
[Theory]
@ -288,13 +288,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertMatch(feature, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
}
[Theory]
@ -317,13 +317,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, feature) = CreateContext(path);
var (httpContext, context) = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, feature);
await matcher.MatchAsync(httpContext, context);
// Assert
MatcherAssert.AssertNotMatch(feature, httpContext);
MatcherAssert.AssertNotMatch(context, httpContext);
}
}
}

View File

@ -14,18 +14,18 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
internal abstract Matcher CreateMatcher(params RouteEndpoint[] endpoints);
internal static (HttpContext httpContext, EndpointFeature feature) CreateContext(string path)
internal static (HttpContext httpContext, EndpointSelectorContext context) CreateContext(string path)
{
var httpContext = new DefaultHttpContext();
httpContext.Request.Method = "TEST";
httpContext.Request.Path = path;
httpContext.RequestServices = CreateServices();
var feature = new EndpointFeature();
httpContext.Features.Set<IEndpointFeature>(feature);
httpContext.Features.Set<IRouteValuesFeature>(feature);
var context = new EndpointSelectorContext();
httpContext.Features.Set<IEndpointFeature>(context);
httpContext.Features.Set<IRouteValuesFeature>(context);
return (httpContext, feature);
return (httpContext, context);
}
// The older routing implementations retrieve services when they first execute.

View File

@ -4,7 +4,6 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Routing.Matching
{
@ -18,25 +17,25 @@ namespace Microsoft.AspNetCore.Routing.Matching
_inner = inner;
}
public async override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
public async override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
{
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}
if (feature == null)
if (context == null)
{
throw new ArgumentNullException(nameof(feature));
throw new ArgumentNullException(nameof(context));
}
var context = new RouteContext(httpContext);
await _inner.RouteAsync(context);
var routeContext = new RouteContext(httpContext);
await _inner.RouteAsync(routeContext);
if (context.Handler != null)
if (routeContext.Handler != null)
{
feature.RouteValues = context.RouteData.Values;
await context.Handler(httpContext);
context.RouteValues = routeContext.RouteData.Values;
await routeContext.Handler(httpContext);
}
}
}

View File

@ -91,18 +91,18 @@ namespace Microsoft.AspNetCore.Routing.Matching
throw new NotImplementedException();
}
public async Task RouteAsync(RouteContext context)
public async Task RouteAsync(RouteContext routeContext)
{
var feature = (EndpointFeature)context.HttpContext.Features.Get<IEndpointFeature>();
var context = (EndpointSelectorContext)routeContext.HttpContext.Features.Get<IEndpointFeature>();
// This is needed due to a quirk of our tests - they reuse the endpoint feature
// across requests.
feature.Endpoint = null;
context.Endpoint = null;
await _selector.SelectAsync(context.HttpContext, feature, new CandidateSet(_candidates, _scores));
if (feature.Endpoint != null)
await _selector.SelectAsync(routeContext.HttpContext, context, new CandidateSet(_candidates, _scores));
if (context.Endpoint != null)
{
context.Handler = (_) => Task.CompletedTask;
routeContext.Handler = (_) => Task.CompletedTask;
}
}
}

View File

@ -19,25 +19,25 @@ namespace Microsoft.AspNetCore.Routing.Matching
_inner = inner;
}
public async override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
public async override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
{
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}
if (feature == null)
if (context == null)
{
throw new ArgumentNullException(nameof(feature));
throw new ArgumentNullException(nameof(context));
}
var context = new RouteContext(httpContext);
await _inner.RouteAsync(context);
var routeContext = new RouteContext(httpContext);
await _inner.RouteAsync(routeContext);
if (context.Handler != null)
if (routeContext.Handler != null)
{
feature.RouteValues = context.RouteData.Values;
await context.Handler(httpContext);
context.RouteValues = routeContext.RouteData.Values;
await routeContext.Handler(httpContext);
}
}
}

View File

@ -93,17 +93,17 @@ namespace Microsoft.AspNetCore.Routing.Matching
throw new NotImplementedException();
}
public async Task RouteAsync(RouteContext context)
public async Task RouteAsync(RouteContext routeContext)
{
var feature = (EndpointFeature)context.HttpContext.Features.Get<IEndpointFeature>();
var context = (EndpointSelectorContext)routeContext.HttpContext.Features.Get<IEndpointFeature>();
// This is needed due to a quirk of our tests - they reuse the endpoint feature.
feature.Endpoint = null;
context.Endpoint = null;
await _selector.SelectAsync(context.HttpContext, feature, new CandidateSet(_candidates, _scores));
if (feature.Endpoint != null)
await _selector.SelectAsync(routeContext.HttpContext, context, new CandidateSet(_candidates, _scores));
if (context.Endpoint != null)
{
context.Handler = (_) => Task.CompletedTask;
routeContext.Handler = (_) => Task.CompletedTask;
}
}
}

View File

@ -17,12 +17,12 @@ namespace Microsoft.AspNetCore.Routing.TestObjects
_isHandled = isHandled;
}
public override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
public override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
{
if (_isHandled)
{
feature.RouteValues = new RouteValueDictionary(new { controller = "Home", action = "Index" });
feature.Endpoint = new Endpoint(TestConstants.EmptyRequestDelegate, EndpointMetadataCollection.Empty, "Test endpoint");
context.RouteValues = new RouteValueDictionary(new { controller = "Home", action = "Index" });
context.Endpoint = new Endpoint(TestConstants.EmptyRequestDelegate, EndpointMetadataCollection.Empty, "Test endpoint");
}
return Task.CompletedTask;