using System;
using System.Data;
using DotNetMock.Framework.Data;
using NUnit.Framework;

namespace DotNetMock.Framework.Tests.Data
{
	[TestFixture]
	public class MockDbConnectionTests
	{
		private MockDbConnection _mockConnection = null;

		[SetUp]
		public void Init()
		{
			_mockConnection = new MockDbConnection();
		}

		[TearDown]
		public void Destroy()
		{
			Verifier.ResetVerifier();
			_mockConnection.Dispose();
			_mockConnection = null;
		}

		[Test]
		public void CloseCalls()
		{
			_mockConnection.SetExpectedCloseCalls(3);
			_mockConnection.Close();
			_mockConnection.Close();
			_mockConnection.Close();
			_mockConnection.Verify();
		}

		[Test]
		[ExpectedException(typeof(AssertionException))]
		public void InvalidCloseCalls()
		{
			_mockConnection.SetExpectedCloseCalls(1);
			_mockConnection.Close();
			_mockConnection.Close();
			_mockConnection.Verify();
		}
		[Test]
		public void OpenCalls()
		{
			_mockConnection.SetExpectedOpenCalls(3);
			_mockConnection.Open();
			_mockConnection.Open();
			_mockConnection.Open();
			_mockConnection.Verify();
		}

		[Test]
		[ExpectedException(typeof(AssertionException))]
		public void InvalidOpenCalls()
		{
			_mockConnection.SetExpectedOpenCalls(1);
			_mockConnection.Open();
			_mockConnection.Open();
			_mockConnection.Verify();
		}
		[Test]
		public void ConnectionString()
		{
			_mockConnection.SetExpectedConnectionString("DSN=localhost");
			_mockConnection.ConnectionString = "DSN=localhost";
			_mockConnection.Verify();
		}
		[Test]
		[ExpectedException(typeof(AssertionException))]
		public void InvalidConnectionString()
		{
			_mockConnection.SetExpectedConnectionString("DSN=localhost");
			_mockConnection.ConnectionString = "DSN=";
			_mockConnection.Verify();
		}
		[Test]
		public void ValidConnectionState()
		{
			_mockConnection.SetExpectedConnectionState( ConnectionState.Open );
			Assertion.AssertEquals("ConnectionState does not equal.", ConnectionState.Open, _mockConnection.State);
		}
		[Test]
		[ExpectedException(typeof(AssertionException))]
		public void InValidConnectionState()
		{
			_mockConnection.SetExpectedConnectionState( ConnectionState.Closed );
			Assertion.AssertEquals("ConnectionState equals", ConnectionState.Open, _mockConnection.State);
		}
		[Test]
		public void DefaultState()
		{
			Assertion.AssertEquals("ConnectionState does not equal.", ConnectionState.Closed, _mockConnection.State);
		}
		[Test]
		public void DefaultTimeout()
		{
			Assertion.AssertEquals("Timeouts do not equal.", 0, _mockConnection.ConnectionTimeout);
		}
		[Test]
		public void ValidTimeout()
		{
			_mockConnection.SetExpectedConnectionTimeout( 5 );
			Assertion.AssertEquals( "Timeouts do not equal.", 5, _mockConnection.ConnectionTimeout);
		}
		[Test]
		[ExpectedException(typeof(AssertionException))]
		public void InValidTimeout()
		{
			_mockConnection.SetExpectedConnectionTimeout( 5 );
			Assertion.AssertEquals( "Timeouts equal.", 0, _mockConnection.ConnectionTimeout );
		}
		[Test]
		[ExpectedException(typeof(System.Data.DataException))]
		public void CreateCommandException()
		{
			_mockConnection.SetCreateCommandException( new System.Data.DataException() );
			_mockConnection.CreateCommand();
		}
		[Test]
		public void ValidCreateCommand()
		{
			MockCommand mockCMD = new MockCommand();
			_mockConnection.SetExpectedCommand( mockCMD );
			Assertion.AssertEquals("Commands do not equal.", mockCMD, _mockConnection.CreateCommand());
		}
		[Test]
		public void DbConnectionPassesReferenceToCommandOnCreateCommand()
		{
			IDbCommand command = _mockConnection.CreateCommand();	
			Assertion.AssertEquals("connections don't equal", _mockConnection, command.Connection );
		}
		[Test]
		public void DbConnectionPassesReferenceToTransactionOnBegin()
		{
			IDbTransaction txn = _mockConnection.BeginTransaction();
			Assertion.AssertEquals( "Connections don't equal", _mockConnection, txn.Connection );
		}
		[Test]
		public void DbConnectionCreatesCorrectIsolationLevelForTxn()
		{
			IDbTransaction txn = _mockConnection.BeginTransaction( IsolationLevel.ReadCommitted );
			Assertion.AssertEquals( "Connections don't equal", _mockConnection, txn.Connection );
			Assertion.AssertEquals( "Isolation level", IsolationLevel.ReadCommitted, txn.IsolationLevel );
		}
	}
}
