a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
305 lines
9.6 KiB
C#
305 lines
9.6 KiB
C#
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.Linq.Expressions;
|
|
using System.Web.Mvc;
|
|
using System.Web.Routing;
|
|
using Xunit;
|
|
using Assert = Microsoft.TestCommon.AssertEx;
|
|
using ExpressionHelper = Microsoft.Web.Mvc.Internal.ExpressionHelper;
|
|
|
|
namespace Microsoft.Web.Mvc.Test
|
|
{
|
|
public class ExpressionHelperTest
|
|
{
|
|
[Fact]
|
|
public void BuildRouteValueDictionary_TargetsAsynchronousAsyncMethod_StripsSuffix()
|
|
{
|
|
// Arrange
|
|
Expression<Action<TestAsyncController>> expr = (c => c.AsynchronousAsync());
|
|
|
|
// Act
|
|
RouteValueDictionary rvd = ExpressionHelper.GetRouteValuesFromExpression(expr);
|
|
|
|
// Assert
|
|
Assert.Equal("Asynchronous", rvd["action"]);
|
|
Assert.Equal("TestAsync", rvd["controller"]);
|
|
Assert.False(rvd.ContainsKey("area"));
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionary_TargetsAsynchronousCompletedMethod_Throws()
|
|
{
|
|
// Arrange
|
|
Expression<Action<TestAsyncController>> expr = (c => c.AsynchronousCompleted());
|
|
|
|
// Act & assert
|
|
Assert.Throws<InvalidOperationException>(
|
|
delegate { ExpressionHelper.GetRouteValuesFromExpression(expr); },
|
|
@"The method 'AsynchronousCompleted' is an asynchronous completion method and cannot be called directly.");
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionary_TargetsControllerWithAreaAttribute_AddsAreaName()
|
|
{
|
|
// Arrange
|
|
Expression<Action<ControllerWithAreaController>> expr = c => c.Index();
|
|
|
|
// Act
|
|
RouteValueDictionary rvd = ExpressionHelper.GetRouteValuesFromExpression(expr);
|
|
|
|
// Assert
|
|
Assert.Equal("Index", rvd["action"]);
|
|
Assert.Equal("ControllerWithArea", rvd["controller"]);
|
|
Assert.Equal("the area name", rvd["area"]);
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionary_TargetsNonActionMethod_Throws()
|
|
{
|
|
// Arrange
|
|
Expression<Action<TestController>> expr = (c => c.NotAnAction());
|
|
|
|
// Act & assert
|
|
Assert.Throws<InvalidOperationException>(
|
|
delegate { ExpressionHelper.GetRouteValuesFromExpression(expr); },
|
|
@"The method 'NotAnAction' is marked [NonAction] and cannot be called directly.");
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionary_TargetsRenamedMethod_UsesNewName()
|
|
{
|
|
// Arrange
|
|
Expression<Action<TestController>> expr = (c => c.Renamed());
|
|
|
|
// Act
|
|
RouteValueDictionary rvd = ExpressionHelper.GetRouteValuesFromExpression(expr);
|
|
|
|
// Assert
|
|
Assert.Equal("NewName", rvd["action"]);
|
|
Assert.Equal("Test", rvd["controller"]);
|
|
Assert.False(rvd.ContainsKey("area"));
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionary_TargetsSynchronousMethodOnAsyncController_ReturnsOriginalName()
|
|
{
|
|
// Arrange
|
|
Expression<Action<TestAsyncController>> expr = (c => c.Synchronous());
|
|
|
|
// Act
|
|
RouteValueDictionary rvd = ExpressionHelper.GetRouteValuesFromExpression(expr);
|
|
|
|
// Assert
|
|
Assert.Equal("Synchronous", rvd["action"]);
|
|
Assert.Equal("TestAsync", rvd["controller"]);
|
|
Assert.False(rvd.ContainsKey("area"));
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionaryWithNullExpressionThrowsArgumentNullException()
|
|
{
|
|
Assert.ThrowsArgumentNull(
|
|
() => ExpressionHelper.GetRouteValuesFromExpression<TestController>(null),
|
|
"action");
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionaryWithNonMethodExpressionThrowsInvalidOperationException()
|
|
{
|
|
// Arrange
|
|
Expression<Action<TestController>> expression = c => new TestController();
|
|
|
|
// Act & Assert
|
|
Assert.Throws<ArgumentException>(
|
|
() => ExpressionHelper.GetRouteValuesFromExpression(expression),
|
|
"Expression must be a method call." + Environment.NewLine + "Parameter name: action");
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionaryWithoutControllerSuffixThrowsInvalidOperationException()
|
|
{
|
|
// Arrange
|
|
Expression<Action<TestControllerNot>> index = (c => c.Index(123));
|
|
|
|
// Act & Assert
|
|
Assert.Throws<ArgumentException>(
|
|
() => ExpressionHelper.GetRouteValuesFromExpression(index),
|
|
"Controller name must end in 'Controller'." + Environment.NewLine + "Parameter name: action");
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionaryWithControllerBaseClassThrowsInvalidOperationException()
|
|
{
|
|
// Arrange
|
|
Expression<Action<Controller>> index = (c => c.Dispose());
|
|
|
|
// Act & Assert
|
|
Assert.Throws<ArgumentException>(
|
|
() => ExpressionHelper.GetRouteValuesFromExpression(index),
|
|
"Cannot route to class named 'Controller'." + Environment.NewLine + "Parameter name: action");
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionaryAddsControllerNameToDictionary()
|
|
{
|
|
// Arrange
|
|
Expression<Action<TestController>> index = (c => c.Index(123));
|
|
|
|
// Act
|
|
RouteValueDictionary rvd = ExpressionHelper.GetRouteValuesFromExpression(index);
|
|
|
|
// Assert
|
|
Assert.Equal("Test", rvd["Controller"]);
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionaryFromExpressionReturnsCorrectDictionary()
|
|
{
|
|
// Arrange
|
|
Expression<Action<TestController>> index = (c => c.Index(123));
|
|
|
|
// Act
|
|
RouteValueDictionary rvd = ExpressionHelper.GetRouteValuesFromExpression(index);
|
|
|
|
// Assert
|
|
Assert.Equal("Test", rvd["Controller"]);
|
|
Assert.Equal("Index", rvd["Action"]);
|
|
Assert.Equal(123, rvd["page"]);
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildRouteValueDictionaryFromNonConstantExpressionReturnsCorrectDictionary()
|
|
{
|
|
// Arrange
|
|
Expression<Action<TestController>> index = (c => c.About(Foo));
|
|
|
|
// Act
|
|
RouteValueDictionary rvd = ExpressionHelper.GetRouteValuesFromExpression(index);
|
|
|
|
// Assert
|
|
Assert.Equal("Test", rvd["Controller"]);
|
|
Assert.Equal("About", rvd["Action"]);
|
|
Assert.Equal("FooValue", rvd["s"]);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetInputNameFromPropertyExpressionReturnsPropertyName()
|
|
{
|
|
// Arrange
|
|
Expression<Func<TestModel, int>> expression = m => m.IntProperty;
|
|
|
|
// Act
|
|
string name = ExpressionHelper.GetInputName(expression);
|
|
|
|
// Assert
|
|
Assert.Equal("IntProperty", name);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetInputNameFromPropertyWithMethodCallExpressionReturnsPropertyName()
|
|
{
|
|
// Arrange
|
|
Expression<Func<TestModel, string>> expression = m => m.IntProperty.ToString();
|
|
|
|
// Act
|
|
string name = ExpressionHelper.GetInputName(expression);
|
|
|
|
// Assert
|
|
Assert.Equal("IntProperty", name);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetInputNameFromPropertyWithTwoMethodCallExpressionReturnsPropertyName()
|
|
{
|
|
// Arrange
|
|
Expression<Func<TestModel, string>> expression = m => m.IntProperty.ToString().ToUpper();
|
|
|
|
// Act
|
|
string name = ExpressionHelper.GetInputName(expression);
|
|
|
|
// Assert
|
|
Assert.Equal("IntProperty", name);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetInputNameFromExpressionWithTwoPropertiesUsesWholeExpression()
|
|
{
|
|
// Arrange
|
|
Expression<Func<TestModel, int>> expression = m => m.StringProperty.Length;
|
|
|
|
// Act
|
|
string name = ExpressionHelper.GetInputName(expression);
|
|
|
|
// Assert
|
|
Assert.Equal("StringProperty.Length", name);
|
|
}
|
|
|
|
public class TestController : Controller
|
|
{
|
|
public ActionResult Index(int page)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public string About(string s)
|
|
{
|
|
return "The value is " + s;
|
|
}
|
|
|
|
[ActionName("NewName")]
|
|
public void Renamed()
|
|
{
|
|
}
|
|
|
|
[NonAction]
|
|
public void NotAnAction()
|
|
{
|
|
}
|
|
}
|
|
|
|
public class TestAsyncController : AsyncController
|
|
{
|
|
public void Synchronous()
|
|
{
|
|
}
|
|
|
|
public void AsynchronousAsync()
|
|
{
|
|
}
|
|
|
|
public void AsynchronousCompleted()
|
|
{
|
|
}
|
|
}
|
|
|
|
public string Foo
|
|
{
|
|
get { return "FooValue"; }
|
|
}
|
|
|
|
public class TestControllerNot : Controller
|
|
{
|
|
public ActionResult Index(int page)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
[ActionLinkArea("the area name")]
|
|
public class ControllerWithAreaController : Controller
|
|
{
|
|
public ActionResult Index()
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public class TestModel
|
|
{
|
|
public int IntProperty { get; set; }
|
|
public string StringProperty { get; set; }
|
|
}
|
|
}
|
|
}
|