comparison 0.1.99 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a1be3dfdb9956ab89e40615d7e019ac31cefb24596e236acb5a99c4e30ff15a
4
- data.tar.gz: b8fce566958ce9801c2ccdab4adce9bbe9739e48b2fd92464763886702f918a6
3
+ metadata.gz: a0a0717dffff6def29846aef2510a3d20a3e5666fe30b5b581b3979172fafc46
4
+ data.tar.gz: 98b3eda0230973ff1c07fa81632be94550dba11930ef58f73adc4193891bbb64
5
5
  SHA512:
6
- metadata.gz: 5a252e4fd07af9024f0972b5a42b5665fac54f1807cbd7f88affd2236bbd9448ad57ae79bc9c78ba31901c723015a0b50fae6ffd46cf78af0d2e8468c6d83ff0
7
- data.tar.gz: f9d8b42bfed576f00e8bb200272b001f64a123f709603445e4a6fe165e7f6d4132f967308b3747cf5364c489d74b1b0647e18ebc1f1b78dd40282ec2ffd51f97
6
+ metadata.gz: dbe04c79ff6e8c17fa0eb0d38ebd60e5a2d7e138b8b807a9b76a606e1abfcbcd6f9af0cf79030a8a50b58e3a2f27f9bd24c990966d2fbdb63532e4f818abceb7
7
+ data.tar.gz: 2d4c10c029538936cfc61b13ac0d79777497fad1d1695c9862808a5421ef1bcc4b06d229fac076c0509ca341ead7dfb034176f27bea641e9934bee661d00c02b
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [![Gem Version](https://badge.fury.io/rb/comparison.svg)](https://badge.fury.io/rb/comparison) [![Build Status](https://travis-ci.org/jparker/comparison.svg?branch=master)](https://travis-ci.org/jparker/comparison)
1
+ # [![Gem Version](https://badge.fury.io/rb/comparison.svg)](https://badge.fury.io/rb/comparison)
2
2
 
3
3
  # Comparison
4
4
 
@@ -10,46 +10,36 @@ color-coded to indicate positive or negative growth. This plugin provides
10
10
  helpers that abstract the logic of deciding what to show into a handful of
11
11
  simple methods and leveraging I18n.
12
12
 
13
- ## Upgrade Notes
14
-
15
- This gem has been getting a facelift, and this has resulted in some changes
16
- from the old behavior.
17
-
18
- `Comparison::Presenter#classes` has been renamed to
19
- `Comparison::Presenter#dom_classes`, and `Comparison::Presenter#css` has been
20
- renamed to `Comparison::Presenter#style`. The old method names continue to
21
- work, but they will emit deprecation warnings.
22
-
23
- The I18n keys used by the above methods have been similarly renamed, but the
24
- methods will continue to fall back on the old keys. Going forward, use
25
- `comparison.dom_classes` instead of `comparison.classes` and `comparison.style`
26
- instead of `comparison.css`.
27
-
28
13
  ## Usage
29
14
 
30
- The library has three components: the Comparison class for performing the
31
- actual math, the Presenter class for decorating the Comparison with
32
- view-friendly output, and a helper module for using the Presenter with the
15
+ The library has three components: the `Comparator` class for performing the
16
+ actual math, the `Presenter` class for decorating the comparator with
17
+ view-friendly output, and a helper module for using the presenter with the
33
18
  view.
34
19
 
35
- `#compare` helper takes the two numbers to be compared and yields the
36
- Comparison presenter to a block.
20
+ The `#compare` helper takes the two numbers to be compared and yields the
21
+ presenter to a block.
37
22
 
38
- `#difference` provides the absolute difference between the two numbers,
39
- literally `m - n`.
23
+ `#difference_as_currency` provides the difference between the two numbers,
24
+ literally `value - other`, formatted as currency. Formatting is handled by
25
+ `ActiveSupport::NumberHelper#number_to_currency`.
40
26
 
41
27
  `#percentage` provides the percentage difference between the two numbers. Under
42
- the hood it uses `ActionView::Helpers::NumberHelper#number_to_percentage` to
43
- format the percentage. Options are passed through to that method.
28
+ the hood it uses `ActiveSupport#NumberHelper#number_to_percentage` to format
29
+ the percentage. Options are passed through to that method.
30
+
31
+ `#unsigned_percentage` returns the absolute value of the percentage. Use this
32
+ if you prefer to use other cues, such as colors or icons, to indicate positive
33
+ or negative changes.
44
34
 
45
35
  `#arrow` returns an HTML character entity for an arrow (up, down, or, for no
46
36
  change, an empty string).
47
37
 
48
38
  ```erb
49
- <%= compare m, n do |cmp| %>
50
- <td><%= number_to_currency m %></td>
51
- <td><%= number_to_currency n %></td>
52
- <td><%= cmp.difference %></td>
39
+ <%= compare value, other do |cmp| %>
40
+ <td><%= number_to_currency value %></td>
41
+ <td><%= number_to_currency other %></td>
42
+ <td><%= cmp.difference_as_currency %></td>
53
43
  <td>
54
44
  <%= cmp.arrow %>
55
45
  <%= cmp.percentage precision: 1 %>
@@ -80,10 +70,10 @@ en:
80
70
  positive: 'comparison positive'
81
71
  negative: 'comparison negative'
82
72
  nochange: 'comparison nochange'
83
- style:
84
- positive_html: 'color: #3c763d; background-color: #dff0d8;'
85
- negative_html: 'color: #a94442; background-color: #f2dede;'
86
- nochange_html: 'color: #777777;'
73
+ inline_style:
74
+ positive: 'color: #3c763d; background-color: #dff0d8;'
75
+ negative: 'color: #a94442; background-color: #f2dede;'
76
+ nochange: 'color: #777777;'
87
77
  icons:
88
78
  positive_html: '<span class="glyphicon glyphicon-arrow-up"></span>'
89
79
  negative_html: '<span class="glyphicon glyphicon-arrow-down"></span>'
@@ -92,8 +82,14 @@ en:
92
82
  positive_html: '&uarr;'
93
83
  negative_html: '&darr;'
94
84
  nochange_html: ''
85
+ infinity_html: '&infin;'
95
86
  ```
96
87
 
88
+ If the `dom_classes` keys are not present, translation falls back on `classes`.
89
+ If the `inline_style` keys are not present, translation falls back on `style`
90
+ and `css`. In both cases, those fallback keys are deprecated. Expect support
91
+ for those keys to eventually be dropped.
92
+
97
93
  ## Installation
98
94
 
99
95
  Add this line to your application's Gemfile:
@@ -107,9 +103,14 @@ And then execute:
107
103
  $ bundle
108
104
  ```
109
105
 
110
- Or install it yourself as:
111
- ```bash
112
- $ gem install comparison
106
+ Include the Comparison helpers by adding the following to your
107
+ application\_helper.rb:
108
+
109
+ ```ruby
110
+ # app/helpers/application_helper.rb
111
+ module ApplicationHelper
112
+ include Comparison::ApplicationHelper
113
+ end
113
114
  ```
114
115
 
115
116
  ## Contributing
@@ -3,16 +3,13 @@
3
3
  module Comparison
4
4
  module ApplicationHelper # :nodoc:
5
5
  ##
6
- # Returns a Presenter for a Comparator for +m+ and +n+.
6
+ # Returns a Presenter for a Comparator for +value+ and +other+.
7
7
  #
8
8
  # If a block is given, the Presenter is yielded to the block.
9
- #
10
- # rubocop:disable Naming/UncommunicativeMethodParamName
11
- def compare(m, n)
12
- comparison = Presenter.new Comparator.new m, n
9
+ def compare(value, other)
10
+ comparison = Presenter.new Comparator.new value, other
13
11
  yield comparison if block_given?
14
12
  comparison
15
13
  end
16
- # rubocop:enable Naming/UncommunicativeMethodParamName
17
14
  end
18
15
  end
@@ -1,6 +1,6 @@
1
1
  en:
2
2
  comparison:
3
- # classes:
3
+ # dom_classes:
4
4
  # positive: 'comparison positive'
5
5
  # negative: 'comparison negative'
6
6
  # nochange: 'comparison nochange'
@@ -10,10 +10,10 @@ en:
10
10
  # negative_html: '<span class="glyphicon glyphicon-arrow-down"></span>'
11
11
  # nochange_html: '<span class="glyphicon glyphicon-minus"></span>'
12
12
 
13
- style:
14
- positive_html: ''
15
- negative_html: ''
16
- nochange_html: ''
13
+ inline_style:
14
+ positive: ''
15
+ negative: ''
16
+ nochange: ''
17
17
 
18
18
  arrows:
19
19
  positive_html: '&uarr;'
@@ -10,40 +10,56 @@ module Comparison
10
10
  class Comparator
11
11
  extend Forwardable
12
12
 
13
+ attr_reader :value, :other
14
+
13
15
  ##
14
- # Instantiates a new Comparator to compare two numbers, +m+ and +n+.
16
+ # Instantiates a new Comparator to compare two numbers, +value+ and +other+.
15
17
  #
16
18
  # Both numbers will be converted to instances of `BigDecimal`.
17
- #
18
- # rubocop:disable Naming/UncommunicativeMethodParamName
19
- def initialize(m, n)
20
- @m = m.to_d
21
- @n = n.to_d
19
+ def initialize(value, other)
20
+ @value = value.to_d
21
+ @other = other.to_d
22
22
  end
23
- # rubocop:enable Naming/UncommunicativeMethodParamName
24
-
25
- attr_reader :m, :n
26
23
 
27
- delegate %i[infinite? nan? negative? positive? zero?] => :relative
24
+ delegate %i[negative? positive? zero? nonzero?] => :difference
25
+ delegate %i[infinite? nan?] => :change
28
26
 
29
27
  ##
30
- # Returns the difference between +@m+ and +@n+.
28
+ # Returns the difference between +@value+ and +@other+.
29
+ def difference
30
+ value - other
31
+ end
32
+
31
33
  def absolute
32
- @absolute ||= m - n
34
+ Kernel.warn "DEPRECATION WARNING: use #difference instead of #absolute (called from #{caller(1..1).first})"
35
+ difference
33
36
  end
34
37
 
35
- alias difference absolute
38
+ ##
39
+ # Returns the relative change of +@value+ from +@other+.
40
+ def change
41
+ difference / other.abs
42
+ end
36
43
 
37
44
  ##
38
- # Returns the percentage difference of +@m+ to +@n+.
45
+ # Returns the relative change of +@value+ from +@other+ as a percentage.
46
+ def percentage
47
+ change * 100
48
+ end
49
+
39
50
  def relative
40
- @relative ||= if n.negative?
41
- (1 - m / n) * 100
42
- else
43
- (m / n - 1) * 100
44
- end
51
+ Kernel.warn "DEPRECATION WARNING: use #percentage instead of #relative (called from #{caller(1..1).first})"
52
+ change
45
53
  end
46
54
 
47
- alias percentage relative
55
+ def m
56
+ Kernel.warn "DEPRECATION WARNING: use #value instead of #m (called from #{caller(1..1).first})"
57
+ value
58
+ end
59
+
60
+ def n
61
+ Kernel.warn "DEPRECATION WARNING: use #other instead of #n (called from #{caller(1..1).first})"
62
+ other
63
+ end
48
64
  end
49
65
  end
@@ -3,9 +3,5 @@
3
3
  module Comparison
4
4
  class Engine < ::Rails::Engine # :nodoc:
5
5
  isolate_namespace Comparison
6
-
7
- initializer 'comparison.view_helpers' do
8
- ActionView::Base.send :include, helpers
9
- end
10
6
  end
11
7
  end
@@ -9,39 +9,62 @@ module Comparison
9
9
  class Presenter < DelegateClass(Comparator)
10
10
  include ActionView::Helpers::TranslationHelper
11
11
 
12
- ARROWS = { up: '&uarr;', down: '&darr;', none: '' }.freeze
13
-
14
- # TODO: This shouldn't necessarily return a currency representation.
12
+ ARROWS = { positive: '&uarr;', negative: '&darr;', nochange: '' }.freeze
15
13
 
16
14
  ##
17
- # Returns Comparator#absolute presented as currency.
18
- def difference(**options)
15
+ # Returns Comparator#difference formatted as currency.
16
+ def difference_as_currency(**options)
19
17
  if positive?
20
- number_to_currency absolute, format: '+%u%n', **options
18
+ number_to_currency __getobj__.difference, format: '+%u%n', **options
21
19
  else
22
- number_to_currency absolute, **options
20
+ number_to_currency __getobj__.difference, **options
23
21
  end
24
22
  end
25
23
 
26
24
  ##
27
- # Returns Comparator#relative formatted as a percentage.
25
+ # Deprecated alias for `#difference_as_currency`.
26
+ #
27
+ # In a future release, this method will be changed to delegate directly
28
+ # `Comparator#difference`.
29
+ def difference(...)
30
+ Kernel.warn 'DEPRECATION WARNING: use #difference_as_currency instead of #difference' \
31
+ " (called from #{caller(3..3).first})"
32
+ difference_as_currency(...)
33
+ end
34
+
35
+ ##
36
+ # Returns Comparator#change formatted as a percentage.
37
+ #
38
+ # If the change evaluates to Infinity or -Infinity, the I18n translaation
39
+ # for infinity is returned. If no translation is defined, `nil` is
40
+ # returned.
28
41
  #
29
- # If the relative percentage evaluates to Infinity or -Infinity, +nil+ is
30
- # returned. If it evaluates to NaN, 0 is returned.
42
+ # If the change evaluates to NaN, it is returned as 0.
31
43
  def percentage(**options)
32
44
  if nan? || zero?
33
45
  number_to_percentage 0, **options
34
46
  elsif infinite?
35
- # TODO: Return nil, or lookup an optional representation in I18n?
36
- nil
47
+ t 'comparison.infinity_html', default: nil
37
48
  elsif positive?
38
- number_to_percentage relative, format: '+%n%', **options
49
+ number_to_percentage __getobj__.percentage, format: '+%n%', **options
39
50
  else
40
- number_to_percentage relative, **options
51
+ number_to_percentage __getobj__.percentage, **options
41
52
  end
42
53
  end
43
54
 
44
- # rubocop:disable Metrics/LineLength
55
+ ##
56
+ # Returns the absolute value of Comparator#change formatted as a percentage.
57
+ #
58
+ # See `#percentage` for additional information on special return scenarios.
59
+ #
60
+ # Use this if you are relying on other cues (colors and/or icons) to
61
+ # indicate positive or negative values.
62
+ def unsigned_percentage(**options)
63
+ return percentage(**options) if nan? || infinite?
64
+
65
+ number_to_percentage __getobj__.percentage.abs, **options
66
+ end
67
+
45
68
  ##
46
69
  # Returns the I18n translation for `comparison.icons`. (See also #arrow.)
47
70
  #
@@ -62,15 +85,9 @@ module Comparison
62
85
  # negative_html: '<span class="glyphicon glyphicon-arrow-down"></span>'
63
86
  # nochange_html: '<span class="glyphicon glyphicon-minus"></span>'
64
87
  #
65
- # rubocop:enable Metrics/LineLength
66
88
  def icon
67
- if positive?
68
- t 'comparison.icons.positive_html'
69
- elsif negative?
70
- t 'comparison.icons.negative_html'
71
- else
72
- t 'comparison.icons.nochange_html'
73
- end
89
+ key, = expand_i18n_keys 'icons', suffix: '_html'
90
+ t key
74
91
  end
75
92
 
76
93
  ##
@@ -104,13 +121,8 @@ module Comparison
104
121
  # #icons is meant to be used from full-featured view contexts. As such,
105
122
  # #icons is the one to use to generate HTML tags.
106
123
  def arrow
107
- if positive?
108
- t 'comparison.arrows.positive_html', default: ARROWS[:up]
109
- elsif negative?
110
- t 'comparison.arrows.negative_html', default: ARROWS[:down]
111
- else
112
- t 'comparison.arrows.nochange_html', default: ARROWS[:none]
113
- end
124
+ key, = expand_i18n_keys 'arrows', suffix: '_html'
125
+ t key, default: ARROWS[description.to_sym]
114
126
  end
115
127
 
116
128
  ##
@@ -142,27 +154,17 @@ module Comparison
142
154
  # # => "<span class=\"comparison positive\">+10%</span>"
143
155
  #
144
156
  # If you need to work with inline styles instead of CSS classes, see the
145
- # `#style` method.
157
+ # `#inline_style` method.
146
158
  def dom_classes
147
- if positive?
148
- t 'comparison.dom_classes.positive',
149
- default: %i[comparison.classes.positive]
150
- elsif negative?
151
- t 'comparison.dom_classes.negative',
152
- default: %i[comparison.classes.negative]
153
- else
154
- t 'comparison.dom_classes.nochange',
155
- default: %i[comparison.classes.nochange]
156
- end
159
+ key, *deprecated_keys = expand_i18n_keys(%w[dom_classes classes])
160
+ t key, default: deprecated_keys
157
161
  end
158
162
 
159
163
  def classes
160
- Kernel.warn '[DEPRECATION WARNING] #classes is deprecated: ' \
161
- "use #dom_classes instead: #{caller(3..3).first}"
164
+ Kernel.warn "DEPRECATION WARNING: use #dom_classes instead of #classes (called from #{caller(3..3).first})"
162
165
  dom_classes
163
166
  end
164
167
 
165
- # rubocop:disable Metrics/LineLength
166
168
  ##
167
169
  # Returns the I18n translation for `comparison.style`.
168
170
  #
@@ -171,49 +173,56 @@ module Comparison
171
173
  #
172
174
  # en:
173
175
  # comparison:
174
- # style:
176
+ # inline_style:
175
177
  # positive: 'color: #3c763d; background-color: #dff0d8;'
176
178
  # negative: 'color: #a94442; background-color: #f2dede;'
177
179
  # nochange: 'color: #777777;'
178
180
  #
179
- # content_tag :span, cmp.difference, style: cmp.style
181
+ # content_tag :span, cmp.difference, style: cmp.inline_style
180
182
  # # => "<span style=\"color: #3c763d; background-color: #dff0d8;\">+10%</span>"
181
183
  #
182
184
  # In general, it's probably preferable to use `#dom_classes` in conjunction
183
185
  # with CSS style rules defined separate CSS files, but this isn't always
184
186
  # possible.
185
187
  #
186
- # rubocop:enable Metrics/LineLength
187
- def style
188
+ def inline_style
189
+ key, *deprecated_keys = expand_i18n_keys(%w[inline_style style css])
190
+ t key, default: [*deprecated_keys, '']
191
+ end
192
+
193
+ alias style inline_style
194
+
195
+ def css
196
+ Kernel.warn "DEPRECATION WARNING: use #inline_style instead of #css (called from #{caller(3..3).first})"
197
+ inline_style
198
+ end
199
+
200
+ ##
201
+ # Returns a string description of the direction of change. Possible
202
+ # descriptions are "positive", "negative", and "nochange".
203
+ def description
188
204
  if positive?
189
- t 'comparison.style.positive',
190
- default: [:'comparison.css.positive', '']
205
+ 'positive'
191
206
  elsif negative?
192
- t 'comparison.style.negative',
193
- default: [:'comparison.css.negative', '']
207
+ 'negative'
194
208
  else
195
- t 'comparison.style.nochange',
196
- default: [:'comparison.css.nochange', '']
209
+ 'nochange'
197
210
  end
198
211
  end
199
212
 
200
- def css
201
- Kernel.warn '[DEPRECATION WARNING] #css is deprecated: ' \
202
- "use #style instead: #{caller(3..3).first}"
203
- style
204
- end
205
-
206
213
  private
207
214
 
208
- def number_to_percentage(value, delimiter: ',', precision: 0, **options)
209
- ActiveSupport::NumberHelper.number_to_percentage value,
210
- delimiter: delimiter,
211
- precision: precision,
212
- **options
215
+ def number_to_percentage(value, **options)
216
+ options = { delimiter: ',', precision: 0, **options }
217
+ ActiveSupport::NumberHelper.number_to_percentage value, options
213
218
  end
214
219
 
215
220
  def number_to_currency(*args)
216
221
  ActiveSupport::NumberHelper.number_to_currency(*args)
217
222
  end
223
+
224
+ def expand_i18n_keys(names, suffix: nil)
225
+ Array(names).map { |name| :"comparison.#{name}.#{description}#{suffix}" }
226
+ end
218
227
  end
219
228
  end
@@ -1,5 +1,5 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Comparison
4
- VERSION = '0.1.99'
4
+ VERSION = '0.2.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: comparison
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.99
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Parker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-30 00:00:00.000000000 Z
11
+ date: 2022-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,22 +16,22 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.0'
19
+ version: '5.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '6.0'
22
+ version: '8.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '4.0'
29
+ version: '5.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '6.0'
32
+ version: '8.0'
33
33
  - !ruby/object:Gem::Dependency
34
- name: minitest-focus
34
+ name: mocha
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
@@ -101,15 +101,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
101
  requirements:
102
102
  - - ">="
103
103
  - !ruby/object:Gem::Version
104
- version: '2.3'
104
+ version: '2.7'
105
105
  required_rubygems_version: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - ">="
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  requirements: []
111
- rubyforge_project:
112
- rubygems_version: 2.7.7
111
+ rubygems_version: 3.3.12
113
112
  signing_key:
114
113
  specification_version: 4
115
114
  summary: Helpers for displaying details of comparing two numbers.