shopify-money 1.0.0.pre → 1.0.1.pre

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: ddeb1f02ca7fda02ed007433687bf2fdbce36e9b11d64724753cf2e2420507c0
4
- data.tar.gz: de0de61cbe5c6ae02b2fbf333e4136edbfcd1c2388441c219ffb1a00e2d0a963
3
+ metadata.gz: ae5e66176d7c6e79d5c6346a3ca6915489d3750d7bb67aa68973c52a0198cb3f
4
+ data.tar.gz: 7219d1edd8665498e64eb06e6212028d8ec559dd5ce9206cbe698e5b1e42d2ed
5
5
  SHA512:
6
- metadata.gz: 86ef224eb66a9d8d6249b921cdd9162594babac0e5fa7525f2e9e5125ad94ab02e395bef9af508d4f6d08622d2c3fa6628b902aac3de803ef81fd30fcae0464c
7
- data.tar.gz: 7332ed67b6d7389123131538c7c05faae5b9e67a4b77ae66c21f0d2bbd7031f4994576fdaa14c54294ad2969c70ffe1e70958528f16116e944fa6457d5c80d6e
6
+ metadata.gz: 4188d1251f442d347b287b3b3ac69c08f716b149ef9cc8a78f2c8e75fb563524f3818a9b8116cf2d433117a9e66cbb96b428aed9bf8cd9f9e79eaefa94ca5c45
7
+ data.tar.gz: 9e70a02a0acdf5eca299ad5f4b201b3fb44a98977d972d08db4167938f24793b732a55f25d6ea3585c8c63d92b014bc108083cce1aef1659b65c628f3ab0b27f
data/README.md CHANGED
@@ -18,7 +18,7 @@ money_column expects a DECIMAL(21,3) database field.
18
18
 
19
19
  ## Installation
20
20
 
21
- gem 'shopify-money', require: 'money'
21
+ gem 'shopify-money'
22
22
 
23
23
  ## Upgrading to v1.0
24
24
 
@@ -73,6 +73,20 @@ mtl:
73
73
  thousands_separator: ","
74
74
  iso_numeric: '470'
75
75
  smallest_denomination: 1
76
+ std:
77
+ priority: 100
78
+ iso_code: STD
79
+ name: São Tomé and Príncipe Dobra
80
+ symbol: Db
81
+ alternate_symbols: []
82
+ subunit: Cêntimo
83
+ subunit_to_unit: 100
84
+ symbol_first: false
85
+ html_entity: ''
86
+ decimal_mark: "."
87
+ thousands_separator: ","
88
+ iso_numeric: '678'
89
+ smallest_denomination: 10000
76
90
  tmm:
77
91
  priority: 100
78
92
  iso_code: TMM
@@ -2029,9 +2029,9 @@ ssp:
2029
2029
  thousands_separator: ","
2030
2030
  iso_numeric: '728'
2031
2031
  smallest_denomination: 5
2032
- std:
2032
+ stn:
2033
2033
  priority: 100
2034
- iso_code: STD
2034
+ iso_code: STN
2035
2035
  name: São Tomé and Príncipe Dobra
2036
2036
  symbol: Db
2037
2037
  alternate_symbols: []
@@ -2041,8 +2041,8 @@ std:
2041
2041
  html_entity: ''
2042
2042
  decimal_mark: "."
2043
2043
  thousands_separator: ","
2044
- iso_numeric: '678'
2045
- smallest_denomination: 10000
2044
+ iso_numeric: '930'
2045
+ smallest_denomination: 1
2046
2046
  svc:
2047
2047
  priority: 100
2048
2048
  iso_code: SVC
@@ -2304,6 +2304,24 @@ uzs:
2304
2304
  thousands_separator: ","
2305
2305
  iso_numeric: '860'
2306
2306
  smallest_denomination: 100
