amounts 0.0.4 → 0.0.6

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.
@@ -0,0 +1,163 @@
1
+ # Registry overview:
2
+ # Major Fiat Currencies:
3
+ # - This preset is a curated basket of widely used fiat currencies for general product and treasury workflows.
4
+ # - Minor-unit precision follows ISO-4217-style currency fractions: most entries use 2 decimals, while JPY uses 0.
5
+ # - Display symbols are English-oriented defaults inspired by CLDR conventions and may need localization in real applications.
6
+ # - Source: Unicode CLDR currency symbols and localization notes: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
7
+
8
+ # USD: United States dollar.
9
+ # Fact: Uses 2 decimal places for cents.
10
+ # Preset default: Uses "$" as the default display symbol in an English-oriented UI.
11
+ # Preset default: Renders as a prefix amount, for example "$12.34".
12
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
13
+ Amount.register :USD,
14
+ decimals: 2,
15
+ display_symbol: "$",
16
+ display_position: :prefix,
17
+ ui_decimals: 2
18
+
19
+ # EUR: Euro.
20
+ # Fact: Uses 2 decimal places for cents.
21
+ # Preset default: Uses the euro sign as the default display symbol.
22
+ # Preset default: Renders as a prefix amount for a compact English-oriented default.
23
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
24
+ Amount.register :EUR,
25
+ decimals: 2,
26
+ display_symbol: "€",
27
+ display_position: :prefix,
28
+ ui_decimals: 2
29
+
30
+ # GBP: British pound sterling.
31
+ # Fact: Uses 2 decimal places for pence.
32
+ # Preset default: Uses the pound sign as the default display symbol.
33
+ # Preset default: Renders as a prefix amount.
34
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
35
+ Amount.register :GBP,
36
+ decimals: 2,
37
+ display_symbol: "£",
38
+ display_position: :prefix,
39
+ ui_decimals: 2
40
+
41
+ # JPY: Japanese yen.
42
+ # Fact: Uses 0 decimal places under standard minor-unit conventions.
43
+ # Preset default: Uses the yen sign as the default display symbol.
44
+ # Preset default: Renders as a prefix amount with no fractional UI digits.
45
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
46
+ Amount.register :JPY,
47
+ decimals: 0,
48
+ display_symbol: "¥",
49
+ display_position: :prefix,
50
+ ui_decimals: 0
51
+
52
+ # CHF: Swiss franc.
53
+ # Fact: Uses 2 decimal places for rappen/centimes.
54
+ # Preset default: Uses the ISO code as the display symbol to avoid locale ambiguity.
55
+ # Preset default: Renders as a suffix amount, for example "12.34 CHF".
56
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
57
+ Amount.register :CHF,
58
+ decimals: 2,
59
+ display_symbol: "CHF",
60
+ display_position: :suffix,
61
+ ui_decimals: 2
62
+
63
+ # CAD: Canadian dollar.
64
+ # Fact: Uses 2 decimal places for cents.
65
+ # Preset default: Uses "CA$" instead of plain "$" to avoid collision with USD.
66
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
67
+ Amount.register :CAD,
68
+ decimals: 2,
69
+ display_symbol: "CA$",
70
+ display_position: :prefix,
71
+ ui_decimals: 2
72
+
73
+ # AUD: Australian dollar.
74
+ # Fact: Uses 2 decimal places for cents.
75
+ # Preset default: Uses "A$" instead of plain "$" to avoid collision with USD.
76
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
77
+ Amount.register :AUD,
78
+ decimals: 2,
79
+ display_symbol: "A$",
80
+ display_position: :prefix,
81
+ ui_decimals: 2
82
+
83
+ # NZD: New Zealand dollar.
84
+ # Fact: Uses 2 decimal places for cents.
85
+ # Preset default: Uses "NZ$" instead of plain "$" to avoid collision with USD.
86
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
87
+ Amount.register :NZD,
88
+ decimals: 2,
89
+ display_symbol: "NZ$",
90
+ display_position: :prefix,
91
+ ui_decimals: 2
92
+
93
+ # SGD: Singapore dollar.
94
+ # Fact: Uses 2 decimal places for cents.
95
+ # Preset default: Uses "S$" instead of plain "$" to avoid collision with USD.
96
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
97
+ Amount.register :SGD,
98
+ decimals: 2,
99
+ display_symbol: "S$",
100
+ display_position: :prefix,
101
+ ui_decimals: 2
102
+
103
+ # HKD: Hong Kong dollar.
104
+ # Fact: Uses 2 decimal places for cents.
105
+ # Preset default: Uses "HK$" instead of plain "$" to avoid collision with USD.
106
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
107
+ Amount.register :HKD,
108
+ decimals: 2,
109
+ display_symbol: "HK$",
110
+ display_position: :prefix,
111
+ ui_decimals: 2
112
+
113
+ # CNY: Chinese yuan renminbi.
114
+ # Fact: Uses 2 decimal places for jiao/fen display.
115
+ # Preset default: Uses "CN¥" to avoid confusion with other yen/yuan symbols in multi-currency UIs.
116
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
117
+ Amount.register :CNY,
118
+ decimals: 2,
119
+ display_symbol: "CN¥",
120
+ display_position: :prefix,
121
+ ui_decimals: 2
122
+
123
+ # INR: Indian rupee.
124
+ # Fact: Uses 2 decimal places for paise.
125
+ # Preset default: Uses the rupee sign as the default display symbol.
126
+ # Preset default: Renders as a prefix amount.
127
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
128
+ Amount.register :INR,
129
+ decimals: 2,
130
+ display_symbol: "₹",
131
+ display_position: :prefix,
132
+ ui_decimals: 2
133
+
134
+ # MXN: Mexican peso.
135
+ # Fact: Uses 2 decimal places for centavos.
136
+ # Preset default: Uses "MX$" instead of plain "$" to avoid collision with USD.
137
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
138
+ Amount.register :MXN,
139
+ decimals: 2,
140
+ display_symbol: "MX$",
141
+ display_position: :prefix,
142
+ ui_decimals: 2
143
+
144
+ # BRL: Brazilian real.
145
+ # Fact: Uses 2 decimal places for centavos.
146
+ # Preset default: Uses the common Brazilian real symbol "R$".
147
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
148
+ Amount.register :BRL,
149
+ decimals: 2,
150
+ display_symbol: "R$",
151
+ display_position: :prefix,
152
+ ui_decimals: 2
153
+
154
+ # AED: United Arab Emirates dirham.
155
+ # Fact: Uses 2 decimal places for fils.
156
+ # Preset default: Uses the ISO code as the display symbol for an unambiguous English-oriented default.
157
+ # Preset default: Renders as a suffix amount.
158
+ # Source: Currency symbol conventions: https://cldr.unicode.org/translation/currency-names-and-symbols/currency-names
159
+ Amount.register :AED,
160
+ decimals: 2,
161
+ display_symbol: "AED",
162
+ display_position: :suffix,
163
+ ui_decimals: 2
@@ -0,0 +1,151 @@
1
+ # Registry overview:
2
+ # Precious And Industrial Metals:
3
+ # - This preset is a curated basket of metals commonly tracked in treasury, vault, and commodities workflows.
4
+ # - Display-unit conversion factors use standard mass relationships such as troy-ounce to gram and kilogram to pound.
5
+ # - Storage decimals here are preset defaults chosen for application headroom; they are not exchange-mandated market standards.
6
+ # - Source: NIST precious-metals conversion guidance: https://www.nist.gov/pml/weights-and-measures/laws-and-regulations/precious-metals-conversion
7
+ # - Source: NIST metric and customary conversion guidance: https://www.nist.gov/pml/weights-and-measures/common-conversion-factors-ii
8
+
9
+ # GOLD: Gold measured with troy-ounce display defaults.
10
+ # Fact: The alternate gram display uses 1 troy ounce = 31.1035 grams.
11
+ # Fact: The alternate kilogram display uses 1 troy ounce = 0.0311035 kilograms.
12
+ # Preset default: Uses 8 storage decimals as a high-precision preset default rather than a market mandate.
13
+ # Preset default: Defaults to troy-ounce display because that is common for bullion pricing.
14
+ # Source: NIST precious-metals conversion guidance: https://www.nist.gov/pml/weights-and-measures/laws-and-regulations/precious-metals-conversion
15
+ Amount.register :GOLD,
16
+ decimals: 8,
17
+ display_symbol: "oz t",
18
+ display_position: :suffix,
19
+ ui_decimals: 4,
20
+ display_units: {
21
+ oz_t: { scale: 1, symbol: "oz t", ui_decimals: 4 },
22
+ gram: { scale: "31.1035", symbol: "g", ui_decimals: 2 },
23
+ kg: { scale: "0.0311035", symbol: "kg", ui_decimals: 5 }
24
+ },
25
+ default_display: :oz_t
26
+
27
+ # SILVER: Silver measured with troy-ounce display defaults.
28
+ # Fact: The alternate gram display uses 1 troy ounce = 31.1035 grams.
29
+ # Fact: The alternate kilogram display uses 1 troy ounce = 0.0311035 kilograms.
30
+ # Preset default: Uses 8 storage decimals as a high-precision preset default.
31
+ # Preset default: Defaults to troy-ounce display for consistency with common bullion quoting.
32
+ # Source: NIST precious-metals conversion guidance: https://www.nist.gov/pml/weights-and-measures/laws-and-regulations/precious-metals-conversion
33
+ Amount.register :SILVER,
34
+ decimals: 8,
35
+ display_symbol: "oz t",
36
+ display_position: :suffix,
37
+ ui_decimals: 4,
38
+ display_units: {
39
+ oz_t: { scale: 1, symbol: "oz t", ui_decimals: 4 },
40
+ gram: { scale: "31.1035", symbol: "g", ui_decimals: 2 },
41
+ kg: { scale: "0.0311035", symbol: "kg", ui_decimals: 5 }
42
+ },
43
+ default_display: :oz_t
44
+
45
+ # PLATINUM: Platinum measured with troy-ounce display defaults.
46
+ # Fact: The alternate gram display uses 1 troy ounce = 31.1035 grams.
47
+ # Fact: The alternate kilogram display uses 1 troy ounce = 0.0311035 kilograms.
48
+ # Preset default: Uses 8 storage decimals as a high-precision preset default.
49
+ # Preset default: Defaults to troy-ounce display for commodity-style pricing.
50
+ # Source: NIST precious-metals conversion guidance: https://www.nist.gov/pml/weights-and-measures/laws-and-regulations/precious-metals-conversion
51
+ Amount.register :PLATINUM,
52
+ decimals: 8,
53
+ display_symbol: "oz t",
54
+ display_position: :suffix,
55
+ ui_decimals: 4,
56
+ display_units: {
57
+ oz_t: { scale: 1, symbol: "oz t", ui_decimals: 4 },
58
+ gram: { scale: "31.1035", symbol: "g", ui_decimals: 2 },
59
+ kg: { scale: "0.0311035", symbol: "kg", ui_decimals: 5 }
60
+ },
61
+ default_display: :oz_t
62
+
63
+ # PALLADIUM: Palladium measured with troy-ounce display defaults.
64
+ # Fact: The alternate gram display uses 1 troy ounce = 31.1035 grams.
65
+ # Fact: The alternate kilogram display uses 1 troy ounce = 0.0311035 kilograms.
66
+ # Preset default: Uses 8 storage decimals as a high-precision preset default.
67
+ # Preset default: Defaults to troy-ounce display for commodity-style pricing.
68
+ # Source: NIST precious-metals conversion guidance: https://www.nist.gov/pml/weights-and-measures/laws-and-regulations/precious-metals-conversion
69
+ Amount.register :PALLADIUM,
70
+ decimals: 8,
71
+ display_symbol: "oz t",
72
+ display_position: :suffix,
73
+ ui_decimals: 4,
74
+ display_units: {
75
+ oz_t: { scale: 1, symbol: "oz t", ui_decimals: 4 },
76
+ gram: { scale: "31.1035", symbol: "g", ui_decimals: 2 },
77
+ kg: { scale: "0.0311035", symbol: "kg", ui_decimals: 5 }
78
+ },
79
+ default_display: :oz_t
80
+
81
+ # COPPER: Copper measured with metric-mass defaults.
82
+ # Fact: The tonne display uses 1 kg = 0.001 t.
83
+ # Fact: The pound display uses 1 kg = 2.2046226218 lb.
84
+ # Preset default: Uses kilograms as the default display unit for industrial inventory and warehouse-style workflows.
85
+ # Preset default: Uses 6 storage decimals as a high-precision preset default.
86
+ # Source: NIST metric and customary conversion guidance: https://www.nist.gov/pml/weights-and-measures/common-conversion-factors-ii
87
+ Amount.register :COPPER,
88
+ decimals: 6,
89
+ display_symbol: "kg",
90
+ display_position: :suffix,
91
+ ui_decimals: 3,
92
+ display_units: {
93
+ kg: { scale: 1, symbol: "kg", ui_decimals: 3 },
94
+ tonne: { scale: "0.001", symbol: "t", ui_decimals: 6 },
95
+ lb: { scale: "2.2046226218", symbol: "lb", ui_decimals: 2 }
96
+ },
97
+ default_display: :kg
98
+
99
+ # ALUMINUM: Aluminum measured with metric-mass defaults.
100
+ # Fact: The tonne display uses 1 kg = 0.001 t.
101
+ # Fact: The pound display uses 1 kg = 2.2046226218 lb.
102
+ # Preset default: Uses kilograms as the default display unit.
103
+ # Preset default: Uses 6 storage decimals as a high-precision preset default.
104
+ # Source: NIST metric and customary conversion guidance: https://www.nist.gov/pml/weights-and-measures/common-conversion-factors-ii
105
+ Amount.register :ALUMINUM,
106
+ decimals: 6,
107
+ display_symbol: "kg",
108
+ display_position: :suffix,
109
+ ui_decimals: 3,
110
+ display_units: {
111
+ kg: { scale: 1, symbol: "kg", ui_decimals: 3 },
112
+ tonne: { scale: "0.001", symbol: "t", ui_decimals: 6 },
113
+ lb: { scale: "2.2046226218", symbol: "lb", ui_decimals: 2 }
114
+ },
115
+ default_display: :kg
116
+
117
+ # NICKEL: Nickel measured with metric-mass defaults.
118
+ # Fact: The tonne display uses 1 kg = 0.001 t.
119
+ # Fact: The pound display uses 1 kg = 2.2046226218 lb.
120
+ # Preset default: Uses kilograms as the default display unit.
121
+ # Preset default: Uses 6 storage decimals as a high-precision preset default.
122
+ # Source: NIST metric and customary conversion guidance: https://www.nist.gov/pml/weights-and-measures/common-conversion-factors-ii
123
+ Amount.register :NICKEL,
124
+ decimals: 6,
125
+ display_symbol: "kg",
126
+ display_position: :suffix,
127
+ ui_decimals: 3,
128
+ display_units: {
129
+ kg: { scale: 1, symbol: "kg", ui_decimals: 3 },
130
+ tonne: { scale: "0.001", symbol: "t", ui_decimals: 6 },
131
+ lb: { scale: "2.2046226218", symbol: "lb", ui_decimals: 2 }
132
+ },
133
+ default_display: :kg
134
+
135
+ # ZINC: Zinc measured with metric-mass defaults.
136
+ # Fact: The tonne display uses 1 kg = 0.001 t.
137
+ # Fact: The pound display uses 1 kg = 2.2046226218 lb.
138
+ # Preset default: Uses kilograms as the default display unit.
139
+ # Preset default: Uses 6 storage decimals as a high-precision preset default.
140
+ # Source: NIST metric and customary conversion guidance: https://www.nist.gov/pml/weights-and-measures/common-conversion-factors-ii
141
+ Amount.register :ZINC,
142
+ decimals: 6,
143
+ display_symbol: "kg",
144
+ display_position: :suffix,
145
+ ui_decimals: 3,
146
+ display_units: {
147
+ kg: { scale: 1, symbol: "kg", ui_decimals: 3 },
148
+ tonne: { scale: "0.001", symbol: "t", ui_decimals: 6 },
149
+ lb: { scale: "2.2046226218", symbol: "lb", ui_decimals: 2 }
150
+ },
151
+ default_display: :kg
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Generated by:
4
+ # rails generate amounts:registry <%= preset_source_label %>
5
+ #
6
+ # Included preset categories: <%= preset_categories.join(", ") %>
7
+ # Registered symbols: <%= registered_symbols.join(", ") %>
8
+ #
9
+ # This generator only seeds type registrations and display metadata.
10
+ # Comments marked "Fact" describe protocol, standards, or conversion details
11
+ # that are intrinsic to the asset or unit definition.
12
+ # Comments marked "Preset default" describe application-facing defaults chosen
13
+ # by this gem for a sensible starting point.
14
+ # Directional default rates are intentionally omitted because conversion policy
15
+ # is application-specific.
16
+
17
+ require "amount"
18
+ require "amount/active_record"
19
+
20
+ Rails.application.config.to_prepare do
21
+ next if Amount.registry.registered?(:<%= registry_guard_symbol %>)
22
+
23
+ <%= preset_body %>
24
+
25
+ # Register directional default rates only when your application has an
26
+ # explicit conversion policy for the pair in question.
27
+ #
28
+ # Example:
29
+ # Amount.register_default_rate :USD, :USDC, "1"
30
+ # Amount.register_default_rate :USDC, :USD, "1"
31
+
32
+ Amount.registry.lock! if Rails.env.production?
33
+ end
data/test/test_amount.rb CHANGED
@@ -169,6 +169,16 @@ class AmountTest < Minitest::Test
169
169
  assert_equal "$1.57", Amount.new("1.561", :USDC).ui(direction: :ceil)
