Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Async.Test
{
public class AsyncActionDescriptorTest
{
[Fact]
public void SynchronousExecuteThrows()
{
// Arrange
AsyncActionDescriptor actionDescriptor = new TestableAsyncActionDescriptor();
// Act & Assert
Assert.Throws<InvalidOperationException>(
() => actionDescriptor.Execute(new Mock<ControllerContext>().Object, parameters: null),
"The asynchronous action method 'testAction' cannot be executed synchronously."
);
}
private class TestableAsyncActionDescriptor : AsyncActionDescriptor
{
public override string ActionName
{
get { return "testAction"; }
}
public override ControllerDescriptor ControllerDescriptor
{
get { throw new NotImplementedException(); }
}
public override IAsyncResult BeginExecute(ControllerContext controllerContext, IDictionary<string, object> parameters, AsyncCallback callback, object state)
{
throw new NotImplementedException();
}
public override object EndExecute(IAsyncResult asyncResult)
{
throw new NotImplementedException();
}
public override ParameterDescriptor[] GetParameters()
{
throw new NotImplementedException();
}
}
}
}

View File

@@ -0,0 +1,379 @@
// 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;
}
}
}
}
}

View File

@@ -0,0 +1,115 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Threading;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Async.Test
{
public class AsyncManagerTest
{
[Fact]
public void FinishEvent_ExplicitCallToFinishMethod()
{
// Arrange
AsyncManager helper = new AsyncManager();
bool delegateCalled = false;
helper.Finished += delegate { delegateCalled = true; };
// Act
helper.Finish();
// Assert
Assert.True(delegateCalled);
}
[Fact]
public void FinishEvent_LinkedToOutstandingOperationsCompletedEvent()
{
// Arrange
AsyncManager helper = new AsyncManager();
bool delegateCalled = false;
helper.Finished += delegate { delegateCalled = true; };
// Act
helper.OutstandingOperations.Increment();
helper.OutstandingOperations.Decrement();
// Assert
Assert.True(delegateCalled);
}
[Fact]
public void OutstandingOperationsProperty()
{
// Act
AsyncManager helper = new AsyncManager();
// Assert
Assert.NotNull(helper.OutstandingOperations);
}
[Fact]
public void ParametersProperty()
{
// Act
AsyncManager helper = new AsyncManager();
// Assert
Assert.NotNull(helper.Parameters);
}
[Fact]
public void Sync()
{
// Arrange
Mock<SynchronizationContext> mockSyncContext = new Mock<SynchronizationContext>();
mockSyncContext
.Setup(c => c.Send(It.IsAny<SendOrPostCallback>(), null))
.Callback(
delegate(SendOrPostCallback d, object state) { d(state); });
AsyncManager helper = new AsyncManager(mockSyncContext.Object);
bool wasCalled = false;
// Act
helper.Sync(() => { wasCalled = true; });
// Assert
Assert.True(wasCalled);
}
[Fact]
public void TimeoutProperty()
{
// Arrange
int setValue = 50;
AsyncManager helper = new AsyncManager();
// Act
int defaultTimeout = helper.Timeout;
helper.Timeout = setValue;
int newTimeout = helper.Timeout;
// Assert
Assert.Equal(45000, defaultTimeout);
Assert.Equal(setValue, newTimeout);
}
[Fact]
public void TimeoutPropertyThrowsIfDurationIsOutOfRange()
{
// Arrange
int timeout = -30;
AsyncManager helper = new AsyncManager();
// Act & assert
Assert.ThrowsArgumentOutOfRange(
delegate { helper.Timeout = timeout; }, "value",
@"The timeout value must be non-negative or Timeout.Infinite.");
}
}
}

View File

