mudrat_projector 0.9.3 → 0.9.4
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/mudrat_projector/date_diff.rb +10 -2
- data/lib/mudrat_projector/projector.rb +5 -1
- data/lib/mudrat_projector/schedule.rb +5 -2
- data/lib/mudrat_projector/transaction_entry.rb +1 -1
- data/lib/mudrat_projector/version.rb +1 -1
- data/test/models/date_diff_test.rb +26 -27
- data/test/models/projector_test.rb +26 -0
- data/test/models/schedule_test.rb +22 -0
- data/test/test_helper.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2181d2b58ff6ff66fc876cb0a69b95c40a73cb8
|
4
|
+
data.tar.gz: 506905ae2d682c9c3dd13712ad381fc2ba71b418
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efafce27f94ec1a5c2a96535cd09fe6a3db785fe5581804cf0e7bd040b1d7adbf39e723d3c0bd55bec33325d4371aa59ac1dc6c19e73b8db7666cf037ab6ae1d
|
7
|
+
data.tar.gz: e3cd5fc24943b3ba408d68fb4ae2c5cefc484f4f1d425b39ed58fb8530791bb1323928daf3a3f6813d4e53d97a9a9805b6eb22c57a91d454403443eaf7dfbc88
|
@@ -28,9 +28,17 @@ module MudratProjector
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def days_between
|
31
|
-
(to - from)
|
31
|
+
to_big_decimal(to - from) + 1
|
32
32
|
end
|
33
33
|
private :days_between
|
34
|
+
|
35
|
+
def to_big_decimal(number)
|
36
|
+
if number.is_a? Rational
|
37
|
+
number.to_d(20)
|
38
|
+
else
|
39
|
+
number.to_d
|
40
|
+
end
|
41
|
+
end
|
34
42
|
end
|
35
43
|
|
36
44
|
class DayCalculator < Calculator
|
@@ -88,7 +96,7 @@ module MudratProjector
|
|
88
96
|
end
|
89
97
|
|
90
98
|
def days_in_unit unit
|
91
|
-
((unit.end + 1) - unit.begin)
|
99
|
+
to_big_decimal((unit.end + 1) - unit.begin)
|
92
100
|
end
|
93
101
|
|
94
102
|
def units_between
|
@@ -18,7 +18,7 @@ module MudratProjector
|
|
18
18
|
@validator = Validator.new projector: self, chart: @chart
|
19
19
|
end
|
20
20
|
|
21
|
-
def_delegators :@chart, *%i(accounts account_balance apply_transaction balance fetch
|
21
|
+
def_delegators :@chart, *%i(accounts account_balance apply_transaction balance fetch split_account)
|
22
22
|
def_delegators :@validator, *%i(must_be_balanced! validate_account! validate_transaction!)
|
23
23
|
|
24
24
|
def accounts= accounts
|
@@ -51,6 +51,10 @@ module MudratProjector
|
|
51
51
|
balance.zero?
|
52
52
|
end
|
53
53
|
|
54
|
+
def net_worth
|
55
|
+
@chart.net_worth.round(2).to_f
|
56
|
+
end
|
57
|
+
|
54
58
|
def project to: end_of_projection, build_next: false, &block
|
55
59
|
must_be_balanced!
|
56
60
|
projection = Projection.new range: (from..to), chart: @chart
|
@@ -12,7 +12,9 @@ module MudratProjector
|
|
12
12
|
split_count_over(range).reduce range.begin do |date, factor|
|
13
13
|
@count -= factor if @count
|
14
14
|
yield [date, factor]
|
15
|
-
|
15
|
+
scalar.times.reduce date do |date, _|
|
16
|
+
DateDiff.advance intervals: factor, unit: unit, from: date
|
17
|
+
end
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
@@ -22,7 +24,8 @@ module MudratProjector
|
|
22
24
|
|
23
25
|
def split_count_over range
|
24
26
|
diff = DateDiff.date_diff unit: unit, from: range.begin, to: range.end
|
25
|
-
full_units, final_prorate = [@count, diff].compact.min.divmod
|
27
|
+
full_units, final_prorate = [@count, diff].compact.min.divmod scalar
|
28
|
+
final_prorate /= scalar
|
26
29
|
([1] * full_units).tap do |list|
|
27
30
|
list.push final_prorate unless final_prorate.zero?
|
28
31
|
end
|
@@ -16,47 +16,46 @@ class DateDiffTest < Minitest::Test
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def test_years_between_a_few_days
|
19
|
-
assert_equal (1
|
20
|
-
assert_equal (31
|
21
|
-
assert_equal (32
|
22
|
-
assert_equal (2/366.
|
19
|
+
assert_equal (1 / 366.to_d), date_diff(:year, jan_1_2000, jan_1_2000)
|
20
|
+
assert_equal (31 / 366.to_d), date_diff(:year, jan_1_2000, jan_31_2000)
|
21
|
+
assert_equal (32 / 366.to_d), date_diff(:year, jan_1_2000, feb_1_2000)
|
22
|
+
assert_equal (2/366.to_d + 2/365.to_d), date_diff(:year, dec_30_2000, jan_2_2001)
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_quarters_between_a_few_days
|
26
|
-
q1_2000 = (31 + 29 + 31).
|
27
|
-
q4_2000 = (31 + 30 + 31).
|
28
|
-
q1_2001 = (31 + 28 + 31).
|
29
|
-
assert_equal (1
|
30
|
-
assert_equal (31
|
31
|
-
assert_equal (32
|
26
|
+
q1_2000 = (31 + 29 + 31).to_d
|
27
|
+
q4_2000 = (31 + 30 + 31).to_d
|
28
|
+
q1_2001 = (31 + 28 + 31).to_d
|
29
|
+
assert_equal (1 / q1_2000), date_diff(:quarter, jan_1_2000, jan_1_2000)
|
30
|
+
assert_equal (31 / q1_2000), date_diff(:quarter, jan_1_2000, jan_31_2000)
|
31
|
+
assert_equal (32 / q1_2000), date_diff(:quarter, jan_1_2000, feb_1_2000)
|
32
32
|
assert_equal (2/q4_2000 + 2/q1_2001), date_diff(:quarter, dec_30_2000, jan_2_2001)
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_months_between_a_few_days
|
36
|
-
assert_equal (1
|
37
|
-
assert_equal (31
|
38
|
-
assert_equal (1
|
39
|
-
assert_equal (2
|
36
|
+
assert_equal (1 / 31.to_d), date_diff(:month, jan_1_2000, jan_1_2000)
|
37
|
+
assert_equal (31 / 31.to_d), date_diff(:month, jan_1_2000, jan_31_2000)
|
38
|
+
assert_equal (1 + 1/29.to_d), date_diff(:month, jan_1_2000, feb_1_2000)
|
39
|
+
assert_equal (2/31.to_d + 2/31.to_d), date_diff(:month, dec_30_2000, jan_2_2001)
|
40
40
|
end
|
41
41
|
|
42
42
|
def test_weeks_between_a_few_days
|
43
|
-
assert_equal (1
|
44
|
-
assert_equal (31
|
45
|
-
assert_equal (32
|
46
|
-
assert_equal (2/7.0 + 2/7.0), date_diff(:week, dec_30_2000, jan_2_2001)
|
43
|
+
assert_equal (1 / 7.to_d), date_diff(:week, jan_1_2000, jan_1_2000)
|
44
|
+
assert_equal (31 / 7.to_d), date_diff(:week, jan_1_2000, jan_31_2000)
|
45
|
+
assert_equal (Rational(32, 7).to_d(19)), date_diff(:week, jan_1_2000, feb_1_2000)
|
47
46
|
end
|
48
47
|
|
49
48
|
def test_days_between_a_few_days
|
50
|
-
assert_equal 1
|
51
|
-
assert_equal 31
|
52
|
-
assert_equal 32
|
53
|
-
assert_equal 4
|
49
|
+
assert_equal 1, date_diff(:day, jan_1_2000, jan_1_2000)
|
50
|
+
assert_equal 31, date_diff(:day, jan_1_2000, jan_31_2000)
|
51
|
+
assert_equal 32, date_diff(:day, jan_1_2000, feb_1_2000)
|
52
|
+
assert_equal 4, date_diff(:day, dec_30_2000, jan_2_2001)
|
54
53
|
end
|
55
54
|
|
56
55
|
def test_six_months
|
57
|
-
assert_equal ((1 + 29 + 31 + 30 + 31 + 2) / 366.
|
58
|
-
assert_equal (1
|
59
|
-
assert_equal ((1 + 29 + 31 + 30 + 31 + 2) / 7.
|
56
|
+
assert_equal ((1 + 29 + 31 + 30 + 31 + 2) / 366.to_d), date_diff(:year, jan_31_2000, jun_2_2000)
|
57
|
+
assert_equal (1/31.to_d + 4 + 2/30.to_d), date_diff(:month, jan_31_2000, jun_2_2000)
|
58
|
+
assert_equal ((1 + 29 + 31 + 30 + 31 + 2) / 7.to_d), date_diff(:week, jan_31_2000, jun_2_2000)
|
60
59
|
assert_equal (1 + 29 + 31 + 30 + 31 + 2), date_diff(:day, jan_31_2000, jun_2_2000)
|
61
60
|
end
|
62
61
|
|
@@ -74,8 +73,8 @@ class DateDiffTest < Minitest::Test
|
|
74
73
|
end
|
75
74
|
|
76
75
|
def test_a_year_and_four_days_across_a_leap_year
|
77
|
-
assert_equal (2/366.
|
78
|
-
assert_equal (2/31.
|
76
|
+
assert_equal (2/366.to_d + 1 + 2/365.to_d), date_diff(:year, dec_30_2000, Date.new(2002, 1, 2))
|
77
|
+
assert_equal (2/31.to_d + 12 + 2/31.to_d), date_diff(:month, dec_30_2000, Date.new(2002, 1, 2))
|
79
78
|
end
|
80
79
|
|
81
80
|
def test_advancing_days
|
@@ -147,6 +147,32 @@ class ProjectorTransactionTest < Minitest::Test
|
|
147
147
|
assert_equal 0, @projector.net_worth
|
148
148
|
end
|
149
149
|
|
150
|
+
def test_annual_transactions_by_12_months
|
151
|
+
@projector.add_transaction(
|
152
|
+
date: apr_1_2012,
|
153
|
+
credit: { amount: 50000, account_id: :nustartup_inc },
|
154
|
+
debit: { amount: 50000, account_id: :checking },
|
155
|
+
schedule: { scalar: 12, unit: :month },
|
156
|
+
)
|
157
|
+
|
158
|
+
@projector.project to: mar_31_2042
|
159
|
+
|
160
|
+
assert_equal 1500000, @projector.net_worth
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_annual_transactions
|
164
|
+
@projector.add_transaction(
|
165
|
+
date: apr_1_2012,
|
166
|
+
credit: { amount: 50000, account_id: :nustartup_inc },
|
167
|
+
debit: { amount: 50000, account_id: :checking },
|
168
|
+
schedule: { scalar: 12, unit: :month },
|
169
|
+
)
|
170
|
+
|
171
|
+
@projector.project to: mar_31_2042
|
172
|
+
|
173
|
+
assert_equal 1500000, @projector.net_worth
|
174
|
+
end
|
175
|
+
|
150
176
|
private
|
151
177
|
|
152
178
|
def add_scheduled_transaction date = jan_1_2000
|
@@ -43,6 +43,28 @@ class ScheduledTransactionTest < Minitest::Test
|
|
43
43
|
assert_equal expected_prorates, actual_prorates
|
44
44
|
end
|
45
45
|
|
46
|
+
def test_slice_handles_scalar_greater_than_1
|
47
|
+
@schedule = Schedule.new scalar: 2, unit: :month
|
48
|
+
|
49
|
+
expected_dates = [jan_1_2000, mar_1_2000]
|
50
|
+
actual_dates, _ = @schedule.slice(jan_1_2000..mar_31_2000)
|
51
|
+
actual_dates.map! &:first
|
52
|
+
|
53
|
+
assert_equal expected_dates, actual_dates
|
54
|
+
|
55
|
+
expected_prorates = [1.0, 0.5]
|
56
|
+
actual_prorates, _ = @schedule.slice(jan_1_2000..mar_31_2000)
|
57
|
+
actual_prorates.map! &:last
|
58
|
+
|
59
|
+
assert_equal expected_prorates, actual_prorates
|
60
|
+
|
61
|
+
expected_prorates = [1.0, 0.75]
|
62
|
+
actual_prorates, _ = @schedule.slice(jan_1_2000..apr_15_2000)
|
63
|
+
actual_prorates.map! &:last
|
64
|
+
|
65
|
+
assert_equal expected_prorates, actual_prorates
|
66
|
+
end
|
67
|
+
|
46
68
|
def test_handles_start_after_projection
|
47
69
|
@schedule = Schedule.new every_month(from: apr_1_2000, until: jun_15_2000)
|
48
70
|
|
data/test/test_helper.rb
CHANGED