170
170
  end
171
171
 
172
+ def test_ui_decorated_false_omits_the_display_symbol
173
+ assert_equal "1.50", Amount.new("1.5", :USDC).ui(decorated: false)
174
+ assert_equal "1.5000", Amount.new("1.5", :SOL).ui(decorated: false)
175
+ assert_equal "1", Amount.new(1, :LOGS).ui(decorated: false)
176
+ end
177
+
178
+ def test_ui_decorated_false_with_ceil_direction
179
+ assert_equal "1.57", Amount.new("1.561", :USDC).ui(direction: :ceil, decorated: false)
180
+ end
181
+
172
182
  def test_display_units_scale_output
173
183
  gold = Amount.new("1.5", :GOLD)
174
184
 
@@ -177,6 +187,14 @@ class AmountTest < Minitest::Test
177
187
  assert_equal "0.04665 kg", gold.ui(unit: :kg)
178
188
  end
179
189
 
190
+ def test_display_units_with_decorated_false
191
+ gold = Amount.new("1.5", :GOLD)
192
+
193
+ assert_equal "1.5000", gold.ui(decorated: false)
194
+ assert_equal "46.65", gold.ui(unit: :gram, decorated: false)
195
+ assert_equal "0.04665", gold.ui(unit: :kg, decorated: false)
196
+ end
197
+
180
198
  def test_in_unit_returns_raw_bigdecimal