@@ -0,0 +1,230 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Threading;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Async.Test
{
public class AsyncResultWrapperTest
{
[Fact]
public void Begin_AsynchronousCompletion()
{
// Arrange
AsyncCallback capturedCallback = null;
IAsyncResult resultGivenToCallback = null;
IAsyncResult innerResult = new MockAsyncResult();
// Act
IAsyncResult outerResult = AsyncResultWrapper.Begin(
ar => { resultGivenToCallback = ar; },
null,
(callback, state) =>
{
capturedCallback = callback;
return innerResult;
},
ar => { });
capturedCallback(innerResult);
// Assert
Assert.Equal(outerResult, resultGivenToCallback);
}
[Fact]
public void Begin_ReturnsAsyncResultWhichWrapsInnerResult()
{
// Arrange
IAsyncResult innerResult = new MockAsyncResult()
{
AsyncState = "inner state",
CompletedSynchronously = true,
IsCompleted = true
};
// Act
IAsyncResult outerResult = AsyncResultWrapper.Begin(
null, "outer state",
(callback, state) => innerResult,
ar => { });
// Assert
Assert.Equal(innerResult.AsyncState, outerResult.AsyncState);
Assert.Equal(innerResult.AsyncWaitHandle, outerResult.AsyncWaitHandle);
Assert.Equal(innerResult.CompletedSynchronously, outerResult.CompletedSynchronously);
Assert.Equal(innerResult.IsCompleted, outerResult.IsCompleted);
}
[Fact]
public void Begin_SynchronousCompletion()
{
// Arrange
IAsyncResult resultGivenToCallback = null;
IAsyncResult innerResult = new MockAsyncResult();
// Act
IAsyncResult outerResult = AsyncResultWrapper.Begin(
ar => { resultGivenToCallback = ar; },
null,
(callback, state) =>
{
callback(innerResult);
return innerResult;
},
ar => { });
// Assert
Assert.Equal(outerResult, resultGivenToCallback);
}
[Fact]
public void Begin_AsynchronousButAlreadyCompleted()
{
// Arrange
Mock<IAsyncResult> innerResultMock = new Mock<IAsyncResult>();
innerResultMock.Setup(ir => ir.CompletedSynchronously).Returns(false);
innerResultMock.Setup(ir => ir.IsCompleted).Returns(true);
// Act
IAsyncResult outerResult = AsyncResultWrapper.Begin(
null,
null,
(callback, state) =>
{
callback(innerResultMock.Object);
return innerResultMock.Object;
},
ar => { });
// Assert
Assert.True(outerResult.CompletedSynchronously);
}
[Fact]
public void BeginSynchronous_Action()
{
// Arrange
bool actionCalled = false;
// Act
IAsyncResult asyncResult = AsyncResultWrapper.BeginSynchronous(null, null, delegate { actionCalled = true; });
AsyncResultWrapper.End(asyncResult);
// Assert
Assert.True(actionCalled);
Assert.True(asyncResult.IsCompleted);
Assert.True(asyncResult.CompletedSynchronously);
}
[Fact]
public void BeginSynchronous_Func()
{
// Act
IAsyncResult asyncResult = AsyncResultWrapper.BeginSynchronous(null, null, () => 42);
int retVal = AsyncResultWrapper.End<int>(asyncResult);
// Assert
Assert.Equal(42, retVal);
Assert.True(asyncResult.IsCompleted);
Assert.True(asyncResult.CompletedSynchronously);
}
[Fact]
public void End_ExecutesStoredDelegateAndReturnsValue()
{
// Arrange
IAsyncResult asyncResult = AsyncResultWrapper.Begin(
null, null,
(callback, state) => new MockAsyncResult(),
ar => 42);
// Act
int returned = AsyncResultWrapper.End<int>(asyncResult);
// Assert
Assert.Equal(42, returned);
}
[Fact]
public void End_ThrowsIfAsyncResultIsIncorrectType()
{
// Arrange
IAsyncResult asyncResult = AsyncResultWrapper.Begin(
null, null,
(callback, state) => new MockAsyncResult(),
ar => { });
// Act & assert
Assert.Throws<ArgumentException>(
delegate { AsyncResultWrapper.End<int>(asyncResult); },
@"The provided IAsyncResult is not valid for this method.
Parameter name: asyncResult");
}
[Fact]
public void End_ThrowsIfAsyncResultIsNull()
{
// Act & assert
Assert.ThrowsArgumentNull(
delegate { AsyncResultWrapper.End(null); }, "asyncResult");
}
[Fact]
public void End_ThrowsIfAsyncResultTagMismatch()
{
// Arrange
IAsyncResult asyncResult = AsyncResultWrapper.Begin(
null, null,
(callback, state) => new MockAsyncResult(),
ar => { },
"some tag");
// Act & assert
Assert.Throws<ArgumentException>(
delegate { AsyncResultWrapper.End(asyncResult, "some other tag"); },
@"The provided IAsyncResult is not valid for this method.
Parameter name: asyncResult");
}
[Fact]
public void End_ThrowsIfCalledTwiceOnSameAsyncResult()
{
// Arrange
IAsyncResult asyncResult = AsyncResultWrapper.Begin(
null, null,
(callback, state) => new MockAsyncResult(),
ar => { });
// Act & assert
AsyncResultWrapper.End(asyncResult);
Assert.Throws<InvalidOperationException>(
delegate { AsyncResultWrapper.End(asyncResult); },
@"The provided IAsyncResult has already been consumed.");
}
[Fact]
public void TimedOut()
{
// Arrange
ManualResetEvent waitHandle = new ManualResetEvent(false /* initialState */);
AsyncCallback callback = ar => { waitHandle.Set(); };
// Act & assert
IAsyncResult asyncResult = AsyncResultWrapper.Begin(
callback, null,
(innerCallback, innerState) => new MockAsyncResult(),
ar => { Assert.True(false, "This callback should never execute since we timed out."); },
null, 0);
// wait for the timeout
waitHandle.WaitOne();
Assert.Throws<TimeoutException>(
delegate { AsyncResultWrapper.End(asyncResult); });
}
}
}

View File

@@ -0,0 +1,100 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Threading;
using Xunit;
namespace System.Web.Mvc.Async.Test
{
public class AsyncUtilTest
{
[Fact]
public void WrapCallbackForSynchronizedExecution_CallsSyncIfOperationCompletedAsynchronously()
{
// Arrange
MockAsyncResult asyncResult = new MockAsyncResult()
{
CompletedSynchronously = false,
IsCompleted = true
};
bool originalCallbackCalled = false;
AsyncCallback originalCallback = ar =>
{
Assert.Equal(asyncResult, ar);
originalCallbackCalled = true;
};
DummySynchronizationContext syncContext = new DummySynchronizationContext();
// Act
AsyncCallback retVal = AsyncUtil.WrapCallbackForSynchronizedExecution(originalCallback, syncContext);
retVal(asyncResult);
// Assert
Assert.True(originalCallbackCalled);
Assert.True(syncContext.SendCalled);
}
[Fact]
public void WrapCallbackForSynchronizedExecution_DoesNotCallSyncIfOperationCompletedSynchronously()
{
// Arrange
MockAsyncResult asyncResult = new MockAsyncResult()
{
CompletedSynchronously = true,
IsCompleted = true
};
bool originalCallbackCalled = false;
AsyncCallback originalCallback = ar =>
{
Assert.Equal(asyncResult, ar);
originalCallbackCalled = true;
};
DummySynchronizationContext syncContext = new DummySynchronizationContext();
// Act
AsyncCallback retVal = AsyncUtil.WrapCallbackForSynchronizedExecution(originalCallback, syncContext);
retVal(asyncResult);
// Assert
Assert.True(originalCallbackCalled);
Assert.False(syncContext.SendCalled);
}
[Fact]
public void WrapCallbackForSynchronizedExecution_ReturnsNullIfCallbackIsNull()
{
// Act
AsyncCallback retVal = AsyncUtil.WrapCallbackForSynchronizedExecution(null, new SynchronizationContext());
// Assert
Assert.Null(retVal);
}
[Fact]
public void WrapCallbackForSynchronizedExecution_ReturnsOriginalCallbackIfSyncContextIsNull()
{
// Arrange
AsyncCallback originalCallback = _ => { };
// Act
AsyncCallback retVal = AsyncUtil.WrapCallbackForSynchronizedExecution(originalCallback, null);
// Assert
Assert.Same(originalCallback, retVal);
}
private class DummySynchronizationContext : SynchronizationContext
{
public bool SendCalled { get; private set; }
public override void Send(SendOrPostCallback d, object state)
{
SendCalled = true;
base.Send(d, state);
}
}
}
}

View File

@@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Threading;
namespace System.Web.Mvc.Async.Test
{
public class MockAsyncResult : IAsyncResult
{
private volatile object _asyncState;
private volatile ManualResetEvent _asyncWaitHandle = new ManualResetEvent(false);
private volatile bool _completedSynchronously;
private volatile bool _isCompleted;
public object AsyncState
{
get { return _asyncState; }
set { _asyncState = value; }
}
public ManualResetEvent AsyncWaitHandle
{
get { return _asyncWaitHandle; }
set { _asyncWaitHandle = value; }
}
public bool CompletedSynchronously
{
get { return _completedSynchronously; }
set { _completedSynchronously = value; }
}
public bool IsCompleted
{
get { return _isCompleted; }
set { _isCompleted = value; }
}
#region IAsyncResult Members
WaitHandle IAsyncResult.AsyncWaitHandle
{
get { return _asyncWaitHandle; }
}
#endregion
}
}

View File

@@ -0,0 +1,112 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using Xunit;
namespace System.Web.Mvc.Async.Test
{
public class OperationCounterTest
{
[Fact]
public void CompletedEvent()
{
// Arrange
bool premature = true;
bool eventFired = false;
OperationCounter ops = new OperationCounter();
ops.Completed += (sender, eventArgs) =>
{
if (premature)
{
Assert.True(false, "Event fired too early!");
}
if (eventFired)
{
Assert.True(false, "Event fired multiple times.");
}
Assert.Equal(ops, sender);
Assert.Equal(eventArgs, EventArgs.Empty);
eventFired = true;
};
// Act & assert
ops.Increment(); // should not fire event (will throw exception)
premature = false;
ops.Decrement(); // should fire event
Assert.True(eventFired);
ops.Increment(); // should not fire event (will throw exception)
}
[Fact]
public void CountStartsAtZero()
{
// Arrange
OperationCounter ops = new OperationCounter();
// Act & assert
Assert.Equal(0, ops.Count);
}
[Fact]
public void DecrementWithIntegerArgument()
{
// Arrange
OperationCounter ops = new OperationCounter();
// Act
int returned = ops.Decrement(3);
int newCount = ops.Count;
// Assert
Assert.Equal(-3, returned);
Assert.Equal(-3, newCount);
}
[Fact]
public void DecrementWithNoArguments()
{
// Arrange
OperationCounter ops = new OperationCounter();
// Act
int returned = ops.Decrement();
int newCount = ops.Count;
// Assert
Assert.Equal(-1, returned);
Assert.Equal(-1, newCount);
}
[Fact]
public void IncrementWithIntegerArgument()
{
// Arrange
OperationCounter ops = new OperationCounter();
// Act
int returned = ops.Increment(3);
int newCount = ops.Count;
// Assert
Assert.Equal(3, returned);
Assert.Equal(3, newCount);
}
[Fact]
public void IncrementWithNoArguments()
{
// Arrange
OperationCounter ops = new OperationCounter();
// Act
int returned = ops.Increment();
int newCount = ops.Count;
// Assert
Assert.Equal(1, returned);
Assert.Equal(1, newCount);
}
}
}

View File

@@ -0,0 +1,316 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Async.Test
{
public class ReflectedAsyncActionDescriptorTest
{
private readonly MethodInfo _asyncMethod = typeof(ExecuteController).GetMethod("FooAsync");
private readonly MethodInfo _completedMethod = typeof(ExecuteController).GetMethod("FooCompleted");
[Fact]
public void Constructor_SetsProperties()
{
// Arrange
string actionName = "SomeAction";
ControllerDescriptor cd = new Mock<ControllerDescriptor>().Object;
// Act
ReflectedAsyncActionDescriptor ad = new ReflectedAsyncActionDescriptor(_asyncMethod, _completedMethod, actionName, cd);
// Assert
Assert.Equal(_asyncMethod, ad.AsyncMethodInfo);
Assert.Equal(_completedMethod, ad.CompletedMethodInfo);
Assert.Equal(actionName, ad.ActionName);
Assert.Equal(cd, ad.ControllerDescriptor);
}
[Fact]
public void Constructor_ThrowsIfActionNameIsEmpty()
{
// Arrange
ControllerDescriptor cd = new Mock<ControllerDescriptor>().Object;
// Act & assert
Assert.ThrowsArgumentNullOrEmpty(
delegate { new ReflectedAsyncActionDescriptor(_asyncMethod, _completedMethod, "", cd); }, "actionName");
}
[Fact]
public void Constructor_ThrowsIfActionNameIsNull()
{
// Arrange
ControllerDescriptor cd = new Mock<ControllerDescriptor>().Object;
// Act & assert
Assert.ThrowsArgumentNullOrEmpty(
delegate { new ReflectedAsyncActionDescriptor(_asyncMethod, _completedMethod, null, cd); }, "actionName");
}
[Fact]
public void Constructor_ThrowsIfAsyncMethodInfoIsInvalid()
{
// Arrange
ControllerDescriptor cd = new Mock<ControllerDescriptor>().Object;
MethodInfo getHashCodeMethod = typeof(object).GetMethod("GetHashCode");
// Act & assert
Assert.Throws<ArgumentException>(
delegate { new ReflectedAsyncActionDescriptor(getHashCodeMethod, _completedMethod, "SomeAction", cd); },
@"Cannot create a descriptor for instance method 'Int32 GetHashCode()' on type 'System.Object' because the type does not derive from ControllerBase.
Parameter name: asyncMethodInfo");
}
[Fact]
public void Constructor_ThrowsIfAsyncMethodInfoIsNull()
{
// Arrange
ControllerDescriptor cd = new Mock<ControllerDescriptor>().Object;
// Act & assert
Assert.ThrowsArgumentNull(
delegate { new ReflectedAsyncActionDescriptor(null, _completedMethod, "SomeAction", cd); }, "asyncMethodInfo");
}
[Fact]
public void Constructor_ThrowsIfCompletedMethodInfoIsInvalid()
{
// Arrange
ControllerDescriptor cd = new Mock<ControllerDescriptor>().Object;
MethodInfo getHashCodeMethod = typeof(object).GetMethod("GetHashCode");
// Act & assert
Assert.Throws<ArgumentException>(
delegate { new ReflectedAsyncActionDescriptor(_asyncMethod, getHashCodeMethod, "SomeAction", cd); },
@"Cannot create a descriptor for instance method 'Int32 GetHashCode()' on type 'System.Object' because the type does not derive from ControllerBase.
Parameter name: completedMethodInfo");
}
[Fact]
public void Constructor_ThrowsIfCompletedMethodInfoIsNull()
{
// Arrange
ControllerDescriptor cd = new Mock<ControllerDescriptor>().Object;
// Act & assert
Assert.ThrowsArgumentNull(
delegate { new ReflectedAsyncActionDescriptor(_asyncMethod, null, "SomeAction", cd); }, "completedMethodInfo");
}
[Fact]
public void Constructor_ThrowsIfControllerDescriptorIsNull()
{
// Act & assert
Assert.ThrowsArgumentNull(
delegate { new ReflectedAsyncActionDescriptor(_asyncMethod, _completedMethod, "SomeAction", null); }, "controllerDescriptor");
}
[Fact]
public void Execute()
{
// Arrange
Mock<ControllerContext> mockControllerContext = new Mock<ControllerContext>();
mockControllerContext.Setup(c => c.Controller).Returns(new ExecuteController());
ControllerContext controllerContext = mockControllerContext.Object;
Dictionary<string, object> parameters = new Dictionary<string, object>()
{
{ "id1", 42 }
};
ReflectedAsyncActionDescriptor ad = GetActionDescriptor(_asyncMethod, _completedMethod);
SignalContainer<object> resultContainer = new SignalContainer<object>();
AsyncCallback callback = ar =>
{
object o = ad.EndExecute(ar);
resultContainer.Signal(o);
};
// Act
ad.BeginExecute(controllerContext, parameters, callback, null);
object retVal = resultContainer.Wait();
// Assert
Assert.Equal("Hello world: 42", retVal);
}
[Fact]
public void Execute_ThrowsIfControllerContextIsNull()
{
// Arrange
ReflectedAsyncActionDescriptor ad = GetActionDescriptor(_asyncMethod, _completedMethod);
// Act & assert
Assert.ThrowsArgumentNull(
delegate { ad.BeginExecute(null, new Dictionary<string, object>(), null, null); }, "controllerContext");
}
[Fact]
public void Execute_ThrowsIfControllerIsNotAsyncManagerContainer()
{
// Arrange
ReflectedAsyncActionDescriptor ad = GetActionDescriptor(_asyncMethod, _completedMethod);
ControllerContext controllerContext = new ControllerContext()
{
Controller = new RegularSyncController()
};
// Act & assert
Assert.Throws<InvalidOperationException>(
delegate { ad.BeginExecute(controllerContext, new Dictionary<string, object>(), null, null); },
@"The controller of type 'System.Web.Mvc.Async.Test.ReflectedAsyncActionDescriptorTest+RegularSyncController' must subclass AsyncController or implement the IAsyncManagerContainer interface.");
}
[Fact]
public void Execute_ThrowsIfParametersIsNull()
{
// Arrange
ReflectedAsyncActionDescriptor ad = GetActionDescriptor(_asyncMethod, _completedMethod);
// Act & assert
Assert.ThrowsArgumentNull(
delegate { ad.BeginExecute(new ControllerContext(), null, null, null); }, "parameters");
}
[Fact]
public void GetCustomAttributes()
{
// Arrange
ReflectedAsyncActionDescriptor ad = GetActionDescriptor(_asyncMethod, _completedMethod);
// Act
object[] attributes = ad.GetCustomAttributes(true /* inherit */);
// Assert
Assert.Single(attributes);
Assert.Equal(typeof(AuthorizeAttribute), attributes[0].GetType());
}
[Fact]
public void GetCustomAttributes_FilterByType()
{
// Shouldn't match attributes on the Completed() method, only the Async() method
// Arrange
ReflectedAsyncActionDescriptor ad = GetActionDescriptor(_asyncMethod, _completedMethod);
// Act
object[] attributes = ad.GetCustomAttributes(typeof(OutputCacheAttribute), true /* inherit */);
// Assert
Assert.Empty(attributes);
}
[Fact]
public void GetParameters()
{
// Arrange
ParameterInfo pInfo = _asyncMethod.GetParameters()[0];
ReflectedAsyncActionDescriptor ad = GetActionDescriptor(_asyncMethod, _completedMethod);
// Act
ParameterDescriptor[] pDescsFirstCall = ad.GetParameters();
ParameterDescriptor[] pDescsSecondCall = ad.GetParameters();
// Assert
Assert.NotSame(pDescsFirstCall, pDescsSecondCall);
Assert.Equal(pDescsFirstCall, pDescsSecondCall);
Assert.Single(pDescsFirstCall);
ReflectedParameterDescriptor pDesc = pDescsFirstCall[0] as ReflectedParameterDescriptor;
Assert.NotNull(pDesc);
Assert.Same(ad, pDesc.ActionDescriptor);
Assert.Same(pInfo, pDesc.ParameterInfo);
}
[Fact]
public void GetSelectors()
{
// Arrange
ControllerContext controllerContext = new Mock<ControllerContext>().Object;
Mock<MethodInfo> mockMethod = new Mock<MethodInfo>();
Mock<ActionMethodSelectorAttribute> mockAttr = new Mock<ActionMethodSelectorAttribute>();
mockAttr.Setup(attr => attr.IsValidForRequest(controllerContext, mockMethod.Object)).Returns(true).Verifiable();
mockMethod.Setup(m => m.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true)).Returns(new ActionMethodSelectorAttribute[] { mockAttr.Object });
ReflectedAsyncActionDescriptor ad = GetActionDescriptor(mockMethod.Object, _completedMethod);
// Act
ICollection<ActionSelector> selectors = ad.GetSelectors();
bool executedSuccessfully = selectors.All(s => s(controllerContext));
// Assert
Assert.Single(selectors);
Assert.True(executedSuccessfully);
mockAttr.Verify();
}
[Fact]
public void IsDefined()
{
// Arrange
ReflectedAsyncActionDescriptor ad = GetActionDescriptor(_asyncMethod, _completedMethod);
// Act
bool isDefined = ad.IsDefined(typeof(AuthorizeAttribute), true /* inherit */);
// Assert
Assert.True(isDefined);
}
private static ReflectedAsyncActionDescriptor GetActionDescriptor(MethodInfo asyncMethod, MethodInfo completedMethod)
{
return new ReflectedAsyncActionDescriptor(asyncMethod, completedMethod, "someName", new Mock<ControllerDescriptor>().Object, false /* validateMethod */)
{
DispatcherCache = new ActionMethodDispatcherCache()
};
}
private class ExecuteController : AsyncController
{
private Func<object, string> _func;
[Authorize]
public void FooAsync(int id1)
{
_func = o => Convert.ToString(o, CultureInfo.InvariantCulture) + id1.ToString(CultureInfo.InvariantCulture);
AsyncManager.Parameters["id2"] = "Hello world: ";
AsyncManager.Finish();
}
[OutputCache]
public string FooCompleted(string id2)
{
return _func(id2);
}
public string FooWithBool(bool id2)
{
return _func(id2);
}
public string FooWithException(Exception id2)
{
return _func(id2);
}
}
private class RegularSyncController : ControllerBase
{
protected override void ExecuteCore()
{
throw new NotImplementedException();
}
}
}
}

View File

@@ -0,0 +1,179 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Reflection;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Async.Test
{
public class ReflectedAsyncControllerDescriptorTest
{
[Fact]
public void ConstructorSetsControllerTypeProperty()
{
// Arrange
Type controllerType = typeof(string);
// Act
ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);
// Assert
Assert.Same(controllerType, cd.ControllerType);
}
[Fact]
public void ConstructorThrowsIfControllerTypeIsNull()
{
// Act & assert
Assert.ThrowsArgumentNull(
delegate { new ReflectedAsyncControllerDescriptor(null); }, "controllerType");
}
[Fact]
public void FindActionReturnsActionDescriptorIfFound()
{
// Arrange
Type controllerType = typeof(MyController);
MethodInfo asyncMethodInfo = controllerType.GetMethod("FooAsync");
MethodInfo completedMethodInfo = controllerType.GetMethod("FooCompleted");
ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);
// Act
ActionDescriptor ad = cd.FindAction(new Mock<ControllerContext>().Object, "NewName");
// Assert
Assert.Equal("NewName", ad.ActionName);
var castAd = Assert.IsType<ReflectedAsyncActionDescriptor>(ad);
Assert.Same(asyncMethodInfo, castAd.AsyncMethodInfo);
Assert.Same(completedMethodInfo, castAd.CompletedMethodInfo);
Assert.Same(cd, ad.ControllerDescriptor);
}
[Fact]
public void FindActionReturnsNullIfNoActionFound()
{
// Arrange
Type controllerType = typeof(MyController);
ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);
// Act
ActionDescriptor ad = cd.FindAction(new Mock<ControllerContext>().Object, "NonExistent");
// Assert
Assert.Null(ad);
}
[Fact]
public void FindActionThrowsIfActionNameIsEmpty()
{
// Arrange
Type controllerType = typeof(MyController);
ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);
// Act & assert
Assert.ThrowsArgumentNullOrEmpty(
delegate { cd.FindAction(new Mock<ControllerContext>().Object, ""); }, "actionName");
}
[Fact]
public void FindActionThrowsIfActionNameIsNull()
{
// Arrange
Type controllerType = typeof(MyController);
ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);
// Act & assert
Assert.ThrowsArgumentNullOrEmpty(
delegate { cd.FindAction(new Mock<ControllerContext>().Object, null); }, "actionName");
}
[Fact]
public void FindActionThrowsIfControllerContextIsNull()
{
// Arrange
Type controllerType = typeof(MyController);
ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);
// Act & assert
Assert.ThrowsArgumentNull(
delegate { cd.FindAction(null, "someName"); }, "controllerContext");
}
[Fact]
public void GetCanonicalActionsReturnsEmptyArray()
{
// this method does nothing by default
// Arrange
Type controllerType = typeof(MyController);
ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);
// Act
ActionDescriptor[] canonicalActions = cd.GetCanonicalActions();
// Assert
Assert.Empty(canonicalActions);
}
[Fact]
public void GetCustomAttributesCallsTypeGetCustomAttributes()
{
// Arrange
object[] expected = new object[0];
Mock<Type> mockType = new Mock<Type>();
mockType.Setup(t => t.GetCustomAttributes(true)).Returns(expected);
ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(mockType.Object);
// Act
object[] returned = cd.GetCustomAttributes(true);
// Assert
Assert.Same(expected, returned);
}
[Fact]
public void GetCustomAttributesWithAttributeTypeCallsTypeGetCustomAttributes()
{
// Arrange
object[] expected = new object[0];
Mock<Type> mockType = new Mock<Type>();
mockType.Setup(t => t.GetCustomAttributes(typeof(ObsoleteAttribute), true)).Returns(expected);
ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(mockType.Object);
// Act
object[] returned = cd.GetCustomAttributes(typeof(ObsoleteAttribute), true);
// Assert
Assert.Same(expected, returned);
}
[Fact]
public void IsDefinedCallsTypeIsDefined()
{
// Arrange
Mock<Type> mockType = new Mock<Type>();
mockType.Setup(t => t.IsDefined(typeof(ObsoleteAttribute), true)).Returns(true);
ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(mockType.Object);
// Act
bool isDefined = cd.IsDefined(typeof(ObsoleteAttribute), true);
// Assert
Assert.True(isDefined);
}
private class MyController : AsyncController
{
[ActionName("NewName")]
public void FooAsync()
{
}
public void FooCompleted()
{
}
}
}
}

