From 616a7b338b2cc42d84da9f450249f810d16c63e8 Mon Sep 17 00:00:00 2001 From: Jeff Felchner Date: Fri, 3 Mar 2023 01:06:45 -0600 Subject: [PATCH] Refactor: The Progress No Longer Needs The Projector Why This Change Is Necessary ======================================================================== We've removed all usages of the projector from the `Progress` object and therefore it is no longer needed to do its job. What These Changes Do To Address the Issue ======================================================================== Remove all usages of the projector from `Progress` and update test setup to reflect that. Side Effects Caused By This Change ======================================================================== None expected. --- lib/ruby-progressbar/base.rb | 2 +- lib/ruby-progressbar/progress.rb | 11 +-- .../calculators/smoothed_average_spec.rb | 53 ++++++++++-- .../ruby-progressbar/components/time_spec.rb | 63 ++++++--------- spec/lib/ruby-progressbar/progress_spec.rb | 80 ++++--------------- 5 files changed, 90 insertions(+), 119 deletions(-) diff --git a/lib/ruby-progressbar/base.rb b/lib/ruby-progressbar/base.rb index 595b55c..4340ad8 100644 --- a/lib/ruby-progressbar/base.rb +++ b/lib/ruby-progressbar/base.rb @@ -62,7 +62,7 @@ def initialize(options = {}) # rubocop:disable Metrics/AbcSize {} end self.projector = Calculators::SmoothedAverage.new(projector_opts) - self.progressable = Progress.new(options.merge(:projector => projector)) + self.progressable = Progress.new(options) options = options.merge(:progress => progressable, :projector => projector, diff --git a/lib/ruby-progressbar/progress.rb b/lib/ruby-progressbar/progress.rb index 5d66176..ac35090 100644 --- a/lib/ruby-progressbar/progress.rb +++ b/lib/ruby-progressbar/progress.rb @@ -7,13 +7,10 @@ class Progress attr_reader :total, :progress - - attr_accessor :starting_position, - :running_average_calculator + attr_accessor :starting_position def initialize(options = {}) - self.total = options.fetch(:total, DEFAULT_TOTAL) - self.running_average_calculator = options[:projector] + self.total = options.fetch(:total, DEFAULT_TOTAL) start(:at => DEFAULT_BEGINNING_POSITION) end @@ -64,10 +61,6 @@ def progress=(new_progress) @progress = new_progress end - def running_average - running_average_calculator.projection - end - def total=(new_total) unless progress.nil? || new_total.nil? || new_total >= progress fail ProgressBar::InvalidProgressError, diff --git a/spec/lib/ruby-progressbar/calculators/smoothed_average_spec.rb b/spec/lib/ruby-progressbar/calculators/smoothed_average_spec.rb index 942168f..2e2d6d4 100644 --- a/spec/lib/ruby-progressbar/calculators/smoothed_average_spec.rb +++ b/spec/lib/ruby-progressbar/calculators/smoothed_average_spec.rb @@ -4,15 +4,54 @@ class ProgressBar module Calculators describe SmoothedAverage do - it 'can properly calculate a projection' do - first_projection = SmoothedAverage.calculate(4.5, 12, 0.1) - expect(first_projection).to be_within(0.001).of 11.25 + describe '.calculate' do + it 'can properly calculate a projection' do + first_projection = SmoothedAverage.calculate(4.5, 12, 0.1) + expect(first_projection).to be_within(0.001).of 11.25 - second_projection = SmoothedAverage.calculate(8.2, 51, 0.7) - expect(second_projection).to be_within(0.001).of 21.04 + second_projection = SmoothedAverage.calculate(8.2, 51, 0.7) + expect(second_projection).to be_within(0.001).of 21.04 - third_projection = SmoothedAverage.calculate(41.8, 100, 0.59) - expect(third_projection).to be_within(0.001).of 65.662 + third_projection = SmoothedAverage.calculate(41.8, 100, 0.59) + expect(third_projection).to be_within(0.001).of 65.662 + end + end + + describe '#projection' do + it 'can properly calculate a running average' do + projector = SmoothedAverage.new(:strength => 0.1) + projector.start + projector.progress = 5 + projector.progress = 12 + + expect(projector.projection).to be_within(0.001).of 11.25 + end + + it 'knows the running average even when progress has been made' do + projector = SmoothedAverage.new(:total => 50) + + projector.instance_variable_set(:@projection, 10) + projector.start :at => 0 + + expect(projector.projection).to be_zero + + projector.progress += 40 + + expect(projector.projection).to be 36.0 + end + + it 'knows the running average is reset even after progress is started' do + projector = SmoothedAverage.new(:total => 50) + + projector.instance_variable_set(:@projection, 10) + projector.start :at => 0 + + expect(projector.projection).to be_zero + + projector.start :at => 40 + + expect(projector.projection).to be 0.0 + end end describe '#start' do diff --git a/spec/lib/ruby-progressbar/components/time_spec.rb b/spec/lib/ruby-progressbar/components/time_spec.rb index 54c7bd5..e4b782c 100644 --- a/spec/lib/ruby-progressbar/components/time_spec.rb +++ b/spec/lib/ruby-progressbar/components/time_spec.rb @@ -8,7 +8,7 @@ module Components it 'displays unknown elapsed time when the timer has not been started' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -19,7 +19,7 @@ module Components it 'displays elapsed time when the timer has just been started' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -33,7 +33,7 @@ module Components it 'displays elapsed time if it was previously started' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -51,7 +51,7 @@ module Components it 'displays elapsed time frozen to a specific time if it was previously stopped' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -74,7 +74,7 @@ module Components it 'displays unknown elapsed time after reset has been called' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -96,8 +96,7 @@ module Components it 'displays estimated time if it is known' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.0) - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -120,7 +119,7 @@ module Components 'but no progress has been made' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector, :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -135,7 +134,7 @@ module Components 'is reset' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector, :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -160,7 +159,7 @@ module Components 'is reset' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector, :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -185,8 +184,7 @@ module Components 'and the out of bounds format is set to "unknown"' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.0) - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:out_of_bounds_time_format => :unknown, :timer => timer, :progress => progress, @@ -210,8 +208,7 @@ module Components 'is made' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.5) - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -237,8 +234,7 @@ module Components it 'displays estimated time if it is known' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.0) - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -261,8 +257,7 @@ module Components 'and the out of bounds format is set to "friendly"' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.0) - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:out_of_bounds_time_format => :friendly, :timer => timer, :progress => progress, @@ -287,8 +282,7 @@ module Components it 'displays estimated time if it is known' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.0) - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -311,8 +305,7 @@ module Components 'out of bounds format is unset' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.0) - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:out_of_bounds_time_format => nil, :timer => timer, :progress => progress, @@ -338,8 +331,7 @@ module Components 'it is incremented' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -355,8 +347,7 @@ module Components it 'displays unsmoothed time remaining when progress has been made' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.0) - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -379,8 +370,7 @@ module Components 'bar is decremented' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.0) - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -408,8 +398,7 @@ module Components 'account' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.5) - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -436,8 +425,7 @@ module Components it 'displays smoothed estimated time after progress has been made' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.5) - progress = Progress.new(:projector => projector, - :total => 100) + progress = Progress.new(:total => 100) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -460,8 +448,7 @@ module Components 'very short intervals' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.1) - progress = Progress.new(:projector => projector, - :total => 10) + progress = Progress.new(:total => 10) time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -506,7 +493,7 @@ module Components it 'displays the wall clock time as unknown when the timer has been reset' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -526,7 +513,7 @@ module Components it 'displays the wall clock time as unknown when the progress has not begun' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -544,7 +531,7 @@ module Components it 'displays the completed wall clock time if the progress is finished' do timer = Timer.new projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new time = Time.new(:timer => timer, :progress => progress, :projector => projector) @@ -567,7 +554,7 @@ module Components it 'displays the estimated wall clock time if the progress is ongoing' do timer = Timer.new projector = Calculators::SmoothedAverage.new(:strength => 0.0) - progress = Progress.new(:projector => projector) + progress = Progress.new time = Time.new(:timer => timer, :progress => progress, :projector => projector) diff --git a/spec/lib/ruby-progressbar/progress_spec.rb b/spec/lib/ruby-progressbar/progress_spec.rb index c817cd7..eb05e42 100644 --- a/spec/lib/ruby-progressbar/progress_spec.rb +++ b/spec/lib/ruby-progressbar/progress_spec.rb @@ -4,8 +4,7 @@ class ProgressBar describe Progress do it 'knows the default total when no parameters are passed' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new expect(progress.total).to eql Progress::DEFAULT_TOTAL end @@ -13,8 +12,7 @@ class ProgressBar it 'knows the default beginning progress when no parameters are passed and ' \ 'the progress has not been started' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new expect(progress.progress).to be_zero end @@ -22,8 +20,7 @@ class ProgressBar it 'knows the default starting value when no parameters are passed and the ' \ 'progress has been started' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new progress.start @@ -33,8 +30,7 @@ class ProgressBar it 'knows the given starting value when no parameters are passed and the ' \ 'progress is started with a starting value' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new progress.start :at => 10 @@ -42,25 +38,21 @@ class ProgressBar end it 'knows how to finish itself even if the total is unknown' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:total => nil, :projector => projector) + progress = Progress.new :total => nil expect(progress.finish).to be(nil) end it 'knows the overridden total when the total is passed in' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector, - :total => 12, - :progress_mark => 'x', - :remainder_mark => '.') + progress = Progress.new(:total => 12, + :progress_mark => 'x', + :remainder_mark => '.') expect(progress.total).to be 12 end it 'knows the percentage completed when begun with no progress' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new progress.start @@ -68,8 +60,7 @@ class ProgressBar end it 'knows the progress after it has been incremented' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:projector => projector) + progress = Progress.new progress.start progress.increment @@ -78,8 +69,7 @@ class ProgressBar end it 'knows the percentage completed after it has been incremented' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:total => 50, :projector => projector) + progress = Progress.new(:total => 50) progress.start progress.increment @@ -88,8 +78,7 @@ class ProgressBar end it 'knows to always round down the percentage completed' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:total => 200, :projector => projector) + progress = Progress.new(:total => 200) progress.start :at => 1 @@ -97,8 +86,7 @@ class ProgressBar end it 'cannot increment past the total' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:total => 50, :projector => projector) + progress = Progress.new(:total => 50) progress.start :at => 50 progress.increment @@ -108,8 +96,7 @@ class ProgressBar end it 'allow progress to be decremented once it is finished' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:total => 50, :projector => projector) + progress = Progress.new(:total => 50) progress.start :at => 50 progress.decrement @@ -118,49 +105,14 @@ class ProgressBar expect(progress.percentage_completed).to be 98 end - # rubocop:disable RSpec/BeEql - it 'knows the running average even when progress has been made' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:total => 50, :projector => projector) - - projector.__send__(:projection=, 10) - projector.start - progress.start :at => 0 - - expect(progress.running_average).to be_zero - - projector.progress += 40 - progress.progress += 40 - - expect(progress.running_average).to eql 36.0 - end - - it 'knows the running average is reset even after progress is started' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:total => 50, :projector => projector) - - projector.__send__(:projection=, 10) - projector.start - progress.start :at => 0 - - expect(progress.running_average).to be_zero - - progress.start :at => 40 - - expect(progress.running_average).to eql 0.0 - end - # rubocop:enable RSpec/BeEql - it 'knows the percentage completed is 100% if the total is zero' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:total => 0, :projector => projector) + progress = Progress.new(:total => 0) expect(progress.percentage_completed).to be 100 end it 'raises an error when passed a number larger than the total' do - projector = Calculators::SmoothedAverage.new - progress = Progress.new(:total => 100, :projector => projector) + progress = Progress.new(:total => 100) expect { progress.progress = 101 }. to \