2307
+ ved:
2308
+ priority: 100
2309
+ iso_code: VED
2310
+ name: Venezuelan Bolívar soberano
2311
+ symbol: Bs.D.
2312
+ alternate_symbols: []
2313
+ subunit: Céntimo
2314
+ subunit_to_unit: 100
2315
+ symbol_first: true
2316
+ html_entity: ''
2317
+ decimal_mark: ","
2318
+ thousands_separator: "."
2319
+ iso_numeric: '926'
2320
+ # "On 1 Oct 2021, [...] another (redenomination) happened, but called 'Nueva expresión monetaria',
2321
+ # or new monetary expression, which removed 6 zeroes from the currency without affecting its denomination."
2322
+ # The VED has banknotes in denominations of 5, 10, 20, 50, and 100, and coins in 50 céntimos and 1 Bs.D.
2323
+ # Source: https://en.wikipedia.org/wiki/Venezuelan_bol%C3%ADvar
2324
+ smallest_denomination: 1
2307
2325
  ves:
2308
2326
  priority: 100
2309
2327
  iso_code: VES
data/lib/money/money.rb CHANGED
@@ -128,12 +128,14 @@ class Money
128
128
 
129
129
  def +(other)
130
130
  arithmetic(other) do |money|
131
+ return self if money.value == 0 && !no_currency?
131
132
  Money.new(value + money.value, calculated_currency(money.currency))
132
133
  end
133
134
  end
134
135
 
135
136
  def -(other)
136
137
  arithmetic(other) do |money|
138
+ return self if money.value == 0 && !no_currency?
137
139
  Money.new(value - money.value, calculated_currency(money.currency))
138
140
  end
139
141
  end
@@ -146,6 +148,7 @@ class Money
146
148
  raise ArgumentError, "Money objects can only be multiplied by a Numeric"
147
149
  end
148
150
  end
151
+ return self if numeric == 1
149
152
  Money.new(value.to_r * numeric, currency)
150
153
  end
151
154
 
@@ -219,14 +222,14 @@ class Money
219
222
  value
220
223
  end
221
224
 
222
- def to_s(style = nil)
225
+ def to_fs(style = nil)
223
226
  units = case style
224
227
  when :legacy_dollars
225
228
  2
226
229
  when :amount, nil
227
230
  currency.minor_units
228
231
  else
229
- raise ArgumentError, "Unexpected style: #{style}"
232
+ raise ArgumentError, "Unexpected format: #{style}"
230
233
  end
231
234
 
232
235
  rounded_value = value.round(units)
@@ -238,17 +241,19 @@ class Money
238
241
  sprintf("%s%d.%0#{units}d", sign, rounded_value.truncate, rounded_value.frac * (10 ** units))
239
242
  end
240
243
  end
244
+ alias_method :to_s, :to_fs
245
+ alias_method :to_formatted_s, :to_fs
241
246
 
242
- def to_json(options = {})
243
- if options.delete(:legacy_format) || Money.config.legacy_json_format
247
+ def to_json(options = nil)
248
+ if (options.is_a?(Hash) && options.delete(:legacy_format)) || Money.config.legacy_json_format
244
249
  to_s
245
250
  else
246
251
  as_json(options).to_json
247
252
  end
248
253
  end
249
254
 
250
- def as_json(options = {})
251
- if options.delete(:legacy_format) || Money.config.legacy_json_format
255
+ def as_json(options = nil)
256
+ if (options.is_a?(Hash) && options.delete(:legacy_format)) || Money.config.legacy_json_format
252
257
  to_s
253
258
  else
254
259
  { value: to_s(:amount), currency: currency.to_s }
@@ -256,15 +261,21 @@ class Money
256
261
  end
257
262
 
258
263
  def abs
259
- Money.new(value.abs, currency)
264
+ abs = value.abs
265
+ return self if value == abs
266
+ Money.new(abs, currency)
260
267
  end
261
268
 
262
269
  def floor
263
- Money.new(value.floor, currency)
270
+ floor = value.floor
271
+ return self if floor == value
272
+ Money.new(floor, currency)
264
273
  end
265
274
 
266
275
  def round(ndigits=0)
267
- Money.new(value.round(ndigits), currency)
276
+ round = value.round(ndigits)
277
+ return self if round == value
278
+ Money.new(round, currency)
268
279
  end
269
280
 
