shopify-money 0.14.8 → 0.15.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.
- checksums.yaml +4 -4
- data/lib/money/currency.rb +4 -0
- data/lib/money/money.rb +0 -18
- data/lib/money/null_currency.rb +32 -1
- data/lib/money/version.rb +1 -1
- data/lib/rubocop/cop/money.rb +1 -0
- data/lib/rubocop/cop/money/missing_currency.rb +16 -8
- data/lib/rubocop/cop/money/zero_money.rb +65 -0
- data/spec/allocator_spec.rb +3 -3
- data/spec/core_extensions_spec.rb +5 -5
- data/spec/currency_spec.rb +10 -0
- data/spec/money_column_spec.rb +1 -1
- data/spec/money_parser_spec.rb +2 -2
- data/spec/money_spec.rb +8 -57
- data/spec/rubocop/cop/money/missing_currency_spec.rb +43 -8
- data/spec/rubocop/cop/money/zero_money_spec.rb +78 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56953634d128da5cb62dfb11b5c60868a162c4ff7edb9bb810110d17c02469f9
|
4
|
+
data.tar.gz: c8e6f0e99b480cfcf9be4183adfc633baf14f0f9ee0d777bea01b225c01cfc09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4888a59e2f50348092b73c2b7255b215f994f9b47efbd379ad88d6f4624f4eca403840f584f4d5760a17c02d20f38f0fc49f286c0e19e3557e4976037d1f8049
|
7
|
+
data.tar.gz: ce77e720fae3724a0cc8303336ac12aee09a7a61862f0ba01f0dc7dce3c4e86f2fd7073ee7828d5cc313b77d9b285dfce07bd84e1d8e289e597e1cf25a349c7d
|
data/lib/money/currency.rb
CHANGED
data/lib/money/money.rb
CHANGED
@@ -26,19 +26,10 @@ class Money
|
|
26
26
|
end
|
27
27
|
alias_method :from_amount, :new
|
28
28
|
|
29
|
-
def zero(currency = NULL_CURRENCY)
|
30
|
-
new(0, currency)
|
31
|
-
end
|
32
|
-
alias_method :empty, :zero
|
33
|
-
|
34
29
|
def parse(*args, **kwargs)
|
35
30
|
parser.parse(*args, **kwargs)
|
36
31
|
end
|
37
32
|
|
38
|
-
def from_cents(cents, currency = nil)
|
39
|
-
new(cents.round.to_f / 100, currency)
|
40
|
-
end
|
41
|
-
|
42
33
|
def from_subunits(subunits, currency_iso, format: :iso4217)
|
43
34
|
currency = Helpers.value_to_currency(currency_iso)
|
44
35
|
|
@@ -106,11 +97,6 @@ class Money
|
|
106
97
|
coder['currency'] = @currency.iso_code
|
107
98
|
end
|
108
99
|
|
109
|
-
def cents
|
110
|
-
# Money.deprecate('`money.cents` is deprecated and will be removed in the next major release. Please use `money.subunits` instead. Keep in mind, subunits are currency aware.')
|
111
|
-
(value * 100).to_i
|
112
|
-
end
|
113
|
-
|
114
100
|
def subunits(format: :iso4217)
|
115
101
|
subunit_to_unit_value = if format == :iso4217
|
116
102
|
@currency.subunit_to_unit
|
@@ -243,10 +229,6 @@ class Money
|
|
243
229
|
end
|
244
230
|
end
|
245
231
|
|
246
|
-
def to_liquid
|
247
|
-
cents
|
248
|
-
end
|
249
|
-
|
250
232
|
def to_json(options = {})
|
251
233
|
to_s
|
252
234
|
end
|
data/lib/money/null_currency.rb
CHANGED
@@ -1,5 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
class Money
|
3
|
+
# A placeholder currency for instances where no actual currency is available,
|
4
|
+
# as defined by ISO4217. You should rarely, if ever, need to use this
|
5
|
+
# directly. It's here mostly for backwards compatibility and for that reason
|
6
|
+
# behaves like a dollar, which is how this gem worked before the introduction
|
7
|
+
# of currency.
|
8
|
+
#
|
9
|
+
# Here follows a list of preferred alternatives over using Money with
|
10
|
+
# NullCurrency:
|
11
|
+
#
|
12
|
+
# For comparisons where you don't know the currency beforehand, you can use
|
13
|
+
# Numeric predicate methods like #positive?/#negative?/#zero?/#nonzero?.
|
14
|
+
# Comparison operators with Numeric (==, !=, <=, =>, <, >) work as well.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# Money.new(1, 'CAD').positive? #=> true
|
18
|
+
# Money.new(2, 'CAD') >= 0 #=> true
|
19
|
+
#
|
20
|
+
# Money with NullCurrency has behaviour that may surprise you, such as
|
21
|
+
# database validations or GraphQL enum not allowing the string representation
|
22
|
+
# of NullCurrency. Prefer using Money.new(0, currency) where possible, as
|
23
|
+
# this sidesteps these issues and provides additional currency check
|
24
|
+
# safeties.
|
25
|
+
#
|
26
|
+
# Unlike other currencies, it is allowed to calculate a Money object with
|
27
|
+
# NullCurrency with another currency. The resulting Money object will have
|
28
|
+
# the other currency.
|
29
|
+
#
|
30
|
+
# @example
|
31
|
+
# Money.new(0, Money::NULL_CURRENCY) + Money.new(5, 'CAD')
|
32
|
+
# #=> #<Money value:5.00 currency:CAD>
|
33
|
+
#
|
3
34
|
class NullCurrency
|
4
35
|
|
5
36
|
attr_reader :iso_code, :iso_numeric, :name, :smallest_denomination, :subunit_symbol,
|
@@ -9,7 +40,7 @@ class Money
|
|
9
40
|
@symbol = '$'
|
10
41
|
@disambiguate_symbol = nil
|
11
42
|
@subunit_symbol = nil
|
12
|
-
@iso_code = 'XXX'
|
43
|
+
@iso_code = 'XXX'
|
13
44
|
@iso_numeric = '999'
|
14
45
|
@name = 'No Currency'
|
15
46
|
@smallest_denomination = 1
|
data/lib/money/version.rb
CHANGED
data/lib/rubocop/cop/money.rb
CHANGED
@@ -20,11 +20,11 @@ module RuboCop
|
|
20
20
|
#
|
21
21
|
|
22
22
|
def_node_matcher :money_new, <<~PATTERN
|
23
|
-
(send (const nil? :Money) {:new :from_amount :from_cents} $...)
|
23
|
+
(send (const {nil? cbase} :Money) {:new :from_amount :from_cents} $...)
|
24
24
|
PATTERN
|
25
25
|
|
26
26
|
def_node_matcher :to_money_without_currency?, <<~PATTERN
|
27
|
-
(send _ :to_money)
|
27
|
+
({send csend} _ :to_money)
|
28
28
|
PATTERN
|
29
29
|
|
30
30
|
def_node_matcher :to_money_block?, <<~PATTERN
|
@@ -42,11 +42,9 @@ module RuboCop
|
|
42
42
|
add_offense(node, message: 'to_money is missing currency argument')
|
43
43
|
end
|
44
44
|
end
|
45
|
+
alias on_csend on_send
|
45
46
|
|
46
47
|
def autocorrect(node)
|
47
|
-
currency = cop_config['ReplacementCurrency']
|
48
|
-
return unless currency
|
49
|
-
|
50
48
|
receiver, method, _ = *node
|
51
49
|
|
52
50
|
lambda do |corrector|
|
@@ -55,20 +53,30 @@ module RuboCop
|
|
55
53
|
|
56
54
|
corrector.replace(
|
57
55
|
node.loc.expression,
|
58
|
-
"#{receiver.source}.#{method}(#{amount&.source || 0},
|
56
|
+
"#{receiver.source}.#{method}(#{amount&.source || 0}, #{replacement_currency})"
|
59
57
|
)
|
60
58
|
end
|
61
59
|
|
62
60
|
if to_money_without_currency?(node)
|
63
|
-
corrector.insert_after(node.loc.expression, "(
|
61
|
+
corrector.insert_after(node.loc.expression, "(#{replacement_currency})")
|
64
62
|
elsif to_money_block?(node)
|
65
63
|
corrector.replace(
|
66
64
|
node.loc.expression,
|
67
|
-
"#{receiver.source}.#{method} { |x| x.to_money(
|
65
|
+
"#{receiver.source}.#{method} { |x| x.to_money(#{replacement_currency}) }"
|
68
66
|
)
|
69
67
|
end
|
70
68
|
end
|
71
69
|
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def replacement_currency
|
74
|
+
if cop_config['ReplacementCurrency']
|
75
|
+
"'#{cop_config['ReplacementCurrency']}'"
|
76
|
+
else
|
77
|
+
'Money::NULL_CURRENCY'
|
78
|
+
end
|
79
|
+
end
|
72
80
|
end
|
73
81
|
end
|
74
82
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Money
|
6
|
+
class ZeroMoney < Cop
|
7
|
+
# `Money.zero` and it's alias `empty`, with or without currency
|
8
|
+
# argument is removed in favour of the more explicit Money.new
|
9
|
+
# syntax. Supplying it with a real currency is preferred for
|
10
|
+
# additional currency safety checks.
|
11
|
+
#
|
12
|
+
# If no currency was supplied, it defaults to
|
13
|
+
# Money::NULL_CURRENCY which was the default setting of
|
14
|
+
# Money.default_currency and should effectively be the same. The cop
|
15
|
+
# can be configured with a ReplacementCurrency in case that is more
|
16
|
+
# appropriate for your application.
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
#
|
20
|
+
# # bad
|
21
|
+
# Money.zero
|
22
|
+
#
|
23
|
+
# # good when configured with `ReplacementCurrency: CAD`
|
24
|
+
# Money.new(0, 'CAD')
|
25
|
+
#
|
26
|
+
|
27
|
+
MSG = 'Money.zero is removed, use `Money.new(0, %<currency>s)`.'
|
28
|
+
|
29
|
+
def_node_matcher :money_zero, <<~PATTERN
|
30
|
+
(send (const {nil? cbase} :Money) {:zero :empty} $...)
|
31
|
+
PATTERN
|
32
|
+
|
33
|
+
def on_send(node)
|
34
|
+
money_zero(node) do |currency_arg|
|
35
|
+
add_offense(node, message: format(MSG, currency: replacement_currency(currency_arg)))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def autocorrect(node)
|
40
|
+
receiver, _ = *node
|
41
|
+
|
42
|
+
lambda do |corrector|
|
43
|
+
money_zero(node) do |currency_arg|
|
44
|
+
replacement_currency = replacement_currency(currency_arg)
|
45
|
+
|
46
|
+
corrector.replace(
|
47
|
+
node.loc.expression,
|
48
|
+
"#{receiver.source}.new(0, #{replacement_currency})"
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def replacement_currency(currency_arg)
|
57
|
+
return currency_arg.first.source unless currency_arg.empty?
|
58
|
+
return "'#{cop_config['ReplacementCurrency']}'" if cop_config['ReplacementCurrency']
|
59
|
+
|
60
|
+
'Money::NULL_CURRENCY'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/spec/allocator_spec.rb
CHANGED
@@ -43,7 +43,7 @@ RSpec.describe "Allocator" do
|
|
43
43
|
|
44
44
|
specify "#allocate will convert rationals with high precision" do
|
45
45
|
ratios = [Rational(1, 1), Rational(0)]
|
46
|
-
expect(new_allocator("858993456.12").allocate(ratios)).to eq([Money.new("858993456.12"), Money.
|
46
|
+
expect(new_allocator("858993456.12").allocate(ratios)).to eq([Money.new("858993456.12"), Money.new(0, Money::NULL_CURRENCY)])
|
47
47
|
ratios = [Rational(1, 6), Rational(5, 6)]
|
48
48
|
expect(new_allocator("3.00").allocate(ratios)).to eq([Money.new("0.50"), Money.new("2.50")])
|
49
49
|
end
|
@@ -131,8 +131,8 @@ RSpec.describe "Allocator" do
|
|
131
131
|
|
132
132
|
specify "#allocate_max_amounts supports all-zero maxima" do
|
133
133
|
expect(
|
134
|
-
new_allocator(3).allocate_max_amounts([Money.
|
135
|
-
).to eq([Money.
|
134
|
+
new_allocator(3).allocate_max_amounts([Money.new(0, Money::NULL_CURRENCY), Money.new(0, Money::NULL_CURRENCY), Money.new(0, Money::NULL_CURRENCY)]),
|
135
|
+
).to eq([Money.new(0, Money::NULL_CURRENCY), Money.new(0, Money::NULL_CURRENCY), Money.new(0, Money::NULL_CURRENCY)])
|
136
136
|
end
|
137
137
|
|
138
138
|
specify "#allocate_max_amounts allocates the right amount without rounding error" do
|
@@ -17,7 +17,7 @@ RSpec.describe Integer do
|
|
17
17
|
it_should_behave_like "an object supporting to_money"
|
18
18
|
|
19
19
|
it "parses 0 to Money.zero" do
|
20
|
-
expect(0.to_money).to eq(Money.
|
20
|
+
expect(0.to_money).to eq(Money.new(0, Money::NULL_CURRENCY))
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -30,7 +30,7 @@ RSpec.describe Float do
|
|
30
30
|
it_should_behave_like "an object supporting to_money"
|
31
31
|
|
32
32
|
it "parses 0.0 to Money.zero" do
|
33
|
-
expect(0.0.to_money).to eq(Money.
|
33
|
+
expect(0.0.to_money).to eq(Money.new(0, Money::NULL_CURRENCY))
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -43,8 +43,8 @@ RSpec.describe String do
|
|
43
43
|
it_should_behave_like "an object supporting to_money"
|
44
44
|
|
45
45
|
it "parses an empty string to Money.zero" do
|
46
|
-
expect(''.to_money).to eq(Money.
|
47
|
-
expect(' '.to_money).to eq(Money.
|
46
|
+
expect(''.to_money).to eq(Money.new(0, Money::NULL_CURRENCY))
|
47
|
+
expect(' '.to_money).to eq(Money.new(0, Money::NULL_CURRENCY))
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -57,6 +57,6 @@ RSpec.describe BigDecimal do
|
|
57
57
|
it_should_behave_like "an object supporting to_money"
|
58
58
|
|
59
59
|
it "parses a zero BigDecimal to Money.zero" do
|
60
|
-
expect(BigDecimal("-0.000").to_money).to eq(Money.
|
60
|
+
expect(BigDecimal("-0.000").to_money).to eq(Money.new(0, Money::NULL_CURRENCY))
|
61
61
|
end
|
62
62
|
end
|
data/spec/currency_spec.rb
CHANGED
@@ -77,6 +77,16 @@ RSpec.describe "Currency" do
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
describe "#hash" do
|
81
|
+
specify "equal currencies from different loaders have the same hash" do
|
82
|
+
currency_1 = Money::Currency.find('USD')
|
83
|
+
currency_2 = YAML.load(Money::Currency.find('USD').to_yaml)
|
84
|
+
|
85
|
+
expect(currency_1.eql?(currency_2)).to eq(true)
|
86
|
+
expect(currency_1.hash).to eq(currency_2.hash)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
80
90
|
describe "==" do
|
81
91
|
it "returns true when both objects have the same currency" do
|
82
92
|
expect(currency == Money.new(1, 'USD').currency).to eq(true)
|
data/spec/money_column_spec.rb
CHANGED
@@ -136,7 +136,7 @@ RSpec.describe 'MoneyColumn' do
|
|
136
136
|
|
137
137
|
it 'does not overwrite a currency column with a default currency when saving zero' do
|
138
138
|
expect(record.currency.to_s).to eq('EUR')
|
139
|
-
record.update(price: Money.
|
139
|
+
record.update(price: Money.new(0, Money::NULL_CURRENCY))
|
140
140
|
expect(record.currency.to_s).to eq('EUR')
|
141
141
|
end
|
142
142
|
|
data/spec/money_parser_spec.rb
CHANGED
@@ -8,12 +8,12 @@ RSpec.describe MoneyParser do
|
|
8
8
|
|
9
9
|
describe "parsing of amounts with period decimal separator" do
|
10
10
|
it "parses an empty string to $0" do
|
11
|
-
expect(@parser.parse("")).to eq(Money.
|
11
|
+
expect(@parser.parse("")).to eq(Money.new(0, Money::NULL_CURRENCY))
|
12
12
|
end
|
13
13
|
|
14
14
|
it "parses an invalid string when not strict" do
|
15
15
|
expect(Money).to receive(:deprecate).twice
|
16
|
-
expect(@parser.parse("no money")).to eq(Money.
|
16
|
+
expect(@parser.parse("no money")).to eq(Money.new(0, Money::NULL_CURRENCY))
|
17
17
|
expect(@parser.parse("1..")).to eq(Money.new(1))
|
18
18
|
end
|
19
19
|
|
data/spec/money_spec.rb
CHANGED
@@ -9,10 +9,6 @@ RSpec.describe "Money" do
|
|
9
9
|
let (:non_fractional_money) { Money.new(1, 'JPY') }
|
10
10
|
let (:zero_money) { Money.new(0) }
|
11
11
|
|
12
|
-
it "is contructable with empty class method" do
|
13
|
-
expect(Money.empty).to eq(Money.new)
|
14
|
-
end
|
15
|
-
|
16
12
|
context "default currency not set" do
|
17
13
|
before(:each) do
|
18
14
|
@default_currency = Money.default_currency
|
@@ -28,15 +24,11 @@ RSpec.describe "Money" do
|
|
28
24
|
end
|
29
25
|
|
30
26
|
it ".zero has no currency" do
|
31
|
-
expect(Money.
|
27
|
+
expect(Money.new(0, Money::NULL_CURRENCY).currency).to be_a(Money::NullCurrency)
|
32
28
|
end
|
33
29
|
|
34
30
|
it ".zero is a 0$ value" do
|
35
|
-
expect(Money.
|
36
|
-
end
|
37
|
-
|
38
|
-
it ".zero accepts an optional currency" do
|
39
|
-
expect(Money.zero('USD')).to eq(Money.new(0, 'USD'))
|
31
|
+
expect(Money.new(0, Money::NULL_CURRENCY)).to eq(Money.new(0))
|
40
32
|
end
|
41
33
|
|
42
34
|
it "returns itself with to_money" do
|
@@ -247,11 +239,6 @@ RSpec.describe "Money" do
|
|
247
239
|
expect((1.50 * Money.new(1.00))).to eq(Money.new(1.50))
|
248
240
|
end
|
249
241
|
|
250
|
-
it "is multipliable by a cents amount" do
|
251
|
-
expect((Money.new(1.00) * 0.50)).to eq(Money.new(0.50))
|
252
|
-
expect((0.50 * Money.new(1.00))).to eq(Money.new(0.50))
|
253
|
-
end
|
254
|
-
|
255
242
|
it "is multipliable by a rational" do
|
256
243
|
expect((Money.new(3.3) * Rational(1, 12))).to eq(Money.new(0.28))
|
257
244
|
expect((Rational(1, 12) * Money.new(3.3))).to eq(Money.new(0.28))
|
@@ -306,10 +293,6 @@ RSpec.describe "Money" do
|
|
306
293
|
expect { Money.new(55.00) / 55 }.to raise_error(RuntimeError)
|
307
294
|
end
|
308
295
|
|
309
|
-
it "returns cents in to_liquid" do
|
310
|
-
expect(Money.new(1.00).to_liquid).to eq(100)
|
311
|
-
end
|
312
|
-
|
313
296
|
it "returns cents in to_json" do
|
314
297
|
expect(Money.new(1.00).to_json).to eq("1.00")
|
315
298
|
end
|
@@ -330,19 +313,7 @@ RSpec.describe "Money" do
|
|
330
313
|
expect(Money.new(1.50).to_f.to_s).to eq("1.5")
|
331
314
|
end
|
332
315
|
|
333
|
-
|
334
|
-
expect(Money.from_cents(1950)).to eq(Money.new(19.50))
|
335
|
-
end
|
336
|
-
|
337
|
-
it "is creatable from an integer value of 0 in cents" do
|
338
|
-
expect(Money.from_cents(0)).to eq(Money.new)
|
339
|
-
end
|
340
|
-
|
341
|
-
it "is creatable from a float cents amount" do
|
342
|
-
expect(Money.from_cents(1950.5)).to eq(Money.new(19.51))
|
343
|
-
end
|
344
|
-
|
345
|
-
describe '#from_subunits' do
|
316
|
+
describe '#from_subunits' do
|
346
317
|
it "creates Money object from an integer value in cents and currency" do
|
347
318
|
expect(Money.from_subunits(1950, 'CAD')).to eq(Money.new(19.50))
|
348
319
|
end
|
@@ -619,10 +590,6 @@ RSpec.describe "Money" do
|
|
619
590
|
expect(money.value).to eq(BigDecimal("1.00"))
|
620
591
|
end
|
621
592
|
|
622
|
-
it "returns cents as 100 cents" do
|
623
|
-
expect(money.cents).to eq(100)
|
624
|
-
end
|
625
|
-
|
626
593
|
it "returns cents as 100 cents" do
|
627
594
|
expect(money.subunits).to eq(100)
|
628
595
|
end
|
@@ -783,20 +750,6 @@ RSpec.describe "Money" do
|
|
783
750
|
end
|
784
751
|
|
785
752
|
describe "from_amount quacks like RubyMoney" do
|
786
|
-
it "accepts numeric values" do
|
787
|
-
expect(Money.from_amount(1)).to eq Money.from_cents(1_00)
|
788
|
-
expect(Money.from_amount(1.0)).to eq Money.from_cents(1_00)
|
789
|
-
expect(Money.from_amount(BigDecimal("1"))).to eq Money.from_cents(1_00)
|
790
|
-
end
|
791
|
-
|
792
|
-
it "accepts string values" do
|
793
|
-
expect(Money.from_amount("1")).to eq Money.from_cents(1_00)
|
794
|
-
end
|
795
|
-
|
796
|
-
it "accepts nil values" do
|
797
|
-
expect(Money.from_amount(nil)).to eq Money.from_cents(0)
|
798
|
-
end
|
799
|
-
|
800
753
|
it "accepts an optional currency parameter" do
|
801
754
|
expect { Money.from_amount(1, "CAD") }.to_not raise_error
|
802
755
|
end
|
@@ -816,10 +769,14 @@ RSpec.describe "Money" do
|
|
816
769
|
money = YAML.dump(Money.new(750, 'usd'))
|
817
770
|
expect(money).to eq("--- !ruby/object:Money\nvalue: '750.0'\ncurrency: USD\n")
|
818
771
|
end
|
772
|
+
|
773
|
+
it "does not change BigDecimal value to Integer while rounding for currencies without subunits" do
|
774
|
+
money = Money.new(100, 'JPY').to_yaml
|
775
|
+
expect(money).to eq("--- !ruby/object:Money\nvalue: '100.0'\ncurrency: JPY\n")
|
776
|
+
end
|
819
777
|
end
|
820
778
|
|
821
779
|
describe "YAML deserialization" do
|
822
|
-
|
823
780
|
it "accepts values with currencies" do
|
824
781
|
money = YAML.load("--- !ruby/object:Money\nvalue: '750.0'\ncurrency: USD\n")
|
825
782
|
expect(money).to eq(Money.new(750, 'usd'))
|
@@ -963,10 +920,4 @@ RSpec.describe "Money" do
|
|
963
920
|
expect(money.currency.iso_code).to eq('EUR')
|
964
921
|
end
|
965
922
|
end
|
966
|
-
|
967
|
-
describe '#to_yaml' do
|
968
|
-
it 'returns a yaml representation' do
|
969
|
-
expect(Money.new(100, 'JPY').to_yaml).to eq("--- !ruby/object:Money\nvalue: '100.0'\ncurrency: JPY\n")
|
970
|
-
end
|
971
|
-
end
|
972
923
|
end
|
@@ -8,12 +8,16 @@ RSpec.describe RuboCop::Cop::Money::MissingCurrency do
|
|
8
8
|
|
9
9
|
let(:config) { RuboCop::Config.new }
|
10
10
|
|
11
|
-
|
12
|
-
it 'registers an offense for Money.new without a currency argument' do
|
11
|
+
context 'with default configuration' do
|
12
|
+
it 'registers an offense and corrects for Money.new without a currency argument' do
|
13
13
|
expect_offense(<<~RUBY)
|
14
14
|
Money.new(1)
|
15
15
|
^^^^^^^^^^^^ Money is missing currency argument
|
16
16
|
RUBY
|
17
|
+
|
18
|
+
expect_correction(<<~RUBY)
|
19
|
+
Money.new(1, Money::NULL_CURRENCY)
|
20
|
+
RUBY
|
17
21
|
end
|
18
22
|
|
19
23
|
it 'does not register an offense for Money.new with currency argument' do
|
@@ -22,18 +26,26 @@ RSpec.describe RuboCop::Cop::Money::MissingCurrency do
|
|
22
26
|
RUBY
|
23
27
|
end
|
24
28
|
|
25
|
-
it 'registers an offense for Money.new without a currency argument' do
|
29
|
+
it 'registers an offense and corrects for Money.new without a currency argument' do
|
26
30
|
expect_offense(<<~RUBY)
|
27
31
|
Money.new
|
28
32
|
^^^^^^^^^ Money is missing currency argument
|
29
33
|
RUBY
|
34
|
+
|
35
|
+
expect_correction(<<~RUBY)
|
36
|
+
Money.new(0, Money::NULL_CURRENCY)
|
37
|
+
RUBY
|
30
38
|
end
|
31
39
|
|
32
|
-
it 'registers an offense for Money.from_amount without a currency argument' do
|
40
|
+
it 'registers an offense and corrects for Money.from_amount without a currency argument' do
|
33
41
|
expect_offense(<<~RUBY)
|
34
42
|
Money.from_amount(1)
|
35
43
|
^^^^^^^^^^^^^^^^^^^^ Money is missing currency argument
|
36
44
|
RUBY
|
45
|
+
|
46
|
+
expect_correction(<<~RUBY)
|
47
|
+
Money.from_amount(1, Money::NULL_CURRENCY)
|
48
|
+
RUBY
|
37
49
|
end
|
38
50
|
|
39
51
|
it 'does not register an offense for Money.from_amount with currency argument' do
|
@@ -42,11 +54,15 @@ RSpec.describe RuboCop::Cop::Money::MissingCurrency do
|
|
42
54
|
RUBY
|
43
55
|
end
|
44
56
|
|
45
|
-
it 'registers an offense for Money.from_cents without a currency argument' do
|
57
|
+
it 'registers an offense and corrects for Money.from_cents without a currency argument' do
|
46
58
|
expect_offense(<<~RUBY)
|
47
59
|
Money.from_cents(1)
|
48
60
|
^^^^^^^^^^^^^^^^^^^ Money is missing currency argument
|
49
61
|
RUBY
|
62
|
+
|
63
|
+
expect_correction(<<~RUBY)
|
64
|
+
Money.from_cents(1, Money::NULL_CURRENCY)
|
65
|
+
RUBY
|
50
66
|
end
|
51
67
|
|
52
68
|
it 'does not register an offense for Money.from_cents with currency argument' do
|
@@ -55,11 +71,26 @@ RSpec.describe RuboCop::Cop::Money::MissingCurrency do
|
|
55
71
|
RUBY
|
56
72
|
end
|
57
73
|
|
58
|
-
it 'registers an offense for to_money without a currency argument' do
|
74
|
+
it 'registers an offense and corrects for to_money without a currency argument' do
|
59
75
|
expect_offense(<<~RUBY)
|
60
76
|
'1'.to_money
|
61
77
|
^^^^^^^^^^^^ to_money is missing currency argument
|
62
78
|
RUBY
|
79
|
+
|
80
|
+
expect_correction(<<~RUBY)
|
81
|
+
'1'.to_money(Money::NULL_CURRENCY)
|
82
|
+
RUBY
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'registers an offense and corrects for safe navigation to_money without a currency argument' do
|
86
|
+
expect_offense(<<~RUBY)
|
87
|
+
item&.to_money
|
88
|
+
^^^^^^^^^^^^^^ to_money is missing currency argument
|
89
|
+
RUBY
|
90
|
+
|
91
|
+
expect_correction(<<~RUBY)
|
92
|
+
item&.to_money(Money::NULL_CURRENCY)
|
93
|
+
RUBY
|
63
94
|
end
|
64
95
|
|
65
96
|
it 'does not register an offense for to_money with currency argument' do
|
@@ -68,15 +99,19 @@ RSpec.describe RuboCop::Cop::Money::MissingCurrency do
|
|
68
99
|
RUBY
|
69
100
|
end
|
70
101
|
|
71
|
-
it 'registers an offense for to_money block pass form' do
|
102
|
+
it 'registers an offense and corrects for to_money block pass form' do
|
72
103
|
expect_offense(<<~RUBY)
|
73
104
|
['1'].map(&:to_money)
|
74
105
|
^^^^^^^^^^^^^^^^^^^^^ to_money is missing currency argument
|
75
106
|
RUBY
|
107
|
+
|
108
|
+
expect_correction(<<~RUBY)
|
109
|
+
['1'].map { |x| x.to_money(Money::NULL_CURRENCY) }
|
110
|
+
RUBY
|
76
111
|
end
|
77
112
|
end
|
78
113
|
|
79
|
-
|
114
|
+
context 'with ReplacementCurrency configuration' do
|
80
115
|
let(:config) do
|
81
116
|
RuboCop::Config.new(
|
82
117
|
'Money/MissingCurrency' => {
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../../rubocop_helper'
|
4
|
+
require 'rubocop/cop/money/zero_money'
|
5
|
+
|
6
|
+
RSpec.describe RuboCop::Cop::Money::ZeroMoney do
|
7
|
+
subject(:cop) { described_class.new(config) }
|
8
|
+
|
9
|
+
let(:config) { RuboCop::Config.new }
|
10
|
+
|
11
|
+
context 'with default configuration' do
|
12
|
+
it 'registers an offense and corrects Money.zero without currency' do
|
13
|
+
expect_offense(<<~RUBY)
|
14
|
+
Money.zero
|
15
|
+
^^^^^^^^^^ Money.zero is removed, use `Money.new(0, Money::NULL_CURRENCY)`.
|
16
|
+
RUBY
|
17
|
+
|
18
|
+
expect_correction(<<~RUBY)
|
19
|
+
Money.new(0, Money::NULL_CURRENCY)
|
20
|
+
RUBY
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'registers an offense and corrects Money.zero with currency' do
|
24
|
+
expect_offense(<<~RUBY)
|
25
|
+
Money.zero('CAD')
|
26
|
+
^^^^^^^^^^^^^^^^^ Money.zero is removed, use `Money.new(0, 'CAD')`.
|
27
|
+
RUBY
|
28
|
+
|
29
|
+
expect_correction(<<~RUBY)
|
30
|
+
Money.new(0, 'CAD')
|
31
|
+
RUBY
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'does not register an offense when using Money.new with a currency' do
|
35
|
+
expect_no_offenses(<<~RUBY)
|
36
|
+
Money.new(0, 'CAD')
|
37
|
+
RUBY
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with ReplacementCurrency configuration' do
|
42
|
+
let(:config) do
|
43
|
+
RuboCop::Config.new(
|
44
|
+
'Money/ZeroMoney' => {
|
45
|
+
'ReplacementCurrency' => 'CAD'
|
46
|
+
}
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'registers an offense and corrects Money.zero without currency' do
|
51
|
+
expect_offense(<<~RUBY)
|
52
|
+
Money.zero
|
53
|
+
^^^^^^^^^^ Money.zero is removed, use `Money.new(0, 'CAD')`.
|
54
|
+
RUBY
|
55
|
+
|
56
|
+
expect_correction(<<~RUBY)
|
57
|
+
Money.new(0, 'CAD')
|
58
|
+
RUBY
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'registers an offense and corrects Money.zero with currency' do
|
62
|
+
expect_offense(<<~RUBY)
|
63
|
+
Money.zero('EUR')
|
64
|
+
^^^^^^^^^^^^^^^^^ Money.zero is removed, use `Money.new(0, 'EUR')`.
|
65
|
+
RUBY
|
66
|
+
|
67
|
+
expect_correction(<<~RUBY)
|
68
|
+
Money.new(0, 'EUR')
|
69
|
+
RUBY
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'does not register an offense when using Money.new with a currency' do
|
73
|
+
expect_no_offenses(<<~RUBY)
|
74
|
+
Money.new(0, 'EUR')
|
75
|
+
RUBY
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shopify-money
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify Inc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -135,6 +135,7 @@ files:
|
|
135
135
|
- lib/money_column/railtie.rb
|
136
136
|
- lib/rubocop/cop/money.rb
|
137
137
|
- lib/rubocop/cop/money/missing_currency.rb
|
138
|
+
- lib/rubocop/cop/money/zero_money.rb
|
138
139
|
- lib/shopify-money.rb
|
139
140
|
- money.gemspec
|
140
141
|
- spec/accounting_money_parser_spec.rb
|
@@ -149,6 +150,7 @@ files:
|
|
149
150
|
- spec/money_spec.rb
|
150
151
|
- spec/null_currency_spec.rb
|
151
152
|
- spec/rubocop/cop/money/missing_currency_spec.rb
|
153
|
+
- spec/rubocop/cop/money/zero_money_spec.rb
|
152
154
|
- spec/rubocop_helper.rb
|
153
155
|
- spec/schema.rb
|
154
156
|
- spec/spec_helper.rb
|
@@ -189,6 +191,7 @@ test_files:
|
|
189
191
|
- spec/money_spec.rb
|
190
192
|
- spec/null_currency_spec.rb
|
191
193
|
- spec/rubocop/cop/money/missing_currency_spec.rb
|
194
|
+
- spec/rubocop/cop/money/zero_money_spec.rb
|
192
195
|
- spec/rubocop_helper.rb
|
193
196
|
- spec/schema.rb
|
194
197
|
- spec/spec_helper.rb
|