progressbar 1.8.1 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE.txt +1 -1
  5. data/README.md +111 -18
  6. data/Rakefile +0 -0
  7. data/lib/progressbar.rb +4 -0
  8. data/lib/ruby-progressbar/base.rb +25 -3
  9. data/lib/ruby-progressbar/calculators/length.rb +15 -3
  10. data/lib/ruby-progressbar/components/bar.rb +7 -1
  11. data/lib/ruby-progressbar/components/rate.rb +1 -1
  12. data/lib/ruby-progressbar/components/time.rb +12 -14
  13. data/lib/ruby-progressbar/format/formatter.rb +1 -1
  14. data/lib/ruby-progressbar/format/molecule.rb +4 -2
  15. data/lib/ruby-progressbar/format/string.rb +3 -3
  16. data/lib/ruby-progressbar/output.rb +14 -7
  17. data/lib/ruby-progressbar/outputs/non_tty.rb +1 -1
  18. data/lib/ruby-progressbar/outputs/null.rb +33 -0
  19. data/lib/ruby-progressbar/outputs/tty.rb +1 -1
  20. data/lib/ruby-progressbar/progress.rb +4 -0
  21. data/lib/ruby-progressbar/refinements.rb +1 -0
  22. data/lib/ruby-progressbar/refinements/enumerator.rb +23 -0
  23. data/lib/ruby-progressbar/time.rb +7 -5
  24. data/lib/ruby-progressbar/timer.rb +1 -1
  25. data/lib/ruby-progressbar/version.rb +1 -1
  26. metadata +50 -97
  27. metadata.gz.sig +0 -0
  28. data/lib/ruby-progressbar/calculators/length_spec.rb +0 -9
  29. data/spec/fixtures/benchmark.rb +0 -28
  30. data/spec/ruby-progressbar/base_spec.rb +0 -949
  31. data/spec/ruby-progressbar/calculators/length_calculator_spec.rb +0 -17
  32. data/spec/ruby-progressbar/calculators/running_average_spec.rb +0 -19
  33. data/spec/ruby-progressbar/components/bar_spec.rb +0 -234
  34. data/spec/ruby-progressbar/components/percentage_spec.rb +0 -9
  35. data/spec/ruby-progressbar/components/rate_spec.rb +0 -9
  36. data/spec/ruby-progressbar/components/throttle_spec.rb +0 -157
  37. data/spec/ruby-progressbar/components/time_spec.rb +0 -307
  38. data/spec/ruby-progressbar/components/title_spec.rb +0 -12
  39. data/spec/ruby-progressbar/format/formatter_spec.rb +0 -9
  40. data/spec/ruby-progressbar/format/molecule_spec.rb +0 -30
  41. data/spec/ruby-progressbar/format/string_spec.rb +0 -9
  42. data/spec/ruby-progressbar/output_spec.rb +0 -7
  43. data/spec/ruby-progressbar/outputs/non_tty_spec.rb +0 -9
  44. data/spec/ruby-progressbar/outputs/tty_spec.rb +0 -9
  45. data/spec/ruby-progressbar/progress_spec.rb +0 -156
  46. data/spec/ruby-progressbar/time_spec.rb +0 -45
  47. data/spec/ruby-progressbar/timer_spec.rb +0 -7
  48. data/spec/spec_helper.rb +0 -6
  49. data/spec/support/time.rb +0 -17
@@ -22,7 +22,7 @@ class NonTty < Output
22
22
  output_string = formatted_string[last_update_length..-1]
23
23
  self.last_update_length = formatted_string.length
24
24
 
25
- output_string
25
+ output_string.to_s
26
26
  end
27
27
 
28
28
  def default_format
@@ -0,0 +1,33 @@
1
+ require 'ruby-progressbar/output'
2
+
3
+ class ProgressBar
4
+ module Outputs
5
+ class Null < Output
6
+ alias refresh_with_format_change with_refresh
7
+
8
+ def clear; end
9
+ def log(_string); end
10
+ def refresh(*); end
11
+
12
+ def clear_string
13
+ ''
14
+ end
15
+
16
+ def bar_update_string
17
+ ''
18
+ end
19
+
20
+ def default_format
21
+ ''
22
+ end
23
+
24
+ def resolve_format(_format)
25
+ ''
26
+ end
27
+
28
+ def eol
29
+ ''
30
+ end
31
+ end
32
+ end
33
+ end
@@ -17,7 +17,7 @@ class Tty < Output
17
17
  end
18
18
 
19
19
  def default_format
20
- DEFAULT_FORMAT_STRING
20
+ ENV['RUBY_PROGRESS_BAR_FORMAT'] || DEFAULT_FORMAT_STRING
21
21
  end
22
22
 
23
23
  def resolve_format(other_format)
@@ -100,6 +100,10 @@ class Progress
100
100
  progress.nil? || total.nil?
101
101
  end
102
102
 
103
+ def total_with_unknown_indicator
104
+ total || '??'
105
+ end
106
+
103
107
  def percentage_completed_with_precision
104
108
  return 100.0 if total == 0
105
109
  return 0.0 if total.nil?
@@ -0,0 +1 @@
1
+ require 'ruby-progressbar/refinements/enumerator'
@@ -0,0 +1,23 @@
1
+ class ProgressBar
2
+ module Refinements
3
+ module Enumerator
4
+ refine ::Enumerator do
5
+ def with_progressbar(options = {}, &block)
6
+ chain = ::Enumerator.new do |yielder|
7
+ progress_bar = ProgressBar.create(options.merge(:starting_at => 0, :total => size))
8
+
9
+ each do |*args|
10
+ yielder.yield(*args).tap do
11
+ progress_bar.increment
12
+ end
13
+ end
14
+ end
15
+
16
+ return chain unless block
17
+
18
+ chain.each(&block)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,10 +1,11 @@
1
+ # rubocop:disable Style/InlineComment
1
2
  class ProgressBar
2
3
  class Time
3
4
  TIME_MOCKING_LIBRARY_METHODS = [
4
- :__simple_stub__now, # ActiveSupport
5
- :now_without_mock_time, # Timecop
6
- :now_without_delorean, # Delorean
7
- :now # Actual
5
+ :__simple_stub__now, # ActiveSupport
6
+ :now_without_mock_time, # Timecop
7
+ :now_without_delorean, # Delorean
8
+ :now # Unmocked
8
9
  ].freeze
9
10
 
10
11
  def initialize(time = ::Time)
@@ -12,7 +13,7 @@ class Time
12
13
  end
13
14
 
14
15
  def now
15
- time.__send__ unmocked_time_method
16
+ time.__send__(unmocked_time_method)
16
17
  end
17
18
 
18
19
  def unmocked_time_method
@@ -28,3 +29,4 @@ class Time
28
29
  attr_accessor :time
29
30
  end
30
31
  end
32
+ # rubocop:enable Style/InlineComment
@@ -6,7 +6,7 @@ class Timer
6
6
  :stopped_at
7
7
 
8
8
  def initialize(options = {})
9
- self.time = options[:time] || Time.new
9
+ self.time = options[:time] || ::ProgressBar::Time.new
10
10
  end
11
11
 
