public virtual void ShouldCallRealDisposeOnlyOnce()
        {
            var config = new UnitOfWorkConfig(string.Empty, IsolationLevel.ReadCommitted, Require.New);
            var sessionBuilder = new Lazy<IDataSession>(() => session, false);
            var policy = new ImmediateTerminationPolicy();

            var context = new DataContext(config, sessionBuilder, policy);

            Awaken(context);

            context.Dispose();
            context.Dispose();

            session.Received(1).Dispose();
        }
        public virtual void ShouldNotCallRealCompleteIfSessionHasNotBeenUsed()
        {
            var config = new UnitOfWorkConfig(string.Empty, IsolationLevel.ReadCommitted, Require.New);
            var sessionBuilder = new Lazy<IDataSession>(() => session, false);
            var policy = new ImmediateTerminationPolicy();

            using (var context = new DataContext(config, sessionBuilder, policy))
            {
                context.Complete();
            }

            session.DidNotReceive().Complete();
        }
        public virtual void ShouldThrowExceptionOnSessionCallIfDisposeHasAlreadyBeenCalled()
        {
            var config = new UnitOfWorkConfig(string.Empty, IsolationLevel.ReadCommitted, Require.New);
            var sessionBuilder = new Lazy<IDataSession>(() => session, false);
            var policy = new ImmediateTerminationPolicy();

            var context = new DataContext(config, sessionBuilder, policy);
            context.Dispose();
            Awaken(context);
        }
        public virtual void ShouldReplaceFinishedEventInSubordinate()
        {
            var config = new UnitOfWorkConfig(string.Empty, IsolationLevel.ReadCommitted, Require.New);
            var sessionBuilder = new Lazy<IDataSession>(() => session, false);
            var policy = new ImmediateTerminationPolicy();

            var called = false;

            var context = new DataContext(config, sessionBuilder, policy);

            var subordinate = new DataContext.Subordinate(context);

            Awaken(subordinate);

            ((IDataContext)subordinate).Finished += (sender, e) => { called = true; };

            context.Dispose();

            called.Should().Be.True();

            session.Received(1).Dispose();

            session.ClearReceivedCalls();

            called = false;
            context = new DataContext(config, sessionBuilder, policy);
            subordinate = new DataContext.Subordinate(context);

            Awaken(subordinate);

            EventHandler<FinishedEventArgs> eventHandler = (sender, e) => { called = true; };
            ((IDataContext)subordinate).Finished += eventHandler;
            ((IDataContext)subordinate).Finished -= eventHandler;
            context.Dispose();
            session.Received(1).Dispose();
            called.Should().Be.False();
        }
        public virtual void ShouldRaiseFinishedEventDuringDecoratorDispose()
        {
            var config = new UnitOfWorkConfig(string.Empty, IsolationLevel.ReadCommitted, Require.New);
            var sessionBuilder = new Lazy<IDataSession>(() => session, false);
            var policy = new ImmediateTerminationPolicy();

            var context = new DataContext(config, sessionBuilder, policy);
            var contextDecorator = new DataContextSupervisor.DataContextDecorator(context, new List<DataContextSupervisor.DataContextDecorator>());

            Awaken(contextDecorator);

            EventHandler<FinishedEventArgs> eventHandler = (sender, e) => { throw new InstanceNotFoundException(); };
            ((IDataContext)contextDecorator).Finished += eventHandler;

            try
            {
                contextDecorator.Dispose();
            }
            catch (InstanceNotFoundException)
            {
            }

            session.Received(1).Dispose();

            session.ClearReceivedCalls();

            context = new DataContext(config, sessionBuilder, policy);
            contextDecorator = new DataContextSupervisor.DataContextDecorator(context, new List<DataContextSupervisor.DataContextDecorator>());

            Awaken(contextDecorator);

            eventHandler = (s, e) => { throw new InstanceNotFoundException(); };
            ((IDataContext)contextDecorator).Finished += eventHandler;
            ((IDataContext)contextDecorator).Finished -= eventHandler;
            contextDecorator.Dispose();
            session.Received(1).Dispose();
        }
        public virtual void ShouldRaiseFinishedEventDuringDispose()
        {
            var config = new UnitOfWorkConfig(string.Empty, IsolationLevel.ReadCommitted, Require.New);
            var sessionBuilder = new Lazy<IDataSession>(() => session, false);
            var policy = new ImmediateTerminationPolicy();

            bool? success = null;

            var context = new DataContext(config, sessionBuilder, policy);

            Awaken(context);

            context.Finished += (sender, e) =>
            {
                success = e.Completed;
                session.Received(0).Dispose();
            };

            context.Dispose();

            session.Received(1).Dispose();
            success.Should().Not.Be(null);
            success.Should().Be.EqualTo(false);

            session.ClearReceivedCalls();

            success = null;

            context = new DataContext(config, sessionBuilder, policy);

            Awaken(context);

            context.Finished += (sender, e) =>
            {
                success = e.Completed;
                session.Received(0).Dispose();
                session.Received(1).Complete();
            };
            context.Complete();
            context.Dispose();
            success.Should().Not.Be(null);
            success.Should().Be.EqualTo(true);
            session.Received(1).Dispose();

            session.ClearReceivedCalls();
        }
        public virtual void ShouldThrowExceptionIfCompleteCalledAfterDispose()
        {
            Assert.That(
                () =>
                {
                    var config = new UnitOfWorkConfig(string.Empty, IsolationLevel.ReadCommitted, Require.New);
                    var sessionBuilder = new Lazy<IDataSession>(() => session, false);
                    var policy = new ImmediateTerminationPolicy();

                    var context = new DataContext(config, sessionBuilder, policy);
                    Awaken(context);
                    context.Dispose();
                    context.Complete();
                }, 
                Throws.Exception.With.Message.EqualTo("Data context has already been disposed(with success - 'False'), so it is not usable anymore."));

            session.Received(1).Dispose();
            session.Received(0).Complete();
        }