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

namespace DotNetMock.Framework.Tests.Data
{
	[TestFixture]
	public class MockTransactionTests 
	{
		private MockTransaction _mockTransaction = null;

		[SetUp]
		public void Init() 
		{
			_mockTransaction = new MockTransaction();
		}
		[TearDown]
		public void Destroy()
		{
			
			_mockTransaction = null;
		}
		[Test]
		public void CommitCallsValid()
		{
			_mockTransaction.ExpectCommitCall( true );
			_mockTransaction.Commit();
			_mockTransaction.Verify();
		}
		[Test]
		[ExpectedException(typeof(AssertionException))]
		public void CommitNoCommitCall()
		{
			_mockTransaction.ExpectCommitCall( false );
			_mockTransaction.Commit();
			_mockTransaction.Verify();
		}
		[Test]
		public void TooManyCommitCalls()
		{
			_mockTransaction.ExpectCommitCall( true );
			_mockTransaction.Commit();
			try 
			{
				_mockTransaction.Commit();
				Assertion.Fail( "Should throw exception ");
			} 
			catch ( InvalidOperationException ) 
			{

			}
			_mockTransaction.Verify();
		}
		[Test]
		public void CommitException()
		{
			_mockTransaction.ExpectCommitCall( true );
			_mockTransaction.SetExpectedCommitException( new AssertionException() );
			try 
			{
				_mockTransaction.Commit();
				Assertion.Fail( "Should throw an exception." );
			} 
			catch ( AssertionException )
			{

			}
			_mockTransaction.Verify();
		}
		[Test]
		public void RollbackValidCall()
		{
			_mockTransaction.ExpectRollbackCall( true );
			_mockTransaction.Rollback();
			_mockTransaction.Verify();
		}
		[Test]
		public void RollbackInValidAfterCommit()
		{
			_mockTransaction.ExpectCommitCall( true );
			_mockTransaction.ExpectRollbackCall( true );
			_mockTransaction.Commit();
			try 
			{
				_mockTransaction.Rollback();
				Assertion.Fail( "Should throw an exception" );
			} 
			catch ( InvalidOperationException ) 
			{

			}
			_mockTransaction.Verify();
		}
		[Test]
		public void RollbackCalledToManyTimes()
		{
			_mockTransaction.ExpectCommitCall( false );
			_mockTransaction.ExpectRollbackCall( true );
			_mockTransaction.Rollback();
			try 
			{
				_mockTransaction.Rollback();
				Assertion.Fail( "SHould throw an exception" );
			} 
			catch ( InvalidOperationException )
			{
		
			}
			_mockTransaction.Verify();
		}
		[Test]
		public void RollbackException()
		{
			_mockTransaction.ExpectCommitCall( false );
			_mockTransaction.ExpectRollbackCall( true );
			_mockTransaction.SetExpectedRollbackException( new AssertionException() );
			try 
			{
				_mockTransaction.Rollback();
				Assertion.Fail( "Should throw an exception" );
			}
			catch ( AssertionException )
			{

			}
			_mockTransaction.Verify();
		}
		[Test]
		public void CommitFailAndRollback()
		{
			_mockTransaction.ExpectCommitCall( true );
			_mockTransaction.ExpectRollbackCall(true);
			_mockTransaction.SetExpectedCommitException( new AssertionException("Simulating commit failure") ); 
			try 
		 			
			{
				_mockTransaction.Commit();
				Assertion.Fail( "Should throw an exception." );
			} 
			catch ( AssertionException )
			{
				_mockTransaction.Rollback();
			}
			_mockTransaction.Verify();
	 			
		}
	}
}