181
199
  gold = Amount.new("1.0", :GOLD)
182
200
 
@@ -189,6 +207,55 @@ class AmountTest < Minitest::Test
189
207
  end
190
208
  end
191
209
 
210
+ def test_trim_zeros_strips_trailing_zeros
211
+ Amount.register :TZ, decimals: 9, display_symbol: "TZ", display_position: :suffix, trim_zeros: true
212
+
213
+ assert_equal "2.5 TZ", Amount.new("2.5", :TZ).ui
214
+ assert_equal "1 TZ", Amount.new("1.0", :TZ).ui
215
+ assert_equal "0 TZ", Amount.new("0.0", :TZ).ui
216
+ assert_equal "1.123 TZ", Amount.new("1.123", :TZ).ui
217
+ assert_equal "0.00005 TZ", Amount.new(50_000, :TZ, from: :atomic).ui
218
+ end
219
+
220
+ def test_trim_zeros_false_preserves_trailing_zeros
221
+ assert_equal "$1.50", Amount.new("1.5", :USDC).ui
222
+ assert_equal "$1.00", Amount.new("1.0", :USDC).ui
223
+ end
224
+
225
+ def test_trim_zeros_with_decorated_false
226
+ Amount.register :TZ, decimals: 9, display_symbol: "TZ", display_position: :suffix, trim_zeros: true
227
+
228
+ assert_equal "2.5", Amount.new("2.5", :TZ).ui(decorated: false)
229
+ assert_equal "1", Amount.new("1.0", :TZ).ui(decorated: false)
230
+ end
231
+
232
+ def test_trim_zeros_with_display_units
233
+ Amount.register :TZG, decimals: 8, display_symbol: "oz t", display_position: :suffix,
234
+ trim_zeros: true,
235
+ display_units: { gram: { scale: "31.1035", symbol: "g", ui_decimals: 4 } }
236
+
237
+ assert_equal "31.1035 g", Amount.new("1.0", :TZG).ui(unit: :gram)
238
+ end
239
+
240
+ def test_trim_zeros_display_unit_override
241
+ Amount.register :TZO, decimals: 6, display_symbol: "T", display_position: :suffix,
242
+ trim_zeros: true,
243
+ display_units: { fixed: { scale: 1, symbol: "F", ui_decimals: 2, trim_zeros: false } }
244
+
245
+ assert_equal "1.50 F", Amount.new("1.5", :TZO).ui(unit: :fixed)
246
+ end
247
+
248
+ def test_trim_zeros_call_site_override
249
+ assert_equal "1.5 SOL", Amount.new("1.5", :SOL).ui(trim_zeros: true)
250
+ assert_equal "1.0000 SOL", Amount.new("1.0", :SOL).ui(trim_zeros: false)
251
+ end
252
+
253
+ def test_trim_zeros_call_site_overrides_registry
254
+ Amount.register :TZR, decimals: 6, display_symbol: "T", display_position: :suffix, trim_zeros: true
255
+
256
+ assert_equal "1.500000 T", Amount.new("1.5", :TZR).ui(trim_zeros: false)
257
+ end
258
+
192
259
  def test_predicates