View File

@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Threading;
namespace System.Web.Mvc.Async.Test
{
public sealed class SignalContainer<T>
{
private volatile object _item;
private readonly AutoResetEvent _waitHandle = new AutoResetEvent(false /* initialState */);
public void Signal(T item)
{
_item = item;
_waitHandle.Set();
}
public T Wait()
{
_waitHandle.WaitOne();
return (T)_item;
}
}
}

View File

@@ -0,0 +1,103 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Threading;
using Xunit;
namespace System.Web.Mvc.Async.Test
{
public class SimpleAsyncResultTest
{
[Fact]
public void AsyncStateProperty()
{
// Arrange
string expected = "Hello!";
SimpleAsyncResult asyncResult = new SimpleAsyncResult(expected);
// Act
object asyncState = asyncResult.AsyncState;
// Assert
Assert.Equal(expected, asyncState);
}
[Fact]
public void AsyncWaitHandleProperty()
{
// Arrange
SimpleAsyncResult asyncResult = new SimpleAsyncResult(null);
// Act
WaitHandle asyncWaitHandle = asyncResult.AsyncWaitHandle;
// Assert
Assert.Null(asyncWaitHandle);
}
[Fact]
public void CompletedSynchronouslyProperty()
{
// Arrange
SimpleAsyncResult asyncResult = new SimpleAsyncResult(null);
// Act
bool completedSynchronously = asyncResult.CompletedSynchronously;
// Assert
Assert.False(completedSynchronously);
}
[Fact]
public void IsCompletedProperty()
{
// Arrange
SimpleAsyncResult asyncResult = new SimpleAsyncResult(null);
// Act
bool isCompleted = asyncResult.IsCompleted;
// Assert
Assert.False(isCompleted);
}
[Fact]
public void MarkCompleted_AsynchronousCompletion()
{
// Arrange
SimpleAsyncResult asyncResult = new SimpleAsyncResult(null);
bool callbackWasCalled = false;
AsyncCallback callback = ar =>
{
callbackWasCalled = true;
Assert.Equal(asyncResult, ar);
Assert.True(ar.IsCompleted);
Assert.False(ar.CompletedSynchronously);
};
// Act & assert
asyncResult.MarkCompleted(false, callback);
Assert.True(callbackWasCalled);
}
[Fact]
public void MarkCompleted_SynchronousCompletion()
{
// Arrange
SimpleAsyncResult asyncResult = new SimpleAsyncResult(null);
bool callbackWasCalled = false;
AsyncCallback callback = ar =>
{
callbackWasCalled = true;
Assert.Equal(asyncResult, ar);
Assert.True(ar.IsCompleted);
Assert.True(ar.CompletedSynchronously);
};
// Act & assert
asyncResult.MarkCompleted(true, callback);
Assert.True(callbackWasCalled);
}
}
}

