Skip to content

Commit

Permalink
Add ability to listen for events on multi bar
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrmurach committed Sep 3, 2017
1 parent dc5ee5e commit 3546e2d
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 1 deletion.
46 changes: 45 additions & 1 deletion lib/tty/progressbar/multi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ def initialize(*args)
@rows = 0
@top_bar = nil
@top_bar = register(format) if format

@callbacks = {
progress: [],
stopped: [],
done: []
}
end

# Register a new progress bar
Expand Down Expand Up @@ -91,7 +97,9 @@ def next_row
#
# @api public
def observe(bar)
bar.on(:progress) { top_bar.current = current }
bar.on(:progress) { top_bar.current = current; emit(:progress) }
.on(:done) { top_bar.finish; emit(:done) if complete? }
.on(:stopped) { top_bar.stop; emit(:stopped) if stopped? }
end

# Get the top level bar if it exists
Expand Down Expand Up @@ -136,6 +144,15 @@ def complete?
(@bars - [@top_bar]).dup.all?(&:complete?)
end

# Check if any of the registered progress bars is stopped
#
# @return [Boolean]
#
# @api public
def stopped?
(@bars - [@top_bar]).dup.any?(&:stopped?)
end

# Stop all progress bars
#
# @api public
Expand All @@ -147,6 +164,7 @@ def stop
#
# @api public
def finish
@top_bar.finish if @top_bar
@bars.dup.each(&:finish)
end

Expand All @@ -172,6 +190,32 @@ def line_inset(bar)
@inset_opts[:middle]
end
end

# Listen on event
#
# @param [Symbol] name
# the event name to listen on
#
# @api public
def on(name, &callback)
unless @callbacks.key?(name)
raise ArgumentError, "The event #{name} does not exist. "\
" Use :progress, :stopped, or :done instead"
end
@callbacks[name] << callback
self
end

private

# Fire an event by name
#
# @api private
def emit(name, *args)
@callbacks[name].each do |callback|
callback.(*args)
end
end
end # Multi
end # ProgressBar
end # TTY
64 changes: 64 additions & 0 deletions spec/unit/multi/events_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# encoding: utf-8

RSpec.describe TTY::ProgressBar::Multi, 'events' do
let(:output) { StringIO.new('', 'w+') }

it "emits :progress eent when any of the registerd bars advances" do
events = []
bars = TTY::ProgressBar::Multi.new("[:bar]", output: output, total: 5)
bars.on(:progress) { events << :progress }

bar = bars.register "one [:bar]"
bar.advance

expect(events).to eq([:progress])
end

it "emits :done event when all progress bars finished" do
events = []
bars = TTY::ProgressBar::Multi.new("[:bar]", output: output, total: 5)
bars.on(:done) { events << :done }

bar = bars.register "one [:bar]"

bar.finish

expect(events).to eq([:done])
end

it "emits :done event when top level bar finished" do
events = []
bars = TTY::ProgressBar::Multi.new("[:bar]", output: output, total: 5)
bars.on(:done) { events << :done }

bars.register "one [:bar]"

bars.finish

expect(events).to eq([:done])
end

it "emits :stopped event when all registerd bars are stopped" do
events = []
bars = TTY::ProgressBar::Multi.new("[:bar]", output: output, total: 5)
bars.on(:stopped) { events << :stopped }

bar = bars.register "one [:bar]"

bar.stop

expect(events).to eq([:stopped])
end

it "emits :stopped event when top level bar finished" do
events = []
bars = TTY::ProgressBar::Multi.new("[:bar]", output: output, total: 5)
bars.on(:stopped) { events << :stopped }

bars.register "one [:bar]"

bars.stop

expect(events).to eq([:stopped])
end
end

0 comments on commit 3546e2d

Please sign in to comment.