Files
acceptance-tests
data
debian
docs
external
Newtonsoft.Json
api-doc-tools
api-snapshot
aspnetwebstack
packages
src
test
Microsoft.TestCommon
Microsoft.Web.Helpers.Test
Microsoft.Web.Http.Data.Test
Microsoft.Web.Mvc.Test
Microsoft.Web.WebPages.OAuth.Test
SPA.Test
System.Json.Test.Integration
System.Json.Test.Unit
System.Net.Http.Formatting.Test.Integration
System.Net.Http.Formatting.Test.Unit
System.Web.Helpers.Test
System.Web.Http.Integration.Test
System.Web.Http.SelfHost.Test
System.Web.Http.Test
System.Web.Http.WebHost.Test
System.Web.Mvc.Test
Ajax
Async
Test
AsyncActionDescriptorTest.cs
AsyncActionMethodSelectorTest.cs
AsyncControllerActionInvokerTest.cs
AsyncManagerTest.cs
AsyncResultWrapperTest.cs
AsyncUtilTest.cs
MockAsyncResult.cs
OperationCounterTest.cs
ReflectedAsyncActionDescriptorTest.cs
ReflectedAsyncControllerDescriptorTest.cs
SignalContainer.cs
SimpleAsyncResultTest.cs
SingleEntryGateTest.cs
SynchronizationContextUtilTest.cs
SynchronousOperationExceptionTest.cs
TaskAsyncActionDescriptorTest.cs
TaskWrapperAsyncResultTest.cs
TriggerListenerTest.cs
ExpressionUtil
Html
Properties
Razor
Test
Util
System.Web.Mvc.Test.csproj
packages.config
System.Web.Razor.Test
System.Web.WebPages.Administration.Test
System.Web.WebPages.Deployment.Test
System.Web.WebPages.Razor.Test
System.Web.WebPages.Test
WebMatrix.Data.Test
WebMatrix.WebData.Test
Settings.StyleCop
tools
.gitattributes
.gitignore
License.txt
README.md
Runtime.msbuild
Runtime.sln
Runtime.xunit
Settings.StyleCop
build.cmd
binary-reference-assemblies
bockbuild
boringssl
cecil
cecil-legacy
corefx
corert
ikdasm
ikvm
linker
nuget-buildtasks
nunit-lite
roslyn-binaries
rx
xunit-binaries
ikvm-native
libgc
llvm
m4
man
mcs
mono
msvc
po
runtime
samples
scripts
support
tools
COPYING.LIB
LICENSE
Makefile.am
Makefile.in
NEWS
README.md
acinclude.m4
aclocal.m4
autogen.sh
code_of_conduct.md
compile
config.guess
config.h.in
config.rpath
config.sub
configure.REMOVED.git-id
configure.ac.REMOVED.git-id
depcomp
install-sh
ltmain.sh.REMOVED.git-id
missing
mkinstalldirs
mono-uninstalled.pc.in
test-driver
winconfig.h
linux-packaging-mono/external/aspnetwebstack/test/System.Web.Mvc.Test/Async/Test/AsyncActionMethodSelectorTest.cs

