﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="WindsorResolverShould.cs" company="Epworth Consulting Ltd.">
//   © Epworth Consulting Ltd.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Atlas.ServiceBus.Resolver.Windsor.Tests
{
   using Atlas.ServiceBus.Resolver.Windsor.Implementations;

   using Castle.Windsor;

   using FakeItEasy;

   using NUnit.Framework;

   public class WindsorResolverShould
   {
      private IWindsorContainer windsorContainer;

      private interface IContract
      {
      }

      [SetUp]
      public void SetupBeforeEachTest()
      {
         this.windsorContainer = A.Fake<IWindsorContainer>();
      }

      [Test]
      public void ShouldResolveFromContainer()
      {
         var componentUnderTest = new WindsorServiceBusResolver(this.windsorContainer);

         componentUnderTest.Resolve<IContract>();

         A.CallTo(() => this.windsorContainer.Resolve<IContract>()).MustHaveHappened(Repeated.Exactly.Once);
      }

      [Test]
      public void ShouldResolveConcreteInstance()
      {
         var componentUnderTest = new WindsorServiceBusResolver();

         componentUnderTest.Register<IContract, Concrete>();

         var result = componentUnderTest.Resolve<IContract>();

         Assert.That(result, Is.InstanceOf<Concrete>());
      }

      [Test]
      public void ShouldRegisterAndResolveTransientInstance()
      {
         var componentUnderTest = new WindsorServiceBusResolver();

         componentUnderTest.Register<IContract, Concrete>();

         var resultA = componentUnderTest.Resolve<IContract>();
         var resultB = componentUnderTest.Resolve<IContract>();

         Assert.That(resultB, Is.Not.SameAs(resultA));
      }

      [Test]
      public void ShouldRegisterAndResolveSingletonInstance()
      {
         var componentUnderTest = new WindsorServiceBusResolver();

         var instance = new Concrete();
         componentUnderTest.Register<IContract>(instance);

         var resultA = componentUnderTest.Resolve<IContract>();
         var resultB = componentUnderTest.Resolve<IContract>();

         Assert.That(resultA, Is.SameAs(instance));
         Assert.That(resultB, Is.SameAs(instance));
      }

      private class Concrete : IContract
      {
      }
   }
}
