Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/console/logger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def initialize(output, **options)
def progress(subject, total, **options)
options[:severity] ||= :info

Progress.new(subject, total, **options)
Progress.new(subject, total, logger: self, **options)
end
end
end
12 changes: 8 additions & 4 deletions lib/console/progress.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ def self.now
#
# @parameter subject [Object] The subject of the progress indicator.
# @parameter total [Integer] The total number of steps.
# @parameter logger [Console::Logger] The logger to use for output.
# @parameter minimum_output_duration [Numeric] The minimum duration between outputs.
# @parameter options [Hash] Additional options to customize the output.
def initialize(subject, total = 0, minimum_output_duration: 0.1, **options)
def initialize(subject, total = 0, logger: Console, minimum_output_duration: 0.1, **options)
@subject = subject
@logger = logger
@options = options

@start_time = Clock.now
Expand Down Expand Up @@ -55,6 +57,8 @@ def duration

# @returns [Rational] The ratio of steps completed to total steps.
def ratio
return Rational(0, 1) if @total.zero?

Rational(@current.to_f, @total.to_f)
end

Expand Down Expand Up @@ -99,7 +103,7 @@ def increment(amount = 1)
@current += amount

if output?
Console.call(@subject, self.to_s, event: self.to_hash, **@options)
@logger.call(@subject, self.to_s, event: self.to_hash, **@options)
@last_output_time = Clock.now
end

Expand All @@ -113,7 +117,7 @@ def increment(amount = 1)
def resize(total)
@total = total

Console.call(@subject, self.to_s, event: self.to_hash, **@options)
@logger.call(@subject, self.to_s, event: self.to_hash, **@options)
@last_output_time = Clock.now

return self
Expand All @@ -125,7 +129,7 @@ def resize(total)
# @parameter **options [Hash] Additional options to log.
# @parameter &block [Proc] An optional block used to generate the log message.
def mark(*arguments, **options, &block)
Console.call(@subject, *arguments, **options, **@options, &block)
@logger.call(@subject, *arguments, **options, **@options, &block)
end

# @returns [String] A human-readable representation of the progress indicator.
Expand Down
8 changes: 3 additions & 5 deletions lib/console/terminal/formatter/progress.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,10 @@ def initialize(terminal)
def format(event, stream, verbose: false, width: 80)
current = event[:current].to_f
total = event[:total].to_f
value = current / total
value = total.zero? ? 0.0 : current / total

# Clamp value to 1.0 to avoid rendering issues:
if value > 1.0
value = 1.0
end
# Clamp value to avoid rendering issues:
value = value.clamp(0.0, 1.0)

stream.puts "#{@terminal[:progress_bar]}#{self.bar(value, width-10)}#{@terminal.reset} #{sprintf('%6.2f', value * 100)}%"
end
Expand Down
4 changes: 4 additions & 0 deletions releases.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Releases

## Unreleased

- Fix `Console::Progress` to emit through the logger that created it and safely handle zero totals.

## v1.37.0

- Show compound units in elapsed time display.
Expand Down
12 changes: 12 additions & 0 deletions test/console/terminal/formatter/progress.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,16 @@

expect(buffer.string).to be =~ /100.00%/
end

it "clamps negative progress to zero percent" do
formatter.format({current: -1, total: 1}, buffer, width: 20)

expect(buffer.string).to be =~ /0.00%/
end

it "formats a zero total as zero percent" do
formatter.format({current: 0, total: 0}, buffer, width: 20)

expect(buffer.string).to be =~ /0.00%/
end
end
50 changes: 50 additions & 0 deletions test/progress.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,48 @@
end
end

with "a specific logger" do
let(:capture) {Console::Capture.new}
let(:logger) {Console::Logger.new(capture)}
let(:progress) {logger.progress("My Measurement", 1)}

it "emits progress through that logger" do
progress.increment

expect(capture.last).to have_keys(
severity: be == :info,
subject: be == "My Measurement",
event: have_keys(type: be == :progress),
)
expect(console_capture).to be(:empty?)
end

it "emits resizing through that logger" do
progress.resize(2)

expect(capture.last).to have_keys(
severity: be == :info,
subject: be == "My Measurement",
event: have_keys(
type: be == :progress,
total: be == 2,
),
)
expect(console_capture).to be(:empty?)
end

it "emits marks through that logger" do
progress.mark("Hello World!")

expect(capture.last).to have_keys(
severity: be == :info,
subject: be == "My Measurement",
arguments: be == ["Hello World!"],
)
expect(console_capture).to be(:empty?)
end
end

with "#resize" do
it "can resize the progress bar total" do
progress.resize(200)
Expand Down Expand Up @@ -77,4 +119,12 @@
)
end
end

with "a zero total" do
let(:progress) {Console::Progress.new("My Measurement")}

it "has a zero ratio" do
expect(progress.ratio).to be == 0.0
end
end
end
Loading