зеркало из https://github.com/aspnet/Routing.git
Родитель
ff5d919e0d
Коммит
3e7d8d54f9
|
@ -1,19 +0,0 @@
|
|||
using Microsoft.AspNet.Abstractions;
|
||||
using Moq;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public static class RouteConstraintExtensions
|
||||
{
|
||||
public static bool EasyMatch(this IRouteConstraint constraint,
|
||||
string routeKey,
|
||||
RouteValueDictionary values)
|
||||
{
|
||||
return constraint.Match(httpContext: new Mock<HttpContext>().Object,
|
||||
route: new Mock<IRouter>().Object,
|
||||
routeKey: routeKey,
|
||||
values: values,
|
||||
routeDirection: RouteDirection.IncomingRequest);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
#if NET45
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
@ -7,30 +8,6 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
{
|
||||
public class ConstraintMatcherTests
|
||||
{
|
||||
private class PassConstraint : IRouteConstraint
|
||||
{
|
||||
public bool Match(HttpContext httpContext,
|
||||
IRouter route,
|
||||
string routeKey,
|
||||
IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class FailConstraint : IRouteConstraint
|
||||
{
|
||||
public bool Match(HttpContext httpContext,
|
||||
IRouter route,
|
||||
string routeKey,
|
||||
IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReturnsTrueOnValidConstraints()
|
||||
{
|
||||
|
@ -40,7 +17,26 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
{"b", new PassConstraint()}
|
||||
};
|
||||
|
||||
var routeValueDictionary = new RouteValueDictionary(new {a = "value", b = "value"});
|
||||
var routeValueDictionary = new RouteValueDictionary(new { a = "value", b = "value" });
|
||||
|
||||
Assert.True(RouteConstraintMatcher.Match(
|
||||
constraints: constraints,
|
||||
routeValues: routeValueDictionary,
|
||||
httpContext: new Mock<HttpContext>().Object,
|
||||
route: new Mock<IRouter>().Object,
|
||||
routeDirection: RouteDirection.IncomingRequest));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConstraintsGetTheRightKey()
|
||||
{
|
||||
var constraints = new Dictionary<string, IRouteConstraint>
|
||||
{
|
||||
{"a", new PassConstraint("a")},
|
||||
{"b", new PassConstraint("b")}
|
||||
};
|
||||
|
||||
var routeValueDictionary = new RouteValueDictionary(new { a = "value", b = "value" });
|
||||
|
||||
Assert.True(RouteConstraintMatcher.Match(
|
||||
constraints: constraints,
|
||||
|
@ -117,5 +113,42 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
route: new Mock<IRouter>().Object,
|
||||
routeDirection: RouteDirection.IncomingRequest));
|
||||
}
|
||||
|
||||
private class PassConstraint : IRouteConstraint
|
||||
{
|
||||
private readonly string _expectedKey;
|
||||
|
||||
public PassConstraint(string expectedKey = null)
|
||||
{
|
||||
_expectedKey = expectedKey;
|
||||
}
|
||||
|
||||
public bool Match(HttpContext httpContext,
|
||||
IRouter route,
|
||||
string routeKey,
|
||||
IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
if (_expectedKey != null)
|
||||
{
|
||||
Assert.Equal(_expectedKey, routeKey);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class FailConstraint : IRouteConstraint
|
||||
{
|
||||
public bool Match(HttpContext httpContext,
|
||||
IRouter route,
|
||||
string routeKey,
|
||||
IDictionary<string, object> values,
|
||||
RouteDirection routeDirection)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
#if NET45
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Abstractions;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
@ -9,25 +11,6 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
{
|
||||
public class ConstraintsBuilderTests
|
||||
{
|
||||
public static IEnumerable<object> EmptyAndNullDictionary
|
||||
{
|
||||
get
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new Object[]
|
||||
{
|
||||
null,
|
||||
},
|
||||
|
||||
new Object[]
|
||||
{
|
||||
new Dictionary<string, object>(),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData("EmptyAndNullDictionary")]
|
||||
public void ConstraintBuilderReturnsNull_OnNullOrEmptyInput(IDictionary<string, object> input)
|
||||
|
@ -106,15 +89,15 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("abc", "abc", true)]
|
||||
[InlineData("abc", "bbb|abc", true)]
|
||||
[InlineData("Abc", "abc", true)]
|
||||
[InlineData("Abc ", "abc", false)]
|
||||
[InlineData("Abcd", "abc", false)]
|
||||
[InlineData("Abc", " abc", false)]
|
||||
public void StringConstraintsMatchesWholeValueCaseInsensitively(string routeValue,
|
||||
string constraintValue,
|
||||
bool shouldMatch)
|
||||
[InlineData("abc", "abc", true)] // simple case
|
||||
[InlineData("abc", "bbb|abc", true)] // Regex or
|
||||
[InlineData("Abc", "abc", true)] // Case insensitive
|
||||
[InlineData("Abc ", "abc", false)] // Matches whole (but no trimming)
|
||||
[InlineData("Abcd", "abc", false)] // Matches whole (additional non whitespace char)
|
||||
[InlineData("Abc", " abc", false)] // Matches whole (less one char)
|
||||
public void StringConstraintsMatchingScenarios(string routeValue,
|
||||
string constraintValue,
|
||||
bool shouldMatch)
|
||||
{
|
||||
// Arrange
|
||||
var dictionary = new RouteValueDictionary(new { controller = routeValue });
|
||||
|
@ -124,7 +107,32 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
var constraint = constraintDictionary["controller"];
|
||||
|
||||
Assert.Equal(shouldMatch,
|
||||
constraint.EasyMatch("controller", dictionary));
|
||||
constraint.Match(
|
||||
httpContext: new Mock<HttpContext>().Object,
|
||||
route: new Mock<IRouter>().Object,
|
||||
routeKey: "controller",
|
||||
values: dictionary,
|
||||
routeDirection: RouteDirection.IncomingRequest));
|
||||
}
|
||||
|
||||
public static IEnumerable<object> EmptyAndNullDictionary
|
||||
{
|
||||
get
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new Object[]
|
||||
{
|
||||
null,
|
||||
},
|
||||
|
||||
new Object[]
|
||||
{
|
||||
new Dictionary<string, object>(),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,71 +1,73 @@
|
|||
using System;
|
||||
#if NET45
|
||||
using Moq;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using Xunit;
|
||||
using Microsoft.AspNet.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNet.Routing.Tests
|
||||
{
|
||||
public class RegexConstraintTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("abc", "abc", true)]
|
||||
[InlineData("Abc", "abc", true)]
|
||||
[InlineData("Abc ", "abc", true)]
|
||||
[InlineData("Abcd", "abc", true)]
|
||||
[InlineData("^Abcd", "abc", true)]
|
||||
[InlineData("Abc", " abc", false)]
|
||||
public void RegexConstraintDoesNotPrepend(string routeValue,
|
||||
string constraintValue,
|
||||
bool shouldMatch)
|
||||
[InlineData("abc", "abc", true)] // simple match
|
||||
[InlineData("Abc", "abc", true)] // case insensitive match
|
||||
[InlineData("Abc ", "abc", true)] // Extra space on input match (because we don't add ^({0})$
|
||||
[InlineData("Abcd", "abc", true)] // Extra char
|
||||
[InlineData("^Abcd", "abc", true)] // Extra special char
|
||||
[InlineData("Abc", " abc", false)] // Missing char
|
||||
public void RegexConstraintBuildRegexVerbatimFromInput(string routeValue,
|
||||
string constraintValue,
|
||||
bool shouldMatch)
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RegexConstraint(constraintValue);
|
||||
var values = new RouteValueDictionary(new {controller = routeValue});
|
||||
|
||||
// Assert
|
||||
Assert.Equal(shouldMatch, constraint.EasyMatch("controller", values));
|
||||
Assert.Equal(shouldMatch, EasyMatch(constraint, "controller", values));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegexConstraintCanTakeARegex_SuccessulMatch()
|
||||
public void RegexConstraint_TakesRegexAsInput_SimpleMatch()
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RegexConstraint(new Regex("^abc$"));
|
||||
var values = new RouteValueDictionary(new { controller = "abc"});
|
||||
|
||||
// Assert
|
||||
Assert.True(constraint.EasyMatch("controller", values));
|
||||
Assert.True(EasyMatch(constraint, "controller", values));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegexConstraintFailsIfKeyIsNotFound()
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RegexConstraint(new Regex("^abc$"));
|
||||
var values = new RouteValueDictionary(new { action = "abc" });
|
||||
|
||||
// Assert
|
||||
Assert.False(constraint.EasyMatch("controller", values));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegexConstraintCanTakeARegex_FailedMatch()
|
||||
public void RegexConstraintConstructedWithRegex_SimpleFailedMatch()
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RegexConstraint(new Regex("^abc$"));
|
||||
var values = new RouteValueDictionary(new { controller = "Abc" });
|
||||
|
||||
// Assert
|
||||
Assert.False(constraint.EasyMatch("controller", values));
|
||||
Assert.False(EasyMatch(constraint, "controller", values));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegexConstraintIsCultureInsensitive()
|
||||
public void RegexConstraintFailsIfKeyIsNotFoundInRouteValues()
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RegexConstraint(new Regex("^abc$"));
|
||||
var values = new RouteValueDictionary(new { action = "abc" });
|
||||
|
||||
// Assert
|
||||
Assert.False(EasyMatch(constraint, "controller", values));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegexConstraintIsCultureInsensitiveWhenConstructredWithString()
|
||||
{
|
||||
// Arrange
|
||||
var constraint = new RegexConstraint("^([a-z]+)$");
|
||||
var values = new RouteValueDictionary(new { controller = "\u0130" });
|
||||
var values = new RouteValueDictionary(new { controller = "\u0130" }); // Turkish upper-case dotted I
|
||||
|
||||
var currentThread = Thread.CurrentThread;
|
||||
var backupCulture = currentThread.CurrentCulture;
|
||||
|
@ -77,10 +79,10 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
try
|
||||
{
|
||||
currentThread.CurrentCulture = new CultureInfo("tr-TR"); // Turkish culture
|
||||
matchInTurkish = constraint.EasyMatch("controller", values);
|
||||
matchInTurkish = EasyMatch(constraint, "controller", values);
|
||||
|
||||
currentThread.CurrentCulture = new CultureInfo("en-US");
|
||||
matchInUsEnglish = constraint.EasyMatch("controller", values);
|
||||
matchInUsEnglish = EasyMatch(constraint, "controller", values);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -91,5 +93,17 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
Assert.False(matchInUsEnglish); // this just verifies the test
|
||||
Assert.False(matchInTurkish);
|
||||
}
|
||||
|
||||
private static bool EasyMatch(IRouteConstraint constraint,
|
||||
string routeKey,
|
||||
RouteValueDictionary values)
|
||||
{
|
||||
return constraint.Match(httpContext: new Mock<HttpContext>().Object,
|
||||
route: new Mock<IRouter>().Object,
|
||||
routeKey: routeKey,
|
||||
values: values,
|
||||
routeDirection: RouteDirection.IncomingRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -179,7 +179,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
|
|||
|
||||
TemplateRoute r = CreateRoute(
|
||||
"{p1}/{p2}",
|
||||
new RouteValueDictionary(new { p2 = "catchall" }),
|
||||
new { p2 = "catchall" },
|
||||
true,
|
||||
new RouteValueDictionary(new { p2 = "\\d{4}" }));
|
||||
|
||||
|
@ -199,7 +199,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
|
|||
|
||||
TemplateRoute r = CreateRoute(
|
||||
"{p1}/{p2}",
|
||||
new RouteValueDictionary(new { p2 = "catchall" }),
|
||||
new { p2 = "catchall" },
|
||||
true,
|
||||
new RouteValueDictionary(new { p2 = "\\d{4}" }));
|
||||
|
||||
|
@ -220,7 +220,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
|
|||
|
||||
TemplateRoute r = CreateRoute(
|
||||
"{p1}/{*p2}",
|
||||
new RouteValueDictionary(new { p2 = "catchall" }),
|
||||
new { p2 = "catchall" },
|
||||
true,
|
||||
new RouteValueDictionary(new { p2 = "\\d{4}" }));
|
||||
|
||||
|
@ -241,7 +241,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
|
|||
|
||||
TemplateRoute r = CreateRoute(
|
||||
"{p1}/{*p2}",
|
||||
new RouteValueDictionary(new { p2 = "catchall" }),
|
||||
new { p2 = "catchall" },
|
||||
true,
|
||||
new RouteValueDictionary(new { p2 = "\\d{4}" }));
|
||||
|
||||
|
@ -271,7 +271,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
|
|||
|
||||
TemplateRoute r = CreateRoute(
|
||||
"{p1}/{p2}",
|
||||
new RouteValueDictionary(new { p2 = "catchall" }),
|
||||
new { p2 = "catchall" },
|
||||
true,
|
||||
new RouteValueDictionary(new { p2 = target.Object }));
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"System.Runtime.Extensions": "4.0.10.0",
|
||||
"System.Threading": "4.0.0.0",
|
||||
"System.Threading.Tasks": "4.0.10.0"
|
||||
"System.Text.RegularExpressions": "4.0.0.0"
|
||||
}
|
||||
},
|
||||
"net45": {
|
||||
|
|
Загрузка…
Ссылка в новой задаче