#region License
// Copyright (c) 2004 Griffin Caprio & Choy Rim. All rights reserved.
#endregion
#region Imports
using System;
using System.Reflection;
using DotNetMock.Dynamic;
using NUnit.Framework;

using DotNetMock.Dynamic.Predicates;
#endregion

namespace DotNetMock.Tests.Dynamic
{
	[TestFixture]
	public class DynamicMockTests : AbstractDynamicMockTests
	{
		protected override IDynamicMock newDynamicMock(Type type, string name)
		{
			return new DynamicMock(type, name);
		}
		protected override IDynamicMock newDynamicMock(Type type)
		{
			return new DynamicMock(type);
		}
		protected override IDynamicMock newDynamicMock(string name)
		{
			return new DynamicMock(name);
		}

		[Test]
		public void CallMultipleMethodsInWrongOrder() 
		{
			mock.Expect("myMethod1");
			mock.Expect("myMethod2");
			mock.Expect("myMethod3");
			mock.Call(myMethod1);
			mock.Call(myMethod3);
			mock.Call(myMethod2);
			mock.Verify();
		}

		[Test]
		[ExpectedException(typeof(AssertionException), "1 more call(s) were expected for myMethod")]
		public void NoCallToVoidMethodWithReason()
		{
			mock.Expect("myMethod");
			mock.Verify();
		}

		[Test]
		[ExpectedException(typeof(VerifyException))]
		public void ThrowsIfUnexpectedMethodCalled()
		{
			IDynamicMock mock = newDynamicMock(typeof(IBlah));
			IBlah blah = (IBlah) mock.Object;
			mock.Strict = true;
			mock.ExpectAndReturn("DoStuff", "world", "hello");

			Assert.AreEqual("world", blah.DoStuff("hello"));
			blah.DoStuffWithParams("ID", "P1", "P2");
			mock.Verify();
		}

		[Test]		
		public void CustomDynamicMock()
		{
			IDynamicMock mock = new CustomMock(typeof(IBlah));
			IBlah blah = (IBlah)mock.Object;
			Assert.AreEqual("CUSTOM", blah.DoStuff("hello"));
			mock.Verify();
		}
		private class CustomMock : DynamicMock
		{
			public CustomMock(Type t) : base(t) {}
			
			public override object Call(MethodInfo mi, params object[] args)
			{
				return "CUSTOM";
			}
		}
	}
}