View File

@@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using Xunit;
namespace System.Web.Mvc.Async.Test
{
public class SingleEntryGateTest
{
[Fact]
public void TryEnterShouldBeTrueForFirstCallAndFalseForSubsequentCalls()
{
// Arrange
SingleEntryGate gate = new SingleEntryGate();
// Act
bool firstCall = gate.TryEnter();
bool secondCall = gate.TryEnter();
bool thirdCall = gate.TryEnter();
// Assert
Assert.True(firstCall);
Assert.False(secondCall);
Assert.False(thirdCall);
}
}
}

View File

@@ -0,0 +1,91 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Threading;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Async.Test
{
public class SynchronizationContextUtilTest
{
[Fact]
public void SyncWithAction()
{
// Arrange
bool actionWasCalled = false;
bool sendWasCalled = false;
Mock<SynchronizationContext> mockSyncContext = new Mock<SynchronizationContext>();
mockSyncContext
.Setup(sc => sc.Send(It.IsAny<SendOrPostCallback>(), null))
.Callback(
delegate(SendOrPostCallback d, object state)
{
sendWasCalled = true;
d(state);
});
// Act
SynchronizationContextUtil.Sync(mockSyncContext.Object, () => { actionWasCalled = true; });
// Assert
Assert.True(actionWasCalled);
Assert.True(sendWasCalled);
}
[Fact]
public void SyncWithActionCapturesException()
{
// Arrange
InvalidOperationException exception = new InvalidOperationException("Some exception text.");
Mock<SynchronizationContext> mockSyncContext = new Mock<SynchronizationContext>();
mockSyncContext
.Setup(sc => sc.Send(It.IsAny<SendOrPostCallback>(), null))
.Callback(
delegate(SendOrPostCallback d, object state)
{
try
{
d(state);
}
catch
{
// swallow exceptions, just like AspNetSynchronizationContext
}
});
// Act & assert
SynchronousOperationException thrownException = Assert.Throws<SynchronousOperationException>(
delegate { SynchronizationContextUtil.Sync(mockSyncContext.Object, () => { throw exception; }); },
@"An operation that crossed a synchronization context failed. See the inner exception for more information.");
Assert.Equal(exception, thrownException.InnerException);
}
[Fact]
public void SyncWithFunc()
{
// Arrange
bool sendWasCalled = false;
Mock<SynchronizationContext> mockSyncContext = new Mock<SynchronizationContext>();
mockSyncContext
.Setup(sc => sc.Send(It.IsAny<SendOrPostCallback>(), null))
.Callback(
delegate(SendOrPostCallback d, object state)
{
sendWasCalled = true;
d(state);
});
// Act
int retVal = SynchronizationContextUtil.Sync(mockSyncContext.Object, () => 42);
// Assert
Assert.Equal(42, retVal);
Assert.True(sendWasCalled);
}
}
}

