|
From: Steve F. <sm...@us...> - 2005-05-26 20:51:57
|
Update of /cvsroot/nmock/nmock2/src/NMock2/Internal In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24181/src/NMock2/Internal Added Files: UnorderedExpectations.cs IMockObject.cs BuildableExpectation.cs IExpectationOrdering.cs OrderedExpectations.cs ExpectationException.cs DescriptionWriter.cs ExpectationBuilder.cs Log Message: first upload of nmock2 --- NEW FILE: IMockObject.cs --- namespace NMock2.Internal { public interface IMockObject { bool HasMethodMatching(Matcher methodMatcher); void AddExpectation(IExpectation expectation); } } --- NEW FILE: IExpectationOrdering.cs --- namespace NMock2.Internal { public interface IExpectationOrdering : IExpectation { void AddExpectation(IExpectation expectation); } } --- NEW FILE: OrderedExpectations.cs --- using System; using System.Collections; using System.IO; using NMock2.Monitoring; namespace NMock2.Internal { public class OrderedExpectations : IExpectationOrdering { private ArrayList expectations = new ArrayList(); private int current = 0; private int depth; public OrderedExpectations(int depth) { this.depth = depth; } public bool IsActive { get { return CurrentExpectation.IsActive; } } public bool HasBeenMet { get { return CurrentExpectation.HasBeenMet; } } public bool Matches(Invocation invocation) { return CurrentExpectation.Matches(invocation) || (CurrentExpectation.HasBeenMet && NextExpectationMatches(invocation)); } private bool NextExpectationMatches(Invocation invocation) { return HasNextExpectation && NextExpectation.Matches(invocation); } public void AddExpectation(IExpectation expectation) { expectations.Add(expectation); } public void Perform(Invocation invocation) { // If the current expectation doesn't match, it must have been met, by the contract // for the IExpectation interface and due to the implementation of this.Matches if (!CurrentExpectation.Matches(invocation)) current++; CurrentExpectation.Perform(invocation); } public void DescribeActiveExpectationsTo(TextWriter writer) { writer.WriteLine("Ordered:"); for (int i = 0; i < expectations.Count; i++) { IExpectation expectation = (IExpectation)expectations[i]; if (expectation.IsActive) { Indent(writer, depth+1); expectation.DescribeActiveExpectationsTo(writer); writer.WriteLine(); } } } public void DescribeUnmetExpectationsTo(TextWriter writer) { writer.WriteLine("Ordered:"); for (int i = 0; i < expectations.Count; i++) { IExpectation expectation = (IExpectation)expectations[i]; if (!expectation.HasBeenMet) { Indent(writer, depth+1); expectation.DescribeUnmetExpectationsTo(writer); writer.WriteLine(); } } } private IExpectation CurrentExpectation { get { return (IExpectation)expectations[current]; } } private bool HasNextExpectation { get { return current < expectations.Count-1; } } private IExpectation NextExpectation { get { return (IExpectation)expectations[current+1]; } } private void Indent(TextWriter writer, int n) { for (int i = 0; i < n; i++) writer.Write(" "); } } } --- NEW FILE: DescriptionWriter.cs --- using System.IO; namespace NMock2.Internal { public class DescriptionWriter : StringWriter { public DescriptionWriter() { } public override void Write(object value) { Write(FormatValue(value)); } private string FormatValue(object value) { if (value == null) { return "null"; } else if (value is string) { return FormatString( (string)value ); } else { return "<" + value.ToString() + ">"; } } private string FormatString(string s) { const string quote = "\""; const string escapedQuote = "\\\""; return quote + s.Replace(quote,escapedQuote) + quote; } } } --- NEW FILE: ExpectationBuilder.cs --- using System; using System.Reflection; using NMock2.Matchers; using NMock2.Syntax; namespace NMock2.Internal { public class ExpectationBuilder : IReceiverSyntax, IMethodSyntax, IArgumentSyntax, IMatchSyntax, IActionSyntax { BuildableExpectation expectation; IMockObject mockObject = null; public ExpectationBuilder(string description, Matcher requiredCountMatcher, Matcher acceptedCountMatcher) { expectation = new BuildableExpectation(description, requiredCountMatcher, acceptedCountMatcher); } public IMethodSyntax On(object receiver) { if (receiver is IMockObject) { mockObject = (IMockObject) receiver; expectation.ReceiverMatcher = new DescriptionOverride(receiver.ToString(), Is.Same(receiver)); mockObject.AddExpectation(expectation); } else { throw new ArgumentException("not a mock object", "receiver"); } return this; } public IArgumentSyntax Method(string methodName) { return Method(new MethodNameMatcher(methodName)); } public IArgumentSyntax Method(MethodInfo method) { return Method(new DescriptionOverride(method.Name, Is.Same(method))); } public IArgumentSyntax Method(Matcher methodMatcher) { if (!mockObject.HasMethodMatching(methodMatcher)) { throw new ArgumentException("mock object " + mockObject + " does not have a method matching " + methodMatcher); } expectation.MethodMatcher = methodMatcher; return this; } public IMatchSyntax GetProperty(string propertyName) { Matcher methodMatcher = NewMethodNameMatcher(propertyName, "get_"+propertyName); if (!mockObject.HasMethodMatching(methodMatcher)) { throw new ArgumentException("mock object " + mockObject + " does not have a getter for property " + propertyName); } expectation.MethodMatcher = methodMatcher; expectation.ArgumentsMatcher = new DescriptionOverride("", new ArgumentsMatcher()); return this; } public IValueSyntax SetProperty(string propertyName) { Matcher methodMatcher = NewMethodNameMatcher(propertyName+" = ", "set_"+propertyName); if (!mockObject.HasMethodMatching(methodMatcher)) { throw new ArgumentException("mock object " + mockObject + " does not have a setter for property " + propertyName); } expectation.MethodMatcher = methodMatcher; return new PropertyValueBuilder(this); } private class PropertyValueBuilder : IValueSyntax { private readonly ExpectationBuilder builder; public PropertyValueBuilder(ExpectationBuilder builder) { this.builder = builder; } public IMatchSyntax To(Matcher valueMatcher) { return builder.With(valueMatcher); } public IMatchSyntax To(object equalValue) { return To(Is.EqualTo(equalValue)); } } public IGetIndexerSyntax Get { get { Matcher methodMatcher = NewMethodNameMatcher("", "get_Item"); if (!mockObject.HasMethodMatching(methodMatcher)) { throw new ArgumentException("mock object " + mockObject + " does not have an indexed setter"); } expectation.DescribeAsIndexer(); expectation.MethodMatcher = methodMatcher; return new IndexGetterBuilder(expectation, this); } } private class IndexGetterBuilder : IGetIndexerSyntax { private readonly BuildableExpectation expectation; private readonly ExpectationBuilder builder; public IndexGetterBuilder(BuildableExpectation expectation, ExpectationBuilder builder) { this.expectation = expectation; this.builder = builder; } public IMatchSyntax this[params Matcher[] matchers] { get { expectation.ArgumentsMatcher = new IndexGetterArgumentsMatcher(matchers); return builder; } } public IMatchSyntax this[params object[] equalValues] { get { return this[IsEqualMatchersFor(equalValues)]; } } } public ISetIndexerSyntax Set { get { Matcher methodMatcher = NewMethodNameMatcher("", "set_Item"); if (!mockObject.HasMethodMatching(methodMatcher)) { throw new ArgumentException("mock object " + mockObject + " does not have an indexed setter"); } expectation.DescribeAsIndexer(); expectation.MethodMatcher = methodMatcher; return new IndexSetterBuilder(expectation, this); } } private class IndexSetterBuilder : ISetIndexerSyntax, IValueSyntax { private readonly BuildableExpectation expectation; private readonly ExpectationBuilder builder; private Matcher[] matchers; public IndexSetterBuilder(BuildableExpectation expectation, ExpectationBuilder builder) { this.expectation = expectation; this.builder = builder; } public IValueSyntax this[params Matcher[] indexMatchers] { get { matchers = new Matcher[indexMatchers.Length + 1]; Array.Copy(indexMatchers, matchers, indexMatchers.Length); SetValueMatcher(Is.Anything); return this; } } public IValueSyntax this[params object[] equalValues] { get { return this[IsEqualMatchersFor(equalValues)]; } } public IMatchSyntax To(Matcher matcher) { SetValueMatcher(matcher); return builder; } public IMatchSyntax To(object equalValue) { return To(Is.EqualTo(equalValue)); } private void SetValueMatcher(Matcher matcher) { matchers[matchers.Length - 1] = matcher; expectation.ArgumentsMatcher = new IndexSetterArgumentsMatcher(matchers); } } public IMatchSyntax EventAdd(string eventName, Matcher listenerMatcher) { Matcher methodMatcher = NewMethodNameMatcher(eventName + " += ", "add_"+eventName); if (!mockObject.HasMethodMatching(methodMatcher)) { throw new ArgumentException("mock object " + mockObject + " does not have an event named " + eventName); } expectation.MethodMatcher = methodMatcher; expectation.ArgumentsMatcher = new ArgumentsMatcher(listenerMatcher); return this; } public IMatchSyntax EventAdd(string eventName, Delegate equalListener) { return EventAdd(eventName, Is.EqualTo(equalListener)); } public IMatchSyntax EventRemove(string eventName, Matcher listenerMatcher) { Matcher methodMatcher = NewMethodNameMatcher(eventName + " -= ", "remove_"+eventName); if (!mockObject.HasMethodMatching(methodMatcher)) { throw new ArgumentException("mock object " + mockObject + " does not have an event named " + eventName); } expectation.MethodMatcher = methodMatcher; expectation.ArgumentsMatcher = new ArgumentsMatcher(listenerMatcher); return this; } public IMatchSyntax EventRemove(string eventName, Delegate equalListener) { return EventRemove(eventName, Is.EqualTo(equalListener)); } public IMatchSyntax With(params Matcher[] argumentMatchers) { expectation.ArgumentsMatcher = new ArgumentsMatcher(argumentMatchers); return this; } public IMatchSyntax With(params object[] equalArgumentValues) { return With(IsEqualMatchersFor(equalArgumentValues)); } private static Matcher[] IsEqualMatchersFor(object[] equalArgumentValues) { Matcher[] matchers = new Matcher[equalArgumentValues.Length]; for (int i = 0; i < matchers.Length; i++) { matchers[i] = new EqualMatcher(equalArgumentValues[i]); } return matchers; } public IMatchSyntax WithNoArguments() { return With(new Matcher[0]); } public IMatchSyntax WithAnyArguments() { expectation.ArgumentsMatcher = new AlwaysMatcher(true, "(any arguments)"); return this; } public IActionSyntax Matching(Matcher matcher) { expectation.AddInvocationMatcher(matcher); return this; } public void Will(params IAction[] actions) { foreach (IAction action in actions) { expectation.AddAction(action); } } private static Matcher NewMethodNameMatcher(string description, string methodName) { return new DescriptionOverride(description, new MethodNameMatcher(methodName)); } } } --- NEW FILE: BuildableExpectation.cs --- using System.Collections; using System.IO; using NMock2.Matchers; using NMock2.Monitoring; namespace NMock2.Internal { public class BuildableExpectation : IExpectation { private int callCount = 0; private string expectationDescription; private Matcher requiredCountMatcher, matchingCountMatcher; private Matcher receiverMatcher = new AlwaysMatcher(true, "<any object>"); private string methodSeparator = "."; private Matcher methodMatcher = new AlwaysMatcher(true, "<any method>"); private Matcher argumentsMatcher = new AlwaysMatcher(true, "(any arguments)"); private ArrayList extraMatchers = new ArrayList(); private ArrayList actions = new ArrayList(); public BuildableExpectation(string expectationDescription, Matcher requiredCountMatcher, Matcher matchingCountMatcher) { this.expectationDescription = expectationDescription; this.requiredCountMatcher = requiredCountMatcher; this.matchingCountMatcher = matchingCountMatcher; } public Matcher ReceiverMatcher { get { return receiverMatcher; } set { receiverMatcher = value; } } public Matcher MethodMatcher { get { return methodMatcher; } set { methodMatcher = value; } } public Matcher ArgumentsMatcher { get { return argumentsMatcher; } set { argumentsMatcher = value; } } public void AddInvocationMatcher(Matcher matcher ) { extraMatchers.Add(matcher); } public void AddAction(IAction action) { actions.Add(action); } public bool Matches(Invocation invocation) { return IsActive && receiverMatcher.Matches(invocation.Receiver) && methodMatcher.Matches(invocation.Method) && argumentsMatcher.Matches(invocation) && ExtraMatchersMatch(invocation); } private bool ExtraMatchersMatch(Invocation invocation) { foreach (Matcher matcher in extraMatchers) { if (!matcher.Matches(invocation)) return false; } return true; } public void Perform(Invocation invocation) { callCount++; foreach (IAction action in actions) { action.Invoke(invocation); } } public bool IsActive { get { return matchingCountMatcher.Matches(callCount+1); } } public bool HasBeenMet { get { return requiredCountMatcher.Matches(callCount); } } public void DescribeActiveExpectationsTo(TextWriter writer) { if (IsActive) DescribeTo(writer); } public void DescribeUnmetExpectationsTo(TextWriter writer) { if (!HasBeenMet) DescribeTo(writer); } private void DescribeTo(TextWriter writer) { writer.Write(expectationDescription); writer.Write(": "); receiverMatcher.DescribeTo(writer); writer.Write(methodSeparator); methodMatcher.DescribeTo(writer); argumentsMatcher.DescribeTo(writer); foreach (Matcher extraMatcher in extraMatchers) { writer.Write(", "); extraMatcher.DescribeTo(writer); } if (actions.Count > 0) { writer.Write(", will "); ((IAction)actions[0]).DescribeTo(writer); for (int i = 1; i < actions.Count; i++) { writer.Write(", "); ((IAction)actions[i]).DescribeTo(writer); } } writer.Write(" [called "); writer.Write(callCount); writer.Write(" time"); if (callCount != 1) writer.Write("s"); writer.Write("]"); } public void DescribeAsIndexer() { methodSeparator = ""; } } } --- NEW FILE: UnorderedExpectations.cs --- using System; using System.Collections; using System.IO; using NMock2.Monitoring; namespace NMock2.Internal { public class UnorderedExpectations : IExpectationOrdering { private ArrayList expectations = new ArrayList(); private int depth; private string prompt; public UnorderedExpectations() { this.depth = 0; this.prompt = "Expected:"; } public UnorderedExpectations(int depth) { this.depth = depth; this.prompt = "Unordered:"; } public bool IsActive { get { foreach (IExpectation e in expectations) { if (e.IsActive) return true; } return false; } } public bool HasBeenMet { get { foreach (IExpectation e in expectations) { if (!e.HasBeenMet) return false; } return true; } } public bool Matches(Invocation invocation) { foreach (IExpectation e in expectations) { if (e.Matches(invocation)) return true; } return false; } public void Perform(Invocation invocation) { foreach (IExpectation e in expectations) { if (e.Matches(invocation)) { e.Perform(invocation); return; } } throw new InvalidOperationException("No matching expectation"); } public void DescribeActiveExpectationsTo(TextWriter writer) { writer.WriteLine(prompt); foreach (IExpectation expectation in expectations) { if (expectation.IsActive) { Indent(writer, depth+1); expectation.DescribeActiveExpectationsTo(writer); writer.WriteLine(); } } } public void DescribeUnmetExpectationsTo(TextWriter writer) { writer.WriteLine(prompt); foreach (IExpectation expectation in expectations) { if (!expectation.HasBeenMet) { Indent(writer, depth+1); expectation.DescribeUnmetExpectationsTo(writer); writer.WriteLine(); } } } private void Indent(TextWriter writer, int n) { for (int i = 0; i < n; i++) writer.Write(" "); } public void AddExpectation(IExpectation expectation) { expectations.Add(expectation); } } } --- NEW FILE: ExpectationException.cs --- using System; using System.Runtime.Serialization; namespace NMock2.Internal { public class ExpectationException : Exception { public ExpectationException() { } public ExpectationException(string message) : base(message) { } public ExpectationException(string message, Exception innerException) : base(message, innerException) { } public ExpectationException(SerializationInfo info, StreamingContext context) : base(info, context) { } } } |