12
12
  def start
@@ -1,3 +1,3 @@
1
1
  class ProgressBar
2
- VERSION = '1.8.1'.freeze
2
+ VERSION = '1.11.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,38 +1,40 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: progressbar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
4
+ version: 1.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - thekompanee
8
8
  - jfelchner
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain:
12
12
  - |
13
13
  -----BEGIN CERTIFICATE-----
14
- MIIDrjCCApagAwIBAgIBATANBgkqhkiG9w0BAQUFADBOMRowGAYDVQQDDBFhY2Nv
15
- dW50c19ydWJ5Z2VtczEbMBkGCgmSJomT8ixkARkWC3RoZWtvbXBhbmVlMRMwEQYK
16
- CZImiZPyLGQBGRYDY29tMB4XDTE2MDQyNDAyNTEyM1oXDTE3MDQyNDAyNTEyM1ow
17
- TjEaMBgGA1UEAwwRYWNjb3VudHNfcnVieWdlbXMxGzAZBgoJkiaJk/IsZAEZFgt0
18
- aGVrb21wYW5lZTETMBEGCgmSJomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEB
19
- BQADggEPADCCAQoCggEBANklzdaVeHtut6LTe/hrl6Krz2Z60InEbNb+TMG43tww
20
- jBpWZrdU/SBkR3EYbTAQv/yGTuMHoVKGK2kDlFvdofW2hX0d14qPyYJUNYt+7VWE
21
- 3UhPSxw1i6MxeU1QwfkIyaN8A5lj0225+rwI/mbplv+lSXPlJEroCQ9EfniZD4jL
22
- URlrHWl/UejcQ32C1IzBwth3+nacrO1197v5nSdozFzQwm4groaggXn9F/WpThu+
23
- MhcE4bfttwEjAfU3zAThyzOFoVPpACP+SwOuyPJSl02+9BiwzeAnFJDfge7+rsd5
24
- 64W/VzBIklEKUZMmxZwr5DwpSXLrknBDtHLABG9Nr3cCAwEAAaOBljCBkzAJBgNV
25
- HRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUP7v0f/qfa0LMrhkzHRI3l10X
26
- LYIwLAYDVR0RBCUwI4EhYWNjb3VudHMrcnVieWdlbXNAdGhla29tcGFuZWUuY29t
27
- MCwGA1UdEgQlMCOBIWFjY291bnRzK3J1YnlnZW1zQHRoZWtvbXBhbmVlLmNvbTAN
28
- BgkqhkiG9w0BAQUFAAOCAQEASqdfJKMun1twosHfvdDH7Vgrb5VqX28qJ6MgnhjF
29
- p+3HYTjYo/KMQqu78TegUFO5xQ4oumU0FTXADW0ryXZvUGV74M0zwqpFqeo8onII
30
- lsVsWdMCLZS21M0uCQmcV+OQMNxL8jV3c0D3x9Srr9yO4oamW3seIdb+b9RfhmV2
31
- ryr+NH8U/4xgzdJ4hWV4qk93nwigp4lwJ4u93XJ7Cdyw7itvaEPnn8HpCfzsiLcw
32
- QwSfDGz6+zsImi5N3UT71+mk7YcviQSgvMRl3VkAv8MZ6wcJ5SQRpf9w0OeFH6Ln
33
- nNbCoHiYeXX/lz/M6AIbxDIZZTwxcyvF7bdrQ2fbH5MsfQ==
14
+ MIIEGDCCAoCgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAyMTAwLgYDVQQDDCdhY2Nv
15
+ dW50c19ydWJ5Z2Vtcy9EQz10aGVrb21wYW5lZS9EQz1jb20wHhcNMjAxMjI2MjIz
16
+ MTE2WhcNMjExMjI2MjIzMTE2WjAyMTAwLgYDVQQDDCdhY2NvdW50c19ydWJ5Z2Vt
17
+ cy9EQz10aGVrb21wYW5lZS9EQz1jb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw
18
+ ggGKAoIBgQCqhYn5ODEoLvuBIF2M1GzoaZU28+ntP5QApvDE0Te04n0JbBC1cNYH
19
+ mr71neeSx7tlZ9w9kJ/8GNcY5bm7pNJqhyhfc+uG9M7FttcxM8AYXogjcdUDP234
20
+ +TdmZIz20JxtWBgAZK2I3ktlgLFLC3Pxq63yzhJ75Xok07Wh+ypwjGzDNofPhz+y
21
+ XR+UeUTp2UGe7kDVoqu/AwwPVhk1qUIRFLfC8SLDTD0CuNW3/AnkwQrKSm8vkiIn
22
+ q9GCnOq0+jQly0b6a1Gi3ZDYEEswnTzziw2gotUZnQkF5bcOcxK1CB/Okk2jtG7i
23
+ ztMEU785tERbOSszZrz9rBS/+GnMxlD0pxy50zFfHX3jY1hwnwGjE8Gg+0iYr/tm
24
+ eysjhcbZfKrMynoqAioCSwstIwtYYYYpYzCPZzwaIBaBqQmUTkuMeiGbAdOdFOrR
25
+ lOgl5jxCYbNOOTaXbm0nGBFaTucB88+JLbsNAuoNGUf/ybDcZ1zKRkMr2vtb+OtL
26
+ GoP81fN6l88CAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
27
+ BBYEFC+HleDjPYe35DNu6n/aeK2oB4ugMA0GCSqGSIb3DQEBCwUAA4IBgQCbuxKj
28
+ ZyvFu5mUDEWCf1dT5mqFSyFznVCjQAQygDnz6JkCQlIG93IDtVLEmHrx7hm3dOYt
29
+ HgPlsSgkoYIgsLYsR9ZIKjA2O5m3QUbo9uOtF4iRi0Obni8fVv7VZVebRfA7ypCo
30
+ n625lDRIzc/zGVcI37bzIlDXC0aK3oaBVFmN1Uj5LNMW62hTDdMBx4HcUKI45R3g
31
+ clUG96OBIyrYky3j6zpy6EpBaEdRWR68Yn4Tdba7xE9WzP3DCInjX3KPx+f0PPVK
32
+ HzsXX6TlwXk2P9DwOTZRjz7vAmvTgZGWjlfq3dgQJBgjB+UKQVHxKEGUC/comr7c
33
+ vPnXgn+nF38pK/hp/O9/lTpNplKrUvOB9+6nkwbxCPTQQO8In3pC6ixUzr/6wx9R
34
+ URbz4/Czf5LMUmzqDni0GvBkXElaXzaIRoPM/T7b1LrRsZO3DwGFAasSrR27+ZgU
35
+ Sv+7zM1SqVOK2Vhp99UBBVIZTHSJWh4sCU7dJrUJTqvwwS3ayTiUlIi5TdQ=
34
36
  -----END CERTIFICATE-----
35
- date: 2016-12-10 00:00:00.000000000 Z
37
+ date: 2020-12-31 00:00:00.000000000 Z
36
38
  dependencies:
37
39
  - !ruby/object:Gem::Dependency
38
40
  name: rspec
@@ -40,14 +42,14 @@ dependencies:
40
42
  requirements:
41
43
  - - "~>"
42
44
  - !ruby/object:Gem::Version
43
- version: '3.2'
45
+ version: '3.7'
44
46
  type: :development
45
47
  prerelease: false
46
48
  version_requirements: !ruby/object:Gem::Requirement
47
49
  requirements:
48
50
  - - "~>"
49
51
  - !ruby/object:Gem::Version
50
- version: '3.2'
52
+ version: '3.7'
51
53
  - !ruby/object:Gem::Dependency
52
54
  name: rspectacular
53
55
  requirement: !ruby/object:Gem::Requirement
@@ -68,47 +70,33 @@ dependencies:
68
70
  requirements:
69
71
  - - "~>"
70
72
  - !ruby/object:Gem::Version
71
- version: '2.0'
73
+ version: '2.3'
72
74
  type: :development
73
75
  prerelease: false
74
76
  version_requirements: !ruby/object:Gem::Requirement
75
77
  requirements:
76
78
  - - "~>"
77
79
  - !ruby/object:Gem::Version
78
- version: '2.0'
79
- - !ruby/object:Gem::Dependency
80
- name: warning_filter
81
- requirement: !ruby/object:Gem::Requirement
82
- requirements:
83
- - - "~>"
84
- - !ruby/object:Gem::Version
85
- version: 0.0.2
86
- type: :development
87
- prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
89
- requirements:
90
- - - "~>"
91
- - !ruby/object:Gem::Version
92
- version: 0.0.2
80
+ version: '2.3'
93
81
  - !ruby/object:Gem::Dependency
94
82
  name: timecop
95
83
  requirement: !ruby/object:Gem::Requirement
96
84
  requirements:
97
85
  - - '='
98
86
  - !ruby/object:Gem::Version
99
- version: 0.6.1
87
+ version: 0.6.0
100
88
  type: :development
101
89
  prerelease: false
102
90
  version_requirements: !ruby/object:Gem::Requirement
103
91
  requirements:
104
92
  - - '='
105
93
  - !ruby/object:Gem::Version
106
- version: 0.6.1
107
- description: |
108
- Ruby/ProgressBar is an extremely flexible text progress bar library for Ruby.
109
- The output can be customized with a flexible formatting system including:
110
- percentage, bars of various formats, elapsed time and estimated time remaining.
111
- email: support@thekompanee.com
94
+ version: 0.6.0
95
+ description: 'Ruby/ProgressBar is an extremely flexible text progress bar library
96
+ for Ruby. The output can be customized with a flexible formatting system including:
97
+ percentage, bars of various formats, elapsed time and estimated time remaining.'
98
+ email:
99
+ - support@thekompanee.com
112
100
  executables: []
113
101
  extensions: []
114
102
  extra_rdoc_files: []
@@ -119,7 +107,6 @@ files:
119
107
  - lib/progressbar.rb
120
108
  - lib/ruby-progressbar/base.rb
121
109
  - lib/ruby-progressbar/calculators/length.rb
122
- - lib/ruby-progressbar/calculators/length_spec.rb
123
110
  - lib/ruby-progressbar/calculators/running_average.rb
124
111
  - lib/ruby-progressbar/components.rb
125
112
  - lib/ruby-progressbar/components/bar.rb
@@ -134,38 +121,26 @@ files:
134
121
  - lib/ruby-progressbar/format/string.rb
135
122
  - lib/ruby-progressbar/output.rb
136
123
  - lib/ruby-progressbar/outputs/non_tty.rb
124
+ - lib/ruby-progressbar/outputs/null.rb
137
125
  - lib/ruby-progressbar/outputs/tty.rb
138
126
  - lib/ruby-progressbar/progress.rb
127
+ - lib/ruby-progressbar/refinements.rb
128
+ - lib/ruby-progressbar/refinements/enumerator.rb
139
129
  - lib/ruby-progressbar/throttle.rb
140
130
  - lib/ruby-progressbar/time.rb
141
131
  - lib/ruby-progressbar/timer.rb
142
132
  - lib/ruby-progressbar/version.rb
143
- - spec/fixtures/benchmark.rb
144
- - spec/ruby-progressbar/base_spec.rb
145
- - spec/ruby-progressbar/calculators/length_calculator_spec.rb
146
- - spec/ruby-progressbar/calculators/running_average_spec.rb
147
- - spec/ruby-progressbar/components/bar_spec.rb
148
- - spec/ruby-progressbar/components/percentage_spec.rb
149
- - spec/ruby-progressbar/components/rate_spec.rb
150
- - spec/ruby-progressbar/components/throttle_spec.rb
151
- - spec/ruby-progressbar/components/time_spec.rb
152
- - spec/ruby-progressbar/components/title_spec.rb
153
- - spec/ruby-progressbar/format/formatter_spec.rb
154
- - spec/ruby-progressbar/format/molecule_spec.rb
155
- - spec/ruby-progressbar/format/string_spec.rb
156
- - spec/ruby-progressbar/output_spec.rb
157
- - spec/ruby-progressbar/outputs/non_tty_spec.rb
158
- - spec/ruby-progressbar/outputs/tty_spec.rb
159
- - spec/ruby-progressbar/progress_spec.rb
160
- - spec/ruby-progressbar/time_spec.rb
161
- - spec/ruby-progressbar/timer_spec.rb
162
- - spec/spec_helper.rb
163
- - spec/support/time.rb
164
133
  homepage: https://github.com/jfelchner/ruby-progressbar
165
134
  licenses:
166
135
  - MIT
167
- metadata: {}
168
- post_install_message:
136
+ metadata:
137
+ bug_tracker_uri: https://github.com/jfelchner/ruby-progressbar/issues
138
+ changelog_uri: https://github.com/jfelchner/ruby-progressbar/blob/master/CHANGELOG.md
139
+ documentation_uri: https://github.com/jfelchner/ruby-progressbar/tree/releases/v1.11.0
140
+ homepage_uri: https://github.com/jfelchner/ruby-progressbar
141
+ source_code_uri: https://github.com/jfelchner/ruby-progressbar
142
+ wiki_uri: https://github.com/jfelchner/ruby-progressbar/wiki
143
+ post_install_message:
169
144
  rdoc_options: []
170
145
  require_paths:
171
146
  - lib
@@ -180,30 +155,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
155
  - !ruby/object:Gem::Version
181
156
  version: '0'
182
157
  requirements: []
183
- rubyforge_project:
184
- rubygems_version: 2.5.1
185
- signing_key:
158
+ rubygems_version: 3.2.3
159
+ signing_key:
186
160
  specification_version: 4
187
161
  summary: Ruby/ProgressBar is a flexible text progress bar library for Ruby.