View File

@@ -0,0 +1,64 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Async.Test
{
public class SynchronousOperationExceptionTest
{
[Fact]
public void ConstructorWithMessageAndInnerExceptionParameter()
{
// Arrange
Exception innerException = new Exception();
// Act
SynchronousOperationException ex = new SynchronousOperationException("the message", innerException);
// Assert
Assert.Equal("the message", ex.Message);
Assert.Equal(innerException, ex.InnerException);
}
[Fact]
public void ConstructorWithMessageParameter()
{
// Act
SynchronousOperationException ex = new SynchronousOperationException("the message");
// Assert
Assert.Equal("the message", ex.Message);
}
[Fact]
public void ConstructorWithoutParameters()
{
// Act & assert
Assert.Throws<SynchronousOperationException>(
delegate { throw new SynchronousOperationException(); });
}
[Fact]
public void TypeIsSerializable()
{
// Arrange
MemoryStream ms = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
SynchronousOperationException ex = new SynchronousOperationException("the message", new Exception("inner exception"));
// Act
formatter.Serialize(ms, ex);
ms.Position = 0;
SynchronousOperationException deserialized = formatter.Deserialize(ms) as SynchronousOperationException;
// Assert
Assert.NotNull(deserialized);
Assert.Equal("the message", deserialized.Message);
Assert.NotNull(deserialized.InnerException);
Assert.Equal("inner exception", deserialized.InnerException.Message);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,64 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Threading;
using System.Threading.Tasks;
using Moq;
using Xunit;
namespace System.Web.Mvc.Async.Test
{
public class TaskWrapperAsyncResultTest
{
[Fact]
public void PropertiesHaveCorrectValues()
{
// Arrange
Mock<MyTask> mockTask = new Mock<MyTask>();
WaitHandle waitHandle = new Mock<WaitHandle>().Object;
mockTask.Setup(o => o.AsyncState).Returns(10);
mockTask.Setup(o => o.AsyncWaitHandle).Returns(waitHandle);
mockTask.Setup(o => o.CompletedSynchronously).Returns(true);
mockTask.Setup(o => o.IsCompleted).Returns(true);
// Act
TaskWrapperAsyncResult taskWrapper = new TaskWrapperAsyncResult(mockTask.Object, asyncState: 20);
// Assert
Assert.Equal(20, taskWrapper.AsyncState);
Assert.Equal(waitHandle, taskWrapper.AsyncWaitHandle);
Assert.True(taskWrapper.CompletedSynchronously);
Assert.True(taskWrapper.IsCompleted);
Assert.Equal(mockTask.Object, taskWrapper.Task);
}
// Assists in mocking a Task by passing a dummy action to the Task constructor [which defers execution]
public class MyTask : Task, IAsyncResult
{
public MyTask()
: base(() => { })
{
}
public new virtual object AsyncState
{
get { throw new NotImplementedException(); }
}
public virtual WaitHandle AsyncWaitHandle
{
get { throw new NotImplementedException(); }
}
public virtual bool CompletedSynchronously
{
get { throw new NotImplementedException(); }
}
public new virtual bool IsCompleted
{
get { throw new NotImplementedException(); }
}
}
}
}

View File

@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using Xunit;
namespace System.Web.Mvc.Async.Test
{
public class TriggerListenerTest
{
[Fact]
public void PerformTest()
{
// Arrange
int count = 0;
TriggerListener listener = new TriggerListener();
Trigger trigger = listener.CreateTrigger();
// Act & assert (hasn't fired yet)
listener.SetContinuation(() => { count++; });
listener.Activate();
Assert.Equal(0, count);
// Act & assert (fire it, get the callback)
trigger.Fire();
Assert.Equal(1, count);
// Act & assert (fire again, but no callback since it already fired)
Trigger trigger2 = listener.CreateTrigger();
trigger2.Fire();
Assert.Equal(1, count);
}
}
}