270
281
  def fraction(rate)
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Money
4
+ module Rails
5
+ class JobArgumentSerializer < ::ActiveJob::Serializers::ObjectSerializer
6
+ def serialize(money)
7
+ super("value" => money.value, "currency" => money.currency.iso_code)
8
+ end
9
+
10
+ def deserialize(hash)
11
+ Money.new(hash["value"], hash["currency"])
12
+ end
13
+
14
+ private
15
+
16
+ def klass
17
+ Money
18
+ end
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Money
4
+ class Railtie < Rails::Railtie
5
+ initializer "shopify-money.setup_active_job_serializer" do
6
+ ActiveSupport.on_load :active_job do
7
+ require_relative "rails/job_argument_serializer"
8
+ ActiveJob::Serializers.add_serializers ::Money::Rails::JobArgumentSerializer
9
+ end
10
+ end
11
+ end
12
+ end
data/lib/money/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  class Money
3
- VERSION = "1.0.0.pre"
3
+ VERSION = "1.0.1.pre"
4
4
  end
data/lib/money.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require_relative 'money/version'
2
3
  require_relative 'money/money_parser'
3
4
  require_relative 'money/helpers'
4
5
  require_relative 'money/currency'
@@ -11,5 +12,6 @@ require_relative 'money/deprecations'
11
12
  require_relative 'money/accounting_money_parser'
12
13
  require_relative 'money/core_extensions'
13
14
  require_relative 'money_column' if defined?(ActiveRecord)
15
+ require_relative 'money/railtie' if defined?(Rails::Railtie)
14
16
 
15
17
  require_relative 'rubocop/cop/money' if defined?(RuboCop)
data/spec/money_spec.rb CHANGED
@@ -8,6 +8,10 @@ RSpec.describe "Money" do
8
8
  let (:non_fractional_money) { Money.new(1, 'JPY') }
9
9
  let (:zero_money) { Money.new(0) }
10
10
 
11
+ it "has a version" do
12
+ expect(Money::VERSION).not_to(eq(nil))
13
+ end
14
+
11
15
  context "default currency not set" do
12
16
  it "raises an error" do
13
17
  configure(default_currency: nil) do
@@ -67,14 +71,14 @@ RSpec.describe "Money" do
67
71
  expect(non_fractional_money.to_s).to eq("1")
68
72
  end
69
73
 
70
- it "to_s with a legacy_dollars style" do
71
- expect(amount_money.to_s(:legacy_dollars)).to eq("1.23")
72
- expect(non_fractional_money.to_s(:legacy_dollars)).to eq("1.00")
74
+ it "to_fs with a legacy_dollars style" do
75
+ expect(amount_money.to_fs(:legacy_dollars)).to eq("1.23")
76
+ expect(non_fractional_money.to_fs(:legacy_dollars)).to eq("1.00")
73
77
  end
74
78
 
75
- it "to_s with a amount style" do
76
- expect(amount_money.to_s(:amount)).to eq("1.23")
77
- expect(non_fractional_money.to_s(:amount)).to eq("1")
79
+ it "to_fs with a amount style" do
80
+ expect(amount_money.to_fs(:amount)).to eq("1.23")
81
+ expect(non_fractional_money.to_fs(:amount)).to eq("1")
78
82
  end
79
83
 
80
84
  it "to_s correctly displays negative numbers" do
@@ -100,8 +104,16 @@ RSpec.describe "Money" do
100
104
  expect(Money.new("999999999999999999.99", "USD").to_s).to eq("999999999999999999.99")
101
105
  end
102
106
 
103
- it "to_s raises ArgumentError on unsupported style" do
104
- expect{ money.to_s(:some_weird_style) }.to raise_error(ArgumentError)
107
+ it "to_fs raises ArgumentError on unsupported style" do
108
+ expect{ money.to_fs(:some_weird_style) }.to raise_error(ArgumentError)
109
+ end
110
+
111
+ it "to_fs is aliased as to_s for backward compatibility" do
112
+ expect(money.method(:to_s)).to eq(money.method(:to_fs))
113
+ end
114
+
115
+ it "to_fs is aliased as to_formatted_s for backward compatibility" do
116
+ expect(money.method(:to_formatted_s)).to eq(money.method(:to_fs))
105
117
  end
106
118
 
107
119
  it "legacy_json_format makes as_json return the legacy format" do
@@ -331,6 +343,7 @@ RSpec.describe "Money" do
331
343
 
332
344
  it "returns value and currency in to_json" do
333
345
  expect(Money.new(1.00).to_json).to eq('{"value":"1.00","currency":"CAD"}')
346
+ expect(JSON.dump(Money.new(1.00, "CAD"))).to eq('{"value":"1.00","currency":"CAD"}')
334
347
  end
