From d257339f0b210fc811f8e8a5405280e00675e93b Mon Sep 17 00:00:00 2001 From: trex22 Date: Tue, 10 Sep 2019 19:22:40 +0200 Subject: [PATCH 1/8] begin to change and expand interface --- lib/progress_bar.rb | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/progress_bar.rb b/lib/progress_bar.rb index 19149cc..1c0d259 100644 --- a/lib/progress_bar.rb +++ b/lib/progress_bar.rb @@ -1,4 +1,3 @@ - require 'options' require 'highline' @@ -6,18 +5,17 @@ class ProgressBar Error = Class.new(StandardError) ArgumentError = Class.new(Error) - attr_accessor :count, :max, :meters + DefaultMeters = [:bar, :counter, :percentage, :elapsed, :eta, :rate] - def initialize(*args) + attr_accessor :count, :max, :meters, :bar, :delimiters + def initialize(max = 100, *meters, bar: '#', delimiters: '[]') @count = 0 - @max = 100 - @meters = [:bar, :counter, :percentage, :elapsed, :eta, :rate] - - @max = args.shift if args.first.is_a? Numeric - raise ArgumentError, "Max must be a positive integer" unless @max >= 0 + @max = max + # TODO: check if max is a bar and set it + raise ArgumentError, "Max must be a positive integer" unless @max.is_a?(Integer) && @max >= 0 - @meters = args unless args.empty? + @meters = meters.empty? ? DefaultMeters : meters @last_write = ::Time.at(0) @start = ::Time.now From f9642de2c53e06d3757ee587e112f836f9362e55 Mon Sep 17 00:00:00 2001 From: trex22 Date: Tue, 10 Sep 2019 22:15:04 +0200 Subject: [PATCH 2/8] update progressbar to have adjustable characters --- lib/progress_bar.rb | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/progress_bar.rb b/lib/progress_bar.rb index 1c0d259..299cb3f 100644 --- a/lib/progress_bar.rb +++ b/lib/progress_bar.rb @@ -9,13 +9,20 @@ class ProgressBar attr_accessor :count, :max, :meters, :bar, :delimiters - def initialize(max = 100, *meters, bar: '#', delimiters: '[]') + def initialize(*args, bar: '#', delimiters: '[]') @count = 0 - @max = max - # TODO: check if max is a bar and set it - raise ArgumentError, "Max must be a positive integer" unless @max.is_a?(Integer) && @max >= 0 + @max = 100 - @meters = meters.empty? ? DefaultMeters : meters + @max = args.shift if args.first.is_a? Numeric + raise ArgumentError, 'Max must be a positive integer' unless @max >= 0 + + @meters = args.empty? ? DefaultMeters : args + + @bar = bar + raise ArgumentError, 'Bar must be a single character' unless @bar.size == 1 + + @delimiters = delimiters + raise ArgumentError, 'Delimiters must be two characters' unless @delimiters.size == 2 @last_write = ::Time.at(0) @start = ::Time.now @@ -71,8 +78,8 @@ def eta def to_s self.count = max if count > max - meters.inject("") do |text, meter| - text << render(meter) + " " + meters.inject('') do |text, meter| + text << render(meter) + ' ' end.strip end @@ -96,12 +103,14 @@ def width_of(meter) def render_bar return '' if bar_width < 2 + progress_width = (ratio * (bar_width - 2)).floor remainder_width = bar_width - 2 - progress_width - "[" + - "#" * progress_width + - " " * remainder_width + - "]" + + delimiters[0] + + bar * progress_width + + ' ' * remainder_width + + delimiters[-1] end def render_counter @@ -186,7 +195,6 @@ def format_interval(interval) "%02i:%02i" % [interval/60, interval%60] end end - end require_relative 'progress_bar/with_progress' From 9c0fbf018b8947b0946dcfbfcc85be6296e21504 Mon Sep 17 00:00:00 2001 From: trex22 Date: Tue, 10 Sep 2019 22:15:24 +0200 Subject: [PATCH 3/8] cleanup spextra spaces --- spec/arguments_spec.rb | 2 -- spec/bar_spec.rb | 2 -- spec/counter_spec.rb | 1 - spec/elapsed_spec.rb | 3 --- spec/eta_spec.rb | 4 ---- spec/percentage_spec.rb | 2 -- spec/progress_bar_spec.rb | 3 --- spec/rate_spec.rb | 6 ------ spec/spec_helper.rb | 2 -- 9 files changed, 25 deletions(-) diff --git a/spec/arguments_spec.rb b/spec/arguments_spec.rb index 964dc8b..019677d 100644 --- a/spec/arguments_spec.rb +++ b/spec/arguments_spec.rb @@ -35,6 +35,4 @@ bar = ProgressBar.new(-1) }.should raise_error(ProgressBar::ArgumentError) end - end - diff --git a/spec/bar_spec.rb b/spec/bar_spec.rb index e8866c8..8e3c341 100644 --- a/spec/bar_spec.rb +++ b/spec/bar_spec.rb @@ -50,6 +50,4 @@ end end end - end - diff --git a/spec/counter_spec.rb b/spec/counter_spec.rb index 65a6acc..0c294e2 100644 --- a/spec/counter_spec.rb +++ b/spec/counter_spec.rb @@ -46,5 +46,4 @@ it { should == '[ 0/4242]' } end - end diff --git a/spec/elapsed_spec.rb b/spec/elapsed_spec.rb index 4128e37..3eaf409 100644 --- a/spec/elapsed_spec.rb +++ b/spec/elapsed_spec.rb @@ -1,4 +1,3 @@ - require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper')) describe 'ProgressBar elapsed output' do @@ -43,6 +42,4 @@ it { should == '[02:00:00]' } end - end - diff --git a/spec/eta_spec.rb b/spec/eta_spec.rb index 5c6bacf..c65837f 100644 --- a/spec/eta_spec.rb +++ b/spec/eta_spec.rb @@ -43,8 +43,4 @@ it { should == '[02:00:00]' } end - end - - - diff --git a/spec/percentage_spec.rb b/spec/percentage_spec.rb index 6465f12..e48e158 100644 --- a/spec/percentage_spec.rb +++ b/spec/percentage_spec.rb @@ -39,6 +39,4 @@ it { should == '[ 50.00%]' } end - end - diff --git a/spec/progress_bar_spec.rb b/spec/progress_bar_spec.rb index f69f8e6..c4d8126 100644 --- a/spec/progress_bar_spec.rb +++ b/spec/progress_bar_spec.rb @@ -41,7 +41,4 @@ it { should == "[##############] [100/100] [100%] [00:10] [00:00] [ 10.00/s]" } end - end - - diff --git a/spec/rate_spec.rb b/spec/rate_spec.rb index 8171c04..53ce38e 100644 --- a/spec/rate_spec.rb +++ b/spec/rate_spec.rb @@ -54,10 +54,4 @@ it { should == '[ 2.10/s]' } end - end - - - - - diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 63cc043..773b3c6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,3 @@ - require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib/progress_bar')) require 'rspec' @@ -9,4 +8,3 @@ Timecop.return end end - From 3f69fd98b694074ab038d153038be66f73b49690 Mon Sep 17 00:00:00 2001 From: trex22 Date: Tue, 10 Sep 2019 22:18:40 +0200 Subject: [PATCH 4/8] reduce line length --- lib/progress_bar.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/progress_bar.rb b/lib/progress_bar.rb index 299cb3f..cc54ae7 100644 --- a/lib/progress_bar.rb +++ b/lib/progress_bar.rb @@ -22,7 +22,9 @@ def initialize(*args, bar: '#', delimiters: '[]') raise ArgumentError, 'Bar must be a single character' unless @bar.size == 1 @delimiters = delimiters - raise ArgumentError, 'Delimiters must be two characters' unless @delimiters.size == 2 + unless @delimiters.size == 2 + raise ArgumentError, 'Delimiters must be two characters' + end @last_write = ::Time.at(0) @start = ::Time.now From 98553fab2a300ed032bd670b1220bcbc752ecc9e Mon Sep 17 00:00:00 2001 From: trex22 Date: Tue, 10 Sep 2019 22:34:11 +0200 Subject: [PATCH 5/8] spec bar and delimiters --- lib/progress_bar.rb | 4 +-- spec/arguments_spec.rb | 48 ++++++++++++++++++++++++---- spec/progress_bar_characters_spec.rb | 44 +++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 spec/progress_bar_characters_spec.rb diff --git a/lib/progress_bar.rb b/lib/progress_bar.rb index cc54ae7..3b8a2b9 100644 --- a/lib/progress_bar.rb +++ b/lib/progress_bar.rb @@ -19,10 +19,10 @@ def initialize(*args, bar: '#', delimiters: '[]') @meters = args.empty? ? DefaultMeters : args @bar = bar - raise ArgumentError, 'Bar must be a single character' unless @bar.size == 1 + raise ArgumentError, 'Bar must be a single character' unless @bar&.size == 1 @delimiters = delimiters - unless @delimiters.size == 2 + unless @delimiters&.size == 2 raise ArgumentError, 'Delimiters must be two characters' end diff --git a/spec/arguments_spec.rb b/spec/arguments_spec.rb index 019677d..e7456e3 100644 --- a/spec/arguments_spec.rb +++ b/spec/arguments_spec.rb @@ -6,33 +6,69 @@ @default_meters = [:bar, :counter, :percentage, :elapsed, :eta, :rate] end - it "should set appropriate defaults without any arguments" do + it 'should set appropriate defaults without any arguments' do bar = ProgressBar.new bar.max.should == @default_max bar.meters.should == @default_meters end - it "should allow a single argument specifying the max" do + it 'should allow a single argument specifying the max' do bar = ProgressBar.new(123) bar.max.should == 123 bar.meters.should == @default_meters end - it "should allow specifying just the meters" do + it 'should allow specifying just the meters' do bar = ProgressBar.new(:bar, :eta) bar.max.should == @default_max bar.meters.should == [:bar, :eta] end - it "should allow specyfing the max and meters" do + it 'should allow specifying the max and meters' do bar = ProgressBar.new(123, :bar, :eta) bar.max.should == 123 bar.meters.should == [:bar, :eta] end - it "should raise an error when initial max is nonsense" do + it 'should allow specifying the bar and delimiters' do + bar = ProgressBar.new(bar: '$', delimiters: '||') + bar.bar.should == '$' + bar.delimiters.should == '||' + end + + it 'should raise an error when initial max is nonsense' do + lambda { + _bar = ProgressBar.new(-1) + }.should raise_error(ProgressBar::ArgumentError) + end + + it 'should raise an error when bar is more than one character' do + lambda { + _bar = ProgressBar.new(bar: 'abc') + }.should raise_error(ProgressBar::ArgumentError) + end + + it 'should raise an error when bar is empty' do + lambda { + _bar = ProgressBar.new(bar: nil) + }.should raise_error(ProgressBar::ArgumentError) + end + + it 'should raise an error when delimiters is less than two characters' do + lambda { + _bar = ProgressBar.new(delimiters: '|') + }.should raise_error(ProgressBar::ArgumentError) + end + + it 'should raise an error when delimiters is more than two characters' do + lambda { + _bar = ProgressBar.new(delimiters: '|||') + }.should raise_error(ProgressBar::ArgumentError) + end + + it 'should raise an error when delimiters is empty' do lambda { - bar = ProgressBar.new(-1) + _bar = ProgressBar.new(delimiters: '') }.should raise_error(ProgressBar::ArgumentError) end end diff --git a/spec/progress_bar_characters_spec.rb b/spec/progress_bar_characters_spec.rb new file mode 100644 index 0000000..3dc2134 --- /dev/null +++ b/spec/progress_bar_characters_spec.rb @@ -0,0 +1,44 @@ +require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper')) + +describe 'ProgressBar bar output with custom characters' do + before do + Timecop.freeze Time.utc(2010, 3, 10, 0, 0, 0) + @progress_bar = ProgressBar.new(100, bar: '█', delimiters: '▕▏') + @progress_bar.stub(:terminal_width) { 60 } + Timecop.freeze Time.utc(2010, 3, 10, 0, 0, 10) # 10 seconds later + end + + subject { @progress_bar.to_s } + + describe 'at count=0' do + before do + @progress_bar.count = 0 + end + + it { should == '▕ ▏ [ 0/100] [ 0%] [00:10] [00:00] [ 0.00/s]' } + end + + describe 'at count=50' do + before do + @progress_bar.count = 50 + end + + it { should == '▕███████ ▏ [ 50/100] [ 50%] [00:10] [00:10] [ 5.00/s]' } + end + + describe 'at count=100' do + before do + @progress_bar.count = 100 + end + + it { should == '▕██████████████▏ [100/100] [100%] [00:10] [00:00] [ 10.00/s]' } + end + + describe 'at count=105' do + before do + @progress_bar.count = 105 + end + + it { should == '▕██████████████▏ [100/100] [100%] [00:10] [00:00] [ 10.00/s]' } + end +end From edd053498c4c4c2c2f4be878b6e54fd14a2a7200 Mon Sep 17 00:00:00 2001 From: trex22 Date: Tue, 10 Sep 2019 22:40:03 +0200 Subject: [PATCH 6/8] update rreadme with the custom character changes --- README.mkd | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.mkd b/README.mkd index ed8d148..4050909 100644 --- a/README.mkd +++ b/README.mkd @@ -20,7 +20,6 @@ lots of progress bar alternatives, and we thank you for using ProgressBar! ## The Easy Way - require 'progress_bar' bar = ProgressBar.new @@ -39,11 +38,16 @@ it.* ## Setting the Max -Usually, the defaults should be fine, the only thing you'll need to -tweak is the max. - bar = ProgressBar.new(1000) +## Setting the progress bar characters + +By default, ProgressBar will use a default bar character to show progress and +side delimiters. You can set any valid character that is supported by your +terminal for either the bar character or the delimiters. + + bar = ProgressBar.new(bar: '█', delimiters: '||') + ## Larger Steps If you want to process several things, and update less often, you can From a7cfd33f38c94d9e54b146cd15c5fd800bdd8a9a Mon Sep 17 00:00:00 2001 From: trex22 Date: Tue, 17 Sep 2019 17:51:06 +0200 Subject: [PATCH 7/8] rename constant --- lib/progress_bar.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/progress_bar.rb b/lib/progress_bar.rb index 3b8a2b9..56b22c9 100644 --- a/lib/progress_bar.rb +++ b/lib/progress_bar.rb @@ -5,7 +5,7 @@ class ProgressBar Error = Class.new(StandardError) ArgumentError = Class.new(Error) - DefaultMeters = [:bar, :counter, :percentage, :elapsed, :eta, :rate] + DEFAULT_METERS = [:bar, :counter, :percentage, :elapsed, :eta, :rate] attr_accessor :count, :max, :meters, :bar, :delimiters @@ -14,9 +14,9 @@ def initialize(*args, bar: '#', delimiters: '[]') @max = 100 @max = args.shift if args.first.is_a? Numeric - raise ArgumentError, 'Max must be a positive integer' unless @max >= 0 + raise ArgumentError, "Max must be a positive integer" unless @max >= 0 - @meters = args.empty? ? DefaultMeters : args + @meters = args.empty? ? DEFAULT_METERS : args @bar = bar raise ArgumentError, 'Bar must be a single character' unless @bar&.size == 1 From 32323abdfd8befbccbfde4e2ae6f09642e823aa0 Mon Sep 17 00:00:00 2001 From: trex22 Date: Tue, 17 Sep 2019 18:44:46 +0200 Subject: [PATCH 8/8] reduce restrictions so multi-sequence emojis can be used as bar characters --- lib/progress_bar.rb | 4 ++-- spec/arguments_spec.rb | 4 ++-- spec/progress_bar_characters_spec.rb | 9 +++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/progress_bar.rb b/lib/progress_bar.rb index 56b22c9..ca68b82 100644 --- a/lib/progress_bar.rb +++ b/lib/progress_bar.rb @@ -18,8 +18,8 @@ def initialize(*args, bar: '#', delimiters: '[]') @meters = args.empty? ? DEFAULT_METERS : args - @bar = bar - raise ArgumentError, 'Bar must be a single character' unless @bar&.size == 1 + @bar = bar # can be an emoji which itself can be a sequence of characters + raise ArgumentError, 'Bar must be a valid string' unless @bar&.is_a?(String) @delimiters = delimiters unless @delimiters&.size == 2 diff --git a/spec/arguments_spec.rb b/spec/arguments_spec.rb index e7456e3..824fc83 100644 --- a/spec/arguments_spec.rb +++ b/spec/arguments_spec.rb @@ -42,9 +42,9 @@ }.should raise_error(ProgressBar::ArgumentError) end - it 'should raise an error when bar is more than one character' do + it 'should raise an error when bar is not a string' do lambda { - _bar = ProgressBar.new(bar: 'abc') + _bar = ProgressBar.new(bar: 5) }.should raise_error(ProgressBar::ArgumentError) end diff --git a/spec/progress_bar_characters_spec.rb b/spec/progress_bar_characters_spec.rb index 3dc2134..6330007 100644 --- a/spec/progress_bar_characters_spec.rb +++ b/spec/progress_bar_characters_spec.rb @@ -41,4 +41,13 @@ it { should == '▕██████████████▏ [100/100] [100%] [00:10] [00:00] [ 10.00/s]' } end + + describe 'at count=100 with a multi-sequence emoji' do + before do + @progress_bar.count = 100 + @progress_bar.bar = "🏴‍☠️" + end + + it { should == '▕🏴‍☠️🏴‍☠️🏴‍☠️🏴‍☠️🏴‍☠️🏴‍☠️🏴‍☠️🏴‍☠️🏴‍☠️🏴‍☠️🏴‍☠️🏴‍☠️🏴‍☠️🏴‍☠️▏ [100/100] [100%] [00:10] [00:00] [ 10.00/s]' } + end end