305 lines
9.6 KiB
C#
Raw Normal View History

// 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; }
}
}
}