public void CanStartSearchAfterAbort()
        {
            // start and abort a search.
            string pw           = TestValues.GetPw(5);
            string foundPw      = string.Empty;
            int    eventCounter = 0;
            var    logic        = new LogicImplementation();

            logic.CollisionFound  += (p) => { foundPw = p; };
            logic.ProgressChanged += (c, l) => { eventCounter++; };
            var startTime = DateTime.Now;

            try
            {
                logic.StartSearchCollisionsTask(Sha1Hash.CalculateFromString(pw));
                startTime = DateTime.Now;
                while ((eventCounter == 0) && ((DateTime.Now - startTime).TotalMilliseconds < 500))
                {
                    Thread.Sleep(5);
                }
            }
            catch (Exception ex)
            {
                Assert.Fail($"Logic - \'StartSearchCollisionsTask\' method throws an exception: {ex.GetType().ToString()} - {ex.Message} ");
            }
            logic.AbortSearch();
            eventCounter = 0;
            startTime    = DateTime.Now;
            while ((eventCounter <= 1) && ((DateTime.Now - startTime).TotalMilliseconds < 200))
            {
                Thread.Sleep(5);
            }
            Assert.IsTrue((eventCounter <= 1), $"Logic - AbortSearch does not stop background Task.");
            // and start a second one
            pw      = TestValues.GetPw(2);
            foundPw = string.Empty;
            try
            {
                logic.StartSearchCollisionsTask(Sha1Hash.CalculateFromString(pw));
                startTime = DateTime.Now;
                while ((foundPw == string.Empty) && ((DateTime.Now - startTime).TotalMilliseconds < 1000))
                {
                    Thread.Sleep(5);
                }
            }
            catch (Exception ex)
            {
                Assert.Fail($"Logic - \'StartSearchCollisionsTask\' method throws an exception when started after an abort request: {ex.GetType().ToString()} - {ex.Message} ");
            }
            Assert.IsFalse((foundPw == string.Empty), $"Logic - does not return a collision when started after an abort request.");
            logic.AbortSearch();
        }
        public void HonorsAbortRequest()
        {
            string pw           = TestValues.GetPw(5);
            int    eventCounter = 0;
            var    logic        = new LogicImplementation();

            logic.CollisionFound  += (p) => { };
            logic.ProgressChanged += (c, l) => { eventCounter++; };
            var startTime = DateTime.Now;

            try
            {
                logic.StartSearchCollisionsTask(Sha1Hash.CalculateFromString(pw));
                startTime = DateTime.Now;
                while ((eventCounter == 0) && ((DateTime.Now - startTime).TotalMilliseconds < 500))
                {
                    Thread.Sleep(5);
                }
            }
            catch (Exception ex)
            {
                Assert.Fail($"Logic - \'StartSearchCollisionsTask\' method throws an exception: {ex.GetType().ToString()} - {ex.Message} ");
            }
            logic.AbortSearch();
            eventCounter = 0;
            startTime    = DateTime.Now;
            while ((eventCounter <= 1) && ((DateTime.Now - startTime).TotalMilliseconds < 200))
            {
                Thread.Sleep(5);
            }
            Assert.IsTrue((eventCounter <= 1), $"Logic - AbortSearch does not stop background Task.");
        }
        public void DetectsCollision()
        {
            string pw      = TestValues.GetPw(2);
            string foundPw = string.Empty;
            var    logic   = new LogicImplementation();

            logic.CollisionFound  += (p) => { foundPw = p; };
            logic.ProgressChanged += (c, l) => { };
            try
            {
                logic.StartSearchCollisionsTask(Sha1Hash.CalculateFromString(pw));
                var startTime = DateTime.Now;
                while ((foundPw == string.Empty) && ((DateTime.Now - startTime).TotalMilliseconds < 1000))
                {
                    Thread.Sleep(5);
                }
            }
            catch (Exception ex)
            {
                Assert.Fail($"Logic - \'StartSearchCollisionsTask\' method throws an exception: {ex.GetType().ToString()} - {ex.Message} ");
            }
            logic.AbortSearch();
            Assert.IsFalse((foundPw == string.Empty), $"Logic - does not return a collision through its 'CollisionFound' event.");
            Assert.IsTrue((pw == foundPw), $"Logic - returns wrong value for a collision: \'{foundPw}\', expected: \'{pw}\'.");
        }
        public void ChecksForNullEvents()
        {
            string pw    = TestValues.GetPw(5);
            var    logic = new LogicImplementation();

            try
            {
                logic.StartSearchCollisionsTask(Sha1Hash.CalculateFromString(pw));
                var startTime = DateTime.Now;
                while ((DateTime.Now - startTime).TotalMilliseconds < 200)
                {
                    Thread.Sleep(5);
                }
            }
            catch (Exception ex)
            {
                Assert.Fail($"Logic - \'StartSearchCollisionsTask\' method throws an exception: {ex.GetType().ToString()} - {ex.Message} ");
            }
            logic.AbortSearch();
        }
        public void ReportsProgress()
        {
            string pw      = TestValues.GetPw(5);
            ulong  pwCount = 0;
            var    logic   = new LogicImplementation();

            logic.CollisionFound  += (p) => { };
            logic.ProgressChanged += (c, l) => { pwCount = c; };
            try
            {
                logic.StartSearchCollisionsTask(Sha1Hash.CalculateFromString(pw));
                var startTime = DateTime.Now;
                while ((pwCount == 0) && ((DateTime.Now - startTime).TotalMilliseconds < 500))
                {
                    Thread.Sleep(5);
                }
            }
            catch (Exception ex)
            {
                Assert.Fail($"Logic - \'StartSearchCollisionsTask\' method throws an exception: {ex.GetType().ToString()} - {ex.Message} ");
            }
            logic.AbortSearch();
            Assert.IsFalse((pwCount == 0), $"Logic does not report # of passwords tested through its 'ProgressChanged' event.");
        }