interception/tests/PolicySetFixture.cs

380 строки
13 KiB
C#

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Practices.Unity.TestSupport;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Microsoft.Practices.Unity.InterceptionExtension.Tests
{
/// <summary>
/// Tests for the PolicySet class.
/// </summary>
[TestClass]
public class PolicySetFixture
{
private IUnityContainer container;
[TestInitialize]
public void SetUp()
{
container = new UnityContainer();
}
//[TestMethod]
//public void ShouldInitializeToEmpty()
//{
// PolicySet policies = new PolicySet();
// Assert.IsFalse(policies.AppliesTo(GetType()));
// MethodInfo thisMember = GetType().GetMethod("ShouldInitializeToEmpty");
// List<ICallHandler> handlers = new List<ICallHandler>(policies.GetHandlersFor(thisMember));
// Assert.AreEqual(0, handlers.Count);
//}
[TestMethod]
public void ShouldBeAbleToAddOnePolicy()
{
container
.RegisterInstance<ICallHandler>("Handler1", new Handler1())
.RegisterInstance<ICallHandler>("Handler2", new Handler2());
PolicySet policies = new PolicySet();
RuleDrivenPolicy p
= new RuleDrivenPolicy(
"NameMatching",
new IMatchingRule[] { new MemberNameMatchingRule("ShouldBeAbleToAddOnePolicy") },
new string[] { "Handler1", "Handler2" });
policies.Add(p);
MethodImplementationInfo thisMember = GetMethodImplInfo<PolicySetFixture>("ShouldBeAbleToAddOnePolicy");
List<ICallHandler> handlers =
new List<ICallHandler>(policies.GetHandlersFor(thisMember, container));
Assert.AreEqual(2, handlers.Count);
Assert.IsTrue(typeof(Handler1) == handlers[0].GetType());
Assert.IsTrue(typeof(Handler2) == handlers[1].GetType());
}
[TestMethod]
public void ShouldMatchPolicyByTypeName()
{
PolicySet policies = GetMultiplePolicySet();
MethodImplementationInfo nameDoesntMatchMember = GetMethodImplInfo<MatchesByType>("NameDoesntMatch");
MethodImplementationInfo nameMatchMember = GetMethodImplInfo<MatchesByType>("NameMatch");
List<ICallHandler> nameDoesntMatchHandlers =
new List<ICallHandler>(policies.GetHandlersFor(nameDoesntMatchMember, container));
List<ICallHandler> nameMatchHandlers =
new List<ICallHandler>(policies.GetHandlersFor(nameMatchMember, container));
Assert.AreEqual(1, nameDoesntMatchHandlers.Count);
Assert.IsTrue(typeof(Handler1) == nameDoesntMatchHandlers[0].GetType());
Assert.AreEqual(2, nameMatchHandlers.Count);
Assert.IsTrue(typeof(Handler1) == nameMatchHandlers[0].GetType());
Assert.IsTrue(typeof(Handler2) == nameMatchHandlers[1].GetType());
}
[TestMethod]
public void ShouldMatchPolicyByMethodName()
{
PolicySet policies = GetMultiplePolicySet();
MethodImplementationInfo noMatchMember = GetMethodImplInfo<MatchesByMemberName>("NoMatch");
MethodImplementationInfo nameMatchMember = GetMethodImplInfo<MatchesByMemberName>("NameMatch");
List<ICallHandler> noMatchHandlers =
new List<ICallHandler>(policies.GetHandlersFor(noMatchMember, container));
List<ICallHandler> nameMatchHandlers =
new List<ICallHandler>(policies.GetHandlersFor(nameMatchMember, container));
Assert.AreEqual(0, noMatchHandlers.Count);
Assert.AreEqual(1, nameMatchHandlers.Count);
Assert.IsTrue(typeof(Handler2) == nameMatchHandlers[0].GetType());
}
[TestMethod]
public void ShouldNotMatchPolicyWhenNoRulesMatch()
{
PolicySet policies = GetMultiplePolicySet();
MethodImplementationInfo noMatchMember = GetMethodImplInfo<NoMatchAnywhere>("NoMatchHere");
List<ICallHandler> noMatchHandlers =
new List<ICallHandler>(policies.GetHandlersFor(noMatchMember, container));
Assert.AreEqual(0, noMatchHandlers.Count);
}
[TestMethod]
public void ShouldGetCorrectHandlersGivenAttributesOnInterfaceMethodsAfterAddingAttributeDrivenPolicy()
{
PolicySet policies = new PolicySet();
List<ICallHandler> oneHandlers
= new List<ICallHandler>(policies.GetHandlersFor(GetMethodImplInfo<TwoType>("One"), container));
Assert.AreEqual(0, oneHandlers.Count);
policies.Add(new AttributeDrivenPolicy());
MethodImplementationInfo oneInfo = new MethodImplementationInfo(
typeof(IOne).GetMethod("One"),
typeof(TwoType).GetMethod("One"));
oneHandlers
= new List<ICallHandler>(policies.GetHandlersFor(oneInfo, container));
Assert.AreEqual(2, oneHandlers.Count);
Assert.IsTrue(oneHandlers[0] is MarkerCallHandler);
Assert.IsTrue(oneHandlers[1] is MarkerCallHandler);
Assert.AreEqual("IOneOne", ((MarkerCallHandler)oneHandlers[0]).HandlerName);
Assert.AreEqual("MethodOneOverride", ((MarkerCallHandler)oneHandlers[1]).HandlerName);
}
[TestMethod]
public void ShouldNotDuplicateHandlersWhenCreatingViaInterface()
{
container
.RegisterInstance<ICallHandler>("Handler1", new CallCountHandler())
.RegisterInstance<ICallHandler>("Handler2", new CallCountHandler());
RuleDrivenPolicy policy
= new RuleDrivenPolicy("MatchesInterfacePolicy",
new IMatchingRule[] { new TypeMatchingRule("ITwo") },
new string[] { "Handler1", "Handler2" });
PolicySet policies = new PolicySet(policy);
MethodImplementationInfo twoInfo = new MethodImplementationInfo(
typeof(ITwo).GetMethod("Two"), typeof(TwoType).GetMethod("Two"));
List<ICallHandler> handlers
= new List<ICallHandler>(policies.GetHandlersFor(twoInfo, container));
Assert.AreEqual(2, handlers.Count);
}
[TestMethod]
public void HandlersOrderedProperly()
{
RuleDrivenPolicy policy
= new RuleDrivenPolicy("MatchesInterfacePolicy",
new IMatchingRule[] { new TypeMatchingRule("ITwo") },
new string[] { "Handler1", "Handler2", "Handler3", "Handler4" });
ICallHandler handler1 = new CallCountHandler();
handler1.Order = 3;
ICallHandler handler2 = new CallCountHandler();
handler2.Order = 0;
ICallHandler handler3 = new CallCountHandler();
handler3.Order = 2;
ICallHandler handler4 = new CallCountHandler();
handler4.Order = 1;
container
.RegisterInstance<ICallHandler>("Handler1", handler1)
.RegisterInstance<ICallHandler>("Handler2", handler2)
.RegisterInstance<ICallHandler>("Handler3", handler3)
.RegisterInstance<ICallHandler>("Handler4", handler4);
PolicySet policies = new PolicySet(policy);
MethodImplementationInfo twoInfo = new MethodImplementationInfo(
typeof(ITwo).GetMethod("Two"), typeof(TwoType).GetMethod("Two"));
List<ICallHandler> handlers
= new List<ICallHandler>(policies.GetHandlersFor(twoInfo, container));
Assert.AreSame(handler4, handlers[0]);
Assert.AreSame(handler3, handlers[1]);
Assert.AreSame(handler1, handlers[2]);
Assert.AreSame(handler2, handlers[3]);
}
[TestMethod]
public void HandlersOrderedProperlyUsingRelativeAndAbsoluteOrder()
{
RuleDrivenPolicy policy
= new RuleDrivenPolicy("MatchesInterfacePolicy",
new IMatchingRule[] { new TypeMatchingRule("ITwo") },
new string[] { "Handler1", "Handler2", "Handler3", "Handler4", "Handler5", "Handler6" });
ICallHandler handler1 = new CallCountHandler();
handler1.Order = 0;
ICallHandler handler2 = new CallCountHandler();
handler2.Order = 3;
ICallHandler handler3 = new CallCountHandler();
handler3.Order = 3;
ICallHandler handler4 = new CallCountHandler();
handler4.Order = 2;
ICallHandler handler5 = new CallCountHandler();
handler5.Order = 4;
ICallHandler handler6 = new CallCountHandler();
handler6.Order = 1;
container
.RegisterInstance<ICallHandler>("Handler1", handler1)
.RegisterInstance<ICallHandler>("Handler2", handler2)
.RegisterInstance<ICallHandler>("Handler3", handler3)
.RegisterInstance<ICallHandler>("Handler4", handler4)
.RegisterInstance<ICallHandler>("Handler5", handler5)
.RegisterInstance<ICallHandler>("Handler6", handler6);
PolicySet policies = new PolicySet(policy);
MethodImplementationInfo twoInfo = new MethodImplementationInfo(
typeof(ITwo).GetMethod("Two"), typeof(TwoType).GetMethod("Two"));
List<ICallHandler> handlers
= new List<ICallHandler>(policies.GetHandlersFor(twoInfo, container));
Assert.AreEqual(handler6, handlers[0]);
Assert.AreEqual(handler4, handlers[1]);
Assert.AreEqual(handler2, handlers[2]);
Assert.AreEqual(handler3, handlers[3]);
Assert.AreEqual(handler5, handlers[4]);
Assert.AreEqual(handler1, handlers[5]);
}
private PolicySet GetMultiplePolicySet()
{
container
.RegisterInstance<ICallHandler>("Handler1", new Handler1())
.RegisterInstance<ICallHandler>("Handler2", new Handler2());
RuleDrivenPolicy typeMatchPolicy
= new RuleDrivenPolicy("MatchesType",
new IMatchingRule[] { new TypeMatchingRule(typeof(MatchesByType)) },
new string[] { "Handler1" });
RuleDrivenPolicy nameMatchPolicy
= new RuleDrivenPolicy("MatchesName",
new IMatchingRule[] { new MemberNameMatchingRule("NameMatch") },
new string[] { "Handler2" });
return new PolicySet(typeMatchPolicy, nameMatchPolicy);
}
private MethodInfo GetNameDoesntMatchMethod()
{
return typeof(MatchesByType).GetMethod("NameDoesntMatch");
}
private MethodImplementationInfo GetMethodImplInfo<T>(string methodName)
{
return new MethodImplementationInfo(null,
typeof(T).GetMethod(methodName));
}
}
internal class MatchesByType
{
// Matches type policy
public void NameDoesntMatch() { }
// matches type & name policies
public void NameMatch() { }
}
internal class MatchesByMemberName
{
public void NameMatch() { }
public void NoMatch() { }
}
internal class NoMatchAnywhere
{
public void NoMatchHere() { }
}
public interface IOne
{
[MarkerCallHandler("IOneOne")]
void One();
}
public interface ITwo
{
void Two();
}
public class OneType : IOne
{
public void MethodOne() { }
public virtual void MethodTwo() { }
public virtual void One() { }
}
public class TwoType : OneType, ITwo
{
public void BarOne() { }
public override void MethodTwo() { }
[MarkerCallHandler("MethodOneOverride")]
public override void One() { }
public void Two() { }
}
public class MarkerCallHandler : ICallHandler
{
private string handlerName;
private int order = 0;
public MarkerCallHandler(string handlerName)
{
this.handlerName = handlerName;
}
public string HandlerName
{
get { return handlerName; }
set { handlerName = value; }
}
/// <summary>
/// Gets or sets the order in which the handler will be executed
/// </summary>
public int Order
{
get { return order; }
set { order = value; }
}
public IMethodReturn Invoke(IMethodInvocation input,
GetNextHandlerDelegate getNext)
{
return getNext()(input, getNext);
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Method)]
public class MarkerCallHandlerAttribute : HandlerAttribute
{
private string handlerName;
public MarkerCallHandlerAttribute(string handlerName)
{
this.handlerName = handlerName;
}
public override ICallHandler CreateHandler(IUnityContainer ignored)
{
return new MarkerCallHandler(this.handlerName);
}
}
}