amounts 0.0.8 → 0.1.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/.rubocop.yml +37 -0
- data/CHANGELOG.md +113 -0
- data/Gemfile +4 -0
- data/README.md +215 -1
- data/Rakefile +47 -10
- data/lib/amount/active_record/amount_validator.rb +9 -18
- data/lib/amount/active_record/attribute_definition.rb +3 -1
- data/lib/amount/active_record/locale/en.yml +7 -0
- data/lib/amount/active_record/model.rb +9 -0
- data/lib/amount/active_record.rb +12 -0
- data/lib/amount/compact.rb +137 -0
- data/lib/amount/{allocation.rb → concerns/allocatable.rb} +1 -1
- data/lib/amount/{arithmetic.rb → concerns/calculable.rb} +1 -1
- data/lib/amount/concerns/coercible.rb +65 -0
- data/lib/amount/concerns/constructible.rb +92 -0
- data/lib/amount/{conversion.rb → concerns/convertible.rb} +1 -1
- data/lib/amount/concerns/formattable.rb +112 -0
- data/lib/amount/concerns/localizable.rb +39 -0
- data/lib/amount/{comparison.rb → concerns/orderable.rb} +2 -2
- data/lib/amount/concerns/parsable.rb +58 -0
- data/lib/amount/concerns/registrable.rb +80 -0
- data/lib/amount/{serialization.rb → concerns/serializable.rb} +3 -3
- data/lib/amount/display.rb +81 -46
- data/lib/amount/locale.rb +102 -0
- data/lib/amount/registry.rb +69 -7
- data/lib/amount/ui_parser.rb +109 -0
- data/lib/amount/version.rb +1 -1
- data/lib/amount.rb +55 -199
- data/test/amount/active_record/amount_validator_test.rb +201 -0
- data/test/amount/active_record/attribute_definition_test.rb +234 -0
- data/test/amount/active_record/migration_methods_test.rb +60 -0
- data/test/amount/active_record/model_test.rb +40 -0
- data/test/amount/active_record/type_test.rb +80 -0
- data/test/amount/active_record_test.rb +12 -0
- data/test/amount/compact_test.rb +371 -0
- data/test/amount/concerns/allocatable_test.rb +166 -0
- data/test/amount/concerns/calculable_test.rb +152 -0
- data/test/amount/concerns/coercible_test.rb +49 -0
- data/test/amount/concerns/constructible_test.rb +113 -0
- data/test/amount/concerns/convertible_test.rb +54 -0
- data/test/amount/concerns/formattable_test.rb +336 -0
- data/test/amount/concerns/localizable_test.rb +59 -0
- data/test/amount/concerns/orderable_test.rb +83 -0
- data/test/amount/concerns/parsable_test.rb +98 -0
- data/test/amount/concerns/registrable_test.rb +67 -0
- data/test/amount/concerns/serializable_test.rb +98 -0
- data/test/amount/display_test.rb +181 -0
- data/test/amount/locale_test.rb +590 -0
- data/test/amount/parser_test.rb +29 -0
- data/test/amount/registry/generated_constructors_test.rb +94 -0
- data/test/amount/registry_test.rb +149 -0
- data/test/amount/ui_parser_test.rb +284 -0
- data/test/amount_test.rb +55 -0
- data/test/dummy/config/application.rb +3 -0
- data/test/generators/amount/active_record/registry_generator_test.rb +116 -0
- data/test/integration/postgresql_test.rb +94 -0
- data/test/support/active_record_test_support.rb +65 -0
- data/test/support/error_helpers.rb +22 -0
- data/test/support/locale_test_setup.rb +36 -0
- data/test/test_helper.rb +1 -0
- metadata +47 -11
- data/test/postgresql_integration_test.rb +0 -71
- data/test/test_active_record.rb +0 -375
- data/test/test_amount.rb +0 -675
- data/test/test_registry_generator.rb +0 -104
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../test_helper"
|
|
4
|
+
|
|
5
|
+
begin
|
|
6
|
+
require "pg"
|
|
7
|
+
rescue LoadError
|
|
8
|
+
# Handled in setup.
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
ENV["RAILS_ENV"] = "test"
|
|
12
|
+
|
|
13
|
+
require_relative "../dummy/config/environment"
|
|
14
|
+
require "active_record/tasks/database_tasks"
|
|
15
|
+
|
|
16
|
+
class PostgreSQLIntegrationTest < Minitest::Test
|
|
17
|
+
DUMMY_ROOT = File.expand_path("../dummy", __dir__)
|
|
18
|
+
|
|
19
|
+
def setup
|
|
20
|
+
skip "pg gem is not installed" unless defined?(PG)
|
|
21
|
+
skip "set AMOUNTS_POSTGRES_URL to run PostgreSQL integration tests" unless ENV["AMOUNTS_POSTGRES_URL"]
|
|
22
|
+
|
|
23
|
+
AmountTestSupport.register_active_record_types!
|
|
24
|
+
configure_database_tasks
|
|
25
|
+
recreate_schema!
|
|
26
|
+
# With a URL set, an unreachable database is an error, not a skip, so a
|
|
27
|
+
# broken CI service can't pass silently.
|
|
28
|
+
Holding.delete_all
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def teardown
|
|
32
|
+
Amount.registry.clear!
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_postgresql_round_trips_large_atomic_values_exactly
|
|
36
|
+
huge_atomic = 10**30
|
|
37
|
+
holding = Holding.create!(amount: Amount.new(huge_atomic, :SOL, from: :atomic))
|
|
38
|
+
|
|
39
|
+
assert_equal huge_atomic, holding.reload.amount.atomic
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_postgresql_uses_default_numeric_precision_for_amount_columns
|
|
43
|
+
assert_equal 78, Holding.columns_hash.fetch("amount_atomic").precision
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Rails reports `scale` as nil for any zero-scale decimal, so check the
|
|
47
|
+
# column type PostgreSQL actually created.
|
|
48
|
+
def test_postgresql_uses_zero_scale_for_amount_columns
|
|
49
|
+
assert_equal "numeric(78,0)", Holding.columns_hash.fetch("amount_atomic").sql_type
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_postgresql_uses_given_numeric_precision_for_amount_columns
|
|
53
|
+
assert_equal 40, Holding.columns_hash.fetch("reserve_atomic").precision
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_postgresql_uses_zero_scale_for_amount_columns_with_given_precision
|
|
57
|
+
assert_equal "numeric(40,0)", Holding.columns_hash.fetch("reserve_atomic").sql_type
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_postgresql_where_query_works_with_amount_columns
|
|
61
|
+
usdc = create_usdc_and_usd_holdings
|
|
62
|
+
|
|
63
|
+
assert_equal [usdc.id], Holding.where_amount("USDC|1.50").pluck(:id)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_postgresql_group_query_works_with_amount_columns
|
|
67
|
+
create_usdc_and_usd_holdings
|
|
68
|
+
|
|
69
|
+
assert_equal({ "USDC" => 1_500_000, "USD" => 300 }, Holding.group(:amount_symbol).sum(:amount_atomic))
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
# The USDC holding; a USD holding is created alongside.
|
|
75
|
+
def create_usdc_and_usd_holdings
|
|
76
|
+
usdc = Holding.create!(amount: "USDC|1.50")
|
|
77
|
+
Holding.create!(amount: "USD|3.00")
|
|
78
|
+
usdc
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def configure_database_tasks
|
|
82
|
+
ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
|
|
83
|
+
ActiveRecord::Tasks::DatabaseTasks.db_dir = File.join(DUMMY_ROOT, "db")
|
|
84
|
+
ActiveRecord::Tasks::DatabaseTasks.env = "test"
|
|
85
|
+
ActiveRecord::Tasks::DatabaseTasks.root = DUMMY_ROOT
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def recreate_schema!
|
|
89
|
+
ActiveRecord::Base.establish_connection(:test)
|
|
90
|
+
ActiveRecord::Migration.verbose = false
|
|
91
|
+
load File.join(DUMMY_ROOT, "db/schema.rb")
|
|
92
|
+
Holding.reset_column_information
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_record"
|
|
4
|
+
require "sqlite3"
|
|
5
|
+
require_relative "amount_test_support"
|
|
6
|
+
require_relative "../../lib/amount/active_record"
|
|
7
|
+
|
|
8
|
+
# In-memory SQLite schema and models shared by the ActiveRecord adapter tests.
|
|
9
|
+
# Loaded once per process however many test files require it.
|
|
10
|
+
|
|
11
|
+
AmountTestSupport.register_active_record_types!
|
|
12
|
+
|
|
13
|
+
::ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
|
14
|
+
|
|
15
|
+
::ActiveRecord::Schema.define do
|
|
16
|
+
create_table :holdings, force: true do |t|
|
|
17
|
+
t.amount :amount, null: true
|
|
18
|
+
t.amount :fee, symbol: :SOL, null: true
|
|
19
|
+
t.amount :reserve, precision: 40, default: "USDC|1.25", null: false
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class Holding < ::ActiveRecord::Base
|
|
24
|
+
has_amount :amount
|
|
25
|
+
has_amount :fee, symbol: :SOL
|
|
26
|
+
has_amount :reserve
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class ValidatedHolding < ::ActiveRecord::Base
|
|
30
|
+
self.table_name = "holdings"
|
|
31
|
+
|
|
32
|
+
has_amount :amount
|
|
33
|
+
has_amount :fee, symbol: :SOL
|
|
34
|
+
has_amount :reserve
|
|
35
|
+
|
|
36
|
+
validates :amount, amount: {
|
|
37
|
+
symbol: :USDC,
|
|
38
|
+
greater_than: "USDC|0",
|
|
39
|
+
less_than_or_equal_to: "USDC|1000"
|
|
40
|
+
}
|
|
41
|
+
validates :fee, amount: {
|
|
42
|
+
symbol: :SOL,
|
|
43
|
+
greater_than: 0,
|
|
44
|
+
less_than: 10,
|
|
45
|
+
allow_nil: true
|
|
46
|
+
}
|
|
47
|
+
validates :reserve, amount: {
|
|
48
|
+
greater_than_or_equal_to: "USDC|1.25"
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Empty tables and the ActiveRecord test types before each test; an empty
|
|
53
|
+
# registry after it.
|
|
54
|
+
module ActiveRecordTestSetup
|
|
55
|
+
def setup
|
|
56
|
+
Holding.delete_all
|
|
57
|
+
ValidatedHolding.delete_all
|
|
58
|
+
|
|
59
|
+
AmountTestSupport.register_active_record_types!
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def teardown
|
|
63
|
+
Amount.registry.clear!
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "minitest"
|
|
4
|
+
|
|
5
|
+
# Helpers for tests that assert on an error's message, so the raise and the
|
|
6
|
+
# message can be checked in separate single-assertion tests.
|
|
7
|
+
module ErrorHelpers
|
|
8
|
+
# The error the block raises. Not an assertion: the test still asserts on
|
|
9
|
+
# the result. Fails the test when nothing is raised.
|
|
10
|
+
#
|
|
11
|
+
# @param klass [Class<Exception>]
|
|
12
|
+
# @return [Exception]
|
|
13
|
+
def error_from(klass = StandardError)
|
|
14
|
+
yield
|
|
15
|
+
rescue klass => e
|
|
16
|
+
e
|
|
17
|
+
else
|
|
18
|
+
raise Minitest::Assertion, "expected #{klass} to be raised, nothing was raised"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
Minitest::Test.include(ErrorHelpers)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18n"
|
|
4
|
+
|
|
5
|
+
# Default types plus a fresh I18n backend with en, de and fr number formats,
|
|
6
|
+
# restored after each test.
|
|
7
|
+
module LocaleTestSetup
|
|
8
|
+
def setup
|
|
9
|
+
AmountTestSupport.register_default_types!
|
|
10
|
+
@previous_locale = I18n.locale
|
|
11
|
+
@previous_backend = I18n.backend
|
|
12
|
+
I18n.backend = I18n::Backend::Simple.new
|
|
13
|
+
I18n.available_locales = %i[en de fr xx]
|
|
14
|
+
I18n.backend.store_translations(:en, number: { format: { delimiter: ",", separator: "." } })
|
|
15
|
+
I18n.backend.store_translations(:de, number: { format: { delimiter: ".", separator: "," } })
|
|
16
|
+
I18n.backend.store_translations(:fr, number: { format: { delimiter: " ", separator: "," } })
|
|
17
|
+
Amount.localize = false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def teardown
|
|
21
|
+
Amount.localize = false
|
|
22
|
+
I18n.backend = @previous_backend
|
|
23
|
+
I18n.locale = @previous_locale
|
|
24
|
+
Amount.registry.clear!
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
# Runs the block as if the i18n gem were not loaded.
|
|
30
|
+
def without_i18n
|
|
31
|
+
i18n = Object.send(:remove_const, :I18n)
|
|
32
|
+
yield
|
|
33
|
+
ensure
|
|
34
|
+
Object.const_set(:I18n, i18n)
|
|
35
|
+
end
|
|
36
|
+
end
|
data/test/test_helper.rb
CHANGED
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
|
+
version: 0.1.0
|
|
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-
|
|
11
|
+
date: 2026-11-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bigdecimal
|
|
@@ -47,24 +47,34 @@ files:
|
|
|
47
47
|
- lib/amount/active_record.rb
|
|
48
48
|
- lib/amount/active_record/amount_validator.rb
|
|
49
49
|
- lib/amount/active_record/attribute_definition.rb
|
|
50
|
+
- lib/amount/active_record/locale/en.yml
|
|
50
51
|
- lib/amount/active_record/migration_methods.rb
|
|
51
52
|
- lib/amount/active_record/model.rb
|
|
52
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
|
|
56
|
-
- lib/amount/
|
|
57
|
-
- lib/amount/
|
|
58
|
-
- lib/amount/
|
|
59
|
-
- lib/amount/
|
|
57
|
+
- lib/amount/compact.rb
|
|
58
|
+
- lib/amount/concerns/allocatable.rb
|
|
59
|
+
- lib/amount/concerns/calculable.rb
|
|
60
|
+
- lib/amount/concerns/coercible.rb
|
|
61
|
+
- lib/amount/concerns/constructible.rb
|
|
62
|
+
- lib/amount/concerns/convertible.rb
|
|
63
|
+
- lib/amount/concerns/formattable.rb
|
|
64
|
+
- lib/amount/concerns/localizable.rb
|
|
65
|
+
- lib/amount/concerns/orderable.rb
|
|
66
|
+
- lib/amount/concerns/parsable.rb
|
|
67
|
+
- lib/amount/concerns/registrable.rb
|
|
68
|
+
- lib/amount/concerns/serializable.rb
|
|
60
69
|
- lib/amount/display.rb
|
|
70
|
+
- lib/amount/locale.rb
|
|
61
71
|
- lib/amount/parser.rb
|
|
62
72
|
- lib/amount/registry.rb
|
|
63
73
|
- lib/amount/registry/generated_constructors.rb
|
|
64
74
|
- lib/amount/rspec.rb
|
|
65
75
|
- lib/amount/rspec/matchers.rb
|
|
66
76
|
- lib/amount/rspec/support.rb
|
|
67
|
-
- lib/amount/
|
|
77
|
+
- lib/amount/ui_parser.rb
|
|
68
78
|
- lib/amount/version.rb
|
|
69
79
|
- lib/amounts.rb
|
|
70
80
|
- lib/generators/amount/active_record/registry_generator.rb
|
|
@@ -73,6 +83,31 @@ files:
|
|
|
73
83
|
- lib/generators/amount/active_record/templates/presets/fiat.fragment
|
|
74
84
|
- lib/generators/amount/active_record/templates/presets/metals.fragment
|
|
75
85
|
- lib/generators/amount/active_record/templates/registry.rb.tt
|
|
86
|
+
- test/amount/active_record/amount_validator_test.rb
|
|
87
|
+
- test/amount/active_record/attribute_definition_test.rb
|
|
88
|
+
- test/amount/active_record/migration_methods_test.rb
|
|
89
|
+
- test/amount/active_record/model_test.rb
|
|
90
|
+
- test/amount/active_record/type_test.rb
|
|
91
|
+
- test/amount/active_record_test.rb
|
|
92
|
+
- test/amount/compact_test.rb
|
|
93
|
+
- test/amount/concerns/allocatable_test.rb
|
|
94
|
+
- test/amount/concerns/calculable_test.rb
|
|
95
|
+
- test/amount/concerns/coercible_test.rb
|
|
96
|
+
- test/amount/concerns/constructible_test.rb
|
|
97
|
+
- test/amount/concerns/convertible_test.rb
|
|
98
|
+
- test/amount/concerns/formattable_test.rb
|
|
99
|
+
- test/amount/concerns/localizable_test.rb
|
|
100
|
+
- test/amount/concerns/orderable_test.rb
|
|
101
|
+
- test/amount/concerns/parsable_test.rb
|
|
102
|
+
- test/amount/concerns/registrable_test.rb
|
|
103
|
+
- test/amount/concerns/serializable_test.rb
|
|
104
|
+
- test/amount/display_test.rb
|
|
105
|
+
- test/amount/locale_test.rb
|
|
106
|
+
- test/amount/parser_test.rb
|
|
107
|
+
- test/amount/registry/generated_constructors_test.rb
|
|
108
|
+
- test/amount/registry_test.rb
|
|
109
|
+
- test/amount/ui_parser_test.rb
|
|
110
|
+
- test/amount_test.rb
|
|
76
111
|
- test/dummy/app/models/holding.rb
|
|
77
112
|
- test/dummy/bin/rails
|
|
78
113
|
- test/dummy/config/application.rb
|
|
@@ -80,12 +115,13 @@ files:
|
|
|
80
115
|
- test/dummy/config/environment.rb
|
|
81
116
|
- test/dummy/db/schema.rb
|
|
82
117
|
- test/dummy/log/test.log
|
|
83
|
-
- test/
|
|
118
|
+
- test/generators/amount/active_record/registry_generator_test.rb
|
|
119
|
+
- test/integration/postgresql_test.rb
|
|
120
|
+
- test/support/active_record_test_support.rb
|
|
84
121
|
- test/support/amount_test_support.rb
|
|
85
|
-
- test/
|
|
86
|
-
- test/
|
|
122
|
+
- test/support/error_helpers.rb
|
|
123
|
+
- test/support/locale_test_setup.rb
|
|
87
124
|
- test/test_helper.rb
|
|
88
|
-
- test/test_registry_generator.rb
|
|
89
125
|
homepage: https://github.com/zarpay/amounts
|
|
90
126
|
licenses:
|
|
91
127
|
- MIT
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "test_helper"
|
|
4
|
-
|
|
5
|
-
begin
|
|
6
|
-
require "pg"
|
|
7
|
-
rescue LoadError
|
|
8
|
-
# Handled in setup.
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
ENV["RAILS_ENV"] = "test"
|
|
12
|
-
|
|
13
|
-
require_relative "dummy/config/environment"
|
|
14
|
-
require "active_record/tasks/database_tasks"
|
|
15
|
-
|
|
16
|
-
class PostgreSQLIntegrationTest < Minitest::Test
|
|
17
|
-
def setup
|
|
18
|
-
skip "pg gem is not installed" unless defined?(PG)
|
|
19
|
-
skip "set AMOUNTS_POSTGRES_URL to run PostgreSQL integration tests" unless ENV["AMOUNTS_POSTGRES_URL"]
|
|
20
|
-
|
|
21
|
-
AmountTestSupport.register_active_record_types!
|
|
22
|
-
configure_database_tasks
|
|
23
|
-
recreate_schema!
|
|
24
|
-
Holding.delete_all
|
|
25
|
-
rescue PG::Error, ActiveRecord::ConnectionNotEstablished => error
|
|
26
|
-
skip "PostgreSQL is unavailable: #{error.message}"
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def teardown
|
|
30
|
-
Amount.registry.clear!
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def test_postgresql_round_trips_large_atomic_values_exactly
|
|
34
|
-
huge_atomic = 10**30
|
|
35
|
-
holding = Holding.create!(amount: Amount.new(huge_atomic, :SOL, from: :atomic))
|
|
36
|
-
|
|
37
|
-
assert_equal huge_atomic, holding.reload.amount.atomic
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def test_postgresql_uses_numeric_precision_for_amount_columns
|
|
41
|
-
columns = Holding.columns_hash
|
|
42
|
-
|
|
43
|
-
assert_equal 78, columns.fetch("amount_atomic").precision
|
|
44
|
-
assert_equal 0, columns.fetch("amount_atomic").scale
|
|
45
|
-
assert_equal 40, columns.fetch("reserve_atomic").precision
|
|
46
|
-
assert_equal 0, columns.fetch("reserve_atomic").scale
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def test_postgresql_where_and_group_queries_work_with_amount_columns
|
|
50
|
-
usdc = Holding.create!(amount: "USDC|1.50")
|
|
51
|
-
Holding.create!(amount: "USD|3.00")
|
|
52
|
-
|
|
53
|
-
assert_equal [usdc.id], Holding.where_amount("USDC|1.50").pluck(:id)
|
|
54
|
-
assert_equal({ "USDC" => 1_500_000, "USD" => 300 }, Holding.group(:amount_symbol).sum(:amount_atomic))
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
private
|
|
58
|
-
|
|
59
|
-
def configure_database_tasks
|
|
60
|
-
ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
|
|
61
|
-
ActiveRecord::Tasks::DatabaseTasks.db_dir = File.expand_path("dummy/db", __dir__)
|
|
62
|
-
ActiveRecord::Tasks::DatabaseTasks.env = "test"
|
|
63
|
-
ActiveRecord::Tasks::DatabaseTasks.root = File.expand_path("dummy", __dir__)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def recreate_schema!
|
|
67
|
-
ActiveRecord::Base.establish_connection(:test)
|
|
68
|
-
load File.expand_path("dummy/db/schema.rb", __dir__)
|
|
69
|
-
Holding.reset_column_information
|
|
70
|
-
end
|
|
71
|
-
end
|