Update of /cvsroot/nmock/nmock/src/NMock In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25016/src/NMock Modified Files: DynamicMock.cs Method.cs MethodSignature.cs Mock.cs MockCall.cs SingleMethod.cs Added Files: ProxyMock.cs TypeCheckedMock.cs Log Message: Added ProxyMock: can mock interface and MarshalByRefObjects, can mock sealed classes/non-empty contructor and nonvirtual members; related refactoring; some MethodSignature methods moved to a new class Index: Method.cs =================================================================== RCS file: /cvsroot/nmock/nmock/src/NMock/Method.cs,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Method.cs 24 Aug 2004 16:00:24 -0000 1.6 --- Method.cs 24 Aug 2004 21:15:28 -0000 1.7 *************** *** 20,24 **** public virtual string Name { ! get { return signature.methodName; } } --- 20,24 ---- public virtual string Name { ! get { return signature.MethodName; } } *************** *** 37,41 **** MockCall mockCall = expectations[timesCalled]; timesCalled++; ! return mockCall.Call(signature.methodName, parameters); } --- 37,41 ---- MockCall mockCall = expectations[timesCalled]; timesCalled++; ! return mockCall.Call(signature.MethodName, parameters); } Index: MethodSignature.cs =================================================================== RCS file: /cvsroot/nmock/nmock/src/NMock/MethodSignature.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** MethodSignature.cs 24 Aug 2004 16:00:24 -0000 1.5 --- MethodSignature.cs 24 Aug 2004 21:15:28 -0000 1.6 *************** *** 10,22 **** public class MethodSignature { ! public readonly string typeName; ! public readonly string methodName; ! public readonly Type[] argumentTypes; public MethodSignature(string typeName, string methodName, params Type[] argumentTypes) { ! this.typeName = typeName; ! this.methodName = methodName; ! this.argumentTypes = argumentTypes; } --- 10,22 ---- public class MethodSignature { ! public readonly string TypeName; ! public readonly string MethodName; ! public readonly Type[] ArgumentTypes; public MethodSignature(string typeName, string methodName, params Type[] argumentTypes) { ! TypeName = typeName; ! MethodName = methodName; ! ArgumentTypes = argumentTypes; } *************** *** 24,28 **** { StringBuilder argumentList = new StringBuilder(); ! foreach (Type type in argumentTypes) { if (argumentList.Length > 0) argumentList.Append(", "); --- 24,28 ---- { StringBuilder argumentList = new StringBuilder(); ! foreach (Type type in ArgumentTypes) { if (argumentList.Length > 0) argumentList.Append(", "); *************** *** 37,41 **** } } ! return string.Format("{0}.{1}({2})", typeName, methodName, argumentList); } --- 37,41 ---- } } ! return string.Format("{0}.{1}({2})", TypeName, MethodName, argumentList); } *************** *** 44,48 **** get { ! foreach(Type argType in argumentTypes) { if(typeof(IConstraint).IsAssignableFrom(argType)) --- 44,48 ---- get { ! foreach(Type argType in ArgumentTypes) { if(typeof(IConstraint).IsAssignableFrom(argType)) *************** *** 52,123 **** } } - - public PropertyInfo FindMatchingPropertyOn(Type type) - { - return type.GetProperty( - methodName, ClassGenerator.ALL_INSTANCE_METHODS); - } - - public MethodInfo FindMatchingMethodIn(Type type) - { - foreach (MethodInfo methodInfo in type.GetMethods(ClassGenerator.ALL_INSTANCE_METHODS)) - { - if (MatchesNameAndAllNonNullArguments(methodInfo)) - { - return methodInfo; - } - } - return null; - } - - public bool IsPropertyOn(Type type) - { - return type.GetProperty(methodName, ClassGenerator.ALL_INSTANCE_METHODS) != null; - } - - public bool HasMatchingMethodIn(Type type) - { - foreach (MethodInfo methodInfo in type.GetMethods(ClassGenerator.ALL_INSTANCE_METHODS)) - { - if (MatchesNameAndAllNonNullArguments(methodInfo)) - { - return true; - } - } - return false; - } - - private bool MatchesNameAndAllNonNullArguments(MethodInfo methodInfo) - { - if (!methodName.Equals(methodInfo.Name)) - return false; - - if (! MatchNonNullArguments(methodInfo.GetParameters())) - return false; - - if(!methodInfo.IsVirtual) - throw new ArgumentException(String.Format("method <{0}> is not virtual", methodName)); - - return true; - } - - - private bool MatchNonNullArguments(ParameterInfo[] parameters) - { - if ( argumentTypes.Length != parameters.Length ) - return false; - - for ( int pi=0; pi<parameters.Length; pi++ ) - { - Type argumentType = argumentTypes[pi]; - if (argumentType == null) - continue; - - Type parameterType = parameters[pi].ParameterType; - if (!parameterType.IsAssignableFrom(argumentType)) - return false; - } - return true; - } } } --- 52,55 ---- Index: DynamicMock.cs =================================================================== RCS file: /cvsroot/nmock/nmock/src/NMock/DynamicMock.cs,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** DynamicMock.cs 18 Aug 2004 14:59:24 -0000 1.22 --- DynamicMock.cs 24 Aug 2004 21:15:28 -0000 1.23 *************** *** 2,14 **** using System.Collections; using System.Reflection; using NMock.Dynamic; - using NMock.Constraints; namespace NMock { ! public class DynamicMock : Mock { private object mockInstance; - private Type type; private IList ignoredMethodNames; private readonly Type superclassIfTypeIsInterface; --- 2,13 ---- using System.Collections; using System.Reflection; + using NMock.Dynamic; namespace NMock { ! public class DynamicMock : TypeCheckedMock { private object mockInstance; private IList ignoredMethodNames; private readonly Type superclassIfTypeIsInterface; *************** *** 18,25 **** public DynamicMock(Type type, string name) : this (type, name, null) {} ! public DynamicMock(Type type, string name, Type superclassIfTypeIsInterface) : base(name) { this.ignoredMethodNames = new ArrayList(); - this.type = type; this.superclassIfTypeIsInterface = superclassIfTypeIsInterface; } --- 17,23 ---- public DynamicMock(Type type, string name) : this (type, name, null) {} ! public DynamicMock(Type type, string name, Type superclassIfTypeIsInterface) : base(type, name) { this.ignoredMethodNames = new ArrayList(); this.superclassIfTypeIsInterface = superclassIfTypeIsInterface; } *************** *** 45,107 **** } ! private ClassGenerator CreateClassGenerator() ! { ! return new ClassGenerator(type, this, ignoredMethodNames, superclassIfTypeIsInterface); ! } ! ! protected override IMethod getMethod(MethodSignature signature) ! { ! CheckMethodIsValidIfNoConstraints(signature); ! return base.getMethod(signature); ! } ! ! public override void SetupResult(string methodName, object returnVal, params Type[] argTypes) ! { ! MethodSignature signature = new MethodSignature(Name, methodName, argTypes); ! CheckReturnTypeIsValid(signature, returnVal); ! SetupResult(signature, returnVal); ! } ! ! private void CheckReturnTypeIsValid(MethodSignature signature, object returnVal) { ! if (returnVal == null) ! return; ! ! if (signature.HasAConstraintArgument) ! return; ! ! Type realReturnType = GetReturnTypeForSignature(signature); ! if (!realReturnType.IsAssignableFrom(returnVal.GetType())) ! { throw new ArgumentException( ! string.Format("method <{0}> should return a {1}", ! signature, realReturnType)); ! } } ! private void CheckMethodIsValidIfNoConstraints(MethodSignature signature) { ! if (signature.HasAConstraintArgument) ! return; ! ! GetReturnTypeForSignature(signature); } - - private Type GetReturnTypeForSignature(MethodSignature signature) - { - foreach (Type t in new InterfaceLister().List(type)) - { - MethodInfo method = signature.FindMatchingMethodIn(t); - if (method != null) - return method.ReturnType; - - PropertyInfo property = signature.FindMatchingPropertyOn(t); - if (property != null) - return property.PropertyType; - } - - throw new MissingMethodException( - string.Format("method <{0}> not defined", signature)); - } } } --- 43,57 ---- } ! protected override void ValidateMethodInfo(MethodInfo methodInfo) { ! if(!methodInfo.IsVirtual) throw new ArgumentException( ! string.Format("method <{0}> is not virtual", methodInfo.Name)); } ! private ClassGenerator CreateClassGenerator() { ! return new ClassGenerator(MockedType, this, ignoredMethodNames, superclassIfTypeIsInterface); } } } --- NEW FILE: ProxyMock.cs --- using System; using NMock.Proxy; namespace NMock { public class ProxyMock : TypeCheckedMock { private readonly MockRealProxy proxy; public ProxyMock(Type type) : this(type, "Mock" + type.Name) { } public ProxyMock(Type type, string name) : base(type, name) { proxy = new MockRealProxy(this, type); } public override object MockInstance { get { return proxy.GetTransparentProxy(); } } } } --- NEW FILE: TypeCheckedMock.cs --- using System; using System.Reflection; using NMock.Dynamic; namespace NMock { public abstract class TypeCheckedMock : Mock { private Type type; public TypeCheckedMock(Type type, string name) : base(name) { this.type = type; } public Type MockedType { get { return type; } } public override void SetupResult(string methodName, object returnVal, params Type[] argTypes) { MethodSignature signature = new MethodSignature(Name, methodName, argTypes); CheckReturnTypeIsValid(signature, returnVal); SetupResult(signature, returnVal); } protected override IMethod getMethod(MethodSignature signature) { CheckMethodIsValidIfNoConstraints(signature); return base.getMethod(signature); } protected void CheckReturnTypeIsValid(MethodSignature signature, object returnVal) { if (returnVal == null) return; if (signature.HasAConstraintArgument) return; Type realReturnType = GetReturnTypeForSignature(signature); if (!realReturnType.IsAssignableFrom(returnVal.GetType())) { throw new ArgumentException( string.Format("method <{0}> should return a {1}", signature, realReturnType)); } } protected void CheckMethodIsValidIfNoConstraints(MethodSignature signature) { if (signature.HasAConstraintArgument) return; GetReturnTypeForSignature(signature); } protected Type GetReturnTypeForSignature(MethodSignature signature) { foreach (Type t in new InterfaceLister().List(MockedType)) { MethodInfo method = FindMatchingMethodIn(signature, t); if (method != null) return method.ReturnType; PropertyInfo property = FindMatchingPropertyOn(signature, t); if (property != null) return property.PropertyType; } throw new MissingMethodException( string.Format("method <{0}> not defined", signature)); } internal static string StripGetSetPrefix(string methodName) { if (methodName.StartsWith("get_") || methodName.StartsWith("set_")) { methodName = methodName.Substring(4); } return methodName; } private PropertyInfo FindMatchingPropertyOn(MethodSignature signature, Type type) { return type.GetProperty( signature.MethodName, ClassGenerator.ALL_INSTANCE_METHODS); } private MethodInfo FindMatchingMethodIn(MethodSignature signature, Type type) { foreach (MethodInfo methodInfo in type.GetMethods(ClassGenerator.ALL_INSTANCE_METHODS)) { if (MatchesNameAndAllNonNullArguments(signature, methodInfo)) { return methodInfo; } } return null; } private bool IsPropertyOn(MethodSignature signature, Type type) { return type.GetProperty(signature.MethodName, ClassGenerator.ALL_INSTANCE_METHODS) != null; } private bool HasMatchingMethodIn(MethodSignature signature, Type type) { foreach (MethodInfo methodInfo in type.GetMethods(ClassGenerator.ALL_INSTANCE_METHODS)) { if (MatchesNameAndAllNonNullArguments(signature, methodInfo)) { return true; } } return false; } private bool MatchesNameAndAllNonNullArguments(MethodSignature signature, MethodInfo methodInfo) { if (!signature.MethodName.Equals(methodInfo.Name)) return false; if (! MatchNonNullArguments(signature, methodInfo.GetParameters())) return false; ValidateMethodInfo(methodInfo); return true; } private bool MatchNonNullArguments(MethodSignature signature, ParameterInfo[] parameters) { if ( signature.ArgumentTypes.Length != parameters.Length ) return false; for ( int pi=0; pi<parameters.Length; pi++ ) { Type argumentType = signature.ArgumentTypes[pi]; if (argumentType == null) continue; Type parameterType = parameters[pi].ParameterType; if (!parameterType.IsAssignableFrom(argumentType)) return false; } return true; } protected virtual void ValidateMethodInfo(MethodInfo methodInfo) { } } } Index: SingleMethod.cs =================================================================== RCS file: /cvsroot/nmock/nmock/src/NMock/SingleMethod.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** SingleMethod.cs 24 Aug 2004 16:00:24 -0000 1.3 --- SingleMethod.cs 24 Aug 2004 21:15:28 -0000 1.4 *************** *** 17,21 **** public string Name { ! get { return signature.methodName; } } --- 17,21 ---- public string Name { ! get { return signature.MethodName; } } *************** *** 27,31 **** public virtual object Call(params object[] parameters) { ! object obj = expectation.Call(signature.methodName, parameters); timesCalled++; return obj; --- 27,31 ---- public virtual object Call(params object[] parameters) { ! object obj = expectation.Call(signature.MethodName, parameters); timesCalled++; return obj; Index: MockCall.cs =================================================================== RCS file: /cvsroot/nmock/nmock/src/NMock/MockCall.cs,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** MockCall.cs 24 Aug 2004 16:00:24 -0000 1.8 --- MockCall.cs 24 Aug 2004 21:15:28 -0000 1.9 *************** *** 24,28 **** } ! public Type[] ArgTypes { get {return signature.argumentTypes; } } private IConstraint[] argsAsConstraints(object[] args) --- 24,28 ---- } ! public Type[] ArgTypes { get {return signature.ArgumentTypes; } } private IConstraint[] argsAsConstraints(object[] args) Index: Mock.cs =================================================================== RCS file: /cvsroot/nmock/nmock/src/NMock/Mock.cs,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** Mock.cs 24 Aug 2004 16:00:24 -0000 1.15 --- Mock.cs 24 Aug 2004 21:15:28 -0000 1.16 *************** *** 81,86 **** if (method == null) { ! method = new CallMethodWithoutExpectation(signature.methodName); ! methods[signature.methodName] = method; } method.SetExpectation(new MockCall(signature, returnVal, null, null)); --- 81,86 ---- if (method == null) { ! method = new CallMethodWithoutExpectation(signature.MethodName); ! methods[signature.MethodName] = method; } method.SetExpectation(new MockCall(signature, returnVal, null, null)); *************** *** 112,116 **** protected virtual IMethod getMethod(MethodSignature signature) { ! return (IMethod)methods[signature.methodName]; } --- 112,116 ---- protected virtual IMethod getMethod(MethodSignature signature) { ! return (IMethod)methods[signature.MethodName]; } |