﻿namespace Series.Core.Unit.Tests.SeriesFactoryTests
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Factorial;
    using Fibonacci;
    using NUnit.Framework;
    using static NUnit.Framework.Assert;

    [TestFixture]
    public class Select
    {
        private List<Series> _candidates;

        [SetUp]
        public void Setup()
        {
            var factorial = new Factorial();
            var fibonacci = new Fibonacci();
            _candidates = new List<Series>
            {
                factorial, fibonacci
            };
        }

        [Test]
        public void ThrowsArgumentNullExceptionForNullCandidatesList()
        {
            // Arrange
            var factory = new SeriesFactory(null);

            // Act | Assert
            Throws<ArgumentNullException>(() => factory.Select("Factorial"));
        }

        [Test]
        public void ThrowsInvalidOperationExceptionForEmptyCandidatesList()
        {
            // Arrange
            var factory = new SeriesFactory(Enumerable.Empty<Series>());

            // Act | Assert
            Throws<InvalidOperationException>(() => factory.Select("Factorial"));
        }

        [Test]
        public void ThrowsInvalidOperationExceptionForNonExistentCandidate()
        {
            // Arrange
            var factory = new SeriesFactory(_candidates);

            // Act | Assert
            Throws<InvalidOperationException>(() => factory.Select("Nothing"));
        }

        [Test]
        public void ReturnsFactorial()
        {
            // Arrange
            var factory = new SeriesFactory(_candidates);

            // Act
            var result = factory.Select("Factorial");

            // Assert
            IsInstanceOf<Factorial>(result);
        }

        [Test]
        public void ReturnsFibonacci()
        {
            // Arrange
            var factory = new SeriesFactory(_candidates);

            // Act
            var result = factory.Select("Fibonacci");

            // Assert
            IsInstanceOf<Fibonacci>(result);
        }
    }
}