ruby-progressbar-1.4.2/0000755000175000017500000000000012534053362014401 5ustar globusglobusruby-progressbar-1.4.2/lib/0000755000175000017500000000000012534053362015147 5ustar globusglobusruby-progressbar-1.4.2/lib/ruby-progressbar/0000755000175000017500000000000012534053362020457 5ustar globusglobusruby-progressbar-1.4.2/lib/ruby-progressbar/base.rb0000644000175000017500000001005712534053362021721 0ustar globusglobusclass ProgressBar class Base include ProgressBar::LengthCalculator include ProgressBar::Formatter DEFAULT_OUTPUT_STREAM = $stdout def initialize(options = {}) self.output = options[:output] || DEFAULT_OUTPUT_STREAM autostart = options.fetch(:autostart, true) super(options) @bar = Components::Bar.new(options) @estimated_time = Components::EstimatedTimer.new(options) @elapsed_time = Components::ElapsedTimer.new @throttle = Components::Throttle.new(options) start :at => options[:starting_at] if autostart end ### # Starting The Bar # def start(options = {}) clear with_update do with_progressables(:start, options) with_timers(:start) end end ### # Updating The Bar's Progress # def decrement update_progress(:decrement) end def increment update_progress(:increment) end def progress=(new_progress) update_progress(:progress=, new_progress) end def total=(new_total) update_progress(:total=, new_total) end ### # Stopping The Bar # def finish with_update { with_progressables(:finish); with_timers(:stop) } unless finished? end def pause with_update { with_timers(:pause) } unless paused? end def stop with_update { with_timers(:stop) } unless stopped? end def resume with_update { with_timers(:resume) } if stopped? end def reset with_update do @bar.reset with_timers(:reset) end end def stopped? (@estimated_time.stopped? && @elapsed_time.stopped?) || finished? end alias :paused? :stopped? def finished? @estimated_time.finished? && @bar.finished? end def started? @estimated_time.started? && @elapsed_time.started? && @bar.started? end ### # UI Updates # def progress_mark=(mark) with_update { @bar.progress_mark = mark } end def remainder_mark=(mark) with_update { @bar.remainder_mark = mark } end def title=(title) with_update { super } end ### # Output # def clear self.last_update_length = 0 if output.tty? output.print clear_string output.print "\r" else output.print "\n" end end def refresh update end def log(string) clear output.puts string update(:force => true) unless stopped? end def to_s(format_string = nil) format_string ||= @format_string format(format_string) end def inspect "#" end private attr_accessor :output, :last_update_length def clear_string "#{" " * length}" end def last_update_length @last_update_length ||= 0 end def with_progressables(*args) @bar.send(*args) @estimated_time.send(*args) end def with_timers(*args) @estimated_time.send(*args) @elapsed_time.send(*args) end def update_progress(*args) with_update do with_progressables(*args) with_timers(:stop) if finished? end end def with_update yield update end def update(options = {}) if length_changed? clear reset_length end @throttle.choke( stopped? || options[:force] ) do if output.tty? formatted_string = self.to_s output_string = formatted_string else formatted_string = self.to_s(DEFAULT_NON_TTY_FORMAT_STRING) formatted_string = formatted_string[0...-1] unless finished? output_string = formatted_string[last_update_length..-1] end self.last_update_length = formatted_string.length output.print output_string + eol output.flush end end def eol if output.tty? stopped? ? "\n" : "\r" else stopped? ? "\n" : "" end end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/components/0000755000175000017500000000000012534053362022644 5ustar globusglobusruby-progressbar-1.4.2/lib/ruby-progressbar/components/estimated_timer.rb0000644000175000017500000000405412534053362026353 0ustar globusglobusclass ProgressBar module Components class EstimatedTimer include Timer include Progressable VALID_OOB_TIME_FORMATS = [:unknown, :friendly, nil] def initialize(options = {}) super end def start(options = {}) as(Timer).start as(Progressable).start(options) end def reset as(Timer).reset as(Progressable).reset end def out_of_bounds_time_format=(format) raise "Invalid Out Of Bounds time format. Valid formats are #{VALID_OOB_TIME_FORMATS.inspect}" unless VALID_OOB_TIME_FORMATS.include? format @out_of_bounds_time_format = format end def to_s " ETA: #{estimated_time}" end private def estimated_time return '??:??:??' if running_average.zero? || total.nil? hours, minutes, seconds = *divide_seconds(estimated_seconds_remaining) if hours > 99 && @out_of_bounds_time_format out_of_bounds_time else sprintf TIME_FORMAT, hours, minutes, seconds end end def estimated_seconds_remaining (elapsed_seconds * (self.total / self.running_average - 1)).round end def out_of_bounds_time case @out_of_bounds_time_format when :unknown '??:??:??' when :friendly '> 4 Days' end end def as(ancestor, &blk) @__as ||= {} unless r = @__as[ancestor] r = (@__as[ancestor] = As.new(self, ancestor)) end r.instance_eval(&blk) if block_given? r end class As private *instance_methods.select { |m| m !~ /(^__|^\W|^binding$)/ } def initialize(subject, ancestor) @subject = subject @ancestor = ancestor end def start(*args, &blk) @ancestor.instance_method(:start).bind(@subject).call(*args,&blk) end def method_missing(sym, *args, &blk) @ancestor.instance_method(sym).bind(@subject).call(*args,&blk) end end end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/components/progressable.rb0000644000175000017500000000610112534053362025657 0ustar globusglobusrequire 'ruby-progressbar/errors/invalid_progress_error' class ProgressBar module Components module Progressable DEFAULT_TOTAL = 100 DEFAULT_BEGINNING_POSITION = 0 DEFAULT_SMOOTHING = 0.1 attr_reader :total attr_reader :progress attr_accessor :starting_position attr_accessor :running_average attr_accessor :smoothing def initialize(options = {}) self.total = options.fetch(:total, DEFAULT_TOTAL) self.smoothing = options[:smoothing] || DEFAULT_SMOOTHING start :at => DEFAULT_BEGINNING_POSITION end def start(options = {}) self.running_average = 0 self.progress = \ self.starting_position = options[:at] || self.progress end def started? !!self.starting_position end def finished? self.progress == self.total end def increment warn "WARNING: Your progress bar is currently at #{progress} out of #{total} and cannot be incremented. In v2.0.0 this will become a ProgressBar::InvalidProgressError." if progress == total self.progress += 1 unless progress == total end def decrement warn "WARNING: Your progress bar is currently at #{progress} out of #{total} and cannot be decremented. In v2.0.0 this will become a ProgressBar::InvalidProgressError." if progress == 0 self.progress -= 1 unless progress == 0 end def reset start :at => self.starting_position end def progress=(new_progress) validate_progress(new_progress) @progress = new_progress update_running_average end def total=(new_total) validate_total(new_total) @total = new_total end def finish self.progress = self.total end def percentage_completed return 100 if total == 0 return 0 if total.nil? # progress / total * 100 # # Doing this way so we can avoid converting each # number to a float and then back to an integer. # (self.progress * 100 / total).to_i end def percentage_completed_with_precision format('%5.2f', (progress.to_f * 100.0 / total * 100.0).floor / 100.0) end private def validate_total(new_total) (progress.nil? || new_total.nil? || new_total >= progress) || raise(ProgressBar::InvalidProgressError, "You can't set the item's total value to be less than the current progress.") end def validate_progress(new_progress) (total.nil? || new_progress <= total) || raise(ProgressBar::InvalidProgressError, "You can't set the item's current value to be greater than the total.") end def progress_made started? ? self.progress - self.starting_position : 0 end def update_running_average self.running_average = RunningAverageCalculator.calculate(self.running_average, self.progress, self.smoothing) end end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/components/bar.rb0000644000175000017500000000370012534053362023735 0ustar globusglobusclass ProgressBar module Components class Bar include Progressable DEFAULT_PROGRESS_MARK = '=' DEFAULT_REMAINDER_MARK = ' ' DEFAULT_UNKNOWN_PROGRESS_ANIMATION_STEPS = ['=---', '-=--', '--=-', '---='] attr_accessor :progress_mark attr_accessor :remainder_mark attr_accessor :length attr_accessor :unknown_progress_animation_steps def initialize(options = {}) super self.unknown_progress_animation_steps = options[:unknown_progress_animation_steps] || DEFAULT_UNKNOWN_PROGRESS_ANIMATION_STEPS self.progress_mark = options[:progress_mark] || DEFAULT_PROGRESS_MARK self.remainder_mark = options[:remainder_mark] || DEFAULT_REMAINDER_MARK end def to_s(options = {:format => :standard}) completed_string = send(:"#{options[:format]}_complete_string") "#{completed_string}#{empty_string}" end def integrated_percentage_complete_string return standard_complete_string if completed_length < 5 " #{percentage_completed} ".to_s.center(completed_length, progress_mark) end def standard_complete_string progress_mark * completed_length end def empty_string incomplete_length = (length - completed_length) if total.nil? current_animation_step = progress % unknown_progress_animation_steps.size animation_graphic = unknown_progress_animation_steps[current_animation_step] unknown_incomplete_string = animation_graphic * ((incomplete_length / unknown_progress_animation_steps.size) + 2) unknown_incomplete_string[0, incomplete_length] else remainder_mark * incomplete_length end end private def completed_length (length * percentage_completed / 100).floor end end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/components/elapsed_timer.rb0000644000175000017500000000056412534053362026013 0ustar globusglobusclass ProgressBar module Components class ElapsedTimer include Timer def to_s "Time: #{elapsed_time}" end private def elapsed_time return '--:--:--' unless started? hours, minutes, seconds = divide_seconds(elapsed_whole_seconds) sprintf TIME_FORMAT, hours, minutes, seconds end end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/components/timer.rb0000644000175000017500000000230012534053362024304 0ustar globusglobusrequire 'ruby-progressbar/time' class ProgressBar module Components module Timer TIME_FORMAT = '%02d:%02d:%02d' def start @started_at = stopped? ? now - (@stopped_at - @started_at) : now @stopped_at = nil end def stop return unless started? @stopped_at = now end def pause stop end def resume start end def started? !!@started_at end def stopped? !!@stopped_at end def reset @started_at = nil @stopped_at = nil end private def now ProgressBar::Time.now end def elapsed_seconds ((@stopped_at || now) - @started_at) end def elapsed_whole_seconds elapsed_seconds.floor end def elapsed_time return '--:--:--' unless started? hours, minutes, seconds = *divide_seconds(elapsed_whole_seconds) sprintf TIME_FORMAT, hours, minutes, seconds end def divide_seconds(seconds) hours, seconds = seconds.divmod(3600) minutes, seconds = seconds.divmod(60) [hours, minutes, seconds] end end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/components/throttle.rb0000644000175000017500000000057212534053362025042 0ustar globusglobusclass ProgressBar module Components class Throttle include Timer def initialize(options = {}) @period = options.delete(:throttle_rate) { 0.01 } || 0.01 end def choke(force = false, &block) if !started? || @period.nil? || force || elapsed_seconds >= @period yield start end end end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/format.rb0000644000175000017500000000012212534053362022267 0ustar globusglobusrequire 'ruby-progressbar/format/molecule' require 'ruby-progressbar/format/base' ruby-progressbar-1.4.2/lib/ruby-progressbar/errors/0000755000175000017500000000000012534053362021773 5ustar globusglobusruby-progressbar-1.4.2/lib/ruby-progressbar/errors/invalid_progress_error.rb0000644000175000017500000000011012534053362027073 0ustar globusglobusclass ProgressBar class InvalidProgressError < RuntimeError end end ruby-progressbar-1.4.2/lib/ruby-progressbar/components.rb0000644000175000017500000000044212534053362023171 0ustar globusglobusrequire 'ruby-progressbar/components/timer' require 'ruby-progressbar/components/progressable' require 'ruby-progressbar/components/bar' require 'ruby-progressbar/components/estimated_timer' require 'ruby-progressbar/components/elapsed_timer' require 'ruby-progressbar/components/throttle' ruby-progressbar-1.4.2/lib/ruby-progressbar/format/0000755000175000017500000000000012534053362021747 5ustar globusglobusruby-progressbar-1.4.2/lib/ruby-progressbar/format/base.rb0000644000175000017500000000307512534053362023213 0ustar globusglobusclass ProgressBar module Format class Base attr_reader :molecules def initialize(format_string) @format_string = format_string @molecules = parse(format_string) end def process(environment) processed_string = @format_string.dup ansi_sgr_codes = %r{\e\[[\d;]+m} non_bar_molecules.each do |molecule| processed_string.gsub!("%#{molecule.key}", environment.send(molecule.method_name).to_s) end remaining_molecules = bar_molecules.size placeholder_length = remaining_molecules * 2 processed_string.gsub! '%%', '%' processed_string_length = processed_string.gsub(ansi_sgr_codes, '').length leftover_bar_length = environment.send(:length) - processed_string_length + placeholder_length leftover_bar_length = leftover_bar_length < 0 ? 0 : leftover_bar_length bar_molecules.each do |molecule| processed_string.gsub!("%#{molecule.key}", environment.send(molecule.method_name, leftover_bar_length).to_s) end processed_string end private def non_bar_molecules @non_bar_molecules ||= molecules.select { |molecule| !molecule.bar_molecule? } end def bar_molecules @bar_molecules ||= molecules.select { |molecule| molecule.bar_molecule? } end def parse(format_string) molecules = [] format_string.scan(/%[a-zA-Z]/) do |match| molecules << Molecule.new(match[1,1]) end molecules end end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/format/molecule.rb0000644000175000017500000000271612534053362024107 0ustar globusglobusclass ProgressBar module Format class Molecule MOLECULES = { :t => [:left_justified_title, :title], :T => [:right_justified_title, :title], :c => [:current_progress, :progress], :C => [:total_capacity, :total], :p => [:percentage_complete_as_integer, :percentage], :P => [:percentage_complete_as_float, :percentage_with_precision], :a => [:elapsed_time, :elapsed_time], :e => [:estimated_time_with_unknown, :estimated_time_with_unknown_oob], :E => [:estimated_time_with_greater_than, :estimated_time_with_friendly_oob], :f => [:force_estimated_time, :estimated_time_with_no_oob], :B => [:complete_bar, :complete_bar], :b => [:bar, :bar], :w => [:bar_with_percentage, :bar_with_percentage], :i => [:incomplete_space, :incomplete_space] } BAR_MOLECULES = %w{w B b i} attr_reader :key attr_reader :method_name attr_reader :method_arguments def initialize(letter) @key = letter @description, @method_name, @method_arguments = MOLECULES.fetch(@key.to_sym) end def bar_molecule? BAR_MOLECULES.include? @key end end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/length_calculator.rb0000644000175000017500000000250312534053362024476 0ustar globusglobusclass ProgressBar module LengthCalculator def initialize(options) @length_override = ENV['RUBY_PROGRESS_BAR_LENGTH'] || options[:length] @length_override = @length_override.to_i if @length_override super() end private def length @current_length || reset_length end def length_changed? @current_length != calculate_length end def calculate_length @length_override || terminal_width || 80 end def reset_length @current_length = calculate_length end # This code was copied and modified from Rake, available under MIT-LICENSE # Copyright (c) 2003, 2004 Jim Weirich def terminal_width return 80 unless unix? result = dynamic_width (result < 20) ? 80 : result rescue 80 end begin require 'io/console' def dynamic_width rows, columns = IO.console.winsize columns end rescue LoadError def dynamic_width dynamic_width_stty.nonzero? || dynamic_width_tput end def dynamic_width_stty %x{stty size 2>/dev/null}.split[1].to_i end def dynamic_width_tput %x{tput cols 2>/dev/null}.to_i end end def unix? RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/time.rb0000644000175000017500000000074412534053362021747 0ustar globusglobusclass ProgressBar class Time def self.now(time = ::Time) @@time = time @@time.send unmocked_time_method end private def self.unmocked_time_method time_mocking_library_methods.find { |method| @@time.respond_to? method } end def self.time_mocking_library_methods [ :now_without_mock_time, # Timecop :now_without_delorean, # Delorean :now # Actual ] end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/version.rb0000644000175000017500000000005212534053362022466 0ustar globusglobusclass ProgressBar VERSION = '1.4.2' end ruby-progressbar-1.4.2/lib/ruby-progressbar/running_average_calculator.rb0000644000175000017500000000036012534053362026366 0ustar globusglobusclass ProgressBar class RunningAverageCalculator def self.calculate(current_average, new_value_to_average, smoothing_factor) new_value_to_average * (1.0 - smoothing_factor) + current_average * smoothing_factor end end end ruby-progressbar-1.4.2/lib/ruby-progressbar/formatter.rb0000644000175000017500000000367112534053362023016 0ustar globusglobusclass ProgressBar module Formatter DEFAULT_FORMAT_STRING = '%t: |%B|' DEFAULT_NON_TTY_FORMAT_STRING = '%t: |%b|' DEFAULT_TITLE = 'Progress' def initialize(options) self.format_string = options[:format] || DEFAULT_FORMAT_STRING @title = options[:title] || DEFAULT_TITLE super(options) end def format(new_format_string = DEFAULT_FORMAT_STRING) self.format_string = new_format_string @format.process(self) end def title=(title) @title = title end def progress @bar.progress end def total @bar.total end private def format_string=(format_string) if @format_string != format_string @format_string = format_string @format = ProgressBar::Format::Base.new(format_string) end end # Format Methods def title @title end def percentage @bar.percentage_completed end def percentage_with_precision @bar.percentage_completed_with_precision end def elapsed_time @elapsed_time end def estimated_time_with_no_oob @estimated_time.out_of_bounds_time_format = nil estimated_time end def estimated_time_with_unknown_oob @estimated_time.out_of_bounds_time_format = :unknown estimated_time end def estimated_time_with_friendly_oob @estimated_time.out_of_bounds_time_format = :friendly estimated_time end def bar(length) @bar.length = length @bar.standard_complete_string end def complete_bar(length) @bar.length = length @bar.to_s end def incomplete_space(length) @bar.length = length @bar.empty_string end def bar_with_percentage(length) @bar.length = length @bar.integrated_percentage_complete_string end def estimated_time finished? ? @elapsed_time : @estimated_time end end end ruby-progressbar-1.4.2/lib/ruby-progressbar.rb0000644000175000017500000000050612534053362021005 0ustar globusglobusrequire 'ruby-progressbar/length_calculator' require 'ruby-progressbar/running_average_calculator' require 'ruby-progressbar/formatter' require 'ruby-progressbar/components' require 'ruby-progressbar/format' require 'ruby-progressbar/base' class ProgressBar def self.create(*args) ProgressBar::Base.new *args end end ruby-progressbar-1.4.2/spec/0000755000175000017500000000000012534053362015333 5ustar globusglobusruby-progressbar-1.4.2/spec/lib/0000755000175000017500000000000012534053362016101 5ustar globusglobusruby-progressbar-1.4.2/spec/lib/ruby-progressbar/0000755000175000017500000000000012534053362021411 5ustar globusglobusruby-progressbar-1.4.2/spec/lib/ruby-progressbar/components/0000755000175000017500000000000012534053362023576 5ustar globusglobusruby-progressbar-1.4.2/spec/lib/ruby-progressbar/components/throttle_spec.rb0000644000175000017500000000433112534053362027003 0ustar globusglobusrequire 'spec_helper' require 'timecop' describe ProgressBar::Components::Throttle do context 'given a numeric period' do before do Timecop.freeze(0) { @throttle = ProgressBar::Components::Throttle.new(:throttle_rate => 10) } end describe '#choke' do it 'yields the first time' do yielded = false @throttle.choke { yielded = true } yielded.should be_true end context 'after initial yield' do before do Timecop.freeze(0) { @throttle.choke { } } end it "doesn't yield if period hasn't passed yet" do yielded = false (1..9).each do |t| Timecop.freeze(t) { @throttle.choke { yielded = true } } yielded.should be_false end end it 'always yields if passed true' do yielded = -1 (0..25).each do |t| Timecop.freeze(t) { @throttle.choke(true) { yielded += 1 } } yielded.should == t end end it "yields after period has passed" do yielded = false Timecop.freeze(15) { @throttle.choke { yielded = true } } yielded.should be_true end end context 'after a yield' do before do Timecop.freeze(0) { @throttle.choke { } } Timecop.freeze(15) { @throttle.choke { } } end it "doesn't yield if period hasn't passed yet" do yielded = false (16..24).each do |t| Timecop.freeze(t) { @throttle.choke { yielded = true } } yielded.should be_false end end it "yields after period has passed" do yielded = false Timecop.freeze(25) { @throttle.choke { yielded = true } } yielded.should be_true end end end end context 'given no throttle period' do before do Timecop.freeze(0) { @throttle = ProgressBar::Components::Throttle.new() } end describe '#choke' do it 'yields every time' do yielded = -1 (0..25).each do |t| Timecop.freeze(t) { @throttle.choke { yielded += 1 } } yielded.should == t end end end end end ruby-progressbar-1.4.2/spec/lib/ruby-progressbar/components/elapsed_timer_spec.rb0000644000175000017500000000411712534053362027755 0ustar globusglobusrequire 'spec_helper' describe ProgressBar::Components::ElapsedTimer do before { @timer = ProgressBar::Components::ElapsedTimer.new } describe '#to_s' do context 'when the timer has not been started' do it 'displays "Time: --:--:--"' do @timer.to_s.should eql 'Time: --:--:--' end end context 'when it has just been started' do it 'displays "Time: 00:00:00"' do @timer.start @timer.to_s.should eql 'Time: 00:00:00' end end context 'when it was started 4 hours, 28 minutes and 13 seconds ago' do before do Timecop.travel(-16093) do @timer.start end end context 'and it was stopped 32 seconds ago' do before do Timecop.travel(-32) do @timer.stop end end context 'and #reset is called' do before { @timer.reset } it 'displays "Time: --:--:--"' do @timer.to_s.should eql 'Time: --:--:--' end end it 'displays "Time: 04:27:41"' do @timer.to_s.should eql 'Time: 04:27:41' end end context 'and #reset is called' do before { @timer.reset } it 'displays "Time: --:--:--"' do @timer.to_s.should eql 'Time: --:--:--' end end it 'displays "Time: 04:28:13"' do @timer.to_s.should eql 'Time: 04:28:13' end end end describe '#stopped?' do context 'when the timer is started' do before { @timer.start } context 'and then it is stopped' do before { @timer.stop } context 'and then it is restarted' do before { @timer.start } it 'is false' do @timer.should_not be_stopped end end end end context "when the timer has yet to be started" do it 'is false' do @timer.should_not be_stopped end end context "when the timer is stopped without having been started" do before { @timer.stop } it 'is false' do @timer.should_not be_stopped end end end end ruby-progressbar-1.4.2/spec/lib/ruby-progressbar/components/estimated_timer_spec.rb0000644000175000017500000001724112534053362030321 0ustar globusglobusrequire 'spec_helper' describe ProgressBar::Components::EstimatedTimer do describe '#progress=' do it 'raises an error when passed a number larger than the total' do @estimated_time = ProgressBar::Components::EstimatedTimer.new(:total => 100) lambda{ @estimated_time.progress = 101 }.should raise_error(ProgressBar::InvalidProgressError, "You can't set the item's current value to be greater than the total.") end end describe '#to_s' do context 'when the timer has been started but no progress has been made' do before do @estimated_time = ProgressBar::Components::EstimatedTimer.new(:total => 100) @estimated_time.start end it 'displays an unknown time remaining' do @estimated_time.to_s.should eql ' ETA: ??:??:??' end context 'and it is incremented' do it 'should not display unknown time remaining' do @estimated_time.increment @estimated_time.to_s.should_not eql ' ETA: ??:??:??' end end end context 'when half the progress has been made' do context 'and smoothing is turned off' do let(:smoothing) { 0.0 } context 'and it took 3:42:12 to do it' do before do @estimated_time = ProgressBar::Components::EstimatedTimer.new(:starting_at => 0, :total => 100, :smoothing => smoothing) Timecop.travel(-13332) do @estimated_time.start 50.times { @estimated_time.increment } end end context 'when #decrement is called' do before { 20.times { @estimated_time.decrement } } it 'displays the correct time remaining' do @estimated_time.to_s.should eql ' ETA: 08:38:28' end end context 'when #reset is called' do before { @estimated_time.reset } it 'displays unknown time remaining' do @estimated_time.to_s.should eql ' ETA: ??:??:??' end end it 'displays the correct time remaining' do @estimated_time.to_s.should eql ' ETA: 03:42:12' end end context 'when it is estimated to take longer than 99:59:59' do before do @estimated_time = ProgressBar::Components::EstimatedTimer.new(:starting_at => 0, :total => 100, :smoothing => smoothing) Timecop.travel(-120000) do @estimated_time.start 25.times { @estimated_time.increment } end end context 'and the out of bounds time format has been set to "friendly"' do before { @estimated_time.out_of_bounds_time_format = :friendly } it 'displays "> 4 Days" remaining' do @estimated_time.to_s.should eql ' ETA: > 4 Days' end end context 'and the out of bounds time format has been set to "unknown"' do before { @estimated_time.out_of_bounds_time_format = :unknown } it 'displays "??:??:??" remaining' do @estimated_time.to_s.should eql ' ETA: ??:??:??' end end it 'displays the correct time remaining' do @estimated_time.to_s.should eql ' ETA: 100:00:00' end end end context 'and smoothing is turned on' do let(:smoothing) { 0.5 } context 'and it took 3:42:12 to do it' do before do @estimated_time = ProgressBar::Components::EstimatedTimer.new(:starting_at => 0, :total => 100, :smoothing => smoothing) Timecop.travel(-13332) do @estimated_time.start 50.times { @estimated_time.increment } end end context 'when #decrement is called' do before { 20.times { @estimated_time.decrement } } it 'displays the correct time remaining' do @estimated_time.to_s.should eql ' ETA: 08:14:34' end end context 'when #reset is called' do before { @estimated_time.reset } it 'displays unknown time remaining' do @estimated_time.to_s.should eql ' ETA: ??:??:??' end end it 'displays the correct time remaining' do @estimated_time.to_s.should eql ' ETA: 03:51:16' end end context 'when it is estimated to take longer than 99:59:59' do before do @estimated_time = ProgressBar::Components::EstimatedTimer.new(:starting_at => 0, :total => 100, :smoothing => smoothing) Timecop.travel(-120000) do @estimated_time.start 25.times { @estimated_time.increment } end end context 'and the out of bounds time format has been set to "friendly"' do before { @estimated_time.out_of_bounds_time_format = :friendly } it 'displays "> 4 Days" remaining' do @estimated_time.to_s.should eql ' ETA: > 4 Days' end end context 'and the out of bounds time format has been set to "unknown"' do before { @estimated_time.out_of_bounds_time_format = :unknown } it 'displays "??:??:??" remaining' do @estimated_time.to_s.should eql ' ETA: ??:??:??' end end it 'displays the correct time remaining' do @estimated_time.to_s.should eql ' ETA: 105:33:20' end end end end it 'displays a good estimate for regular increments' do begin Timecop.freeze(t = Time.now) n = 10 estimated_time = ProgressBar::Components::EstimatedTimer.new(:total => n) estimated_time.start results = (1..n).map do |i| Timecop.freeze(t + 0.5 * i) estimated_time.increment estimated_time.to_s end results.should == [ ' ETA: 00:00:05', ' ETA: 00:00:04', ' ETA: 00:00:04', ' ETA: 00:00:03', ' ETA: 00:00:03', ' ETA: 00:00:02', ' ETA: 00:00:02', ' ETA: 00:00:01', ' ETA: 00:00:01', ' ETA: 00:00:00', ] ensure Timecop.return end end end describe '#out_of_bounds_time_format=' do context 'when set to an invalid format' do it 'raises an exception' do @estimated_time = ProgressBar::Components::EstimatedTimer.new(:total => 100) lambda{ @estimated_time.out_of_bounds_time_format = :foo }.should raise_error('Invalid Out Of Bounds time format. Valid formats are [:unknown, :friendly, nil]') end end end describe '#start' do ### # Using ruby-debug under jruby pulls in ruby-debug-base, which defines # Kernel.start. This causes a bug, as EstimatedTimer::As::method_missing calls # Kernel.start instead of EstimatedTimer.start. This spec duplicates the bug. # Without the fix, this results in the following exception: # # 1) ruby-debug-base doesn't stop the progressbar from working # Failure/Error: COUNT.times { bar.increment } # NoMethodError: # undefined method `+' for nil:NilClass # # ./lib/ruby-progressbar/components/progressable.rb:33:in `increment' # it 'properly delegates' do @output = StringIO.new('', 'w+') module Kernel def start(options={}, &block) puts "Kernel.start has been called" return nil end end begin COUNT = 100 bar = ProgressBar.create(:output => @output, :title => 'ruby-debug-base', :total => COUNT) COUNT.times { bar.increment } ensure module Kernel remove_method :start end end end end end ruby-progressbar-1.4.2/spec/lib/ruby-progressbar/components/progressable_spec.rb0000644000175000017500000000172312534053362027630 0ustar globusglobusrequire 'spec_helper' class ProgressableClass include ProgressBar::Components::Progressable end describe ProgressBar::Components::Progressable do subject { ProgressableClass.new } describe '#running_average' do it 'is always reset when the progressable is started' do subject.running_average = 10 subject.start :at => 0 subject.running_average.should be_zero subject.start :at => 40 subject.running_average.should eql 36.0 end end describe '#smoothing' do it 'can be passed in as an option to the initializer' do ProgressableClass.new(:smoothing => 0.3).smoothing.should eql 0.3 end it 'does not have to be passed in as an option to the initializer' do ProgressableClass.new.smoothing.should eql 0.1 end end describe '#percentage_completed' do it 'returns the default total if total is zero' do subject.total = 0 subject.percentage_completed.should eql 100 end end end ruby-progressbar-1.4.2/spec/lib/ruby-progressbar/components/bar_spec.rb0000644000175000017500000001416312534053362025706 0ustar globusglobusrequire 'spec_helper' describe ProgressBar::Components::Bar do context 'when a new bar is created' do context 'and no parameters are passed' do before { @progressbar = ProgressBar::Components::Bar.new } describe '#total' do it 'returns the default total' do @progressbar.total.should eql ProgressBar::Components::Bar::DEFAULT_TOTAL end end describe '#progress_mark' do it 'returns the default mark' do @progressbar.progress_mark.should eql ProgressBar::Components::Bar::DEFAULT_PROGRESS_MARK end end describe '#remainder_mark' do it 'returns the default remainder mark' do @progressbar.remainder_mark.should eql ProgressBar::Components::Bar::DEFAULT_REMAINDER_MARK end end context 'and the bar has not been started' do describe '#progress' do it 'returns the default beginning position' do @progressbar.progress.should be_zero end end end context 'and the bar has been started with no starting value given' do before { @progressbar.start } describe '#progress' do it 'returns the default starting value' do @progressbar.progress.should eql ProgressBar::Components::Progressable::DEFAULT_BEGINNING_POSITION end end end context 'and the bar has been started with a starting value' do before { @progressbar.start :at => 10 } describe '#progress' do it 'returns the given starting value' do @progressbar.progress.should eql 10 end end end end context 'and options are passed' do before { @progressbar = ProgressBar::Components::Bar.new(:total => 12, :progress_mark => 'x', :remainder_mark => '.') } describe '#total' do it 'returns the overridden total' do @progressbar.total.should eql 12 end end describe '#progress_mark' do it 'returns the overridden mark' do @progressbar.progress_mark.should eql 'x' end end describe '#remainder_mark' do it 'returns the overridden mark' do @progressbar.remainder_mark.should eql '.' end end end end context 'when just begun' do before do @progressbar = ProgressBar::Components::Bar.new(:total => 50) @progressbar.length = 100 @progressbar.start end describe '#percentage_completed' do it 'calculates the amount' do @progressbar.percentage_completed.should eql 0 end end describe '#to_s' do it 'displays the bar with no indication of progress' do @progressbar.to_s.should eql ' ' end end end context 'when nothing has been completed' do before do @progressbar = ProgressBar::Components::Bar.new(:total => 50) @progressbar.length = 100 @progressbar.start end context 'and the bar is incremented' do before { @progressbar.increment } it 'adds to the progress amount' do @progressbar.progress.should eql 1 end describe '#percentage_completed' do it 'calculates the amount completed' do @progressbar.percentage_completed.should eql 2 end end describe '#to_s' do it 'displays the bar with an indication of progress' do @progressbar.to_s.should eql '== ' end end end describe '#percentage_completed' do it 'is zero' do @progressbar.percentage_completed.should eql 0 end end describe '#to_s' do it 'displays the bar with no indication of progress' do @progressbar.to_s.should eql ' ' end end end context 'when a fraction of a percentage has been completed' do before do @progressbar = ProgressBar::Components::Bar.new(:total => 200) @progressbar.length = 100 @progressbar.start :at => 1 end describe '#percentage_completed' do it 'always rounds down' do @progressbar.percentage_completed.should eql 0 end end describe '#to_s' do it 'displays the bar with no indication of progress' do @progressbar.to_s.should eql ' ' end end end context 'when completed' do before do @progressbar = ProgressBar::Components::Bar.new(:total => 50) @progressbar.length = 100 @progressbar.start :at => 50 end context 'and the bar is incremented' do before { @progressbar.increment } it 'does not increment past the total' do @progressbar.progress.should eql 50 @progressbar.percentage_completed.should eql 100 end describe '#to_s' do it 'displays the bar as 100% complete' do @progressbar.to_s.should eql '=' * 100 end end end context 'and the bar is decremented' do before { @progressbar.decrement } it 'removes some progress from the bar' do @progressbar.progress.should eql 49 @progressbar.percentage_completed.should eql 98 end describe '#to_s' do it 'displays the bar as 98% complete' do @progressbar.to_s.should eql "#{'=' * 98} " end end end describe '#to_s' do it 'displays the bar as 100% complete' do @progressbar.to_s.should eql ('=' * 100) end end end context "when attempting to set the bar's current value to be greater than the total" do describe '#new' do it 'raises an error' do @progressbar = ProgressBar::Components::Bar.new(:total => 10) lambda { @progressbar.start :at => 11 }.should raise_error(ProgressBar::InvalidProgressError, "You can't set the item's current value to be greater than the total.") end end end end ruby-progressbar-1.4.2/spec/lib/ruby-progressbar/base_spec.rb0000644000175000017500000006237612534053362023700 0ustar globusglobusrequire 'spec_helper' require 'stringio' describe ProgressBar::Base do let(:output) do StringIO.new('', 'w+').tap do |io| io.stub(:tty?).and_return true end end let(:non_tty_output) do StringIO.new('', 'w+').tap do |io| io.stub(:tty?).and_return false end end let(:progressbar) { ProgressBar::Base.new(:output => output, :length => 80, :throttle_rate => 0.0) } context 'when the terminal width is shorter than the string being output' do it 'can properly handle outputting the bar when the length changes on the fly to less than the minimum width' do progressbar = ProgressBar::Base.new(:output => output, :title => 'a' * 25, :format => '%t%B', :throttle_rate => 0.0) allow(progressbar).to receive(:terminal_width). and_return 30 progressbar.start allow(progressbar).to receive(:terminal_width). and_return 20 progressbar.increment output.rewind output.read.should match /\raaaaaaaaaaaaaaaaaaaaaaaaa \r\s+\raaaaaaaaaaaaaaaaaaaaaaaaa\r\z/ end context 'and the bar length is calculated' do it 'returns the proper string' do progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21), :starting_at => 5, :total => 10, :autostart => false) allow(progressbar).to receive(:terminal_width). and_return 20 progressbar.to_s('%t%w').should eql '*********************' end end context 'and the incomplete bar length is calculated' do it 'returns the proper string' do progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21), :autostart => false) allow(progressbar).to receive(:terminal_width). and_return 20 progressbar.to_s('%t%i').should eql '*********************' end it 'returns the proper string' do progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21), :starting_at => 5, :total => 10, :autostart => false) allow(progressbar).to receive(:terminal_width). and_return 20 progressbar.to_s('%t%i').should eql '*********************' end end context 'and the full bar length is calculated (but lacks the space to output the entire bar)' do it 'returns the proper string' do progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 19), :starting_at => 5, :total => 10, :autostart => false) allow(progressbar).to receive(:terminal_width). and_return 20 progressbar.to_s('%t%B').should eql '******************* ' end it 'returns the proper string' do progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 19), :starting_at => 5, :total => 10, :autostart => false) allow(progressbar).to receive(:terminal_width). and_return 20 progressbar.to_s('%t%w%i').should eql '******************* ' end end end context 'when a new bar is created' do context 'and no options are passed' do let(:progressbar) { ProgressBar::Base.new } describe '#title' do it 'returns the default title' do progressbar.send(:title).to_s.should eql ProgressBar::Base::DEFAULT_TITLE end end describe '#output' do it 'returns the default output stream' do progressbar.send(:output).should eql ProgressBar::Base::DEFAULT_OUTPUT_STREAM end end describe '#length' do context 'when the RUBY_PROGRESS_BAR_LENGTH environment variable exists' do before { ENV['RUBY_PROGRESS_BAR_LENGTH'] = '44' } after { ENV['RUBY_PROGRESS_BAR_LENGTH'] = nil } it 'returns the length of the environment variable as an integer' do progressbar = ProgressBar::Base.new progressbar.send(:length).should eql 44 end end context 'when the RUBY_PROGRESS_BAR_LENGTH environment variable does not exist' do before { ENV['RUBY_PROGRESS_BAR_LENGTH'] = nil } context 'but the length option was passed in' do it 'returns the length specified in the option' do progressbar = ProgressBar::Base.new(:length => 88) progressbar.send(:length).should eql 88 end end context 'and no length option was passed in' do it 'returns the width of the terminal if it is a Unix environment' do progressbar.stub(:terminal_width).and_return(99) progressbar.send(:reset_length) progressbar.send(:length).should eql 99 end it 'returns 80 if it is not a Unix environment' do progressbar.stub(:unix?).and_return(false) progressbar.send(:reset_length) progressbar.send(:length).should eql 80 end end end end end context 'and options are passed' do let(:progressbar) { ProgressBar::Base.new(:title => 'We All Float', :total => 12, :output => STDOUT, :progress_mark => 'x', :length => 88, :starting_at => 5) } describe '#title' do it 'returns the overridden title' do progressbar.send(:title).to_s.should eql 'We All Float' end end describe '#output' do it 'returns the overridden output stream' do progressbar.send(:output).should eql STDOUT end end describe '#length' do it 'returns the overridden length' do progressbar.send(:length).should eql 88 end end end context 'if the bar was started 4 minutes ago' do before do Timecop.travel(-240) do progressbar.start end end context 'and within 2 minutes it was halfway done' do before do Timecop.travel(-120) do 50.times { progressbar.increment } end end describe '#finish' do before do Timecop.travel(-120) do progressbar.finish end end it 'completes the bar' do output.rewind output.read.should match /Progress: \|#{'=' * 68}\|\n/ end it 'shows the elapsed time instead of the estimated time since the bar is completed' do progressbar.to_s('%e').should eql 'Time: 00:02:00' end it 'calculates the elapsed time to 00:02:00' do progressbar.to_s('%a').should eql 'Time: 00:02:00' end end end end context 'which includes ANSI SGR codes in the format string' do it 'properly calculates the length of the bar by removing the long version of the ANSI codes from the calculated length' do @color_code = "\e[0m\e[32m\e[7m\e[1m" @reset_code = "\e[0m" @progress_mark = "#{@color_code} #{@reset_code}" progressbar = ProgressBar::Base.new(:format => "#{@color_code}Processing... %b%i#{@reset_code}#{@color_code} %p%%#{@reset_code}", :progress_mark => @progress_mark, :output => output, :length => 24, :starting_at => 3, :total => 6, :throttle_rate => 0.0) progressbar.increment progressbar.increment output.rewind output.read.should include "#{@color_code}Processing... #{@progress_mark * 3}#{' ' * 3}#{@reset_code}#{@color_code} 50%#{@reset_code}\r#{@color_code}Processing... #{@progress_mark * 3}#{' ' * 3}#{@reset_code}#{@color_code} 66%#{@reset_code}\r#{@color_code}Processing... #{@progress_mark * 4}#{' ' * 2}#{@reset_code}#{@color_code} 83%#{@reset_code}\r" end it 'properly calculates the length of the bar by removing the short version of the ANSI codes from the calculated length' do @color_code = "\e[0;32;7;1m" @reset_code = "\e[0m" @progress_mark = "#{@color_code} #{@reset_code}" progressbar = ProgressBar::Base.new(:format => "#{@color_code}Processing... %b%i#{@reset_code}#{@color_code} %p%%#{@reset_code}", :progress_mark => @progress_mark, :output => output, :length => 24, :starting_at => 3, :total => 6, :throttle_rate => 0.0) progressbar.increment progressbar.increment output.rewind output.read.should include "#{@color_code}Processing... #{@progress_mark * 3}#{' ' * 3}#{@reset_code}#{@color_code} 50%#{@reset_code}\r#{@color_code}Processing... #{@progress_mark * 3}#{' ' * 3}#{@reset_code}#{@color_code} 66%#{@reset_code}\r#{@color_code}Processing... #{@progress_mark * 4}#{' ' * 2}#{@reset_code}#{@color_code} 83%#{@reset_code}\r" end end context 'for a TTY enabled device' do it 'can log messages' do progressbar = ProgressBar::Base.new(:output => output, :length => 20, :starting_at => 3, :total => 6, :throttle_rate => 0.0) progressbar.increment progressbar.log 'We All Float' progressbar.increment output.rewind output.read.should include "Progress: |==== |\rProgress: |===== |\r \rWe All Float\nProgress: |===== |\rProgress: |====== |\r" end end context 'for a non-TTY enabled device' do it 'can log messages' do progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 4, :total => 6, :throttle_rate => 0.0) progressbar.increment progressbar.log 'We All Float' progressbar.increment progressbar.finish non_tty_output.rewind non_tty_output.read.should include "We All Float\nProgress: |========|\n" end it 'can output the bar properly so that it does not spam the screen' do progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0) 6.times { progressbar.increment } non_tty_output.rewind non_tty_output.read.should eql "\n\nProgress: |========|\n" end it 'can output the bar properly if finished in the middle of its progress' do progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0) 3.times { progressbar.increment } progressbar.finish non_tty_output.rewind non_tty_output.read.should eql "\n\nProgress: |========|\n" end it 'can output the bar properly if stopped in the middle of its progress' do progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0) 3.times { progressbar.increment } progressbar.stop non_tty_output.rewind non_tty_output.read.should eql "\n\nProgress: |====\n" end end end context 'when a bar is about to be completed' do let(:progressbar) { ProgressBar::Base.new(:starting_at => 5, :total => 6, :output => output, :length => 20) } context 'and it is incremented' do before { progressbar.increment } it 'registers as being "finished"' do progressbar.should be_finished end it 'prints a new line' do output.rewind output.read.end_with?("\n").should be_true end it 'does not continue to print bars if finish is subsequently called' do progressbar.finish output.rewind output.read.should end_with " \rProgress: |====== |\rProgress: |========|\n" end end end context 'when a bar has an unknown amount to completion' do let(:progressbar) { ProgressBar::Base.new(:total => nil, :output => output, :length => 80, :unknown_progress_animation_steps => ['=--', '-=-', '--=']) } it 'is represented correctly' do progressbar.to_s('%i').should eql '=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=-' end it 'is represented after being incremented once' do progressbar.increment progressbar.to_s('%i').should eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=' end it 'is represented after being incremented twice' do progressbar.increment progressbar.increment progressbar.to_s('%i').should eql '--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--' end it 'displays the proper ETA' do progressbar.increment progressbar.to_s('%i%e').should eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=- ETA: ??:??:??' progressbar.to_s('%i%E').should eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=- ETA: ??:??:??' end end context 'when a bar is started' do let(:progressbar) { ProgressBar::Base.new(:starting_at => 0, :total => 100, :output => output, :length => 80, :throttle_rate => 0.0) } context 'and it is incremented any number of times' do before { 10.times { progressbar.increment } } describe '#progress_mark=' do it 'changes the mark used to represent progress and updates the output' do progressbar.progress_mark = 'x' output.rewind output.read.should match /\rProgress: \|xxxxxx#{' ' * 62}\|\r\z/ end end describe '#remainder_mark=' do it 'changes the mark used to represent the remaining part of the bar and updates the output' do progressbar.remainder_mark = 'x' output.rewind output.read.should match /\rProgress: \|======#{'x' * 62}\|\r\z/ end end describe '#title=' do it 'changes the title used to represent the items being progressed and updates the output' do progressbar.title = 'Items' output.rewind output.read.should match /\rItems: \|=======#{' ' * 64}\|\r\z/ end end describe '#reset' do before { progressbar.reset } it 'resets the bar back to the starting value' do output.rewind output.read.should match /\rProgress: \|#{' ' * 68}\|\r\z/ end end describe '#stop' do before { progressbar.stop } it 'forcibly halts the bar wherever it is and cancels it' do output.rewind output.read.should match /\rProgress: \|======#{' ' * 62}\|\n\z/ end it 'does not output the bar multiple times if the bar is already stopped' do output.rewind progressbar.stop output.rewind output.read.should_not start_with "Progress: |======#{' ' * 62}|" end end describe '#resume' do it 'does not output the bar multiple times' do output.rewind progressbar.resume output.rewind output.read.should_not start_with "Progress: |======#{' ' * 62}|" end end end end context 'when a bar is started from 10/100' do let(:progressbar) { ProgressBar::Base.new(:starting_at => 10, :total => 100, :output => output, :length => 112) } context 'and it is incremented any number of times' do before { 10.times { progressbar.increment } } describe '#reset' do before { progressbar.reset } it 'resets the bar back to the starting value' do output.rewind output.read.should match /\rProgress: \|==========#{' ' * 90}\|\r\z/ end end end end describe '#clear' do it 'clears the current terminal line and/or bar text' do progressbar.clear output.rewind output.read.should match /^#{progressbar.send(:clear_string)}/ end end describe '#start' do it 'clears the current terminal line' do progressbar.start output.rewind output.read.should match /^#{progressbar.send(:clear_string)}/ end it 'prints the bar for the first time' do progressbar.start output.rewind output.read.should match /Progress: \| \|\r\z/ end it 'prints correctly if passed a position to start at' do progressbar.start(:at => 20) output.rewind output.read.should match /Progress: \|============= \|\r\z/ end end context 'when the bar has not been completed' do let(:progressbar) { ProgressBar::Base.new(:length => 112, :starting_at => 0, :total => 50, :output => output, :throttle_rate => 0.0) } describe '#increment' do before { progressbar.increment } it 'displays the bar with the correct formatting' do output.rewind output.read.should match /Progress: \|== \|\r\z/ end end end context 'when a new bar is created with a specific format' do context '#format' do let(:progressbar) { ProgressBar::Base.new(:format => '%B %p%%') } context 'if called with no arguments' do before { progressbar.format } it 'resets the format back to the default' do progressbar.to_s.should match /^Progress: \|\s+\|\z/ end end context 'if called with a specific format string' do before { progressbar.format '%t' } it 'sets it as the new format for the bar' do progressbar.to_s.should match /^Progress\z/ end end end context '#to_s' do it 'displays the title when passed the "%t" format flag' do progressbar.to_s('%t').should match /^Progress\z/ end it 'displays the title when passed the "%T" format flag' do progressbar.to_s('%T').should match /^Progress\z/ end it 'displays the bar when passed the "%B" format flag (including empty space)' do progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20) progressbar.to_s('%B').should match /^#{'=' * 20}#{' ' * 80}\z/ end it 'displays the bar when passed the combined "%b%i" format flags' do progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20) progressbar.to_s('%b%i').should match /^#{'=' * 20}#{' ' * 80}\z/ end it 'displays the bar when passed the "%b" format flag (excluding empty space)' do progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20) progressbar.to_s('%b').should match /^#{'=' * 20}\z/ end it 'displays the incomplete space when passed the "%i" format flag' do progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20) progressbar.to_s('%i').should match /^#{' ' * 80}\z/ end it 'displays the bar when passed the "%w" format flag' do progressbar = ProgressBar::Base.new(:output => output, :length => 100, :starting_at => 0) progressbar.to_s('%w').should match /^\z/ 4.times { progressbar.increment } progressbar.to_s('%w').should match /^====\z/ progressbar.increment progressbar.to_s('%w').should match /^= 5 =\z/ 5.times { progressbar.increment } progressbar.to_s('%w').should match /^=== 10 ===\z/ progressbar.decrement progressbar.to_s('%w').should match /^=== 9 ===\z/ 91.times { progressbar.increment } progressbar.to_s('%w').should match /^#{'=' * 47} 100 #{'=' * 48}\z/ end it 'calculates the remaining negative space properly with an integrated percentage bar of 0 percent' do progressbar = ProgressBar::Base.new(:output => output, :length => 100, :total => 200, :starting_at => 0) progressbar.to_s('%w%i').should match /^\s{100}\z/ 9.times { progressbar.increment } progressbar.to_s('%w%i').should match /^====\s{96}\z/ progressbar.increment progressbar.to_s('%w%i').should match /^= 5 =\s{95}\z/ end it 'displays the current capacity when passed the "%c" format flag' do progressbar = ProgressBar::Base.new(:output => output, :starting_at => 0) progressbar.to_s('%c').should match /^0\z/ progressbar.increment progressbar.to_s('%c').should match /^1\z/ progressbar.decrement progressbar.to_s('%c').should match /^0\z/ end it 'displays the total capacity when passed the "%C" format flag' do progressbar = ProgressBar::Base.new(:total => 100) progressbar.to_s('%C').should match /^100\z/ end it 'displays the percentage complete when passed the "%p" format flag' do progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200) progressbar.to_s('%p').should match /^16\z/ end it 'displays the percentage complete when passed the "%P" format flag' do progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200) progressbar.to_s('%P').should match /^16.50\z/ end it 'displays only up to 2 decimal places when using the "%P" flag' do progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99) progressbar.to_s('%P').should match /^66.66\z/ end it 'displays a literal percent sign when using the "%%" flag' do progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99) progressbar.to_s('%%').should match /^%\z/ end it 'displays a literal percent sign when using the "%%" flag' do progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99) progressbar.to_s('%%').should match /^%\z/ end # Autostarting for now. This will be applicable later. # context "when called before #start" do # it "displays unknown time elapsed when using the %a flag" do # progressbar.to_s('%a').should match /^Time: --:--:--\z/ # end # end context 'when called after #start' do before do Timecop.travel(-3723) do progressbar.start end end context 'and the bar is reset' do before { progressbar.reset } it 'displays "??:??:??" until finished when passed the %e flag' do progressbar.to_s('%a').should match /^Time: --:--:--\z/ end end it 'displays the time elapsed when using the "%a" flag' do progressbar.to_s('%a').should match /^Time: 01:02:03\z/ end end context 'when called before #start' do it 'displays unknown time until finished when passed the "%e" flag' do progressbar = ProgressBar::Base.new progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/ end end context 'when called after #start' do let(:progressbar) do Timecop.travel(-3723) do progressbar = ProgressBar::Base.new(:starting_at => 0, :output => output, :smoothing => 0.0) progressbar.start progressbar.progress = 50 progressbar end end context 'and the bar is reset' do before { progressbar.reset } it 'displays "??:??:??" until finished when passed the "%e" flag' do progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/ end end it 'displays the estimated time remaining when using the "%e" flag' do progressbar.to_s('%e').should match /^ ETA: 01:02:03\z/ end end context 'when it could take 100 hours or longer to finish' do let(:progressbar) do Timecop.travel(-120000) do progressbar = ProgressBar::Base.new(:starting_at => 0, :total => 100, :output => output, :smoothing => 0.0) progressbar.start progressbar.progress = 25 progressbar end end it 'displays "> 4 Days" until finished when passed the "%E" flag' do progressbar.to_s('%E').should match /^ ETA: > 4 Days\z/ end it 'displays "??:??:??" until finished when passed the "%e" flag' do progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/ end it 'displays the exact estimated time until finished when passed the "%f" flag' do progressbar.to_s('%f').should match /^ ETA: 100:00:00\z/ end end end end context 'when the bar is started after having total set to 0' do let(:progressbar) { ProgressBar::Base.new(:output => output, :autostart => false) } it 'does not throw an error' do progressbar.total = 0 expect { progressbar.start }.not_to raise_error end end context 'when the bar has no items to process' do context 'and it has not been started' do let(:progressbar) { ProgressBar::Base.new(:started_at => 0, :total => 0, :autostart => false, :smoothing => 0.0, :format => ' %c/%C |%w>%i| %e ', :output => output) } it 'does not throw an error if told to stop' do progressbar.stop expect { progressbar.start }.not_to raise_error end end end end ruby-progressbar-1.4.2/spec/lib/ruby-progressbar/running_average_calculator_spec.rb0000644000175000017500000000071712534053362030340 0ustar globusglobusrequire 'spec_helper' describe ProgressBar::RunningAverageCalculator do describe '.calculate' do it 'calculates properly' do ProgressBar::RunningAverageCalculator.calculate(4.5, 12, 0.1).should be_within(0.001).of 11.25 ProgressBar::RunningAverageCalculator.calculate(8.2, 51, 0.7).should be_within(0.001).of 21.04 ProgressBar::RunningAverageCalculator.calculate(41.8, 100, 0.59).should be_within(0.001).of 65.662 end end end ruby-progressbar-1.4.2/spec/lib/ruby-progressbar/format/0000755000175000017500000000000012534053362022701 5ustar globusglobusruby-progressbar-1.4.2/spec/lib/ruby-progressbar/format/molecule_spec.rb0000644000175000017500000000114112534053362026042 0ustar globusglobusrequire 'spec_helper' describe ProgressBar::Format::Molecule do describe '#new' do before { @molecule = ProgressBar::Format::Molecule.new('e') } it 'sets the key when initialized' do @molecule.key.should eql 'e' end it 'sets the method name when initialized' do @molecule.method_name.should eql :estimated_time_with_unknown_oob end end describe '#bar_molecule?' do it "is true if the molecule's key is a representation of the progress bar graphic" do molecule = ProgressBar::Format::Molecule.new('B') molecule.should be_bar_molecule end end end ruby-progressbar-1.4.2/spec/lib/ruby-progressbar/time_spec.rb0000644000175000017500000000230312534053362023704 0ustar globusglobusrequire 'spec_helper' class TimeMockedWithTimecop def self.now; end def self.now_without_mock_time; end end class TimeMockedWithDelorean def self.now; end def self.now_without_delorean; end end class UnmockedTime def self.now; end end describe ProgressBar::Time do describe '#now' do context 'when Time is being mocked by Timecop' do subject { ProgressBar::Time.now ::TimeMockedWithTimecop } it 'retrieves the unmocked Timecop time' do ::TimeMockedWithTimecop.should_receive(:now_without_mock_time).once ::TimeMockedWithTimecop.should_not_receive(:now) subject end end context 'when Time is being mocked by Delorean' do subject { ProgressBar::Time.now ::TimeMockedWithDelorean } it 'retrieves the unmocked Delorean time' do ::TimeMockedWithDelorean.should_receive(:now_without_delorean).once ::TimeMockedWithDelorean.should_not_receive(:now) subject end end context 'when Time is not being mocked' do subject { ProgressBar::Time.now ::UnmockedTime } it 'will return the actual time' do ::UnmockedTime.should_receive(:now).once subject end end end end ruby-progressbar-1.4.2/spec/support/0000755000175000017500000000000012534053362017047 5ustar globusglobusruby-progressbar-1.4.2/spec/support/time.rb0000644000175000017500000000050312534053362020330 0ustar globusglobus### # In our specs, I want to make sure time gets mocked so I can accurately test # times displayed to the user. # class PBTimeTester def self.now ::Time.now end end class ::ProgressBar::Time class << self alias_method :old_now, :now def now(time = ::PBTimeTester) old_now(time) end end end ruby-progressbar-1.4.2/spec/fixtures/0000755000175000017500000000000012534053362017204 5ustar globusglobusruby-progressbar-1.4.2/spec/fixtures/benchmark.rb0000644000175000017500000000060012534053362021457 0ustar globusglobus# bundle exec ruby-prof --printer=graph_html --file=../results.html --require 'ruby-progressbar' --sort=total ./spec/fixtures/benchmark.rb total = 10 # output = File.open('/Users/jfelchner/Downloads/benchmark.txt', 'w+') output = $stdout bar = ProgressBar.create(:output => output, :length => 80, :start => 0, :total => total) total.times do |i| bar.log i bar.increment end ruby-progressbar-1.4.2/spec/spec_helper.rb0000644000175000017500000000036612534053362020156 0ustar globusglobusrequire 'mathn' require 'rspec' require 'timecop' Dir[File.join(File.dirname(__FILE__), '..', 'lib', 'ruby-progressbar.rb')].each {|f| require f} Dir[File.join(File.dirname(__FILE__), '..', 'spec', 'support', '**', '*.rb')].each {|f| require f} ruby-progressbar-1.4.2/LICENSE0000644000175000017500000000210312534053362015402 0ustar globusglobus(The MIT License) Copyright (c) 2011 The Kompanee - Jeff Felchner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ruby-progressbar-1.4.2/README.md0000644000175000017500000004534212534053362015670 0ustar globusglobusRuby/ProgressBar: A Text Progress Bar Library for Ruby ================================ The **ultimate** text progress bar library for Ruby! It'll **SMASH YOU OVER THE HEAD** with a **PURE RUSH** of progress bar excitement! Don't miss out on what all the kids are talking about! If you want everyone to know that your gem or app can survive _in the cage_ then YOU WANT **RUBY-PROGRESSBAR**! ![The Cage](http://www.thekompanee.com/public_files/the-cage.png) Supported Rubies -------------------------------- * MRI Ruby 1.8.7 * MRI Ruby 1.9.2 * MRI Ruby 1.9.3 * MRI Ruby 2.0.0 * JRuby (in 1.8 compat mode) * JRuby (in 1.9 compat mode) It's Better Than The Other 186,312 Progress Bar Libraries Because... -------------------------------- * Full test suite [![Build Status](https://secure.travis-ci.org/jfelchner/ruby-progressbar.png?branch=master)](http://travis-ci.org/jfelchner/ruby-progressbar) * _**ZERO**_ dependencies * Used by tons of other open source projects (which means we find out about bugs quickly) * It's pretty [freakin' sweet](https://www.youtube.com/watch?v=On3IoVhf_GM) * We have a road map of new features to make it even better * And most importantly... our awesome [contributors](#contributors) Installation -------------------------------- First: ```ruby gem install ruby-progressbar ``` Then in your script: ```ruby require 'ruby-progressbar' ``` or in your Gemfile ```ruby gem 'ruby-progressbar' ``` or from IRB ```ruby irb -r 'ruby-progressbar' ``` Basic Usage -------------------------------- ### Creation It's simple to get started: ```ruby ProgressBar.create ``` Creates a basic progress bar beginning at `0`, a total capacity of `100` and tells it to start. Progress: | | ### Marking Progress Every call to `#increment` will advance the bar by `1`. Therefore: ```ruby 50.times { progressbar.increment } ``` Would output an advancing line which would end up here: Progress: |=================================== | Advanced Usage -------------------------------- ### Options If you would like to customize your prompt, you can pass options when you call `.create`. ```ruby ProgressBar.create(:title => "Items", :starting_at => 20, :total => 200) ``` Will output: Items: |======= | The following are the list of options you can use: * `:title` - _(Defaults to `Progress`)_ - The title of the progress bar. * `:total` - _(Defaults to `100`)_ The total number of the items that can be completed. * `:starting_at` - _(Defaults to `0`)_ The number of items that should be considered completed when the bar first starts. This is also the default number that the bar will be set to if `#reset` is called. * `:progress_mark` - _(Defaults to `=`)_ The mark which indicates the amount of progress that has been made. * `:remainder_mark` - _(Defaults to ` `)_ The mark which indicates the remaining amount of progress to be made. * `:format` - _(Defaults to `%t: |%B|`)_ The format string which determines how the bar is displayed. See [**Formatting**](#formatting) below. * `:length` - _(Defaults to full width if possible, otherwise `80`)_ The preferred width of the entire progress bar including any format options. * `:output` - _(Defaults to `STDOUT`)_ All output will be sent to this object. Can be any object which responds to `.print`. * `:smoothing` - _(Defaults to `0.1`)_ See [**Smoothing Out Estimated Time Jitters**](#smoothing-out-estimated-time-jitters) below. * `:throttle_rate` - _(Defaults to `0.01`)_ See [**Throttling**](#throttling) below. * `:unknown_progress_animation_steps` - _(Defaults to `['=---', '-=--', '--=-', '---=']`)_ See [**Unknown Progress**](#unknown-progress) The graphical elements used to cycle when progress is changed but the total amount of items being processed is unknown. ### Changing Progress * `#increment`: Will advance the bar's progress by `1` unit. This is the main way of progressing the bar. * `#decrement`: Will retract the bar's progress by `1` unit. * `#progress +=`: Will allow you to increment by a relative amount. * `#progress -=`: Will allow you to decrement by a relative amount. * `#progress=`: Will allow you to jump the amount of progress directly to whatever value you would like. _Note: This will almost always mess up your estimated time if you're using it._ * `#total=`: Will change the total number of items being processed by the bar. This can be anything (even nil) but cannot be less than the amount of progress already accumulated by the bar. ### Stopping The bar can be stopped in four ways: * `#finish`: Will stop the bar by completing it immediately. The current position will be advanced to the total. * `#stop`: Will stop the bar by immediately cancelling it. The current position will remain where it is. * `#pause`: Will stop the bar similar to `#stop` but will allow it to be restarted where it previously left off by calling `#resume`. _Note: Elapsed Time and Estimated Time will stop being affected while the bar is paused._ * `#reset`: Will stop the bar by resetting all information. The current position of the bar will be reset to where it began when it was created. _(eg if you passed `:starting_at => 5` when you created the bar, it would reset to `5` and not `0`)_ ### Finishing * See `#finish` above. _Note: The bar will be finished automatically if the current value ever becomes equal to the total._ ### Refreshing * If you need to have the bar be redisplayed to give your users more of a "real-time" feel, you can call `#refresh` which will not affect the current position but will update the elapsed and estimated timers. ### Unknown Progress Sometimes when processing work, you don't know at the beginning of the job exactly how many items you will be processing. Maybe this might be because you're downloading a chunked file or processing a set of jobs that hasn't fully loaded yet. In times like these, you can set total to `nil` and continue to increment the bar as usual. The bar will display an 'unknown' animation which will change every time you increment. This will give the appearance (by default) that the bar is processing work even though there is no "progress". ```ruby progressbar = ProgressBar.create(:starting_at => 20, :total => nil) ``` Will output: Progress: |=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---| Calling ```ruby progressbar.increment ``` once more will output: Progress: |-=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=--| ad infinitum. At whatever point you discover the total that you will be processing, you can call: ```ruby progressbar.total = 100 ``` And the bar will magically transform into its typical state: Progress: |======== | ### Logging Many times while using the progress bar, you may wish to log some output for the user. If you attempt to do this using a standard `puts` statement, you'll find that the text will overwrite that which makes up the bar. For example if you were to `puts "hello"` after progress has already begun, you may get something like this: helloess: |======= | Progress: |======== | The reason is that ruby-progressbar has to keep redrawing itself every time you change the progress. It's a limitation of terminal output. Using `puts` messes that up because `puts` adds a newline which moves the cursor to the next line, then when ruby-progressbar updates, it does so on the following line. To circumvent this, use `#log` instead. ```ruby progressbar = ProgressBar.create progressbar.progress = 20 progressbar.log 'hello' ``` hello Progress: |============= | `#log` will automatically clear the bar, print your desired text and then redraw the bar on the following line. Notice that we did not get a bar **above** the logged output. If you consistently use `#log`, you should only every see one bar on the screen at any time. Formatting -------------------------------- The format of the progress bar is extremely easy to customize. When you create the progress bar and pass the `:format` option, that string will be used to determine what the bar looks like. The flags you can use in the format string are as follows: * `%t`: Title * `%a`: Elapsed (absolute) time * `%e`: Estimated time (will fall back to `ETA: ??:??:??` when it exceeds `99:00:00`) * `%E`: Estimated time (will fall back to `ETA: > 4 Days` when it exceeds `99:00:00`) * `%f`: Force estimated time to be displayed even if it exceeds `99:00:00` * `%p`: Percentage complete represented as a whole number (eg: `82`) * `%P`: Percentage complete represented as a decimal number (eg: `82.33`) * `%c`: Number of items currently completed * `%C`: Total number of items to be completed * `%B`: The full progress bar including 'incomplete' space (eg: `========== `) * `%b`: Progress bar only (eg: `==========`) * `%w`: Bar With Integrated Percentage (eg: `==== 75 ====`) * `%i`: Display the incomplete space of the bar (this string will only contain whitespace eg: ` `) * `%%`: A literal percent sign `%` All values have an absolute length with the exception of the bar flags (eg `%B`, `%b`, etc) which will occupy any leftover space. You can use as many bar flags as you'd like, but if you do weird things, weird things will happen; so be wary. ### Example If you would like a bar with the elapsed time on the left and the percentage complete followed by the title on the right, you'd do this: ```ruby ProgressBar.create(:format => '%a %B %p%% %t') ``` Which will output something like this: Time: --:--:-- 0% Progress Hard to see where the bar is? Just add your own end caps, whatever you'd like. Like so: ```ruby ProgressBar.create(:format => '%a <%B> %p%% %t') ``` Becomes: Time: --:--:-- < > 0% Progress Want to put an end cap on your bar? Nothing special, just use the bar flag `%b` combined with the incomplete space flag `%i` like so: ```ruby ProgressBar.create(:format => '%a |%b>>%i| %p%% %t', :starting_at => 10) ``` Becomes: Time: --:--:-- |====>> | 10% Progress Notice that the absolute length doesn't get any longer, the bar just shrinks to fill the remaining space. Want to play a game of PAC-MAN while you wait for your progress? ```ruby ProgressBar.create( :format => '%a %bᗧ%i %p%% %t', :progress_mark => ' ', :remainder_mark => '・', :starting_at => 10) ``` Becomes **PAC-MAN**! Time: --:--:-- ᗧ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 10% Progress ### Overriding the Length By default, the progressbar will try to be as smart as possible about how wide it can be. Under most Unix systems, it should be as wide as the terminal will allow while still fitting on one line. If you wish to override this behavior, you can pass in the `:length` option when creating the bar like so: ```ruby ProgressBar.create(:length => 40) ``` Additionally, if you don't have access to the code calling the progressbar itself (say if you're using a gem like Fuubar), you can set the `RUBY_PROGRESS_BAR_LENGTH` environment variable and it will always override any other setting. _Note: If the terminal width is less than 20 characters or ruby-progressbar is being used on a non-*nix system, the bar will default to an 80 character width._ ### Realtime Customization The following items can be set at any time. Changes cause an immediate bar refresh so no other action is needed: * `#progress_mark=`: Sets the string used to represent progress along the bar. * `#remainder_mark=`: Sets the string used to represent the empty part of the bar. * `#title=`: Sets the string used to represent the items the bar is tracking (or I guess whatever else you want it to be). * `#format(format_string)`: If you need to adjust the format that the bar uses when rendering itself, just pass in a string in the same format as describe [above](#formatting). ## In The Weeds This is some stuff that makes ruby-progressbar extra awesome, but for the most part it "Just Works" and you won't have to even know it's there, but if you're curious like us, here it is. ### Times... They Are A Changin' #### Smoothing Out Estimated Time Jitters Sometimes when you're tracking progress, you could have some items which take significantly longer than others. When this is the case, the ETA gauge can vary wildly from increment to increment. __RUBY PROGRESS BAR TO THE RESCUE!__ Thanks to [@L2G](https://github.com/L2G) and 'the maths' you can pass the `:smoothing` option when creating a new bar and it will use an exponentially smoothed average rather than a linear one. A value of `0.0` means no smoothing and is equivalent to the classic behavior. A value of `1.0` is the maximum amount of smoothing. Any values between those two are valid. `0.1` is the default. ```ruby ProgressBar.create(:smoothing => 0.6) ``` #### Time Mocking Support When mocking time, the concept of when `now` is becomes distorted. You can imagine that because ruby-progressbar tracks elapsed and estimated times, if it used the mocked version of `now` the results would be very undesirable. Fortunately, if you use one of our supported Ruby time mocking libraries, your elapsed and estimated times will appear correctly no matter when your 'now' is. Currently supported are: * [Timecop](https://github.com/jtrupiano/timecop) * [Delorean](https://github.com/bebanjo/delorean) ### Throttling When reporting progress of large amounts of very fast operations, whose duration is comparable to the output time of a progress bar, it becomes desirable to throttle output to the console and only perform it once in a set period. ProgressBar supports throttling if given `:throttle_rate` option: ProgressBar.create(:throttle_rate => 0.1) The above progress bar will output at most 10 times a second. The default throttling rate if none is specified is 100 times per second (or 0.01) ### Custom Unknown Progress Animations Following up on [unknown progress](#unknown-progress), you may wish to update the unknown progress animation to suit your specific needs. This can be easily done by passing in the `:unknown_progress_animation_steps` option. This item should be an array of strings representing each step of the animation. The specific step used for a given progress is determined by the current progress of the bar. For example: ```ruby progressbar = ProgressBar.create(:unknown_progress_animation_steps => ['==>', '>==', '=>=']) ``` Would use element 0 ('==>') for a progress of 1, 4, 7, 10, etc. It would use element 3 for a progress of 3, 6, 9, 12, etc. You can have an array of as many elements as you'd like and they will be used in the same manner. For example if you have an array of 50 animation steps, element 0 would only be used for every 50th progress (eg: 1, 51, 101, etc). Whatever element is chosen is repeated along the entire 'incomplete' portion of the bar. ### Non-TTY Output Typically, when the progress bar is updated, the entire previous bar is 'overwritten' with the updated information. Unfortunately when the bar is being output on a non-TTY enabled output stream (such as a file or pipe), that standard behavior of outputting the progress bar will not work. This is mainly due to the fact that we can't easily go back and replace the content that the bar had previously written. To try to solve this, ruby-progressbar, when it determines that it is being used on a non-TTY device, will override any format which was set in the initializer to something which more closely resembles this: Progress: |============= Notice that there are no dynamically updating segments like counters or ETA. Dynamic segments are not compatible with non-TTY devices because, by their very nature, they must be updated on each refresh of the bar and as stated previously, that is not possible in non-TTY mode. Also notice that there is no end cap on the righthand side of the bar. Again, we cannot output something which is past the point at which we next need to output text. If we added an end cap, that would mean that any additional progress text would be placed _after_ the end cap. Definitely not what we want. So how does it work? First we output the title and the first end cap: Progress: | Next, every time we increment the bar, we check whether the progress bar has grown. If it has, we output _only the additional portion_ of the bar to the output. For example, given the previous title output, if we increment the bar once, we would get: Progress: |= But in this case, only one `=` was output. Not the entire `Progress: |=`. Once the bar gets to be completely finished though: Progress: |====================================================================| The end cap can now be added (since there is no more progress to be displayed). Issues -------------------------------- If you have problems, please create a [Github issue](https://github.com/nex3/ruby-progressbar/issues). Credits -------------------------------- ![thekompanee](http://www.thekompanee.com/public_files/kompanee-github-readme-logo.png) ruby-progressbar is maintained by [The Kompanee, Ltd.](http://www.thekompanee.com) The names and logos for The Kompanee are trademarks of The Kompanee, Ltd. Contributors -------------------------------- * [Lawrence Leonard "Larry" Gilbert](https://github.com/L2G) * [Aleksei Gusev](https://github.com/hron) * [Yves Senn](https://github.com/senny) * [Nathan Weizenbaum](https://github.com/nex3) * [Oleg Dashevskii](https://github.com/be9) * [Chris Griego](https://github.com/cgriego) * [Tim Harper](https://github.com/timcharper) * [Chalo Fernandez](https://github.com/chalofa) * [Laust Rud Jacobsen](https://github.com/rud) * [Ryan Wood](https://github.com/ryanwood) * [Jim Benton](https://github.com/jim) Thanks -------------------------------- Thanks to [@nex3](https://github.com/nex3) for giving us contributor access to the initial repo. Thanks to Hiroyuki Iwatsuki for giving us access to the gem on [rubygems.org](http://rubygems.org) to allow us to push our new versions. And a special thanks to [Satoru Takabayashi](http://namazu.org/~satoru/) who was the original author of the `progressbar` gem and who inspired us to do this rewrite. License -------------------------------- ruby-progressbar 1.0 is Copyright © 2011-2014 The Kompanee. It is free software, and may be redistributed under the terms specified in the LICENSE file. ruby-progressbar 0.9.0 is Copyright © 2008 [Satoru Takabayashi](http://namazu.org/~satoru/) ruby-progressbar-1.4.2/metadata.yml0000644000175000017500000001041112534053362016701 0ustar globusglobus--- !ruby/object:Gem::Specification name: ruby-progressbar version: !ruby/object:Gem::Version version: 1.4.2 prerelease: platform: ruby authors: - thekompanee - jfelchner autorequire: bindir: bin cert_chain: [] date: 2014-03-01 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: rspec requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '2.13' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '2.13' - !ruby/object:Gem::Dependency name: fuubar requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '1.3' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '1.3' - !ruby/object:Gem::Dependency name: timecop requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '0.6' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '0.6' description: ! 'Ruby/ProgressBar is an extremely flexible text progress bar library for Ruby. The output can be customized with a flexible formatting system including: percentage, bars of various formats, elapsed time and estimated time remaining. ' email: support@thekompanee.com executables: [] extensions: [] extra_rdoc_files: - README.md - LICENSE files: - lib/ruby-progressbar/base.rb - lib/ruby-progressbar/components/bar.rb - lib/ruby-progressbar/components/elapsed_timer.rb - lib/ruby-progressbar/components/estimated_timer.rb - lib/ruby-progressbar/components/progressable.rb - lib/ruby-progressbar/components/throttle.rb - lib/ruby-progressbar/components/timer.rb - lib/ruby-progressbar/components.rb - lib/ruby-progressbar/errors/invalid_progress_error.rb - lib/ruby-progressbar/format/base.rb - lib/ruby-progressbar/format/molecule.rb - lib/ruby-progressbar/format.rb - lib/ruby-progressbar/formatter.rb - lib/ruby-progressbar/length_calculator.rb - lib/ruby-progressbar/running_average_calculator.rb - lib/ruby-progressbar/time.rb - lib/ruby-progressbar/version.rb - lib/ruby-progressbar.rb - README.md - LICENSE - spec/fixtures/benchmark.rb - spec/lib/ruby-progressbar/base_spec.rb - spec/lib/ruby-progressbar/components/bar_spec.rb - spec/lib/ruby-progressbar/components/elapsed_timer_spec.rb - spec/lib/ruby-progressbar/components/estimated_timer_spec.rb - spec/lib/ruby-progressbar/components/progressable_spec.rb - spec/lib/ruby-progressbar/components/throttle_spec.rb - spec/lib/ruby-progressbar/format/molecule_spec.rb - spec/lib/ruby-progressbar/running_average_calculator_spec.rb - spec/lib/ruby-progressbar/time_spec.rb - spec/spec_helper.rb - spec/support/time.rb homepage: https://github.com/jfelchner/ruby-progressbar licenses: [] post_install_message: rdoc_options: - --charset - UTF-8 require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: ruby-progressbar rubygems_version: 1.8.23 signing_key: specification_version: 3 summary: Ruby/ProgressBar is a flexible text progress bar library for Ruby. test_files: - spec/fixtures/benchmark.rb - spec/lib/ruby-progressbar/base_spec.rb - spec/lib/ruby-progressbar/components/bar_spec.rb - spec/lib/ruby-progressbar/components/elapsed_timer_spec.rb - spec/lib/ruby-progressbar/components/estimated_timer_spec.rb - spec/lib/ruby-progressbar/components/progressable_spec.rb - spec/lib/ruby-progressbar/components/throttle_spec.rb - spec/lib/ruby-progressbar/format/molecule_spec.rb - spec/lib/ruby-progressbar/running_average_calculator_spec.rb - spec/lib/ruby-progressbar/time_spec.rb - spec/spec_helper.rb - spec/support/time.rb has_rdoc: