double_entry 1.0.1 → 2.0.0.beta5
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 +5 -5
- data/CHANGELOG.md +497 -0
- data/README.md +107 -44
- data/double_entry.gemspec +22 -49
- data/lib/active_record/locking_extensions.rb +3 -3
- data/lib/active_record/locking_extensions/log_subscriber.rb +1 -1
- data/lib/double_entry.rb +29 -21
- data/lib/double_entry/account.rb +39 -46
- data/lib/double_entry/account_balance.rb +20 -3
- data/lib/double_entry/balance_calculator.rb +5 -5
- data/lib/double_entry/configurable.rb +1 -0
- data/lib/double_entry/configuration.rb +8 -2
- data/lib/double_entry/errors.rb +13 -13
- data/lib/double_entry/line.rb +7 -6
- data/lib/double_entry/locking.rb +5 -5
- data/lib/double_entry/transfer.rb +37 -30
- data/lib/double_entry/validation.rb +1 -0
- data/lib/double_entry/validation/account_fixer.rb +36 -0
- data/lib/double_entry/validation/line_check.rb +25 -43
- data/lib/double_entry/version.rb +1 -1
- data/lib/generators/double_entry/install/install_generator.rb +22 -1
- data/lib/generators/double_entry/install/templates/initializer.rb +20 -0
- data/lib/generators/double_entry/install/templates/migration.rb +45 -55
- metadata +35 -256
- data/.gitignore +0 -32
- data/.rspec +0 -2
- data/.travis.yml +0 -29
- data/.yardopts +0 -2
- data/Gemfile +0 -2
- data/Rakefile +0 -15
- data/lib/double_entry/reporting.rb +0 -181
- data/lib/double_entry/reporting/aggregate.rb +0 -110
- data/lib/double_entry/reporting/aggregate_array.rb +0 -76
- data/lib/double_entry/reporting/day_range.rb +0 -42
- data/lib/double_entry/reporting/hour_range.rb +0 -45
- data/lib/double_entry/reporting/line_aggregate.rb +0 -16
- data/lib/double_entry/reporting/line_aggregate_filter.rb +0 -79
- data/lib/double_entry/reporting/month_range.rb +0 -94
- data/lib/double_entry/reporting/time_range.rb +0 -59
- data/lib/double_entry/reporting/time_range_array.rb +0 -49
- data/lib/double_entry/reporting/week_range.rb +0 -107
- data/lib/double_entry/reporting/year_range.rb +0 -40
- data/script/jack_hammer +0 -210
- data/script/setup.sh +0 -8
- data/spec/active_record/locking_extensions_spec.rb +0 -110
- data/spec/double_entry/account_balance_spec.rb +0 -7
- data/spec/double_entry/account_spec.rb +0 -130
- data/spec/double_entry/balance_calculator_spec.rb +0 -88
- data/spec/double_entry/configuration_spec.rb +0 -50
- data/spec/double_entry/line_spec.rb +0 -80
- data/spec/double_entry/locking_spec.rb +0 -214
- data/spec/double_entry/performance/double_entry_performance_spec.rb +0 -32
- data/spec/double_entry/performance/reporting/aggregate_performance_spec.rb +0 -50
- data/spec/double_entry/reporting/aggregate_array_spec.rb +0 -123
- data/spec/double_entry/reporting/aggregate_spec.rb +0 -205
- data/spec/double_entry/reporting/line_aggregate_filter_spec.rb +0 -90
- data/spec/double_entry/reporting/line_aggregate_spec.rb +0 -39
- data/spec/double_entry/reporting/month_range_spec.rb +0 -139
- data/spec/double_entry/reporting/time_range_array_spec.rb +0 -169
- data/spec/double_entry/reporting/time_range_spec.rb +0 -45
- data/spec/double_entry/reporting/week_range_spec.rb +0 -103
- data/spec/double_entry/reporting_spec.rb +0 -181
- data/spec/double_entry/transfer_spec.rb +0 -93
- data/spec/double_entry/validation/line_check_spec.rb +0 -99
- data/spec/double_entry_spec.rb +0 -428
- data/spec/generators/double_entry/install/install_generator_spec.rb +0 -30
- data/spec/spec_helper.rb +0 -118
- data/spec/support/accounts.rb +0 -21
- data/spec/support/blueprints.rb +0 -43
- data/spec/support/database.example.yml +0 -21
- data/spec/support/database.travis.yml +0 -24
- data/spec/support/double_entry_spec_helper.rb +0 -27
- data/spec/support/gemfiles/Gemfile.rails-3.2.x +0 -8
- data/spec/support/gemfiles/Gemfile.rails-4.1.x +0 -6
- data/spec/support/gemfiles/Gemfile.rails-4.2.x +0 -5
- data/spec/support/gemfiles/Gemfile.rails-5.0.x +0 -5
- data/spec/support/performance_helper.rb +0 -26
- data/spec/support/reporting_configuration.rb +0 -6
- data/spec/support/schema.rb +0 -74
@@ -1,50 +0,0 @@
|
|
1
|
-
module DoubleEntry
|
2
|
-
module Reporting
|
3
|
-
RSpec.describe Aggregate do
|
4
|
-
include PerformanceHelper
|
5
|
-
let(:user) { User.make! }
|
6
|
-
let(:amount) { Money.new(10_00) }
|
7
|
-
let(:test) { DoubleEntry.account(:test, :scope => user) }
|
8
|
-
let(:savings) { DoubleEntry.account(:savings, :scope => user) }
|
9
|
-
|
10
|
-
subject(:transfer) { Transfer.transfer(amount, options) }
|
11
|
-
|
12
|
-
context '200 transfers in a single day, half with metadata' do
|
13
|
-
# Surprisingly, the number of transfers makes no difference to the time taken to aggregate them. Some sample results:
|
14
|
-
# 20,000 => 524ms
|
15
|
-
# 10,000 => 573ms
|
16
|
-
# 1,000 => 486ms
|
17
|
-
# 100 => 608ms
|
18
|
-
# 10 => 509ms
|
19
|
-
# 1 => 473ms
|
20
|
-
before do
|
21
|
-
Timecop.freeze Time.local(2015, 06, 30) do
|
22
|
-
100.times { Transfer.transfer(amount, :from => test, :to => savings, :code => :bonus) }
|
23
|
-
100.times { Transfer.transfer(amount, :from => test, :to => savings, :code => :bonus, :metadata => { :country => 'AU', :tax => 'GST' }) }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'calculates monthly all_time ranges quickly without a filter' do
|
28
|
-
profile_aggregation_with_filter(nil)
|
29
|
-
# local results: 517ms, 484ms, 505ms, 482ms, 525ms
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'calculates monthly all_time ranges quickly with a filter' do
|
33
|
-
profile_aggregation_with_filter([:metadata => { :country => 'AU' }])
|
34
|
-
# local results when run independently (caching improves performance when run consecutively):
|
35
|
-
# 655ms, 613ms, 597ms, 607ms, 627ms
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def profile_aggregation_with_filter(filter)
|
40
|
-
start_profiling
|
41
|
-
range = TimeRange.make(:year => 2015, :month => 06, :range_type => :all_time)
|
42
|
-
options = {}
|
43
|
-
options[:filter] = filter if filter
|
44
|
-
Reporting.aggregate(:sum, :savings, :bonus, range, options)
|
45
|
-
profile_name = filter ? 'aggregate-with-metadata' : 'aggregate'
|
46
|
-
stop_profiling(profile_name)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,123 +0,0 @@
|
|
1
|
-
module DoubleEntry
|
2
|
-
module Reporting
|
3
|
-
RSpec.describe AggregateArray do
|
4
|
-
let(:user) { User.make! }
|
5
|
-
let(:start) { nil }
|
6
|
-
let(:finish) { nil }
|
7
|
-
let(:range_type) { 'year' }
|
8
|
-
let(:function) { 'sum' }
|
9
|
-
let(:account) { :savings }
|
10
|
-
let(:transfer_code) { :bonus }
|
11
|
-
subject(:aggregate_array) do
|
12
|
-
AggregateArray.new(
|
13
|
-
function,
|
14
|
-
account,
|
15
|
-
transfer_code,
|
16
|
-
:range_type => range_type,
|
17
|
-
:start => start,
|
18
|
-
:finish => finish,
|
19
|
-
)
|
20
|
-
end
|
21
|
-
|
22
|
-
context 'given a deposit was made in 2007 and 2008' do
|
23
|
-
before do
|
24
|
-
Timecop.travel(Time.local(2007)) do
|
25
|
-
perform_deposit user, 10_00
|
26
|
-
end
|
27
|
-
Timecop.travel(Time.local(2008)) do
|
28
|
-
perform_deposit user, 20_00
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
context 'given the date is 2009-03-19' do
|
33
|
-
before { Timecop.travel(Time.local(2009, 3, 19)) }
|
34
|
-
|
35
|
-
context 'when called with range type of "year"' do
|
36
|
-
let(:range_type) { 'year' }
|
37
|
-
let(:start) { '2006-08-03' }
|
38
|
-
it { should eq [Money.zero, Money.new(10_00), Money.new(20_00), Money.zero] }
|
39
|
-
|
40
|
-
describe 'reuse of aggregates' do
|
41
|
-
let(:years) { TimeRangeArray.make(range_type, start, finish) }
|
42
|
-
|
43
|
-
context 'and some aggregates were created previously' do
|
44
|
-
before do
|
45
|
-
Aggregate.formatted_amount(function, account, transfer_code, years[0])
|
46
|
-
Aggregate.formatted_amount(function, account, transfer_code, years[1])
|
47
|
-
allow(Aggregate).to receive(:formatted_amount)
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'only asks Aggregate for the non-existent ones' do
|
51
|
-
expect(Aggregate).not_to receive(:formatted_amount).with(function, account, transfer_code, years[0], :filter => nil)
|
52
|
-
expect(Aggregate).not_to receive(:formatted_amount).with(function, account, transfer_code, years[1], :filter => nil)
|
53
|
-
|
54
|
-
expect(Aggregate).to receive(:formatted_amount).with(function, account, transfer_code, years[2], :filter => nil)
|
55
|
-
expect(Aggregate).to receive(:formatted_amount).with(function, account, transfer_code, years[3], :filter => nil)
|
56
|
-
aggregate_array
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
context 'given a deposit was made in October and December 2006' do
|
65
|
-
before do
|
66
|
-
Timecop.travel(Time.local(2006, 10)) do
|
67
|
-
perform_deposit user, 10_00
|
68
|
-
end
|
69
|
-
Timecop.travel(Time.local(2006, 12)) do
|
70
|
-
perform_deposit user, 20_00
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
context 'when called with range type of "month", a start of "2006-09-01", and finish of "2007-01-02"' do
|
75
|
-
let(:range_type) { 'month' }
|
76
|
-
let(:start) { '2006-09-01' }
|
77
|
-
let(:finish) { '2007-01-02' }
|
78
|
-
it { should eq [Money.zero, Money.new(10_00), Money.zero, Money.new(20_00), Money.zero] }
|
79
|
-
end
|
80
|
-
|
81
|
-
context 'given the date is 2007-02-02' do
|
82
|
-
before { Timecop.travel(Time.local(2007, 2, 2)) }
|
83
|
-
|
84
|
-
context 'when called with range type of "month"' do
|
85
|
-
let(:range_type) { 'month' }
|
86
|
-
let(:start) { '2006-08-03' }
|
87
|
-
it { should eq [Money.zero, Money.zero, Money.new(10_00), Money.zero, Money.new(20_00), Money.zero, Money.zero] }
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'when account is in BTC currency' do
|
93
|
-
let(:account) { :btc_savings }
|
94
|
-
let(:range_type) { 'year' }
|
95
|
-
let(:start) { "#{Time.now.year}-01-01" }
|
96
|
-
let(:transfer_code) { :btc_test_transfer }
|
97
|
-
|
98
|
-
before do
|
99
|
-
perform_btc_deposit(user, 100_000_000)
|
100
|
-
perform_btc_deposit(user, 100_000_000)
|
101
|
-
end
|
102
|
-
|
103
|
-
it { should eq [Money.new(200_000_000, :btc)] }
|
104
|
-
end
|
105
|
-
|
106
|
-
context 'when called with range type of "invalid_and_should_not_work"' do
|
107
|
-
let(:range_type) { 'invalid_and_should_not_work' }
|
108
|
-
it 'raises an argument error' do
|
109
|
-
expect { aggregate_array }.to raise_error ArgumentError, "Invalid range type 'invalid_and_should_not_work'"
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
context 'when an invalid function is provided' do
|
114
|
-
let(:range_type) { 'month' }
|
115
|
-
let(:start) { '2006-08-03' }
|
116
|
-
let(:function) { :invalid_function }
|
117
|
-
it 'raises an AggregateFunctionNotSupported error' do
|
118
|
-
expect { aggregate_array }.to raise_error AggregateFunctionNotSupported
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
@@ -1,205 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
module DoubleEntry
|
3
|
-
module Reporting
|
4
|
-
RSpec.describe Aggregate do
|
5
|
-
let(:user) { User.make! }
|
6
|
-
let(:expected_weekly_average) do
|
7
|
-
(Money.new(20_00) + Money.new(40_00) + Money.new(50_00)) / 3
|
8
|
-
end
|
9
|
-
let(:expected_monthly_average) do
|
10
|
-
(Money.new(20_00) + Money.new(40_00) + Money.new(50_00) + Money.new(40_00) + Money.new(50_00)) / 5
|
11
|
-
end
|
12
|
-
|
13
|
-
before do
|
14
|
-
# Thursday
|
15
|
-
Timecop.freeze Time.local(2009, 10, 1) do
|
16
|
-
perform_deposit user, 20_00
|
17
|
-
end
|
18
|
-
|
19
|
-
# Saturday
|
20
|
-
Timecop.freeze Time.local(2009, 10, 3) do
|
21
|
-
perform_deposit user, 40_00
|
22
|
-
end
|
23
|
-
|
24
|
-
Timecop.freeze Time.local(2009, 10, 10) do
|
25
|
-
perform_deposit user, 50_00
|
26
|
-
end
|
27
|
-
Timecop.freeze Time.local(2009, 11, 1, 0, 59, 0) do
|
28
|
-
perform_deposit user, 40_00
|
29
|
-
end
|
30
|
-
Timecop.freeze Time.local(2009, 11, 1, 1, 00, 0) do
|
31
|
-
perform_deposit user, 50_00
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'should store the aggregate for quick retrieval' do
|
36
|
-
Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :month => 10)).amount
|
37
|
-
expect(LineAggregate.count).to eq 1
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'should only store the aggregate once if it is requested more than once' do
|
41
|
-
Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :month => 9)).amount
|
42
|
-
Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :month => 9)).amount
|
43
|
-
Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :month => 10)).amount
|
44
|
-
expect(LineAggregate.count).to eq 2
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'should calculate the complete year correctly' do
|
48
|
-
amount = Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009)).formatted_amount
|
49
|
-
expect(amount).to eq Money.new(200_00)
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'should calculate seperate months correctly' do
|
53
|
-
amount = Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :month => 10)).formatted_amount
|
54
|
-
expect(amount).to eq Money.new(110_00)
|
55
|
-
|
56
|
-
amount = Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :month => 11)).formatted_amount
|
57
|
-
expect(amount).to eq Money.new(90_00)
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'should calculate seperate weeks correctly' do
|
61
|
-
# Week 40 - Mon Sep 28, 2009 to Sun Oct 4 2009
|
62
|
-
amount = Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :week => 40)).formatted_amount
|
63
|
-
expect(amount).to eq Money.new(60_00)
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'should calculate seperate days correctly' do
|
67
|
-
# 1 Nov 2009
|
68
|
-
amount = Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :week => 44, :day => 7)).formatted_amount
|
69
|
-
expect(amount).to eq Money.new(90_00)
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'should calculate seperate hours correctly' do
|
73
|
-
# 1 Nov 2009
|
74
|
-
amount = Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :week => 44, :day => 7, :hour => 0)).formatted_amount
|
75
|
-
expect(amount).to eq Money.new(40_00)
|
76
|
-
amount = Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :week => 44, :day => 7, :hour => 1)).formatted_amount
|
77
|
-
expect(amount).to eq Money.new(50_00)
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'should calculate, but not store aggregates when the time range is still current' do
|
81
|
-
Timecop.freeze Time.local(2009, 11, 21) do
|
82
|
-
amount = Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :month => 11)).formatted_amount
|
83
|
-
expect(amount).to eq Money.new(90_00)
|
84
|
-
expect(LineAggregate.count).to eq 0
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'should calculate, but not store aggregates when the time range is in the future' do
|
89
|
-
Timecop.freeze Time.local(2009, 11, 21) do
|
90
|
-
amount = Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :month => 12)).formatted_amount
|
91
|
-
expect(amount).to eq Money.new(0)
|
92
|
-
expect(LineAggregate.count).to eq 0
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'should calculate monthly all_time ranges correctly' do
|
97
|
-
amount = Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :month => 12, :range_type => :all_time)).formatted_amount
|
98
|
-
expect(amount).to eq Money.new(200_00)
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'calculates the average monthly all_time ranges correctly' do
|
102
|
-
amount = Aggregate.new(:average, :savings, :bonus, TimeRange.make(:year => 2009, :month => 12, :range_type => :all_time)).formatted_amount
|
103
|
-
expect(amount).to eq expected_monthly_average
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'returns the correct count for weekly all_time ranges correctly' do
|
107
|
-
amount = Aggregate.new(:count, :savings, :bonus, TimeRange.make(:year => 2009, :month => 12, :range_type => :all_time)).formatted_amount
|
108
|
-
expect(amount).to eq 5
|
109
|
-
end
|
110
|
-
|
111
|
-
it 'should calculate weekly all_time ranges correctly' do
|
112
|
-
amount = Aggregate.new(:sum, :savings, :bonus, TimeRange.make(:year => 2009, :week => 43, :range_type => :all_time)).formatted_amount
|
113
|
-
expect(amount).to eq Money.new(110_00)
|
114
|
-
end
|
115
|
-
|
116
|
-
it 'calculates the average weekly all_time ranges correctly' do
|
117
|
-
amount = Aggregate.new(:average, :savings, :bonus, TimeRange.make(:year => 2009, :week => 43, :range_type => :all_time)).formatted_amount
|
118
|
-
expect(amount).to eq expected_weekly_average
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'returns the correct count for weekly all_time ranges correctly' do
|
122
|
-
amount = Aggregate.new(:count, :savings, :bonus, TimeRange.make(:year => 2009, :week => 43, :range_type => :all_time)).formatted_amount
|
123
|
-
expect(amount).to eq 3
|
124
|
-
end
|
125
|
-
|
126
|
-
it 'raises an AggregateFunctionNotSupported exception' do
|
127
|
-
expect do
|
128
|
-
Aggregate.new(
|
129
|
-
:not_supported_calculation, :savings, :bonus, TimeRange.make(:year => 2009, :week => 43, :range_type => :all_time)
|
130
|
-
).amount
|
131
|
-
end.to raise_error(AggregateFunctionNotSupported)
|
132
|
-
end
|
133
|
-
|
134
|
-
context 'filters' do
|
135
|
-
let(:range) { TimeRange.make(:year => 2011, :month => 10) }
|
136
|
-
let(:filter) do
|
137
|
-
[
|
138
|
-
:scope => {
|
139
|
-
:name => :test_filter,
|
140
|
-
},
|
141
|
-
]
|
142
|
-
end
|
143
|
-
|
144
|
-
DoubleEntry::Line.class_eval do
|
145
|
-
scope :test_filter, -> { where(:amount => 10_00) }
|
146
|
-
end
|
147
|
-
|
148
|
-
before do
|
149
|
-
Timecop.freeze Time.local(2011, 10, 10) do
|
150
|
-
perform_deposit user, 10_00
|
151
|
-
end
|
152
|
-
|
153
|
-
Timecop.freeze Time.local(2011, 10, 10) do
|
154
|
-
perform_deposit user, 9_00
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
it 'saves filtered aggregations' do
|
159
|
-
expect do
|
160
|
-
Aggregate.new(:sum, :savings, :bonus, range, :filter => filter).amount
|
161
|
-
end.to change { LineAggregate.count }.by 1
|
162
|
-
end
|
163
|
-
|
164
|
-
it 'saves filtered aggregation only once for a range' do
|
165
|
-
expect do
|
166
|
-
Aggregate.new(:sum, :savings, :bonus, range, :filter => filter).amount
|
167
|
-
Aggregate.new(:sum, :savings, :bonus, range, :filter => filter).amount
|
168
|
-
end.to change { LineAggregate.count }.by 1
|
169
|
-
end
|
170
|
-
|
171
|
-
it 'saves filtered aggregations and non filtered aggregations separately' do
|
172
|
-
expect do
|
173
|
-
Aggregate.new(:sum, :savings, :bonus, range, :filter => filter).amount
|
174
|
-
Aggregate.new(:sum, :savings, :bonus, range).amount
|
175
|
-
end.to change { LineAggregate.count }.by 2
|
176
|
-
end
|
177
|
-
|
178
|
-
it 'loads the correct saved aggregation' do
|
179
|
-
# cache the results for filtered and unfiltered aggregations
|
180
|
-
Aggregate.new(:sum, :savings, :bonus, range, :filter => filter).amount
|
181
|
-
Aggregate.new(:sum, :savings, :bonus, range).amount
|
182
|
-
|
183
|
-
# ensure a second call loads the correct cached value
|
184
|
-
amount = Aggregate.new(:sum, :savings, :bonus, range, :filter => filter).formatted_amount
|
185
|
-
expect(amount).to eq Money.new(10_00)
|
186
|
-
|
187
|
-
amount = Aggregate.new(:sum, :savings, :bonus, range).formatted_amount
|
188
|
-
expect(amount).to eq Money.new(19_00)
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
192
|
-
RSpec.describe Aggregate, 'currencies' do
|
193
|
-
let(:user) { User.make! }
|
194
|
-
before do
|
195
|
-
perform_btc_deposit(user, 100_000_000)
|
196
|
-
perform_btc_deposit(user, 200_000_000)
|
197
|
-
end
|
198
|
-
|
199
|
-
it 'should calculate the sum in the correct currency' do
|
200
|
-
amount = Aggregate.new(:sum, :btc_savings, :btc_test_transfer, TimeRange.make(:year => Time.now.year)).formatted_amount
|
201
|
-
expect(amount).to eq(Money.new(300_000_000, :btc))
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
RSpec.describe DoubleEntry::Reporting::LineAggregateFilter do
|
3
|
-
describe '.filter' do
|
4
|
-
let(:function) { :sum }
|
5
|
-
let(:account) { :account }
|
6
|
-
let(:code) { :transfer_code }
|
7
|
-
let(:filter_criteria) { nil }
|
8
|
-
let(:start) { Time.parse('2014-07-27 10:55:44 +1000') }
|
9
|
-
let(:finish) { Time.parse('2015-07-27 10:55:44 +1000') }
|
10
|
-
let(:range) do
|
11
|
-
instance_double(DoubleEntry::Reporting::MonthRange, :start => start, :finish => finish)
|
12
|
-
end
|
13
|
-
|
14
|
-
let(:lines_scope) { spy(DoubleEntry::Line) }
|
15
|
-
|
16
|
-
subject(:filter) do
|
17
|
-
DoubleEntry::Reporting::LineAggregateFilter.new(account, code, range, filter_criteria)
|
18
|
-
end
|
19
|
-
|
20
|
-
before do
|
21
|
-
stub_const('DoubleEntry::Line', lines_scope)
|
22
|
-
|
23
|
-
allow(DoubleEntry::LineMetadata).to receive(:table_name).and_return('double_entry_line_metadata')
|
24
|
-
|
25
|
-
allow(lines_scope).to receive(:where).and_return(lines_scope)
|
26
|
-
allow(lines_scope).to receive(:joins).and_return(lines_scope)
|
27
|
-
allow(lines_scope).to receive(:ten_dollar_purchases).and_return(lines_scope)
|
28
|
-
allow(lines_scope).to receive(:ten_dollar_purchases_by_category).and_return(lines_scope)
|
29
|
-
|
30
|
-
filter.filter
|
31
|
-
end
|
32
|
-
|
33
|
-
context 'with named scopes specified' do
|
34
|
-
let(:filter_criteria) do
|
35
|
-
[
|
36
|
-
# an example of calling a named scope called with arguments
|
37
|
-
{
|
38
|
-
:scope => {
|
39
|
-
:name => :ten_dollar_purchases_by_category,
|
40
|
-
:arguments => [:cat_videos, :cat_pictures],
|
41
|
-
},
|
42
|
-
},
|
43
|
-
# an example of calling a named scope with no arguments
|
44
|
-
{
|
45
|
-
:scope => {
|
46
|
-
:name => :ten_dollar_purchases,
|
47
|
-
},
|
48
|
-
},
|
49
|
-
# an example of providing a single metadatum criteria to filter on
|
50
|
-
{
|
51
|
-
:metadata => {
|
52
|
-
:meme => 'business_cat',
|
53
|
-
},
|
54
|
-
},
|
55
|
-
]
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'filters by all the scopes provided' do
|
59
|
-
expect(DoubleEntry::Line).to have_received(:ten_dollar_purchases)
|
60
|
-
expect(DoubleEntry::Line).to have_received(:ten_dollar_purchases_by_category).
|
61
|
-
with(:cat_videos, :cat_pictures)
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'filters by all the metadata provided' do
|
65
|
-
expect(DoubleEntry::Line).to have_received(:joins).with(:metadata)
|
66
|
-
expect(DoubleEntry::Line).to have_received(:where).
|
67
|
-
with(:double_entry_line_metadata => { :key => :meme, :value => 'business_cat' })
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'with a code specified' do
|
72
|
-
let(:code) { :transfer_code }
|
73
|
-
|
74
|
-
it 'retrieves the appropriate lines for aggregation' do
|
75
|
-
expect(DoubleEntry::Line).to have_received(:where).with(:account => account)
|
76
|
-
expect(DoubleEntry::Line).to have_received(:where).with(:created_at => start..finish)
|
77
|
-
expect(DoubleEntry::Line).to have_received(:where).with(:code => code)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
context 'with no code specified' do
|
82
|
-
let(:code) { nil }
|
83
|
-
|
84
|
-
it 'retrieves the appropriate lines for aggregation' do
|
85
|
-
expect(DoubleEntry::Line).to have_received(:where).with(:account => account)
|
86
|
-
expect(DoubleEntry::Line).to have_received(:where).with(:created_at => start..finish)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|