mudrat_projector 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 99cf860a7f16e297d956e8b018652994a216552c
4
- data.tar.gz: 51de6ef4a9280d86339c5e045cd3514f6475259c
3
+ metadata.gz: d2181d2b58ff6ff66fc876cb0a69b95c40a73cb8
4
+ data.tar.gz: 506905ae2d682c9c3dd13712ad381fc2ba71b418
5
5
  SHA512:
6
- metadata.gz: 25820eacfe06c533db174462a6cc9ae66a826751ddbeda829250ae2970fb92ed8a15ffdc3366d92b9a76b478a3996206ec074ea7f965609d24b1904435b00834
7
- data.tar.gz: 89671345c7a2ebd2ef4513a20312d676bd1d0a023df1a066def36a6fa3c855eb6ec3400745431f375800ac7cc35240d795b84b0dff917d3f9b4d56c0c20ca0e4
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).to_f + 1
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).to_f
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 net_worth split_account)
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
- DateDiff.advance intervals: factor, unit: unit, from: date
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 1
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
@@ -99,7 +99,7 @@ module MudratProjector
99
99
  private
100
100
 
101
101
  def fmt number
102
- number.respond_to?(:round) ? number.round(2).to_f : number
102
+ number.respond_to?(:round) ? number.round(2).to_d : number
103
103
  end
104
104
  end
105
105
 
@@ -1,3 +1,3 @@
1
1
  module MudratProjector
2
- VERSION = "0.9.3"
2
+ VERSION = "0.9.4"
3
3
  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.0 / 366.0), date_diff(:year, jan_1_2000, jan_1_2000)
20
- assert_equal (31.0 / 366.0), date_diff(:year, jan_1_2000, jan_31_2000)
21
- assert_equal (32.0 / 366.0), date_diff(:year, jan_1_2000, feb_1_2000)
22
- assert_equal (2/366.0 + 2/365.0), date_diff(:year, dec_30_2000, jan_2_2001)
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).to_f
27
- q4_2000 = (31 + 30 + 31).to_f
28
- q1_2001 = (31 + 28 + 31).to_f
29
- assert_equal (1.0 / q1_2000), date_diff(:quarter, jan_1_2000, jan_1_2000)
30
- assert_equal (31.0 / q1_2000), date_diff(:quarter, jan_1_2000, jan_31_2000)
31
- assert_equal (32.0 / q1_2000), date_diff(:quarter, jan_1_2000, feb_1_2000)
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.0 / 31.0), date_diff(:month, jan_1_2000, jan_1_2000)
37
- assert_equal (31.0 / 31.0), date_diff(:month, jan_1_2000, jan_31_2000)
38
- assert_equal (1.0 + 1/29.0), date_diff(:month, jan_1_2000, feb_1_2000)
39
- assert_equal (2.0/31.0 + 2.0/31.0), date_diff(:month, dec_30_2000, jan_2_2001)
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.0 / 7.0), date_diff(:week, jan_1_2000, jan_1_2000)
44
- assert_equal (31.0 / 7.0), date_diff(:week, jan_1_2000, jan_31_2000)
45
- assert_equal (32.0 / 7.0), date_diff(:week, jan_1_2000, feb_1_2000)
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.0, date_diff(:day, jan_1_2000, jan_1_2000)
51
- assert_equal 31.0, date_diff(:day, jan_1_2000, jan_31_2000)
52
- assert_equal 32.0, date_diff(:day, jan_1_2000, feb_1_2000)
53
- assert_equal 4.0, date_diff(:day, dec_30_2000, jan_2_2001)
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.0), date_diff(:year, jan_31_2000, jun_2_2000)
58
- assert_equal (1.0/31.0 + 4.0 + 2.0/30.0), date_diff(:month, jan_31_2000, jun_2_2000)
59
- assert_equal ((1 + 29 + 31 + 30 + 31 + 2) / 7.0), date_diff(:week, jan_31_2000, jun_2_2000)
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.0 + 1.0 + 2/365.0), date_diff(:year, dec_30_2000, Date.new(2002, 1, 2))
78
- assert_equal (2/31.0 + 12.0 + 2/31.0), date_diff(:month, dec_30_2000, Date.new(2002, 1, 2))
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
@@ -31,7 +31,7 @@ end
31
31
  # BigDecimal needs friendlier output
32
32
  class BigDecimal < Numeric
33
33
  def inspect
34
- "#<BigDecmial:#{round(10).to_f.inspect}>"
34
+ "#<BigDecmial:#{round(20).to_f.inspect}>"
35
35
  end
36
36
  end
37
37
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mudrat_projector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - ntl