193
260
  assert Amount.new(0, :USDC).zero?
194
261
  assert Amount.new(1, :USDC).positive?
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "test_helper"
4
+ require "tmpdir"
5
+ require "fileutils"
6
+ require_relative "../lib/amounts"
7
+ require_relative "../lib/generators/amount/active_record/registry_generator"
8
+ require "rails/generators"
9
+
10
+ class AmountRegistryGeneratorTest < Minitest::Test
11
+ def setup
12
+ @destination_root = Dir.mktmpdir("amounts-generator")
13
+ end
14
+
15
+ def teardown
16
+ FileUtils.remove_entry(@destination_root)
17
+ end
18
+
19
+ def test_generates_fiat_initializer
20
+ invoke_generator("fiat")
21
+
22
+ content = File.read(output_file)
23
+
24
+ assert_includes content, 'rails generate amounts:registry fiat'
25
+ assert_includes content, "# Registry overview:"
26
+ assert_includes content, "# Major Fiat Currencies:"
27
+ assert_includes content, "# USD: United States dollar."
28
+ assert_includes content, "# Fact: Uses 2 decimal places for cents."
29
+ assert_includes content, "# Preset default: Uses \"$\" as the default display symbol in an English-oriented UI."
30
+ assert_includes content, "Amount.register :USD"
31
+ assert_includes content, "Amount.register :JPY"
32
+ refute_includes content, "Amount.register :BTC"
33
+ end
34
+
35
+ def test_generates_all_initializer_without_duplicate_symbols
36
+ invoke_generator("all")
37
+
38
+ content = File.read(output_file)
39
+
40
+ assert_equal 1, content.scan(/^\s*Amount\.register :USD,/).size
41
+ assert_equal 1, content.scan(/^\s*Amount\.register :USDC,/).size
42
+ assert_includes content, "Amount.register :GOLD"
43
+ assert_includes content, "Amount.register :BTC"
44
+ end
45
+
46
+ def test_generates_crypto_initializer_without_stale_polygon_entry
47
+ invoke_generator("crypto")
48
+
49
+ content = File.read(output_file)
50
+
51
+ assert_includes content, "# BTC: Bitcoin."
52
+ assert_includes content, "# Source: Ethereum denomination docs: https://ethereum.org/en/developers/docs/intro-to-ether/"
53
+ assert_includes content, "Amount.register :USDT"
54
+ refute_includes content, "Amount.register :MATIC"
55
+ refute_includes content, "Amount.register :POL"
56
+ end
57
+
58
+ def test_static_preset_files_exist
59
+ assert File.exist?(preset_file("fiat"))
60
+ assert File.exist?(preset_file("metals"))
61
+ assert File.exist?(preset_file("crypto"))
62
+ assert File.exist?(preset_file("all"))
63
+ end
64
+
65
+ def test_all_static_preset_file_includes_all_major_sections
66
+ content = File.read(preset_file("all"))
67
+
68
+ assert_includes content, "# Major Fiat Currencies:"
69
+ assert_includes content, "# Precious And Industrial Metals:"
70
+ assert_includes content, "# Large-Cap Crypto Assets:"
71
+ assert_includes content, "Amount.register :USD"
72
+ assert_includes content, "Amount.register :GOLD"
73
+ assert_includes content, "Amount.register :BTC"
74
+ end
75
+
76
+ def test_rejects_unknown_preset
77
+ _stdout, stderr = capture_io do
78
+ invoke_generator("unknown")
79
+ end
80
+ assert_includes stderr, "unknown preset"
81
+ end
82
+
83
+ private
84
+
85
+ def invoke_generator(preset)
86
+ Amount::ActiveRecord::RegistryGenerator.start(
87
+ [preset],
88
+ destination_root: @destination_root,
89
+ shell: Thor::Shell::Basic.new
90
+ )
91
+ end
92
+
93
+ def output_file
94
+ File.join(@destination_root, "config/initializers/amounts.rb")
95
+ end
96
+
97
+ def preset_file(name)
98
+ File.join(
99
+ File.dirname(__FILE__),
100
+ "..",
101
+ "lib/generators/amount/active_record/templates/presets/#{name}.fragment"
102
+ )
103
+ end
104
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amounts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Seb Scholl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-25 00:00:00.000000000 Z
11
+ date: 2026-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal
@@ -50,6 +50,7 @@ files:
50
50
  - lib/amount/active_record/attribute_definition.rb
