public void PercentComplete_should_automatically_stop_if_AutoStop_is_true_and_the_percent_is_100()
        {
            var vm = new LongRunningProcessProgressViewModel(new FakeAsyncCommand(), new FakeDispatcherTimer());

            vm.StartTimer();
            vm.PercentComplete = 100;
            vm.IsStarted.Should().BeFalse();

            vm.PercentComplete = 0;
            vm.AutoStop        = false;
            vm.StartTimer();
            vm.PercentComplete = 100;
            vm.IsStarted.Should().BeTrue();
        }
        public void EstimatedTimeRemaining_should_return_the_max_value_if_the_percent_is_zero()
        {
            var vm = new LongRunningProcessProgressViewModel(new FakeAsyncCommand(), new FakeDispatcherTimer());

            vm.StartTimer();
            vm.EstimatedTimeRemaining.Should().Be(TimeSpan.MaxValue);
        }
        public void Start_should_start_the_timer()
        {
            var timer = new FakeDispatcherTimer();
            var vm    = new LongRunningProcessProgressViewModel(new FakeAsyncCommand(), timer);

            vm.StartTimer();
            timer.IsEnabled.Should().BeTrue();
        }
        public void Start_should_set_PercentComplete_to_0()
        {
            var vm = new LongRunningProcessProgressViewModel(new FakeAsyncCommand(), new FakeDispatcherTimer())
            {
                PercentComplete = 50
            };

            vm.StartTimer();
            vm.PercentComplete.Should().Be(0);
        }
        public void ElapsedTime_should_track_the_time_since_Start_was_called()
        {
            int callCount = 0;
            var baseDate  = new DateTime(2020, 1, 1);

            DateTime GetNow() =>
            callCount switch
            {
                0 => baseDate,
                1 => baseDate.AddMilliseconds(500),
                2 => baseDate.AddSeconds(5),
                3 => baseDate.AddMinutes(10),
                4 => baseDate.AddHours(20),
                5 => baseDate.AddDays(2),
                6 => baseDate.AddHours(14).AddMinutes(13).AddSeconds(12),
                _ => throw new InvalidOperationException(),
            };

            var vm = new LongRunningProcessProgressViewModel(new FakeAsyncCommand(), new FakeDispatcherTimer(), GetNow);

            vm.StartTimer();

            vm.ElapsedTime.TotalMilliseconds.Should().Be(0);
            vm.FormattedElapsedTime.Should().Be("0m:00s:000ms");

            callCount++;
            vm.ElapsedTime.TotalMilliseconds.Should().Be(500);
            vm.FormattedElapsedTime.Should().Be("0m:00s:500ms");

            callCount++;
            vm.ElapsedTime.TotalSeconds.Should().Be(5);
            vm.FormattedElapsedTime.Should().Be("0m:05s:000ms");

            callCount++;
            vm.ElapsedTime.TotalMinutes.Should().Be(10);
            vm.FormattedElapsedTime.Should().Be("10m:00s:000ms");

            callCount++;
            vm.ElapsedTime.TotalHours.Should().Be(20);
            vm.FormattedElapsedTime.Should().Be("20h:00m:00s");

            callCount++;
            vm.ElapsedTime.TotalDays.Should().Be(2);
            vm.FormattedElapsedTime.Should().Be("48h:00m:00s");

            callCount++;
            vm.ElapsedTime.TotalHours.Should().Be(14.22);
            vm.FormattedElapsedTime.Should().Be("14h:13m:12s");
        }
        public void EstimatedTimeRemaining_should_calculate_correctly()
        {
            // Assume the total time is 10 minutes, make sure that the estimated time is correct for different percentages.
            int callCount = 0;
            var baseDate  = new DateTime(2020, 1, 1);

            DateTime GetNow() =>
            callCount switch
            {
                /* 0% */
                0 => baseDate,
                /* 10% */
                1 => baseDate.AddMinutes(1),
                /* 25% */
                2 => baseDate.AddMinutes(2.5),
                /* 50% */
                3 => baseDate.AddMinutes(5),
                /* 75% */
                4 => baseDate.AddMinutes(7.5),
                /* 80% */
                5 => baseDate.AddMinutes(8),
                /* 90% */
                6 => baseDate.AddMinutes(9),
                /* 99% */
                7 => baseDate.AddMinutes(9).AddSeconds(45),
                /* 100% */
                8 => baseDate.AddMinutes(10),
                _ => throw new InvalidOperationException(),
            };

            var vm = new LongRunningProcessProgressViewModel(new FakeAsyncCommand(), new FakeDispatcherTimer(), GetNow);

            vm.StartTimer();

            vm.EstimatedTimeRemaining.Should().Be(TimeSpan.MaxValue);
            vm.FormattedEstimatedTimeRemaining.Should().Be("");

            callCount++;
            vm.PercentComplete = 10;
            vm.EstimatedTimeRemaining.Should().Be(TimeSpan.FromMinutes(9));
            vm.FormattedEstimatedTimeRemaining.Should().Be("9m:00s");

            callCount++;
            vm.PercentComplete = 25;
            vm.EstimatedTimeRemaining.Should().Be(TimeSpan.FromMinutes(7.5));
            vm.FormattedEstimatedTimeRemaining.Should().Be("7m:30s");

            callCount++;
            vm.PercentComplete = 50;
            vm.EstimatedTimeRemaining.Should().Be(TimeSpan.FromMinutes(5));
            vm.FormattedEstimatedTimeRemaining.Should().Be("5m:00s");

            callCount++;
            vm.PercentComplete = 75;
            vm.EstimatedTimeRemaining.Should().Be(TimeSpan.FromMinutes(2.5));
            vm.FormattedEstimatedTimeRemaining.Should().Be("2m:30s");

            callCount++;
            vm.PercentComplete = 80;
            vm.EstimatedTimeRemaining.Should().BeCloseTo(TimeSpan.FromMinutes(2));
            vm.FormattedEstimatedTimeRemaining.Should().Be("1m:59s");

            callCount++;
            vm.PercentComplete = 90;
            vm.EstimatedTimeRemaining.Should().BeCloseTo(TimeSpan.FromMinutes(1));
            vm.FormattedEstimatedTimeRemaining.Should().Be("0m:59s");

            callCount++;
            vm.PercentComplete = 99;
            vm.EstimatedTimeRemaining.Should().BeCloseTo(TimeSpan.FromSeconds(5.9));
            vm.FormattedEstimatedTimeRemaining.Should().Be("0m:05s");

            callCount++;
            vm.PercentComplete = 100;
            vm.EstimatedTimeRemaining.Should().BeCloseTo(TimeSpan.FromSeconds(0));
            vm.FormattedEstimatedTimeRemaining.Should().Be("0m:00s");
        }