188
- test_files:
189
- - spec/fixtures/benchmark.rb
190
- - spec/ruby-progressbar/base_spec.rb
191
- - spec/ruby-progressbar/calculators/length_calculator_spec.rb
192
- - spec/ruby-progressbar/calculators/running_average_spec.rb
193
- - spec/ruby-progressbar/components/bar_spec.rb
194
- - spec/ruby-progressbar/components/percentage_spec.rb
195
- - spec/ruby-progressbar/components/rate_spec.rb
196
- - spec/ruby-progressbar/components/throttle_spec.rb
197
- - spec/ruby-progressbar/components/time_spec.rb
198
- - spec/ruby-progressbar/components/title_spec.rb
199
- - spec/ruby-progressbar/format/formatter_spec.rb
200
- - spec/ruby-progressbar/format/molecule_spec.rb
201
- - spec/ruby-progressbar/format/string_spec.rb
202
- - spec/ruby-progressbar/output_spec.rb
203
- - spec/ruby-progressbar/outputs/non_tty_spec.rb
204
- - spec/ruby-progressbar/outputs/tty_spec.rb
205
- - spec/ruby-progressbar/progress_spec.rb
206
- - spec/ruby-progressbar/time_spec.rb
207
- - spec/ruby-progressbar/timer_spec.rb
208
- - spec/spec_helper.rb
209
- - spec/support/time.rb
162
+ test_files: []
metadata.gz.sig CHANGED
Binary file
@@ -1,9 +0,0 @@
1
- require 'rspectacular'
2
- require 'ruby-progressbar/calculators/length'
3
-
4
- class ProgressBar
5
- module Calculators
6
- describe Length do
7
- end
8
- end
9
- end
@@ -1,28 +0,0 @@
1
- # bundle exec ruby-prof --printer=graph_html
2
- # --file=../results.html
3
- # --require 'ruby-progressbar'
4
- # --sort=total ./spec/fixtures/benchmark.rb
5
-
6
- total = 100_000
7
- # output = File.open('/Users/jfelchner/Downloads/benchmark.txt', 'w+')
8
- output = $stdout
9
-
10
- # Progressbar gem
11
- # bar = ProgressBar.new('Progress', total)
12
- #
13
- # total.times do |i|
14
- # bar.inc
15
- # end
16
- #
17
- # bar.finish
18
-
19
- # Ruby/ProgressBar
20
- bar = ProgressBar.create(:output => output,
21
- :length => 80,
22
- :start => 0,
23
- :total => total)
24
-
25
- total.times do |_i|
26
- # bar.log i
27
- bar.increment
28
- end
@@ -1,949 +0,0 @@
1
- require 'spec_helper'
2
- require 'support/time'
3
- require 'stringio'
4
-
5
- # rubocop:disable Metrics/LineLength, Style/UnneededInterpolation
6
- RSpec.describe ProgressBar::Base do
7
- let(:output) do
8
- StringIO.new('', 'w+').tap do |io|
9
- allow(io).to receive(:tty?).and_return true
10
- end
11
- end
12
-
13
- let(:non_tty_output) do
14
- StringIO.new('', 'w+').tap do |io|
15
- allow(io).to receive(:tty?).and_return false
16
- end
17
- end
18
-
19
- let(:progressbar) { ProgressBar::Base.new(:output => output, :length => 80, :throttle_rate => 0.0) }
20
-
21
- context 'when the terminal width is shorter than the string being output' do
22
- it 'can properly handle outputting the bar when the length changes on the fly to less than the minimum width' do
23
- progressbar = ProgressBar::Base.new(:output => output, :title => 'a' * 25, :format => '%t%B', :throttle_rate => 0.0)
24
-
25
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
26
- and_return 30
27
-
28
- progressbar.start
29
-
30
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
31
- and_return 20
32
-
33
- progressbar.increment
34
-
35
- output.rewind
36
- expect(output.read).to match(/\raaaaaaaaaaaaaaaaaaaaaaaaa \r\s+\raaaaaaaaaaaaaaaaaaaaaaaaa\r\z/)
37
- end
38
-
39
- context 'and the bar length is calculated' do
40
- it 'returns the proper string' do
41
- progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21), :starting_at => 5, :total => 10, :autostart => false)
42
-
43
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
44
- and_return 20
45
-
46
- expect(progressbar.to_s('%t%w')).to eql '*********************'
47
- end
48
- end
49
-
50
- context 'and the incomplete bar length is calculated' do
51
- it 'returns the proper string' do
52
- progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21), :autostart => false)
53
-
54
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
55
- and_return 20
56
-
57
- expect(progressbar.to_s('%t%i')).to eql '*********************'
58
- end
59
-
60
- it 'returns the proper string' do
61
- progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21), :starting_at => 5, :total => 10, :autostart => false)
62
-
63
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
64
- and_return 20
65
-
66
- expect(progressbar.to_s('%t%i')).to eql '*********************'
67
- end
68
- end
69
-
70
- context 'and the full bar length is calculated (but lacks the space to output the entire bar)' do
71
- it 'returns the proper string' do
72
- progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 19), :starting_at => 5, :total => 10, :autostart => false)
73
-
74
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
75
- and_return 20
76
-
77
- expect(progressbar.to_s('%t%B')).to eql '******************* '
78
- end
79
-
80
- it 'returns the proper string' do
81
- progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 19), :starting_at => 5, :total => 10, :autostart => false)
82
-
83
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
84
- and_return 20
85
-
86
- expect(progressbar.to_s('%t%w%i')).to eql '******************* '
87
- end
88
- end
89
- end
90
-
91
- context 'when a new bar is created' do
92
- context 'and no options are passed' do
93
- let(:progressbar) { ProgressBar::Base.new }
94
-
95
- describe '#title' do
96
- it 'returns the default title' do
97
- expect(progressbar.send(:title).to_s).to eql ProgressBar::Components::Title::DEFAULT_TITLE
98
- end
99
- end
100
-
101
- describe '#output' do
102
- it 'returns the default output stream' do
103
- expect(progressbar.send(:output).send(:stream)).to eql ProgressBar::Output::DEFAULT_OUTPUT_STREAM
104
- end
105
- end
106
-
107
- describe '#length' do
108
- context 'when the RUBY_PROGRESS_BAR_LENGTH environment variable exists' do
109
- before { ENV['RUBY_PROGRESS_BAR_LENGTH'] = '44' }
110
- after { ENV['RUBY_PROGRESS_BAR_LENGTH'] = nil }
111
-
112
- it 'returns the length of the environment variable as an integer' do
113
- progressbar = ProgressBar::Base.new
114
- expect(progressbar.send(:output).send(:length_calculator).send(:length)).to eql 44
115
- end
116
- end
117
-
118
- context 'when the RUBY_PROGRESS_BAR_LENGTH environment variable does not exist' do
119
- before { ENV['RUBY_PROGRESS_BAR_LENGTH'] = nil }
120
-
121
- context 'but the length option was passed in' do
122
- it 'returns the length specified in the option' do
123
- progressbar = ProgressBar::Base.new(:length => 88)
124
- expect(progressbar.send(:output).send(:length_calculator).send(:length)).to eql 88
125
- end
126
- end
127
-
128
- context 'and no length option was passed in' do
129
- it 'returns the width of the terminal if it is a Unix environment' do
130
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).and_return(99)
131
- progressbar.send(:output).send(:length_calculator).send(:reset_length)
132
- expect(progressbar.send(:output).send(:length_calculator).send(:length)).to eql 99
133
- end
134
-
135
- it 'returns 80 if it is not a Unix environment' do
136
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:unix?).and_return(false)
137
- progressbar.send(:output).send(:length_calculator).send(:reset_length)
138
- expect(progressbar.send(:output).send(:length_calculator).send(:length)).to eql 80
139
- end
140
- end
141
- end
142
- end
143
- end
144
-
145
- context 'and options are passed' do
146
- let(:progressbar) { ProgressBar::Base.new(:title => 'We All Float', :total => 12, :output => STDOUT, :progress_mark => 'x', :length => 88, :starting_at => 5) }
147
-
148
- describe '#title' do
149
- it 'returns the overridden title' do
150
- expect(progressbar.send(:title).to_s).to eql 'We All Float'
151
- end
152
- end
153
-
154
- describe '#output' do
155
- it 'returns the overridden output stream' do
156
- expect(progressbar.send(:output).send(:stream)).to eql STDOUT
157
- end
158
- end
159
-
160
- describe '#length' do
161
- it 'returns the overridden length' do
162
- expect(progressbar.send(:output).send(:length_calculator).send(:length)).to eql 88
163
- end
164
- end
165
- end
166
-
167
- context 'if the bar was started 4 minutes ago' do
168
- before do
169
- Timecop.travel(-240) do
170
- progressbar.start
171
- end
172
- end
173
-
174
- context 'and within 2 minutes it was halfway done' do
175
- before do
176
- Timecop.travel(-120) do
177
- 50.times { progressbar.increment }
178
- end
179
- end
180
-
181
- describe '#finish' do
182
- before do
183
- Timecop.travel(-120) do
184
- progressbar.finish
185
- end
186
- end
187
-
188
- it 'completes the bar' do
189
- output.rewind
190
- expect(output.read).to match(/Progress: \|#{'=' * 68}\|\n/)
191
- end
192
-
193
- it 'shows the elapsed time instead of the estimated time since the bar is completed' do
194
- expect(progressbar.to_s('%e')).to eql 'Time: 00:02:00'
195
- end
196
-
197
- it 'calculates the elapsed time to 00:02:00' do
198
- expect(progressbar.to_s('%a')).to eql 'Time: 00:02:00'
199
- end
200
- end
201
- end
202
- end
203
-
204
- context 'which includes ANSI SGR codes in the format string' do
205
- it 'properly calculates the length of the bar by removing the long version of the ANSI codes from the calculated length' do
206
- @color_code = "\e[0m\e[32m\e[7m\e[1m"
207
- @reset_code = "\e[0m"
208
- @progress_mark = "#{@color_code} #{@reset_code}"
209
- progressbar = ProgressBar::Base.new(:format => "#{@color_code}Processing... %b%i#{@reset_code}#{@color_code} %p%%#{@reset_code}",
210
- :progress_mark => @progress_mark,
211
- :output => output,
212
- :length => 24,
213
- :starting_at => 3,
214
- :total => 6,
215
- :throttle_rate => 0.0)
216
-
217
- progressbar.increment
218
- progressbar.increment
219
-
220
- output.rewind
221
- expect(output.read).to 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"
222
- end
223
-
224
- it 'properly calculates the length of the bar by removing the short version of the ANSI codes from the calculated length' do
225
- @color_code = "\e[0;32;7;1m"
226
- @reset_code = "\e[0m"
227
- @progress_mark = "#{@color_code} #{@reset_code}"
228
- progressbar = ProgressBar::Base.new(:format => "#{@color_code}Processing... %b%i#{@reset_code}#{@color_code} %p%%#{@reset_code}",
229
- :progress_mark => @progress_mark,
230
- :output => output,
231
- :length => 24,
232
- :starting_at => 3,
233
- :total => 6,
234
- :throttle_rate => 0.0)
235
-
236
- progressbar.increment
237
- progressbar.increment
238
-
239
- output.rewind
240
- expect(output.read).to 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"
241
- end
242
- end
243
-
244
- context 'for a TTY enabled device' do
245
- it 'can log messages' do
246
- progressbar = ProgressBar::Base.new(:output => output, :length => 20, :starting_at => 3, :total => 6, :throttle_rate => 0.0)
247
- progressbar.increment
248
- progressbar.log 'We All Float'
249
- progressbar.increment
250
-
251
- output.rewind
252
- expect(output.read).to include "Progress: |==== |\rProgress: |===== |\r \rWe All Float\nProgress: |===== |\rProgress: |====== |\r"
253
- end
254
- end
255
-
256
- context 'for a non-TTY enabled device' do
257
- it 'can log messages' do
258
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 4, :total => 6, :throttle_rate => 0.0)
259
- progressbar.increment
260
- progressbar.log 'We All Float'
261
- progressbar.increment
262
- progressbar.finish
263
-
264
- non_tty_output.rewind
265
- expect(non_tty_output.read).to include "We All Float\nProgress: |========|\n"
266
- end
267
-
268
- it 'can output the bar properly so that it does not spam the screen' do
269
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
270
-
271
- 6.times { progressbar.increment }
272
-
273
- non_tty_output.rewind
274
- expect(non_tty_output.read).to eql "\n\nProgress: |========|\n"
275
- end
276
-
277
- it 'can output the bar properly if finished in the middle of its progress' do
278
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
279
-
280
- 3.times { progressbar.increment }
281
-
282
- progressbar.finish
283
-
284
- non_tty_output.rewind
285
- expect(non_tty_output.read).to eql "\n\nProgress: |========|\n"
286
- end
287
-
288
- it 'can output the bar properly if stopped in the middle of its progress' do
289
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
290
-
291
- 3.times { progressbar.increment }
292
-
293
- progressbar.stop
294
-
295
- non_tty_output.rewind
296
- expect(non_tty_output.read).to eql "\n\nProgress: |====\n"
297
- end
298
-
299
- it 'ignores changes to the title due to the fact that the bar length cannot change' do
300
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
301
-
302
- 3.times { progressbar.increment }
303
-
304
- progressbar.title = 'Testing'
305
- progressbar.stop
306
-
307
- non_tty_output.rewind
308
-
309
- expect(non_tty_output.read).to eql "\n\nProgress: |====\n"
310
- end
311
-
312
- it 'allows the title to be customized when the bar is created' do
313
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :title => 'Custom', :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
314
-
315
- 3.times { progressbar.increment }
316
-
317
- progressbar.stop
318
-
319
- non_tty_output.rewind
320
-
321
- expect(non_tty_output.read).to eql "\n\nCustom: |=====\n"
322
- end
323
- end
324
- end
325
-
326
- context 'when a bar is about to be completed' do
327
- let(:progressbar) { ProgressBar::Base.new(:starting_at => 5, :total => 6, :output => output, :length => 20, :throttle_rate => 0.0) }
328
-
329
- context 'and it is incremented' do
330
- before { progressbar.increment }
331
-
332
- it 'registers as being "finished"' do
333
- expect(progressbar).to be_finished
334
- end
335
-
336
- it 'prints a new line' do
337
- output.rewind
338
- expect(output.read.end_with?("\n")).to eql true
339
- end
340
-
341
- it 'does not continue to print bars if finish is subsequently called' do
342
- progressbar.finish
343
-
344
- output.rewind
345
- expect(output.read).to end_with " \rProgress: |====== |\rProgress: |========|\n"
346
- end
347
- end
348
- end
349
-
350
- context 'when a bar with autofinish=false is about to be completed' do
351
- let(:progressbar) { ProgressBar::Base.new(:autofinish => false, :starting_at => 5, :total => 6, :output => output, :length => 20, :throttle_rate => 0.0) }
352
-
353
- context 'and it is incremented' do
354
- before { progressbar.increment }
355
-
356
- it 'does not automatically finish' do
357
- expect(progressbar).not_to be_finished
358
- end
359
-
360
- it 'does not prints a new line' do
361
- output.rewind
362
-
363
- expect(output.read.end_with?("\n")).to eql false
364
- end
365
-
366
- it 'allows reset' do
367
- progressbar.finish
368
- expect(progressbar).to be_finished
369
-
370
- progressbar.reset
371
-
372
- expect(progressbar).not_to be_finished
373
- end
374
-
375
- it 'does prints a new line when manually finished' do
376
- progressbar.finish
377
- expect(progressbar).to be_finished
378
-
379
- output.rewind
380
-
381
- expect(output.read.end_with?("\n")).to eql true
382
- end
383
-
384
- it 'does not continue to print bars if finish is subsequently called' do
385
- progressbar.finish
386
-
387
- output.rewind
388
-
389
- expect(output.read).to end_with " \rProgress: |====== |\rProgress: |========|\rProgress: |========|\n"
390
- end
391
- end
392
- end
393
-
394
- context 'when a bar has an unknown amount to completion' do
395
- let(:progressbar) { ProgressBar::Base.new(:total => nil, :output => output, :length => 80, :unknown_progress_animation_steps => ['=--', '-=-', '--=']) }
396
-
397
- it 'is represented correctly' do
398
- expect(progressbar.to_s('%i')).to eql '=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=-'
399
- end
400
-
401
- it 'is represented after being incremented once' do
402
- progressbar.increment
403
- expect(progressbar.to_s('%i')).to eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--='
404
- end
405
-
406
- it 'is represented after being incremented twice' do
407
- progressbar.increment
408
- progressbar.increment
409
- expect(progressbar.to_s('%i')).to eql '--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--'
410
- end
411
-
412
- it 'displays the proper ETA' do
413
- progressbar.increment
414
-
415
- expect(progressbar.to_s('%i%e')).to eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=- ETA: ??:??:??'
416
- expect(progressbar.to_s('%i%E')).to eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=- ETA: ??:??:??'
417
- end
418
- end
419
-
420
- context 'when a bar is started' do
421
- let(:progressbar) { ProgressBar::Base.new(:starting_at => 0, :total => 100, :output => output, :length => 80, :throttle_rate => 0.0) }
422
-
423
- context 'and it is incremented any number of times' do
424
- before { 10.times { progressbar.increment } }
425
-
426
- describe '#progress_mark=' do
427
- it 'changes the mark used to represent progress and updates the output' do
428
- progressbar.progress_mark = 'x'
429
-
430
- output.rewind
431
- expect(output.read).to match(/\rProgress: \|xxxxxx#{' ' * 62}\|\r\z/)
432
- end
433
- end
434
-
435
- describe '#remainder_mark=' do
436
- it 'changes the mark used to represent the remaining part of the bar and updates the output' do
437
- progressbar.remainder_mark = 'x'
438
-
439
- output.rewind
440
- expect(output.read).to match(/\rProgress: \|======#{'x' * 62}\|\r\z/)
441
- end
442
- end
443
-
444
- describe '#title=' do
445
- it 'changes the title used to represent the items being progressed and updates the output' do
446
- progressbar.title = 'Items'
447
-
448
- output.rewind
449
- expect(output.read).to match(/\rItems: \|=======#{' ' * 64}\|\r\z/)
450
- end
451
- end
452
-
453
- describe '#reset' do
454
- before { progressbar.reset }
455
-
456
- it 'resets the bar back to the starting value' do
457
- output.rewind
458
- expect(output.read).to match(/\rProgress: \|#{' ' * 68}\|\r\z/)
459
- end
460
- end
461
-
462
- describe '#stop' do
463
- before { progressbar.stop }
464
-
465
- it 'forcibly halts the bar wherever it is and cancels it' do
466
- output.rewind
467
- expect(output.read).to match(/\rProgress: \|======#{' ' * 62}\|\n\z/)
468
- end
469
-
470
- it 'does not output the bar multiple times if the bar is already stopped' do
471
- output.rewind
472
- progressbar.stop
473
- output.rewind
474
-
475
- expect(output.read).to start_with "#{' ' * 80}"
476
- end
477
- end
478
-
479
- describe '#resume' do
480
- it 'does not output the bar multiple times' do
481
- output.rewind
482
- progressbar.resume
483
- output.rewind
484
-
485
- expect(output.read).to start_with "#{' ' * 80}"
486
- end
487
- end
488
- end
489
- end
490
-
491
- context 'when a bar is started from 10/100' do
492
- let(:progressbar) { ProgressBar::Base.new(:starting_at => 10, :total => 100, :output => output, :length => 112) }
493
-
494
- context 'and it is incremented any number of times' do
495
- before { 10.times { progressbar.increment } }
496
-
497
- describe '#reset' do
498
- before { progressbar.reset }
499
-
500
- it 'resets the bar back to the starting value' do
501
- output.rewind
502
- expect(output.read).to match(/\rProgress: \|==========#{' ' * 90}\|\r\z/)
503
- end
504
- end
505
- end
506
- end
507
-
508
- describe '#clear' do
509
- it 'clears the current terminal line and/or bar text' do
510
- progressbar.clear
511
-
512
- output.rewind
513
- expect(output.read).to match(/^#{progressbar.send(:output).send(:clear_string)}/)
514
- end
515
- end
516
-
517
- describe '#start' do
518
- it 'clears the current terminal line' do
519
- progressbar.start
520
-
521
- output.rewind
522
- expect(output.read).to match(/^#{progressbar.send(:output).send(:clear_string)}/)
523
- end
524
-
525
- it 'prints the bar for the first time' do
526
- progressbar.start
527
-
528
- output.rewind
529
- expect(output.read).to match(/Progress: \| \|\r\z/)
530
- end
531
-
532
- it 'prints correctly if passed a position to start at' do
533
- progressbar.start(:at => 20)
534
-
535
- output.rewind
536
- expect(output.read).to match(/Progress: \|============= \|\r\z/)
537
- end
538
- end
539
-
540
- context 'when the bar has not been completed' do
541
- let(:progressbar) { ProgressBar::Base.new(:length => 112, :starting_at => 0, :total => 50, :output => output, :throttle_rate => 0.0) }
542
-
543
- describe '#increment' do
544
- before { progressbar.increment }
545
-
546
- it 'displays the bar with the correct formatting' do
547
- output.rewind
548
- expect(output.read).to match(/Progress: \|== \|\r\z/)
549
- end
550
- end
551
- end
552
-
553
- context 'when a new bar is created with a specific format' do
554
- context '#format' do
555
- let(:progressbar) { ProgressBar::Base.new(:format => '%B %p%%') }
556
-
557
- context 'if called with no arguments' do
558
- before { progressbar.format = nil }
559
-
560
- it 'resets the format back to the default' do
561
- expect(progressbar.to_s).to match(/^Progress: \|\s+\|\z/)
562
- end
563
- end
564
-
565
- context 'if called with a specific format string' do
566
- before { progressbar.format = '%t' }
567
-
568
- it 'sets it as the new format for the bar' do
569
- expect(progressbar.to_s).to match(/^Progress\z/)
570
- end
571
- end
572
- end
573
-
574
- context '#to_s' do
575
- context 'when no time has elapsed' do
576
- it 'displays zero for the rate' do
577
- Timecop.freeze do
578
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0)
579
-
580
- expect(progressbar.to_s('%r')).to match(/^0\z/)
581
- end
582
- end
583
- end
584
-
585
- context 'when any time has elasped' do
586
- context 'and the standard rate is applied' do
587
- it 'displays zero for %r if no progress has been made' do
588
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
589
-
590
- Timecop.travel(2) do
591
- expect(progressbar.to_s('%r')).to match(/^0\z/)
592
- end
593
- end
594
-
595
- it 'displays zero for %R if no progress has been made' do
596
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
597
-
598
- Timecop.travel(2) do
599
- expect(progressbar.to_s('%R')).to match(/^0.00\z/)
600
- end
601
- end
602
-
603
- it 'takes into account the starting position when calculating %r' do
604
- Timecop.freeze do
605
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
606
- progressbar.start
607
- progressbar.progress += 20
608
-
609
- Timecop.travel(2) do
610
- expect(progressbar.to_s('%r')).to match(/^10\z/)
611
- end
612
- end
613
- end
614
-
615
- it 'takes into account the starting position when calculating %R' do
616
- Timecop.freeze do
617
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
618
- progressbar.start
619
- progressbar.progress += 13
620
-
621
- Timecop.travel(2) do
622
- expect(progressbar.to_s('%R')).to match(/^6.50\z/)
623
- end
624
- end
625
- end
626
-
627
- it 'displays the rate when passed the "%r" format flag' do
628
- Timecop.freeze do
629
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0)
630
- progressbar.start
631
- progressbar.progress += 20
632
-
633
- Timecop.travel(2) do
634
- expect(progressbar.to_s('%r')).to match(/^10\z/)
635
- end
636
- end
637
- end
638
-
639
- it 'displays the rate when passed the "%R" format flag' do
640
- Timecop.freeze do
641
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0)
642
- progressbar.start
643
- progressbar.progress += 10
644
-
645
- Timecop.travel(6) do
646
- expect(progressbar.to_s('%R')).to match(/^1.67\z/)
647
- end
648
- end
649
- end
650
- end
651
-
652
- context 'and the a custom rate is applied' do
653
- it 'displays zero for %r if no progress has been made' do
654
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
655
-
656
- Timecop.travel(2) do
657
- expect(progressbar.to_s('%r')).to match(/^0\z/)
658
- end
659
- end
660
-
661
- it 'displays zero for %R if no progress has been made' do
662
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
663
-
664
- Timecop.travel(2) do
665
- expect(progressbar.to_s('%R')).to match(/^0.00\z/)
666
- end
667
- end
668
-
669
- it 'takes into account the starting position when calculating %r' do
670
- Timecop.freeze do
671
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
672
- progressbar.start
673
- progressbar.progress += 20
674
-
675
- Timecop.travel(2) do
676
- expect(progressbar.to_s('%r')).to match(/^5\z/)
677
- end
678
- end
679
- end
680
-
681
- it 'takes into account the starting position when calculating %R' do
682
- Timecop.freeze do
683
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
684
- progressbar.start
685
- progressbar.progress += 13
686
-
687
- Timecop.travel(2) do
688
- expect(progressbar.to_s('%R')).to match(/^3.25\z/)
689
- end
690
- end
691
- end
692
-
693
- it 'displays the rate when passed the "%r" format flag' do
694
- Timecop.freeze do
695
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0, :rate_scale => lambda { |rate| rate / 2 })
696
- progressbar.start
697
- progressbar.progress += 20
698
-
699
- Timecop.travel(2) do
700
- expect(progressbar.to_s('%r')).to match(/^5\z/)
701
- end
702
- end
703
- end
704
-
705
- it 'displays the rate when passed the "%R" format flag' do
706
- Timecop.freeze do
707
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0, :rate_scale => lambda { |rate| rate / 2 })
708
- progressbar.start
709
- progressbar.progress += 10
710
-
711
- Timecop.travel(6) do
712
- expect(progressbar.to_s('%R')).to match(/^0.83\z/)
713
- end
714
- end
715
- end
716
- end
717
- end
718
-
719
- it 'displays the title when passed the "%t" format flag' do
720
- expect(progressbar.to_s('%t')).to match(/^Progress\z/)
721
- end
722
-
723
- it 'displays the title when passed the "%T" format flag' do
724
- expect(progressbar.to_s('%T')).to match(/^Progress\z/)
725
- end
726
-
727
- it 'displays the bar when passed the "%B" format flag (including empty space)' do
728
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
729
- expect(progressbar.to_s('%B')).to match(/^#{'=' * 20}#{' ' * 80}\z/)
730
- end
731
-
732
- it 'displays the bar when passed the combined "%b%i" format flags' do
733
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
734
- expect(progressbar.to_s('%b%i')).to match(/^#{'=' * 20}#{' ' * 80}\z/)
735
- end
736
-
737
- it 'displays the bar when passed the "%b" format flag (excluding empty space)' do
738
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
739
- expect(progressbar.to_s('%b')).to match(/^#{'=' * 20}\z/)
740
- end
741
-
742
- it 'displays the incomplete space when passed the "%i" format flag' do
743
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
744
- expect(progressbar.to_s('%i')).to match(/^#{' ' * 80}\z/)
745
- end
746
-
747
- it 'displays the bar when passed the "%w" format flag' do
748
- progressbar = ProgressBar::Base.new(:output => output, :length => 100, :starting_at => 0)
749
-
750
- expect(progressbar.to_s('%w')).to match(/^\z/)
751
- 4.times { progressbar.increment }
752
- expect(progressbar.to_s('%w')).to match(/^====\z/)
753
- progressbar.increment
754
- expect(progressbar.to_s('%w')).to match(/^= 5 =\z/)
755
- 5.times { progressbar.increment }
756
- expect(progressbar.to_s('%w')).to match(/^=== 10 ===\z/)
757
- progressbar.decrement
758
- expect(progressbar.to_s('%w')).to match(/^=== 9 ===\z/)
759
- 91.times { progressbar.increment }
760
- expect(progressbar.to_s('%w')).to match(/^#{'=' * 47} 100 #{'=' * 48}\z/)
761
- end
762
-
763
- it 'calculates the remaining negative space properly with an integrated percentage bar of 0 percent' do
764
- progressbar = ProgressBar::Base.new(:output => output, :length => 100, :total => 200, :starting_at => 0)
765
-
766
- expect(progressbar.to_s('%w%i')).to match(/^\s{100}\z/)
767
- 9.times { progressbar.increment }
768
- expect(progressbar.to_s('%w%i')).to match(/^====\s{96}\z/)
769
- progressbar.increment
770
- expect(progressbar.to_s('%w%i')).to match(/^= 5 =\s{95}\z/)
771
- end
772
-
773
- it 'can display a percentage, even if the total is unknown' do
774
- progressbar = ProgressBar::Base.new(:output => output, :length => 100, :total => nil, :starting_at => 0)
775
-
776
- expect(progressbar.to_s('%p')).to match(/\A0\z/)
777
- expect(progressbar.to_s('%P')).to match(/\A0\.0\z/)
778
- end
779
-
780
- it 'can display a percentage, even if the total is zero' do
781
- progressbar = ProgressBar::Base.new(:output => output, :length => 100, :total => 0, :starting_at => 0)
782
-
783
- expect(progressbar.to_s('%p')).to match(/\A100\z/)
784
- expect(progressbar.to_s('%P')).to match(/\A100\.0\z/)
785
- end
786
-
787
- it 'displays the current capacity when passed the "%c" format flag' do
788
- progressbar = ProgressBar::Base.new(:output => output, :starting_at => 0)
789
-
790
- expect(progressbar.to_s('%c')).to match(/^0\z/)
791
- progressbar.increment
792
- expect(progressbar.to_s('%c')).to match(/^1\z/)
793
- progressbar.decrement
794
- expect(progressbar.to_s('%c')).to match(/^0\z/)
795
- end
796
-
797
- it 'displays the total capacity when passed the "%C" format flag' do
798
- progressbar = ProgressBar::Base.new(:total => 100)
799
-
800
- expect(progressbar.to_s('%C')).to match(/^100\z/)
801
- end
802
-
803
- it 'displays the percentage complete when passed the "%p" format flag' do
804
- progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
805
-
806
- expect(progressbar.to_s('%p')).to match(/^16\z/)
807
- end
808
-
809
- it 'displays the justified percentage complete when passed the "%j" format flag' do
810
- progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
811
-
812
- expect(progressbar.to_s('%j')).to match(/^ 16\z/)
813
- end
814
-
815
- it 'displays the percentage complete when passed the "%P" format flag' do
816
- progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
817
-
818
- expect(progressbar.to_s('%P')).to match(/^16.50\z/)
819
- end
820
-
821
- it 'displays the justified percentage complete when passed the "%J" format flag' do
822
- progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
823
-
824
- expect(progressbar.to_s('%J')).to match(/^ 16.50\z/)
825
- end
826
-
827
- it 'displays only up to 2 decimal places when using the "%P" flag' do
828
- progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
829
-
830
- expect(progressbar.to_s('%P')).to match(/^66.66\z/)
831
- end
832
-
833
- it 'displays a literal percent sign when using the "%%" flag' do
834
- progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
835
-
836
- expect(progressbar.to_s('%%')).to match(/^%\z/)
837
- end
838
-
839
- it 'displays a literal percent sign when using the "%%" flag' do
840
- progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
841
-
842
- expect(progressbar.to_s('%%')).to match(/^%\z/)
843
- end
844
-
845
- context 'when called after #start' do
846
- before do
847
- Timecop.travel(-3_723) do
848
- progressbar.start
849
- end
850
- end
851
-
852
- context 'and the bar is reset' do
853
- before { progressbar.reset }
854
-
855
- it 'displays "??:??:??" until finished when passed the %e flag' do
856
- expect(progressbar.to_s('%a')).to match(/^Time: --:--:--\z/)
857
- end
858
- end
859
-
860
- it 'displays the time elapsed when using the "%a" flag' do
861
- expect(progressbar.to_s('%a')).to match(/^Time: 01:02:03\z/)
862
- end
863
- end
864
-
865
- context 'when called before #start' do
866
- it 'displays unknown time until finished when passed the "%e" flag' do
867
- progressbar = ProgressBar::Base.new
868
- expect(progressbar.to_s('%e')).to match(/^ ETA: \?\?:\?\?:\?\?\z/)
869
- end
870
-
871
- context 'when started_at is set to a value greater than 0' do
872
- it 'displays unknown time until finished when passed the "%e" flag' do
873
- progressbar = ProgressBar::Base.new(:starting_at => 1)
874
- expect(progressbar.to_s('%e')).to match(/^ ETA: \?\?:\?\?:\?\?\z/)
875
- end
876
- end
877
- end
878
-
879
- context 'when called after #start' do
880
- let(:progressbar) do
881
- Timecop.travel(-3_723) do
882
- progressbar = ProgressBar::Base.new(:starting_at => 0, :output => output, :smoothing => 0.0)
883
- progressbar.start
884
- progressbar.progress = 50
885
- progressbar
886
- end
887
- end
888
-
889
- context 'and the bar is reset' do
890
- before { progressbar.reset }
891
-
892
- it 'displays "??:??:??" until finished when passed the "%e" flag' do
893
- expect(progressbar.to_s('%e')).to match(/^ ETA: \?\?:\?\?:\?\?\z/)
894
- end
895
- end
896
-
897
- it 'displays the estimated time remaining when using the "%e" flag' do
898
- expect(progressbar.to_s('%e')).to match(/^ ETA: 01:02:03\z/)
899
- end
900
- end
901
-
902
- context 'when it could take 100 hours or longer to finish' do
903
- let(:progressbar) do
904
- Timecop.travel(-120_000) do
905
- progressbar = ProgressBar::Base.new(:starting_at => 0, :total => 100, :output => output, :smoothing => 0.0)
906
- progressbar.start
907
- progressbar.progress = 25
908
- progressbar
909
- end
910
- end
911
-
912
- it 'displays "> 4 Days" until finished when passed the "%E" flag' do
913
- expect(progressbar.to_s('%E')).to match(/^ ETA: > 4 Days\z/)
914
- end
915
-
916
- it 'displays "??:??:??" until finished when passed the "%e" flag' do
917
- expect(progressbar.to_s('%e')).to match(/^ ETA: \?\?:\?\?:\?\?\z/)
918
- end
919
-
920
- it 'displays the exact estimated time until finished when passed the "%f" flag' do
921
- expect(progressbar.to_s('%f')).to match(/^ ETA: 100:00:00\z/)
922
- end
923
- end
924
- end
925
- end
926
-
927
- context 'when the bar is started after having total set to 0' do
928
- let(:progressbar) { ProgressBar::Base.new(:output => output, :autostart => false) }
929
-
930
- it 'does not throw an error' do
931
- progressbar.total = 0
932
-
933
- expect { progressbar.start }.not_to raise_error
934
- end
935
- end
936
-
937
- context 'when the bar has no items to process' do
938
- context 'and it has not been started' do
939
- let(:progressbar) { ProgressBar::Base.new(:started_at => 0, :total => 0, :autostart => false, :smoothing => 0.0, :format => ' %c/%C |%w>%i| %e ', :output => output) }
940
-
941
- it 'does not throw an error if told to stop' do
942
- progressbar.stop
943
-
944
- expect { progressbar.start }.not_to raise_error
945
- end
946
- end
947
- end
948
- end
949
- # rubocop:enable Metrics/LineLength