diff --git a/src/Spectre.Console.Tests/Unit/Progress/ProgressTests.cs b/src/Spectre.Console.Tests/Unit/Progress/ProgressTests.cs index 64960c8..a0f93fc 100644 --- a/src/Spectre.Console.Tests/Unit/Progress/ProgressTests.cs +++ b/src/Spectre.Console.Tests/Unit/Progress/ProgressTests.cs @@ -115,5 +115,74 @@ namespace Spectre.Console.Tests.Unit task.MaxValue.ShouldBe(20); task.Value.ShouldBe(20); } + + [Fact] + public void Setting_Value_Should_Override_Incremented_Value() + { + // Given + var task = default(ProgressTask); + var console = new FakeConsole(); + var progress = new Progress(console) + .Columns(new[] { new ProgressBarColumn() }) + .AutoRefresh(false) + .AutoClear(false); + + // When + progress.Start(ctx => + { + task = ctx.AddTask("foo"); + task.Increment(50); + task.Value = 20; + }); + + // Then + task.MaxValue.ShouldBe(100); + task.Value.ShouldBe(20); + } + + [Fact] + public void Setting_Value_To_MaxValue_Should_Finish_Task() + { + // Given + var task = default(ProgressTask); + var console = new FakeConsole(); + var progress = new Progress(console) + .Columns(new[] { new ProgressBarColumn() }) + .AutoRefresh(false) + .AutoClear(false); + + // When + progress.Start(ctx => + { + task = ctx.AddTask("foo"); + task.Value = task.MaxValue; + }); + + // Then + task.IsFinished.ShouldBe(true); + } + + [Fact] + public void Should_Increment_Manually_Set_Value() + { + // Given + var task = default(ProgressTask); + var console = new FakeConsole(); + var progress = new Progress(console) + .Columns(new[] { new ProgressBarColumn() }) + .AutoRefresh(false) + .AutoClear(false); + + // When + progress.Start(ctx => + { + task = ctx.AddTask("foo"); + task.Value = 50; + task.Increment(10); + }); + + // Then + task.Value.ShouldBe(60); + } } } diff --git a/src/Spectre.Console/Extensions/Progress/ProgressTaskExtensions.cs b/src/Spectre.Console/Extensions/Progress/ProgressTaskExtensions.cs index 63ba2b0..a30876b 100644 --- a/src/Spectre.Console/Extensions/Progress/ProgressTaskExtensions.cs +++ b/src/Spectre.Console/Extensions/Progress/ProgressTaskExtensions.cs @@ -40,5 +40,22 @@ namespace Spectre.Console task.MaxValue = value; return task; } + + /// + /// Sets the value of the task. + /// + /// The task. + /// The value. + /// The same instance so that multiple calls can be chained. + public static ProgressTask Value(this ProgressTask task, double value) + { + if (task is null) + { + throw new ArgumentNullException(nameof(task)); + } + + task.Value = value; + return task; + } } } diff --git a/src/Spectre.Console/Widgets/Progress/ProgressTask.cs b/src/Spectre.Console/Widgets/Progress/ProgressTask.cs index 91b30c0..1df68be 100644 --- a/src/Spectre.Console/Widgets/Progress/ProgressTask.cs +++ b/src/Spectre.Console/Widgets/Progress/ProgressTask.cs @@ -14,6 +14,7 @@ namespace Spectre.Console private double _maxValue; private string _description; + private double _value; /// /// Gets the task ID. @@ -39,9 +40,13 @@ namespace Spectre.Console } /// - /// Gets the value of the task. + /// Gets or sets the value of the task. /// - public double Value { get; private set; } + public double Value + { + get => _value; + set => Update(value: value); + } /// /// Gets the start time of the task. @@ -100,6 +105,7 @@ namespace Spectre.Console _samples = new List(); _lock = new object(); _maxValue = maxValue; + _value = 0; _description = description?.RemoveNewLines()?.Trim() ?? throw new ArgumentNullException(nameof(description)); if (string.IsNullOrWhiteSpace(_description)) @@ -109,7 +115,6 @@ namespace Spectre.Console Id = id; State = new ProgressTaskState(); - Value = 0; StartTime = autoStart ? DateTime.Now : null; } @@ -151,7 +156,8 @@ namespace Spectre.Console private void Update( string? description = null, double? maxValue = null, - double? increment = null) + double? increment = null, + double? value = null) { lock (_lock) { @@ -175,13 +181,18 @@ namespace Spectre.Console if (increment != null) { - Value += increment.Value; + _value += increment.Value; + } + + if (value != null) + { + _value = value.Value; } // Need to cap the max value? - if (Value > _maxValue) + if (_value > _maxValue) { - Value = _maxValue; + _value = _maxValue; } var timestamp = DateTime.Now;