using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestCaseExtension;

namespace TestCaseTesting
{
    [TestCaseClass]
    public class MoreTestCaseExamples
    {
        // The Explicit attribute is included to make NUnit porting easier
        [TestMethod, Explicit("This test will not be run")]
        public void TestExplicitNotRun()
        {
            Assert.AreEqual(5, 7, "These are *not* equal");
        }

        // Flat arrays are supported in Attributes, though you cannot mix types
        [TestMethod]
        [TestCase(new int[] { 1, 2, 3 }, 6)]
        [TestCase(new int[] { 1, 2, 3, 4 }, 10)]
        [TestCase(new int[] { 5, 6 }, 11)]
        public void TestArraysAsTestCases(int[] array, int expectedSum)
        {
            Assert.AreEqual(expectedSum, array.Aggregate(0, (a, b) => a + b));
        }

        // You can instead create (flat) object arrays
        [TestMethod]
        [TestCase(new object[] { 1, 2, 3, 4 }, 4)]
        [TestCase(new object[] { "a", "b" }, 2)]
        [TestCase(new object[] { 3.3, 2.2, 1.1 }, 3)]
        public void TestObjectArraysAsTestCases(object[] array, int length)
        {
            Assert.AreEqual(length, array.Length);
        }

        // TestCaseSources can also be static methods/fields/properties of a different class
        [TestMethod]
        [TestCaseSource(typeof(SumSourceClass), "SumSourceField")]
        [TestCaseSource(typeof(SumSourceClass), "SumSourceProperty")]
        public void TestSumWithExternalSources(int expected, int a, int b)
        {
            Assert.AreEqual(expected, a + b);
        }
    }

    public class SumSourceClass
    {
        protected static TestCaseData[] SumSourceField = new[]
        {
                new TestCaseData(3, 2, 1),
                new TestCaseData(5, 2, 3),
                new TestCaseData(6, 4, 2)
        };

        private static IEnumerable<TestCaseData> SumSourceProperty
        {
            get
            {
                yield return new TestCaseData(3, 2, 1);
                yield return new TestCaseData(4, 2, 2);
                yield return new TestCaseData(8, 3, 5);
            }
        }
    }
}