double_entry 0.1.0 → 0.2.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.
- data/README.md +16 -14
- data/lib/double_entry.rb +9 -62
- data/lib/double_entry/account.rb +5 -1
- data/lib/double_entry/configuration.rb +21 -0
- data/lib/double_entry/reporting.rb +51 -0
- data/lib/double_entry/{aggregate.rb → reporting/aggregate.rb} +9 -7
- data/lib/double_entry/{aggregate_array.rb → reporting/aggregate_array.rb} +3 -1
- data/lib/double_entry/{day_range.rb → reporting/day_range.rb} +2 -0
- data/lib/double_entry/{hour_range.rb → reporting/hour_range.rb} +2 -0
- data/lib/double_entry/{line_aggregate.rb → reporting/line_aggregate.rb} +4 -2
- data/lib/double_entry/{month_range.rb → reporting/month_range.rb} +4 -2
- data/lib/double_entry/{time_range.rb → reporting/time_range.rb} +7 -5
- data/lib/double_entry/{time_range_array.rb → reporting/time_range_array.rb} +2 -0
- data/lib/double_entry/{week_range.rb → reporting/week_range.rb} +3 -1
- data/lib/double_entry/{year_range.rb → reporting/year_range.rb} +4 -3
- data/lib/double_entry/transfer.rb +4 -0
- data/lib/double_entry/validation.rb +1 -0
- data/lib/double_entry/{line_check.rb → validation/line_check.rb} +2 -0
- data/lib/double_entry/version.rb +1 -1
- data/script/jack_hammer +21 -16
- data/spec/double_entry/account_spec.rb +9 -0
- data/spec/double_entry/configuration_spec.rb +23 -0
- data/spec/double_entry/locking_spec.rb +24 -13
- data/spec/double_entry/{aggregate_array_spec.rb → reporting/aggregate_array_spec.rb} +2 -2
- data/spec/double_entry/reporting/aggregate_spec.rb +171 -0
- data/spec/double_entry/reporting/line_aggregate_spec.rb +10 -0
- data/spec/double_entry/{month_range_spec.rb → reporting/month_range_spec.rb} +23 -21
- data/spec/double_entry/{time_range_array_spec.rb → reporting/time_range_array_spec.rb} +41 -39
- data/spec/double_entry/{time_range_spec.rb → reporting/time_range_spec.rb} +10 -9
- data/spec/double_entry/{week_range_spec.rb → reporting/week_range_spec.rb} +26 -25
- data/spec/double_entry/reporting_spec.rb +24 -0
- data/spec/double_entry/transfer_spec.rb +17 -0
- data/spec/double_entry/{line_check_spec.rb → validation/line_check_spec.rb} +17 -16
- data/spec/double_entry_spec.rb +409 -0
- data/spec/support/accounts.rb +16 -17
- metadata +70 -35
- checksums.yaml +0 -15
- data/spec/double_entry/aggregate_spec.rb +0 -168
- data/spec/double_entry/double_entry_spec.rb +0 -391
- data/spec/double_entry/line_aggregate_spec.rb +0 -8
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module DoubleEntry
|
3
|
+
module Reporting
|
3
4
|
# We use a particularly crazy week numbering system: week 1 of any given year
|
4
5
|
# is the first week with any days that fall into that year.
|
5
6
|
#
|
@@ -43,7 +44,7 @@ module DoubleEntry
|
|
43
44
|
end
|
44
45
|
|
45
46
|
def earliest_week
|
46
|
-
from_time(
|
47
|
+
from_time(Reporting.configuration.start_of_business)
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
@@ -96,4 +97,5 @@ module DoubleEntry
|
|
96
97
|
self.class.send(:start_of_year, year) + (week - 1).weeks
|
97
98
|
end
|
98
99
|
end
|
100
|
+
end
|
99
101
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
3
2
|
module DoubleEntry
|
3
|
+
module Reporting
|
4
4
|
class YearRange < TimeRange
|
5
5
|
attr_reader :year
|
6
6
|
|
@@ -13,11 +13,11 @@ module DoubleEntry
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.current
|
16
|
-
|
16
|
+
new(:year => Time.now.year)
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.from_time(time)
|
20
|
-
|
20
|
+
new(:year => time.year)
|
21
21
|
end
|
22
22
|
|
23
23
|
def ==(other)
|
@@ -36,4 +36,5 @@ module DoubleEntry
|
|
36
36
|
year.to_s
|
37
37
|
end
|
38
38
|
end
|
39
|
+
end
|
39
40
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'double_entry/validation/line_check'
|
@@ -2,6 +2,7 @@
|
|
2
2
|
require 'set'
|
3
3
|
|
4
4
|
module DoubleEntry
|
5
|
+
module Validation
|
5
6
|
class LineCheck < ActiveRecord::Base
|
6
7
|
extend EncapsulateAsMoney
|
7
8
|
|
@@ -115,4 +116,5 @@ module DoubleEntry
|
|
115
116
|
account_balance.update_attribute(:balance, balance)
|
116
117
|
end
|
117
118
|
end
|
119
|
+
end
|
118
120
|
end
|
data/lib/double_entry/version.rb
CHANGED
data/script/jack_hammer
CHANGED
@@ -68,24 +68,29 @@ end
|
|
68
68
|
def create_accounts_and_transfers
|
69
69
|
puts "Setting up #{$account_count} accounts..."
|
70
70
|
|
71
|
-
|
72
|
-
scope = lambda {|x| x }
|
73
|
-
DoubleEntry.accounts = DoubleEntry::Account::Set.new
|
74
|
-
$account_count.times do |i|
|
75
|
-
DoubleEntry.accounts << DoubleEntry::Account.new(:identifier => :"account-#{i}", :scope_identifier => scope)
|
76
|
-
end
|
71
|
+
DoubleEntry.configure do |config|
|
77
72
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
73
|
+
# Create the accounts.
|
74
|
+
config.define_accounts do |accounts|
|
75
|
+
scope = ->(x) { x }
|
76
|
+
$account_count.times do |i|
|
77
|
+
accounts.define(:identifier => :"account-#{i}", :scope_identifier => scope)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Create all the possible transfers.
|
82
|
+
config.define_transfers do |transfers|
|
83
|
+
config.accounts.each do |from|
|
84
|
+
config.accounts.each do |to|
|
85
|
+
transfers.define(:from => from.identifier, :to => to.identifier, :code => :test)
|
86
|
+
end
|
87
|
+
end
|
83
88
|
end
|
84
|
-
end
|
85
89
|
|
86
|
-
|
87
|
-
|
88
|
-
|
90
|
+
# Find account instances so we have something to work with.
|
91
|
+
$accounts = config.accounts.map do |account|
|
92
|
+
DoubleEntry.account(account.identifier, :scope => 1)
|
93
|
+
end
|
89
94
|
end
|
90
95
|
end
|
91
96
|
|
@@ -93,7 +98,7 @@ end
|
|
93
98
|
def run_tests
|
94
99
|
puts "Spawning #{$process_count} processes..."
|
95
100
|
|
96
|
-
iterations_per_process = $transfer_count / $process_count / $balance_flush_count
|
101
|
+
iterations_per_process = [ ($transfer_count / $process_count / $balance_flush_count), 1 ].max
|
97
102
|
|
98
103
|
$balance_flush_count.times do
|
99
104
|
puts "Flushing balances"
|
@@ -19,5 +19,14 @@ describe DoubleEntry::Account do
|
|
19
19
|
expect(a1.hash).to eq a2.hash
|
20
20
|
expect(a1.hash).to_not eq b.hash
|
21
21
|
end
|
22
|
+
end
|
22
23
|
|
24
|
+
describe DoubleEntry::Account::Set do
|
25
|
+
describe "#define" do
|
26
|
+
context "given a 'savings' account is defined" do
|
27
|
+
before { subject.define(:identifier => "savings") }
|
28
|
+
its(:first) { should be_a DoubleEntry::Account }
|
29
|
+
its("first.identifier") { should eq "savings" }
|
30
|
+
end
|
31
|
+
end
|
23
32
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
describe DoubleEntry::Configuration do
|
4
|
+
|
5
|
+
its(:accounts) { should be_a DoubleEntry::Account::Set }
|
6
|
+
its(:transfers) { should be_a DoubleEntry::Transfer::Set }
|
7
|
+
|
8
|
+
describe "#define_accounts" do
|
9
|
+
it "yields the accounts set" do
|
10
|
+
expect { |block|
|
11
|
+
subject.define_accounts(&block)
|
12
|
+
}.to yield_with_args(be_a DoubleEntry::Account::Set)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#define_transfers" do
|
17
|
+
it "yields the transfers set" do
|
18
|
+
expect { |block|
|
19
|
+
subject.define_transfers(&block)
|
20
|
+
}.to yield_with_args(be_a DoubleEntry::Transfer::Set)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -3,22 +3,33 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe DoubleEntry::Locking do
|
5
5
|
|
6
|
-
before(:all) { @saved_accounts, @saved_transfers = DoubleEntry.accounts, DoubleEntry.transfers }
|
7
|
-
after(:all) { DoubleEntry.accounts, DoubleEntry.transfers = @saved_accounts, @saved_transfers }
|
8
|
-
|
9
6
|
before do
|
10
|
-
|
7
|
+
@config_accounts = DoubleEntry.configuration.accounts
|
8
|
+
@config_transfers = DoubleEntry.configuration.transfers
|
9
|
+
DoubleEntry.configuration.accounts = DoubleEntry::Account::Set.new
|
10
|
+
DoubleEntry.configuration.transfers = DoubleEntry::Transfer::Set.new
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
accounts << DoubleEntry::Account.new(:identifier => :account_d, :scope_identifier => scope)
|
17
|
-
end
|
13
|
+
after do
|
14
|
+
DoubleEntry.configuration.accounts = @config_accounts
|
15
|
+
DoubleEntry.configuration.transfers = @config_transfers
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
before do
|
19
|
+
scope = ->(x) { x }
|
20
|
+
|
21
|
+
DoubleEntry.configure do |config|
|
22
|
+
config.define_accounts do |accounts|
|
23
|
+
accounts.define(:identifier => :account_a, :scope_identifier => scope)
|
24
|
+
accounts.define(:identifier => :account_b, :scope_identifier => scope)
|
25
|
+
accounts.define(:identifier => :account_c, :scope_identifier => scope)
|
26
|
+
accounts.define(:identifier => :account_d, :scope_identifier => scope)
|
27
|
+
end
|
28
|
+
|
29
|
+
config.define_transfers do |transfers|
|
30
|
+
transfers.define(:from => :account_a, :to => :account_b, :code => :test)
|
31
|
+
transfers.define(:from => :account_c, :to => :account_d, :code => :test)
|
32
|
+
end
|
22
33
|
end
|
23
34
|
|
24
35
|
@account_a = DoubleEntry.account(:account_a, :scope => "1")
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
describe DoubleEntry::AggregateArray do
|
2
|
+
describe DoubleEntry::Reporting::AggregateArray do
|
3
3
|
|
4
4
|
let(:user) { User.make! }
|
5
5
|
let(:start) { nil }
|
@@ -7,7 +7,7 @@ describe DoubleEntry::AggregateArray do
|
|
7
7
|
let(:range_type) { 'year' }
|
8
8
|
|
9
9
|
subject(:aggregate_array) {
|
10
|
-
DoubleEntry.aggregate_array(
|
10
|
+
DoubleEntry::Reporting.aggregate_array(
|
11
11
|
:sum,
|
12
12
|
:savings,
|
13
13
|
:bonus,
|
@@ -0,0 +1,171 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
module DoubleEntry
|
4
|
+
module Reporting
|
5
|
+
describe Aggregate do
|
6
|
+
|
7
|
+
let(:user) { User.make! }
|
8
|
+
|
9
|
+
before do
|
10
|
+
# Thursday
|
11
|
+
Timecop.freeze Time.local(2009, 10, 1) do
|
12
|
+
perform_deposit user, 20_00
|
13
|
+
end
|
14
|
+
|
15
|
+
# Saturday
|
16
|
+
Timecop.freeze Time.local(2009, 10, 3) do
|
17
|
+
perform_deposit user, 40_00
|
18
|
+
end
|
19
|
+
|
20
|
+
Timecop.freeze Time.local(2009, 10, 10) do
|
21
|
+
perform_deposit user, 50_00
|
22
|
+
end
|
23
|
+
Timecop.freeze Time.local(2009, 11, 1, 0, 59, 0) do
|
24
|
+
perform_deposit user, 40_00
|
25
|
+
end
|
26
|
+
Timecop.freeze Time.local(2009, 11, 1, 1, 00, 0) do
|
27
|
+
perform_deposit user, 50_00
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should store the aggregate for quick retrieval' do
|
32
|
+
Reporting.aggregate(:sum, :savings, :bonus,
|
33
|
+
:range => TimeRange.make(:year => 2009, :month => 10))
|
34
|
+
expect(LineAggregate.count).to eq 1
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should only store the aggregate once if it is requested more than once' do
|
38
|
+
Reporting.aggregate(:sum, :savings, :bonus,
|
39
|
+
:range => TimeRange.make(:year => 2009, :month => 9))
|
40
|
+
Reporting.aggregate(:sum, :savings, :bonus,
|
41
|
+
:range => TimeRange.make(:year => 2009, :month => 9))
|
42
|
+
Reporting.aggregate(:sum, :savings, :bonus,
|
43
|
+
:range => TimeRange.make(:year => 2009, :month => 10))
|
44
|
+
expect(LineAggregate.count).to eq 2
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should calculate the complete year correctly' do
|
48
|
+
expect(
|
49
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => TimeRange.make(:year => 2009))
|
50
|
+
).to eq Money.new(200_00)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should calculate seperate months correctly' do
|
54
|
+
expect(
|
55
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => TimeRange.make(:year => 2009, :month => 10))
|
56
|
+
).to eq Money.new(110_00)
|
57
|
+
expect(
|
58
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => TimeRange.make(:year => 2009, :month => 11))
|
59
|
+
).to eq Money.new(90_00)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should calculate seperate weeks correctly' do
|
63
|
+
# Week 40 - Mon Sep 28, 2009 to Sun Oct 4 2009
|
64
|
+
expect(
|
65
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => TimeRange.make(:year => 2009, :week => 40))
|
66
|
+
).to eq Money.new(60_00)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should calculate seperate days correctly' do
|
70
|
+
# 1 Nov 2009
|
71
|
+
expect(
|
72
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => TimeRange.make(:year => 2009, :week => 44, :day => 7))
|
73
|
+
).to eq Money.new(90_00)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should calculate seperate hours correctly' do
|
77
|
+
# 1 Nov 2009
|
78
|
+
expect(
|
79
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => TimeRange.make(:year => 2009, :week => 44, :day => 7, :hour => 0))
|
80
|
+
).to eq Money.new(40_00)
|
81
|
+
expect(
|
82
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => TimeRange.make(:year => 2009, :week => 44, :day => 7, :hour => 1))
|
83
|
+
).to eq Money.new(50_00)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should calculate, but not store aggregates when the time range is still current' do
|
87
|
+
Timecop.freeze Time.local(2009, 11, 21) do
|
88
|
+
expect(
|
89
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => TimeRange.make(:year => 2009, :month => 11))
|
90
|
+
).to eq Money.new(90_00)
|
91
|
+
expect(LineAggregate.count).to eq 0
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should calculate, but not store aggregates when the time range is in the future' do
|
96
|
+
Timecop.freeze Time.local(2009, 11, 21) do
|
97
|
+
expect(
|
98
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => TimeRange.make(:year => 2009, :month => 12))
|
99
|
+
).to eq Money.new(0)
|
100
|
+
expect(LineAggregate.count).to eq 0
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should calculate monthly all_time ranges correctly' do
|
105
|
+
expect(
|
106
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => TimeRange.make(:year => 2009, :month => 12, :range_type => :all_time))
|
107
|
+
).to eq Money.new(200_00)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should calculate weekly all_time ranges correctly' do
|
111
|
+
expect(
|
112
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => TimeRange.make(:year => 2009, :week => 43, :range_type => :all_time))
|
113
|
+
).to eq Money.new(110_00)
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'filters' do
|
117
|
+
|
118
|
+
let(:range) { TimeRange.make(:year => 2011, :month => 10) }
|
119
|
+
|
120
|
+
class ::DoubleEntry::Line
|
121
|
+
scope :test_filter, -> { where(:amount => 10_00) }
|
122
|
+
end
|
123
|
+
|
124
|
+
before do
|
125
|
+
Timecop.freeze Time.local(2011, 10, 10) do
|
126
|
+
perform_deposit user, 10_00
|
127
|
+
end
|
128
|
+
|
129
|
+
Timecop.freeze Time.local(2011, 10, 10) do
|
130
|
+
perform_deposit user, 9_00
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'saves filtered aggregations' do
|
135
|
+
expect {
|
136
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => range, :filter => [:test_filter])
|
137
|
+
}.to change { LineAggregate.count }.by 1
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'saves filtered aggregation only once for a range' do
|
141
|
+
expect {
|
142
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => range, :filter => [:test_filter])
|
143
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => range, :filter => [:test_filter])
|
144
|
+
}.to change { LineAggregate.count }.by 1
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'saves filtered aggregations and non filtered aggregations separately' do
|
148
|
+
expect {
|
149
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => range, :filter => [:test_filter])
|
150
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => range)
|
151
|
+
}.to change { LineAggregate.count }.by 2
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'loads the correct saved aggregation' do
|
155
|
+
|
156
|
+
# cache the results for filtered and unfiltered aggregations
|
157
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => range, :filter => [:test_filter])
|
158
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => range)
|
159
|
+
|
160
|
+
# ensure a second call loads the correct cached value
|
161
|
+
expect(
|
162
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => range, :filter => [:test_filter])
|
163
|
+
).to eq Money.new(10_00)
|
164
|
+
expect(
|
165
|
+
Reporting.aggregate(:sum, :savings, :bonus, :range => range)
|
166
|
+
).to eq Money.new(19_00)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "spec_helper"
|
3
|
-
|
3
|
+
module DoubleEntry::Reporting
|
4
|
+
describe MonthRange do
|
4
5
|
|
5
6
|
describe "::from_time" do
|
6
|
-
subject(:from_time) {
|
7
|
+
subject(:from_time) { MonthRange.from_time(given_time) }
|
7
8
|
|
8
9
|
context "given the Time 31st March 2012" do
|
9
10
|
let(:given_time) { Time.new(2012, 3, 31) }
|
@@ -19,15 +20,15 @@ describe DoubleEntry::MonthRange do
|
|
19
20
|
end
|
20
21
|
|
21
22
|
describe "::reportable_months" do
|
22
|
-
subject(:reportable_months) {
|
23
|
+
subject(:reportable_months) { MonthRange.reportable_months }
|
23
24
|
|
24
25
|
context "The date is 1st March 1970" do
|
25
26
|
before { Timecop.freeze(Time.new(1970, 3, 1)) }
|
26
27
|
|
27
28
|
it { should eq [
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
MonthRange.new(year: 1970, month: 1),
|
30
|
+
MonthRange.new(year: 1970, month: 2),
|
31
|
+
MonthRange.new(year: 1970, month: 3),
|
31
32
|
] }
|
32
33
|
|
33
34
|
context "My business started on 5th Feb 1970" do
|
@@ -38,8 +39,8 @@ describe DoubleEntry::MonthRange do
|
|
38
39
|
end
|
39
40
|
|
40
41
|
it { should eq [
|
41
|
-
|
42
|
-
|
42
|
+
MonthRange.new(year: 1970, month: 2),
|
43
|
+
MonthRange.new(year: 1970, month: 3),
|
43
44
|
] }
|
44
45
|
end
|
45
46
|
end
|
@@ -47,24 +48,24 @@ describe DoubleEntry::MonthRange do
|
|
47
48
|
context "The date is 1st Jan 1970" do
|
48
49
|
before { Timecop.freeze(Time.new(1970, 1, 1)) }
|
49
50
|
|
50
|
-
it { should eq [
|
51
|
+
it { should eq [ MonthRange.new(year: 1970, month: 1) ] }
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
54
55
|
describe "::beginning_of_financial_year" do
|
55
|
-
let(:month_range) {
|
56
|
+
let(:month_range) { MonthRange.new(:year => year, :month => month) }
|
56
57
|
let(:year) { 2014 }
|
57
58
|
|
58
59
|
context "the first month of the financial year is July" do
|
59
60
|
subject(:beginning_of_financial_year) { month_range.beginning_of_financial_year }
|
60
61
|
context "returns the current year if the month is after July" do
|
61
62
|
let(:month) { 10 }
|
62
|
-
it { should eq(
|
63
|
+
it { should eq(MonthRange.new(:year => 2014, :month => 7)) }
|
63
64
|
end
|
64
65
|
|
65
66
|
context "returns the previous year if the month is before July" do
|
66
67
|
let(:month) { 3 }
|
67
|
-
it { should eq(
|
68
|
+
it { should eq(MonthRange.new(:year => 2013, :month => 7)) }
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
@@ -79,12 +80,12 @@ describe DoubleEntry::MonthRange do
|
|
79
80
|
|
80
81
|
context "returns the current year if the month is after January" do
|
81
82
|
let(:month) { 10 }
|
82
|
-
it { should eq(
|
83
|
+
it { should eq(MonthRange.new(:year => 2014, :month => 1)) }
|
83
84
|
end
|
84
85
|
|
85
86
|
context "returns the current year if the month is January" do
|
86
87
|
let(:month) { 1 }
|
87
|
-
it { should eq(
|
88
|
+
it { should eq(MonthRange.new(:year => 2014, :month => 1)) }
|
88
89
|
end
|
89
90
|
end
|
90
91
|
|
@@ -99,33 +100,34 @@ describe DoubleEntry::MonthRange do
|
|
99
100
|
|
100
101
|
context "returns the previous year if the month is before December (in the same year)" do
|
101
102
|
let(:month) { 11 }
|
102
|
-
it { should eq(
|
103
|
+
it { should eq(MonthRange.new(:year => 2013, :month => 12)) }
|
103
104
|
end
|
104
105
|
|
105
106
|
context "returns the previous year if the month is after December (in the next year)" do
|
106
107
|
let(:year) { 2015 }
|
107
108
|
let(:month) { 1 }
|
108
|
-
it { should eq(
|
109
|
+
it { should eq(MonthRange.new(:year => 2014, :month => 12)) }
|
109
110
|
end
|
110
111
|
|
111
112
|
context "returns the current year if the month is December" do
|
112
113
|
let(:month) { 12 }
|
113
|
-
it { should eq(
|
114
|
+
it { should eq(MonthRange.new(:year => 2014, :month => 12)) }
|
114
115
|
end
|
115
116
|
end
|
116
117
|
|
117
118
|
context "Given a start time of 3rd Dec 1982" do
|
118
|
-
subject(:reportable_months) {
|
119
|
+
subject(:reportable_months) { MonthRange.reportable_months(from: Time.new(1982, 12, 3)) }
|
119
120
|
|
120
121
|
context "The date is 2nd Feb 1983" do
|
121
122
|
before { Timecop.freeze(Time.new(1983, 2, 2)) }
|
122
123
|
|
123
124
|
it { should eq [
|
124
|
-
|
125
|
-
|
126
|
-
|
125
|
+
MonthRange.new(year: 1982, month: 12),
|
126
|
+
MonthRange.new(year: 1983, month: 1),
|
127
|
+
MonthRange.new(year: 1983, month: 2),
|
127
128
|
] }
|
128
129
|
end
|
129
130
|
end
|
130
131
|
end
|
132
|
+
end
|
131
133
|
end
|