using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnitTestSharp;
using UnitTestSharp.DataDriven;

namespace TestsForUnitTestSharp.DataDriven
{
    public class RunOnceTests
    {
        [DataDriven(typeof(NumbersTable))]
        public class MethodTest : UnitTestSharp.TestFixture
        {
            static bool runBefore = false;

            [RunOnce]
            public void RunOnceTest()
            {
                //Make sure this test would be run more than once without the above attribute
                Check(DataTable.Rows.Count > 1);

                //Make sure we haven't run this test before
                CheckFalse(runBefore);

                runBefore = true;
            }

            [RunOnce]
            public void VirtualRowTest_Implicit()
            {
                CheckEqual(1, DataRow["Numbers"]);
            }

            [RunOnce(ActualRow = 1)]
            public void ActualRowTest_1()
            {
                CheckEqual(1, DataRow["Numbers"]);
            }

            [RunOnce(ActualRow = 2)]
            public void ActualRowTest_2()
            {
                CheckEqual(1.25, DataRow["Numbers"]);
            }

            [RunOnce(ActualRow = 3)]
            public void ActualRowTest_3()
            {
                CheckEqual(-50, DataRow["Numbers"]);
            }
        }

        [DataDriven(typeof(NumbersTable))]
        [RunOnce]
        public class ClassTest : UnitTestSharp.TestFixture
        {
            static bool runBefore = false;

            public void RunOnceTest()
            {
                //Make sure this test would be run more than once without the above attribute
                Check(DataTable.Rows.Count > 1);

                //Make sure we haven't run this test before
                CheckFalse(runBefore);

                runBefore = true;
            }

            public void VirtualRowTest_Implicit()
            {
                CheckEqual(1, DataRow["Numbers"]);
            }
        }

        [DataDriven(typeof(NumbersTable))]
        [RunOnce(ActualRow = 3)]
        public class ClassTest_ActualRow : TestFixture
        {
            static bool runBefore = false;

            public void RunOnceTest()
            {
                //Make sure this test would be run more than once without the above attribute
                Check(DataTable.Rows.Count > 1);

                //Make sure we haven't run this test before
                CheckFalse(runBefore);

                runBefore = true;
            }

            public void ActualRowTest_3()
            {
                CheckEqual(-50, DataRow["Numbers"]);
            }
        }

        public class RunOnceNonsense : TestFixture
        {
            [DataDriven(typeof(NumbersTable))]
            [IgnoreFixture]
            public class NonsenseMethodParameters : TestFixture
            {
                [RunOnce(ActualRow = -20)]
                public void NegativeActualRow()
                {
                    
                }

                [RunOnce(ActualRow = 4)]
                public void ActualRowIsNotAVirtualRow_Inside()
                {
                    
                }

                [RunOnce(ActualRow = 100)]
                public void ActualRow_OutOfBounds()
                {
                    
                }

                [RunOnce(ActualRow = 0)]
                public void ActualRow_0()
                {
                    
                }
            }

            public void NonsenseMethodParameters_AllFail()
            {
                string output = "";
                int totalTests = 0;
                int failedTests = 0;
                int failedChecks = 0;
                TestRunner.RunTestFixture(typeof(NonsenseMethodParameters),
                    ref output, ref totalTests, ref failedTests, ref failedChecks);

                CheckEqual(4, totalTests);
                CheckEqual(4, failedTests);
                CheckEqual(4, failedChecks);
                CheckNotEqual("", output);
            }

            [IgnoreFixture]
            public class RunOnceOnNonDataDriven_Method : TestFixture
            {
                [RunOnce]
                public void Test()
                {
                    
                }
            }

            public void NotDataDrivenWarning_Method()
            {
                string output = "";
                int totalTests = 0;
                int failedTests = 0;
                int failedChecks = 0;
                TestRunner.RunTestFixture(typeof(RunOnceOnNonDataDriven_Method),
                    ref output, ref totalTests, ref failedTests, ref failedChecks);

                CheckEqual(1, totalTests);
                CheckEqual(0, failedTests);
                CheckEqual(0, failedChecks);
                CheckNotEqual("", output);
            }

            [RunOnce]
            [IgnoreFixture]
            public class RunOnceOnNonDataDriven_Class : TestFixture
            {
                public void Test()
                {
                    
                }
            }

            public void NotDataDrivenWarning_Class()
            {
                string output = "";
                int totalTests = 0;
                int failedTests = 0;
                int failedChecks = 0;
                TestRunner.RunTestFixture(typeof(RunOnceOnNonDataDriven_Class),
                    ref output, ref totalTests, ref failedTests, ref failedChecks);

                CheckEqual(1, totalTests);
                CheckEqual(0, failedTests);
                CheckEqual(0, failedChecks);
                CheckNotEqual("", output);
            }
        }
    }
}