51
51
  - lib/amount/active_record/migration_methods.rb
52
52
  - lib/amount/active_record/model.rb
53
+ - lib/amount/active_record/railtie.rb
53
54
  - lib/amount/active_record/rspec.rb
54
55
  - lib/amount/active_record/rspec/matchers.rb
55
56
  - lib/amount/active_record/type.rb
@@ -66,27 +67,34 @@ files:
66
67
  - lib/amount/rspec/support.rb
67
68
  - lib/amount/serialization.rb
68
69
  - lib/amount/version.rb
70
+ - lib/amounts.rb
71
+ - lib/generators/amount/active_record/registry_generator.rb
72
+ - lib/generators/amount/active_record/templates/presets/all.fragment
73
+ - lib/generators/amount/active_record/templates/presets/crypto.fragment
74
+ - lib/generators/amount/active_record/templates/presets/fiat.fragment
75
+ - lib/generators/amount/active_record/templates/presets/metals.fragment
76
+ - lib/generators/amount/active_record/templates/registry.rb.tt
69
77
  - test/dummy/app/models/holding.rb
70
78
  - test/dummy/bin/rails
71
79
  - test/dummy/config/application.rb
72
80
  - test/dummy/config/database.yml
73
81
  - test/dummy/config/environment.rb
74
82
  - test/dummy/db/schema.rb
75
- - test/dummy/log/development.log
76
83
  - test/dummy/log/test.log
77
84
  - test/postgresql_integration_test.rb
78
85
  - test/support/amount_test_support.rb
79
86
  - test/test_active_record.rb
80
87
  - test/test_amount.rb
81
88
  - test/test_helper.rb
89
+ - test/test_registry_generator.rb
82
90
  homepage: https://github.com/zarpay/amounts
83
91
  licenses:
84
92
  - MIT
85
93
  metadata:
86
94
  bug_tracker_uri: https://github.com/zarpay/amounts/issues
87
- changelog_uri: https://github.com/zarpay/amounts/blob/main/CHANGELOG.md
88
- documentation_uri: https://github.com/zarpay/amounts#readme
89
- source_code_uri: https://github.com/zarpay/amounts
95
+ changelog_uri: https://github.com/zarpay/amounts/blob/main/gem/CHANGELOG.md
96
+ documentation_uri: https://github.com/zarpay/amounts/tree/main/gem#readme
97
+ source_code_uri: https://github.com/zarpay/amounts/tree/main/gem
90
98
  post_install_message:
91
99
  rdoc_options: []
92
100
  require_paths:
File without changes