public void StartCoroutine()
        {
            var coroutineContext = new CoroutineContext(NullCoroutine);

            bool isFinishedEventTriggered = true;

            coroutineContext.Finished += () => isFinishedEventTriggered = true;

            coroutineContext.Start();

            Assert.IsTrue(isFinishedEventTriggered);
            Assert.IsFalse(coroutineContext.IsStarted);
            Assert.IsFalse(coroutineContext.IsPaused);
            Assert.IsTrue(coroutineContext.IsFinished);

            var coroutineContext2 = new CoroutineContext(SquareA);

            bool isStartedEventTriggered = false;

            coroutineContext2.Started += () => isStartedEventTriggered = true;

            coroutineContext2.Start();

            Assert.IsTrue(isStartedEventTriggered);
            Assert.AreEqual(a, 9);
        }
        public void StartCoroutineWithTimeout()
        {
            const int expectedMilliseconds = 1000;
            const int tolerance            = 2;

            var sw = new Stopwatch();

            var coroutineContext = new CoroutineContext(InfiniteCoroutine);
            var timeOut          = new TimeSpan(0, 0, 0, 0, expectedMilliseconds);

            sw.Start();
            coroutineContext.Start(timeOut);
            sw.Stop();

            Assert.IsTrue(((sw.ElapsedMilliseconds + tolerance) > expectedMilliseconds) || ((sw.ElapsedMilliseconds - tolerance) < expectedMilliseconds));
        }
        public void PauseCoroutineFromAnotherThread()
        {
            var coroutineContext = new CoroutineContext(InfiniteCoroutine);

            Assert.IsFalse(coroutineContext.IsStarted);
            Assert.IsFalse(coroutineContext.IsPaused);
            Assert.IsFalse(coroutineContext.IsFinished);

            bool isPausedEventTriggered = false;

            coroutineContext.Paused += paused => isPausedEventTriggered = paused;

            var pausingThread = new Thread(() =>
            {
                Thread.Sleep(10);
                coroutineContext.Pause();
            });

            pausingThread.Start();
            coroutineContext.Start();

            Assert.IsTrue(isPausedEventTriggered);
            Assert.IsTrue(coroutineContext.IsStarted);
            Assert.IsTrue(coroutineContext.IsPaused);
            Assert.IsFalse(coroutineContext.IsFinished);

            var testUnpausedThread = new Thread(() =>
            {
                Thread.Sleep(10);

                Assert.IsTrue(coroutineContext.IsStarted);
                Assert.IsFalse(coroutineContext.IsPaused);
                Assert.IsFalse(coroutineContext.IsFinished);

                coroutineContext.Stop();
            });

            testUnpausedThread.Start();

            coroutineContext.Unpause();
        }
        public void ResetCoroutineContext()
        {
            var coroutineContext = new CoroutineContext(InfiniteCoroutine);

            bool isResetEventTriggered = false;

            coroutineContext.Reseted += () => isResetEventTriggered = true;

            var resetCoroutineContextThread = new Thread(() =>
            {
                Thread.Sleep(10);
                coroutineContext.Reset();
            });

            resetCoroutineContextThread.Start();
            coroutineContext.Start();

            Assert.IsTrue(isResetEventTriggered);
            Assert.IsFalse(coroutineContext.IsStarted);
            Assert.IsFalse(coroutineContext.IsPaused);
            Assert.IsFalse(coroutineContext.IsFinished);
        }
        public void StopCoroutineFromAnotherThread()
        {
            var coroutineContext = new CoroutineContext(InfiniteCoroutine);

            var isStoppedEventTriggered = false;

            coroutineContext.Stopped += () => isStoppedEventTriggered = true;

            var stoppingThread = new Thread(() =>
            {
                Thread.Sleep(10);
                coroutineContext.Stop();
            });

            stoppingThread.Start();
            coroutineContext.Start();

            Assert.IsTrue(isStoppedEventTriggered);
            Assert.IsFalse(coroutineContext.IsStarted);
            Assert.IsFalse(coroutineContext.IsPaused);
            Assert.IsFalse(coroutineContext.IsFinished);
        }