380 lines
14 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.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Async.Test
{
public class AsyncActionMethodSelectorTest
{
[Fact]
public void AliasedMethodsProperty()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
// Act
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Assert
Assert.Equal(3, selector.AliasedMethods.Length);
List<MethodInfo> sortedAliasedMethods = selector.AliasedMethods.OrderBy(methodInfo => methodInfo.Name).ToList();
Assert.Equal("Bar", sortedAliasedMethods[0].Name);
Assert.Equal("FooRenamed", sortedAliasedMethods[1].Name);
Assert.Equal("Renamed", sortedAliasedMethods[2].Name);
}
[Fact]
public void ControllerTypeProperty()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act & Assert
Assert.Same(controllerType, selector.ControllerType);
}
[Fact]
public void FindAction_DoesNotMatchAsyncMethod()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act
ActionDescriptorCreator creator = selector.FindAction(null, "EventPatternAsync");
// Assert
Assert.Null(creator);
}
[Fact]
public void FindAction_DoesNotMatchCompletedMethod()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act
ActionDescriptorCreator creator = selector.FindAction(null, "EventPatternCompleted");
// Assert
Assert.Null(creator);
}
[Fact]
public void FindAction_ReturnsMatchingMethodIfOneMethodMatches()
{
// Arrange
Type controllerType = typeof(SelectionAttributeController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act
ActionDescriptorCreator creator = selector.FindAction(null, "OneMatch");
ActionDescriptor actionDescriptor = creator("someName", new Mock<ControllerDescriptor>().Object);
// Assert
var castActionDescriptor = Assert.IsType<ReflectedActionDescriptor>(actionDescriptor);
Assert.Equal("OneMatch", castActionDescriptor.MethodInfo.Name);
Assert.Equal(typeof(string), castActionDescriptor.MethodInfo.GetParameters()[0].ParameterType);
}
[Fact]
public void FindAction_ReturnsMethodWithActionSelectionAttributeIfMultipleMethodsMatchRequest()
{
// DevDiv Bugs 212062: If multiple action methods match a request, we should match only the methods with an
// [ActionMethod] attribute since we assume those methods are more specific.
// Arrange
Type controllerType = typeof(SelectionAttributeController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act
ActionDescriptorCreator creator = selector.FindAction(null, "ShouldMatchMethodWithSelectionAttribute");
ActionDescriptor actionDescriptor = creator("someName", new Mock<ControllerDescriptor>().Object);
// Assert
var castActionDescriptor = Assert.IsType<ReflectedActionDescriptor>(actionDescriptor);
Assert.Equal("MethodHasSelectionAttribute1", castActionDescriptor.MethodInfo.Name);
}
[Fact]
public void FindAction_ReturnsNullIfNoMethodMatches()
{
// Arrange
Type controllerType = typeof(SelectionAttributeController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act
ActionDescriptorCreator creator = selector.FindAction(null, "ZeroMatch");
// Assert
Assert.Null(creator);
}
[Fact]
public void FindAction_ThrowsIfMultipleMethodsMatch()
{
// Arrange
Type controllerType = typeof(SelectionAttributeController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act & veriy
Assert.Throws<AmbiguousMatchException>(
delegate { selector.FindAction(null, "TwoMatch"); },
@"The current request for action 'TwoMatch' on controller type 'SelectionAttributeController' is ambiguous between the following action methods:
Void TwoMatch2() on type System.Web.Mvc.Async.Test.AsyncActionMethodSelectorTest+SelectionAttributeController
Void TwoMatch() on type System.Web.Mvc.Async.Test.AsyncActionMethodSelectorTest+SelectionAttributeController");
}
[Fact]
public void FindActionMethod_Asynchronous()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act
ActionDescriptorCreator creator = selector.FindAction(null, "EventPattern");
ActionDescriptor actionDescriptor = creator("someName", new Mock<ControllerDescriptor>().Object);
// Assert
var castActionDescriptor = Assert.IsType<ReflectedAsyncActionDescriptor>(actionDescriptor);
Assert.Equal("EventPatternAsync", castActionDescriptor.AsyncMethodInfo.Name);
Assert.Equal("EventPatternCompleted", castActionDescriptor.CompletedMethodInfo.Name);
}
[Fact]
public void FindActionMethod_Task()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act
ActionDescriptorCreator creator = selector.FindAction(null, "TaskPattern");
ActionDescriptor actionDescriptor = creator("someName", new Mock<ControllerDescriptor>().Object);
// Assert
var castActionDescriptor = Assert.IsType<TaskAsyncActionDescriptor>(actionDescriptor);
Assert.Equal("TaskPattern", castActionDescriptor.TaskMethodInfo.Name);
Assert.Equal(typeof(Task), castActionDescriptor.TaskMethodInfo.ReturnType);
}
[Fact]
public void FindActionMethod_GenericTask()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act
ActionDescriptorCreator creator = selector.FindAction(null, "GenericTaskPattern");
ActionDescriptor actionDescriptor = creator("someName", new Mock<ControllerDescriptor>().Object);
// Assert
var castActionDescriptor = Assert.IsType<TaskAsyncActionDescriptor>(actionDescriptor);
Assert.Equal("GenericTaskPattern", castActionDescriptor.TaskMethodInfo.Name);
Assert.Equal(typeof(Task<string>), castActionDescriptor.TaskMethodInfo.ReturnType);
}
[Fact]
public void FindActionMethod_Asynchronous_ThrowsIfCompletionMethodNotFound()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act & assert
Assert.Throws<InvalidOperationException>(
delegate { ActionDescriptorCreator creator = selector.FindAction(null, "EventPatternWithoutCompletionMethod"); },
@"Could not locate a method named 'EventPatternWithoutCompletionMethodCompleted' on controller type System.Web.Mvc.Async.Test.AsyncActionMethodSelectorTest+MethodLocatorController.");
}
[Fact]
public void FindActionMethod_Asynchronous_ThrowsIfMultipleCompletedMethodsMatched()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Act & assert
Assert.Throws<AmbiguousMatchException>(
delegate { ActionDescriptorCreator creator = selector.FindAction(null, "EventPatternAmbiguous"); },
@"Lookup for method 'EventPatternAmbiguousCompleted' on controller type 'MethodLocatorController' failed because of an ambiguity between the following methods:
Void EventPatternAmbiguousCompleted(Int32) on type System.Web.Mvc.Async.Test.AsyncActionMethodSelectorTest+MethodLocatorController
Void EventPatternAmbiguousCompleted(System.String) on type System.Web.Mvc.Async.Test.AsyncActionMethodSelectorTest+MethodLocatorController");
}
[Fact]
public void NonAliasedMethodsProperty()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
// Act
AsyncActionMethodSelector selector = new AsyncActionMethodSelector(controllerType);
// Assert
Assert.Equal(6, selector.NonAliasedMethods.Count);
List<MethodInfo> sortedMethods = selector.NonAliasedMethods["foo"].OrderBy(methodInfo => methodInfo.GetParameters().Length).ToList();
Assert.Equal("Foo", sortedMethods[0].Name);
Assert.Empty(sortedMethods[0].GetParameters());
Assert.Equal("Foo", sortedMethods[1].Name);
Assert.Equal(typeof(string), sortedMethods[1].GetParameters()[0].ParameterType);
Assert.Equal(1, selector.NonAliasedMethods["EventPattern"].Count());
Assert.Equal("EventPatternAsync", selector.NonAliasedMethods["EventPattern"].First().Name);
Assert.Equal(1, selector.NonAliasedMethods["EventPatternAmbiguous"].Count());
Assert.Equal("EventPatternAmbiguousAsync", selector.NonAliasedMethods["EventPatternAmbiguous"].First().Name);
Assert.Equal(1, selector.NonAliasedMethods["EventPatternWithoutCompletionMethod"].Count());
Assert.Equal("EventPatternWithoutCompletionMethodAsync", selector.NonAliasedMethods["EventPatternWithoutCompletionMethod"].First().Name);
Assert.Equal(1, selector.NonAliasedMethods["TaskPattern"].Count());
Assert.Equal("TaskPattern", selector.NonAliasedMethods["TaskPattern"].First().Name);
Assert.Equal(1, selector.NonAliasedMethods["GenericTaskPattern"].Count());
Assert.Equal("GenericTaskPattern", selector.NonAliasedMethods["GenericTaskPattern"].First().Name);
}
private class MethodLocatorController : Controller
{
public void Foo()
{
}
public void Foo(string s)
{
}
[ActionName("Foo")]
public void FooRenamed()
{
}
[ActionName("Bar")]
public void Bar()
{
}
[ActionName("PrivateVoid")]
private void PrivateVoid()
{
}
protected void ProtectedVoidAction()
{
}
public static void StaticMethod()
{
}
public void EventPatternAsync()
{
}
public void EventPatternCompleted()
{
}
public void EventPatternWithoutCompletionMethodAsync()
{
}
public void EventPatternAmbiguousAsync()
{
}
public void EventPatternAmbiguousCompleted(int i)
{
}
public void EventPatternAmbiguousCompleted(string s)
{
}
public Task TaskPattern()
{
return Task.Factory.StartNew(() => "foo");
}
public Task<string> GenericTaskPattern()
{
return Task.Factory.StartNew(() => "foo");
}
[ActionName("RenamedCompleted")]
public void Renamed()
{
}
// ensure that methods inheriting from Controller or a base class are not matched
[ActionName("Blah")]
protected override void ExecuteCore()
{
throw new NotImplementedException();
}
public string StringProperty { get; set; }
#pragma warning disable 0067
public event EventHandler<EventArgs> SomeEvent;
#pragma warning restore 0067
}
private class SelectionAttributeController : Controller
{
[Match(false)]
public void OneMatch()
{
}
public void OneMatch(string s)
{
}
public void TwoMatch()
{
}
[ActionName("TwoMatch")]
public void TwoMatch2()
{
}
[Match(true), ActionName("ShouldMatchMethodWithSelectionAttribute")]
public void MethodHasSelectionAttribute1()
{
}
[ActionName("ShouldMatchMethodWithSelectionAttribute")]
public void MethodDoesNotHaveSelectionAttribute1()
{
}
private class MatchAttribute : ActionMethodSelectorAttribute
{
private bool _match;
public MatchAttribute(bool match)
{
_match = match;
}
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
return _match;
}
}
}
}
}