using System;
using System.Reflection;
using DotNetMock.Dynamic;
using NUnit.Framework;
namespace DotNetMock.Tests.Dynamic
{
	[TestFixture]
	public class MethodSignatureTest
	{
		#region Test Cases
		/// <summary>
		/// Test Equals method.
		/// </summary>
		[Test]
		public void TestEquals( )
		{
			MethodSignature sign1 = new MethodSignature( "Method1", typeof ( Exception ), typeof ( bool ), typeof ( object ), typeof ( Exception ) );
			MethodSignature sign2 = new MethodSignature( "Method1", typeof ( Exception ), typeof ( bool ), typeof ( object ), typeof ( Exception ) );
			MethodSignature sign3 = new MethodSignature( "Method2", typeof ( Exception ), typeof ( bool ), typeof ( object ), typeof ( Exception ) );
			MethodSignature sign4 = new MethodSignature( "Method1", typeof ( void ), typeof ( bool ), typeof ( object ), typeof ( Exception ) );
			MethodSignature sign5 = new MethodSignature( "Method1", typeof ( Exception ), typeof ( object ), typeof ( Exception ) );
			Assert.IsTrue( sign1.Equals( sign2 ), "sign1.Equals(sign2) shall be true." );
			Assert.IsFalse( sign1.Equals( sign3 ), "sign1.Equals(sign3) shall be false." );
			Assert.IsFalse( sign1.Equals( sign4 ), "sign1.Equals(sign4) shall be false." );
			Assert.IsFalse( sign1.Equals( sign5 ), "sign1.Equals(sign5) shall be false." );
		}
		/// <summary>
		/// New instance of signature can be created from MethodInfo type parameter.
		/// </summary>
		[Test]
		public void ConstructorWithMethodInfoParameter( )
		{
			MethodInfo methodInfo = typeof ( MethodSignatureTest ).GetMethod( "TestMethod" );
			MethodSignature signature1 = new MethodSignature( methodInfo );
			MethodSignature signature2 = new MethodSignature( "TestMethod", typeof ( int ), typeof ( object ), typeof ( int ) );
			Assert.AreEqual( signature1, signature2, "signature1 shall be equal to signature2." );
		}
		/// <summary>
		/// Test ToString() routine.
		/// </summary>
		[Test]
		public void TestToString( )
		{
			MethodSignature sign = new MethodSignature( "Method1", typeof ( Exception ), typeof ( bool ), typeof ( object ), typeof ( Exception ) );
			string actual = sign.ToString( );
			string expected = "System.Exception Method1(System.Boolean, System.Object, System.Exception)";
			Assert.AreEqual( expected, actual );
		}
		[Test]
			public void TestNotEqualToNull()
		{
			MethodSignature sign = new MethodSignature( "Method1", typeof ( Exception ), typeof ( bool ), typeof ( object ), typeof ( Exception ) );
			Assert.IsFalse( sign.Equals(null) );
		}
		[Test]
		public void TestNotEqualToNonMethodSignatureObject()
		{
			MethodSignature sign = new MethodSignature( "Method1", typeof ( Exception ), typeof ( bool ), typeof ( object ), typeof ( Exception ) );
			Assert.IsFalse( sign.Equals(new MockObject()) );
		}
		[Test]
			public void TestGetHashCode()
		{
			MethodSignature sign = new MethodSignature( "Method1", typeof ( Exception ), typeof ( bool ), typeof ( object ), typeof ( Exception ) );
			Assert.IsNotNull( sign.GetHashCode() );
		}
		[Test]
			public void TestNotEqualsDifferentParameterTypes()
		{
			MethodSignature sign = new MethodSignature( "Method1", typeof ( Exception ), typeof ( bool ), typeof ( object ), typeof ( Exception ) );
			MethodSignature sign1 = new MethodSignature( "Method1", typeof ( Exception ), typeof ( object ), typeof ( bool ), typeof ( Exception ) );
			Assert.IsFalse( sign.Equals(sign1) );
		}
		#endregion

		/// <summary>
		/// Method used for testing. This method is not being called but simply here to supply MethodInfo
		/// structure for testing.
		/// </summary>
		public int TestMethod( object obj, int i )
		{
			throw new InvalidOperationException( "This method is for testing purposes only and shall never be called." );
		}
	}
}