comparison 0.1.99 → 0.2.1

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.
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.