335
348
 
336
349
  it "supports absolute value" do
@@ -396,6 +409,30 @@ RSpec.describe "Money" do
396
409
  end
397
410
  end
398
411
 
412
+ it "does not allocate a new money object when multiplying by 1" do
413
+ expect((money * 1).object_id).to eq(money.object_id)
414
+ end
415
+
416
+ it "does not allocate a new money object when adding 0" do
417
+ expect((money + 0).object_id).to eq(money.object_id)
418
+ end
419
+
420
+ it "does not allocate a new money object when subtracting 0" do
421
+ expect((money - 0).object_id).to eq(money.object_id)
422
+ end
423
+
424
+ it "does not allocate when computing absolute value when already positive" do
425
+ expect((money.abs).object_id).to eq(money.object_id)
426
+ end
427
+
428
+ it "does not allocate when computing floor value when already floored" do
429
+ expect((money.floor).object_id).to eq(money.object_id)
430
+ end
431
+
432
+ it "does not allocate when computing floor value when already rounded" do
433
+ expect((money.round).object_id).to eq(money.object_id)
434
+ end
435
+
399
436
  describe "frozen with amount of $1" do
400
437
  let (:money) { Money.new(1.00) }
401
438
 
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_spec_helper"
4
+
5
+ RSpec.describe Money::Rails::JobArgumentSerializer do
6
+ it "roundtrip a Money argument returns the same object" do
7
+ job = MoneyTestJob.new(value: Money.new(10.21, "BRL"))
8
+
9
+ serialized_job = job.serialize
10
+ serialized_value = serialized_job["arguments"][0]["value"]
11
+ expect(serialized_value["_aj_serialized"]).to eq("Money::Rails::JobArgumentSerializer")
12
+ expect(serialized_value["value"]).to eq(BigDecimal("10.21"))
13
+ expect(serialized_value["currency"]).to eq("BRL")
14
+
15
+ job2 = MoneyTestJob.deserialize(serialized_job)
16
+ job2.send(:deserialize_arguments_if_needed)
17
+
18
+ expect(job2.arguments.first[:value]).to eq(Money.new(10.21, "BRL"))
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_job"
4
+ require_relative "spec_helper"
5
+
6
+ Money::Railtie.initializers.each(&:run)
7
+
8
+ class MoneyTestJob < ActiveJob::Base
9
+ def perform(_params)
10
+ end
11
+ 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: 1.0.0.pre
4
+ version: 1.0.1.pre
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-05-11 00:00:00.000000000 Z
11
+ date: 2022-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -129,6 +129,8 @@ files:
129
129
  - lib/money/money.rb
130
130
  - lib/money/money_parser.rb
131
131
  - lib/money/null_currency.rb
132
+ - lib/money/rails/job_argument_serializer.rb
133
+ - lib/money/railtie.rb
132
134
  - lib/money/version.rb
133
135
  - lib/money_column.rb
134
136
  - lib/money_column/active_record_hooks.rb
@@ -150,6 +152,8 @@ files:
150
152
  - spec/money_parser_spec.rb
151
153
  - spec/money_spec.rb
152
154
  - spec/null_currency_spec.rb
155
+ - spec/rails/job_argument_serializer_spec.rb
156
+ - spec/rails_spec_helper.rb
153
157
  - spec/rubocop/cop/money/missing_currency_spec.rb
154
158
  - spec/rubocop/cop/money/zero_money_spec.rb
155
159
  - spec/rubocop_helper.rb
@@ -175,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
179
  - !ruby/object:Gem::Version
176
180
  version: 1.3.1
177
181
  requirements: []
178
- rubygems_version: 3.0.3
182
+ rubygems_version: 3.2.20
179
183
  signing_key:
180
184
  specification_version: 4
181
185
  summary: Shopify's money gem
@@ -191,6 +195,8 @@ test_files:
191
195
  - spec/money_parser_spec.rb
192
196
  - spec/money_spec.rb
193
197
  - spec/null_currency_spec.rb
198
+ - spec/rails/job_argument_serializer_spec.rb
199
+ - spec/rails_spec_helper.rb
194
200
  - spec/rubocop/cop/money/missing_currency_spec.rb
195
201
  - spec/rubocop/cop/money/zero_money_spec.rb
196
202
  - spec/rubocop_helper.rb