financial 0.0.1
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/.gitignore +4 -0
- data/.infinity_test +16 -0
- data/.rspec +3 -0
- data/.rvmrc +1 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +74 -0
- data/README.markdown +157 -0
- data/Rakefile +1 -0
- data/duck_tales.gif +0 -0
- data/example.png +0 -0
- data/examples/two_accounts.rb +32 -0
- data/features/portuguese_dsl.feature +93 -0
- data/features/print_financial_table.feature +318 -0
- data/features/support/env.rb +1 -0
- data/financial.gemspec +22 -0
- data/lib/financial.rb +39 -0
- data/lib/financial/account.rb +129 -0
- data/lib/financial/account_manager.rb +26 -0
- data/lib/financial/balance.rb +11 -0
- data/lib/financial/balance_calculation.rb +35 -0
- data/lib/financial/cost.rb +34 -0
- data/lib/financial/costs.rb +30 -0
- data/lib/financial/deposit.rb +30 -0
- data/lib/financial/deposits.rb +15 -0
- data/lib/financial/dsl.rb +16 -0
- data/lib/financial/financial_date.rb +18 -0
- data/lib/financial/financial_table.rb +109 -0
- data/lib/financial/locale.rb +153 -0
- data/lib/financial/locales/en.yml +34 -0
- data/lib/financial/locales/pt.yml +67 -0
- data/lib/financial/parcels.rb +87 -0
- data/lib/financial/per_cent.rb +12 -0
- data/lib/financial/print_table.rb +34 -0
- data/lib/financial/revenue.rb +40 -0
- data/lib/financial/revenues.rb +16 -0
- data/lib/financial/rspec_matchers.rb +32 -0
- data/lib/financial/tax.rb +4 -0
- data/lib/financial/version.rb +3 -0
- data/spec/financial/account_manager_spec.rb +38 -0
- data/spec/financial/account_spec.rb +399 -0
- data/spec/financial/balance_spec.rb +44 -0
- data/spec/financial/cost_spec.rb +78 -0
- data/spec/financial/costs_spec.rb +18 -0
- data/spec/financial/deposit_spec.rb +78 -0
- data/spec/financial/deposits_spec.rb +23 -0
- data/spec/financial/english_spec.rb +76 -0
- data/spec/financial/financial_date_spec.rb +50 -0
- data/spec/financial/financial_spec.rb +14 -0
- data/spec/financial/financial_table_spec.rb +31 -0
- data/spec/financial/locale_spec.rb +37 -0
- data/spec/financial/parcels_spec.rb +179 -0
- data/spec/financial/per_cent_spec.rb +24 -0
- data/spec/financial/portuguese_spec.rb +117 -0
- data/spec/financial/print_table_spec.rb +76 -0
- data/spec/financial/revenue_spec.rb +89 -0
- data/spec/financial/revenues_spec.rb +18 -0
- data/spec/financial/tax_spec.rb +42 -0
- data/spec/spec_helper.rb +25 -0
- metadata +139 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
module Financial
|
2
|
+
module RSpecMatchers
|
3
|
+
def self.included(base)
|
4
|
+
create_include_balance_matcher
|
5
|
+
end
|
6
|
+
|
7
|
+
def create_include_balance_matcher
|
8
|
+
RSpec::Matchers.define :include_balance do |expected|
|
9
|
+
chain :in_date do |date|
|
10
|
+
@date = Financial::FinancialDate.new(date).date
|
11
|
+
end
|
12
|
+
|
13
|
+
failure_message_for_should do |actual|
|
14
|
+
if @date
|
15
|
+
"expected #{actual} to have balance #{expected} in date #{@date}"
|
16
|
+
else
|
17
|
+
"expected #{actual} to have balance #{expected}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
match do |actual|
|
22
|
+
actual.should_not be_empty
|
23
|
+
if @date
|
24
|
+
actual.any? { |balance| balance.date == @date and balance.value == expected }
|
25
|
+
else
|
26
|
+
actual.any? { |balance| balance.value == expected }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Financial
|
4
|
+
describe AccountManager do
|
5
|
+
let(:account_manager) { AccountManager.instance }
|
6
|
+
|
7
|
+
describe '.instance' do
|
8
|
+
it 'should have the singleton pattern' do
|
9
|
+
account_manager.should be_equal AccountManager.instance
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#accounts' do
|
14
|
+
it 'should initialize with an Array' do
|
15
|
+
account_manager.accounts.should be_instance_of(Array)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#find_account' do
|
20
|
+
before do
|
21
|
+
@lucy_bank = account_manager.new_account(:lucy_bank)
|
22
|
+
@leo_bank = account_manager.new_account(:leo_bank)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should find the account specified' do
|
26
|
+
account_manager.find_account(:lucy_bank).should == [@lucy_bank]
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should find all the accounts when pass :all option' do
|
30
|
+
account_manager.find_account(:all).should equal account_manager.accounts
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should find all the accounts when pass :all option' do
|
34
|
+
account_manager.find_account(:todas).should equal account_manager.accounts
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,399 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Financial
|
4
|
+
describe Account do
|
5
|
+
let(:reserved_bank) { Financial.account_manager.new_account(:reserved_bank) }
|
6
|
+
let(:bank_account) { Account.new([:bank_account, {:as=>"Bank Account"}]) }
|
7
|
+
let(:super_bank_account) { Account.new(:super_bank_account) }
|
8
|
+
|
9
|
+
describe '#name' do
|
10
|
+
it 'should return the name of the account' do
|
11
|
+
reserved_bank.name.should equal :reserved_bank
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should assign the name when pass many args' do
|
15
|
+
bank_account.name.should equal :bank_account
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#banner' do
|
20
|
+
it 'should assign the name with spaces and capitalize if dont pass a name' do
|
21
|
+
reserved_bank.banner.should == "Reserved bank"
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should assign the banner as a option' do
|
25
|
+
bank_account.banner.should == 'Bank Account'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#total' do
|
30
|
+
it 'should return zero if dont pass any value' do
|
31
|
+
bank_account.total.should be 0
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should return the value passed in argument' do
|
35
|
+
bank_account.total(400)
|
36
|
+
bank_account.total.should be 400
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#total_costs' do
|
41
|
+
it 'should calculate total costs' do
|
42
|
+
bank_account.costs do
|
43
|
+
credit_card 100
|
44
|
+
other_costs 1040
|
45
|
+
end
|
46
|
+
bank_account.total_costs.should be 1140
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should calculate total costs counting parcels' do
|
50
|
+
bank_account.costs do
|
51
|
+
credit_card 1000
|
52
|
+
parcels(10).of(300)
|
53
|
+
end
|
54
|
+
bank_account.total_costs.should be 4000
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should calculate floats too' do
|
58
|
+
bank_account.costs do
|
59
|
+
credit 500.55
|
60
|
+
other 100.10
|
61
|
+
end
|
62
|
+
bank_account.total_costs.should == 600.65
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should assign to instance variable' do
|
66
|
+
bank_account.costs { some_costs 300 }
|
67
|
+
bank_account.total_costs
|
68
|
+
bank_account.instance_variable_get(:@total_costs).should be 300
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should return zero when dont have costs' do
|
72
|
+
bank_account.total_costs.should be 0
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should assign a instance variable zero if dont have revenues' do
|
76
|
+
bank_account.total_costs
|
77
|
+
bank_account.instance_variable_get(:@total_costs).should be 0
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should count the deposits with costs' do
|
81
|
+
bank_account.costs { credit 1000 }
|
82
|
+
bank_account.deposits { deposit(2000) }
|
83
|
+
bank_account.total_costs.should be 3000
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should count the deposits' do
|
87
|
+
bank_account.deposits { deposit(100) }
|
88
|
+
bank_account.total_costs.should be 100
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#deposits' do
|
93
|
+
it 'should have some deposits' do
|
94
|
+
bank_account.deposits do
|
95
|
+
deposit(100)
|
96
|
+
end
|
97
|
+
bank_account.deposits.should have(1).item
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#taxes' do
|
102
|
+
it 'should have some taxes' do
|
103
|
+
bank_account.revenues do
|
104
|
+
billing(100).tax(1)
|
105
|
+
end
|
106
|
+
bank_account.taxes.should == [Tax.new(:billing, 100)]
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should ignore the revenues without taxes' do
|
110
|
+
bank_account.revenues { billing 100 }
|
111
|
+
bank_account.taxes.should == []
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#total_revenues' do
|
116
|
+
it 'should return the revenue value if have one revenue only' do
|
117
|
+
bank_account.revenues { billing_value 500 }
|
118
|
+
bank_account.total_revenues.should be 500
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should return calculate the revenue value' do
|
122
|
+
bank_account.revenues do
|
123
|
+
billing_value 499
|
124
|
+
other_value 1000
|
125
|
+
end
|
126
|
+
bank_account.total_revenues.should be 1499
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should return zero when dont have revenues' do
|
130
|
+
bank_account.total_revenues.should be 0
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should assign a instance variable' do
|
134
|
+
bank_account.revenues { a_revenue 100 }
|
135
|
+
bank_account.total_revenues
|
136
|
+
bank_account.instance_variable_get(:@total_revenues).should be 100
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should assign a instance variable zero if dont have revenues' do
|
140
|
+
bank_account.total_revenues
|
141
|
+
bank_account.instance_variable_get(:@total_revenues).should be 0
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#costs' do
|
146
|
+
it 'should return an empty costs when does not have any costs' do
|
147
|
+
reserved_bank.costs.should be_empty
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should return an Costs' do
|
151
|
+
reserved_bank.costs.should be_instance_of(Costs)
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'with parcels' do
|
155
|
+
before { reserved_bank.costs { parcels(2).of(400) } }
|
156
|
+
|
157
|
+
it 'should split all the parcels in cost' do
|
158
|
+
reserved_bank.costs.all? { |cost| cost.class == Cost }.should be_true
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should keep the value of the parcel and setting in the cost' do
|
162
|
+
reserved_bank.costs.all? { |cost| cost.value.equal?(400) }.should be_true
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should keep the dates of the parcel and setting in the cost' do
|
166
|
+
reserved_bank.costs.all? { |cost| cost.date.is_a?(Date) }.should be_true
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'with a block' do
|
171
|
+
let(:cost) { reserved_bank.costs.first }
|
172
|
+
before do
|
173
|
+
Financial.locale = :en
|
174
|
+
reserved_bank.costs do
|
175
|
+
a_cost(400).in_date('09/20/2011')
|
176
|
+
end
|
177
|
+
cost.should_not be_nil
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'cost should be instance of Cost' do
|
181
|
+
cost.should be_instance_of(Financial::Cost)
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'cost should set the cost_name' do
|
185
|
+
cost.name.should == 'A cost'
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'cost should set the value' do
|
189
|
+
cost.value.should equal 400
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'cost should set the date' do
|
193
|
+
cost.date.should == Date.new(2011, 9, 20)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe '#revenues' do
|
199
|
+
it 'should return an empty revenues when does not have revenues' do
|
200
|
+
reserved_bank.revenues.should be_empty
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'should return an Array' do
|
204
|
+
reserved_bank.revenues.should be_instance_of(Financial::Revenues)
|
205
|
+
end
|
206
|
+
|
207
|
+
context 'with a block should push a revenue that:' do
|
208
|
+
let(:revenue) { reserved_bank.revenues.first }
|
209
|
+
before do
|
210
|
+
reserved_bank.revenues do
|
211
|
+
a_revenue(100).in_date('7/17/2011')
|
212
|
+
end
|
213
|
+
revenue.should_not be_nil
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'contain a instance of Financial::Revenue' do
|
217
|
+
revenue.should be_instance_of(Financial::Revenue)
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'contain the name of the revenue' do
|
221
|
+
revenue.name.should == 'A revenue'
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'contain the value of the revenue' do
|
225
|
+
revenue.value.should equal 100
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'contain the date of the revenue' do
|
229
|
+
revenue.date.should == Date.civil(2011, 7, 17)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
describe '#balances' do
|
235
|
+
before do
|
236
|
+
reserved_bank.total 300
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'should include a balance that subtract costs' do
|
240
|
+
reserved_bank.costs { credit(100).in_date('1/1/2011')}
|
241
|
+
reserved_bank.calculate_balances.should include_balance(200).in_date('1/1/2011')
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'should include a balance that subtract deposits' do
|
245
|
+
reserved_bank.deposits { deposit(900).in_date('1/2/2011')}
|
246
|
+
reserved_bank.calculate_balances.should include_balance(-600).in_date('1/2/2011')
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'should include a balance that subtract the tax' do
|
250
|
+
reserved_bank.revenues { bill(100).in_date('1/2/2011').tax(0.1).in_date('1/3/2011') }
|
251
|
+
reserved_bank.calculate_balances.should include_balance(390).in_date('1/3/2011')
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'should include a balance that add a revenue' do
|
255
|
+
reserved_bank.revenues { bill(1000).in_date('4/4/2011') }
|
256
|
+
reserved_bank.calculate_balances.should include_balance(1300).in_date('4/4/2011')
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'should include a balance that add a revenue and subtract a cost in the same date' do
|
260
|
+
reserved_bank.revenues { bill(900).in_date('3/3/2011')}
|
261
|
+
reserved_bank.costs { credit(600).in_date('3/3/2011')}
|
262
|
+
reserved_bank.calculate_balances.should include_balance(600).in_date('3/3/2011')
|
263
|
+
reserved_bank.balances.should include_balance(600).in_date('3/3/2011')
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'should include a balance that subtract costs, deposits and taxes in the same date' do
|
267
|
+
reserved_bank.revenues { bill(1000).in_date('5/5/2011').tax(0.1).in_date('5/5/2011')}
|
268
|
+
reserved_bank.costs { credit(400).in_date('5/5/2011') }
|
269
|
+
reserved_bank.deposits { deposit(600).in_date('5/5/2011') }
|
270
|
+
reserved_bank.calculate_balances.should have(1).item
|
271
|
+
reserved_bank.calculate_balances.should include_balance(200.0).in_date('5/5/2011')
|
272
|
+
end
|
273
|
+
|
274
|
+
it 'should include a balance for the reserved_bank that receives a deposit' do
|
275
|
+
bank_account.total 110.0
|
276
|
+
reserved_bank.deposits { deposit(150).in_account(:bank_account).in_date('9/20/2011') }
|
277
|
+
bank_account.balances.should include_balance(260.0).in_date('9/20/2011')
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'should include a balance of all receiveds deposits in the same date' do
|
281
|
+
super_bank_account.total 4000
|
282
|
+
account :other_super_account do
|
283
|
+
deposits do
|
284
|
+
deposit(100).in_account(:super_bank_account).in_date('9/20/2011')
|
285
|
+
end
|
286
|
+
end
|
287
|
+
account :hiper do
|
288
|
+
deposits do
|
289
|
+
deposit(1000).in_account(:super_bank_account).in_date('9/20/2011')
|
290
|
+
end
|
291
|
+
end
|
292
|
+
super_bank_account.balances.should include_balance(5100).in_date('9/20/2011')
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
describe '#costs_in_date' do
|
297
|
+
let(:date) { Date.civil(2011, 7, 1) }
|
298
|
+
|
299
|
+
it 'should return all costs in date' do
|
300
|
+
bank_account.costs do
|
301
|
+
credit_card(400).in_date '7/1/2011'
|
302
|
+
other(300).in_date '3/4/2011'
|
303
|
+
end
|
304
|
+
bank_account.costs_in_date(date).should == [bank_account.costs.first]
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'should return an empty array when dont have costs' do
|
308
|
+
bank_account.costs_in_date(date).should == []
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
describe '#revenues_in_date' do
|
313
|
+
let(:date) { Date.civil(2011, 7, 1) }
|
314
|
+
|
315
|
+
it 'should return all costs in date' do
|
316
|
+
bank_account.revenues do
|
317
|
+
bill(400).in_date '7/1/2011'
|
318
|
+
salary(300).in_date '3/4/2011'
|
319
|
+
end
|
320
|
+
bank_account.revenues_in_date(date).should == [bank_account.revenues.first]
|
321
|
+
end
|
322
|
+
|
323
|
+
it 'should return the receiveds deposits for bank_account' do
|
324
|
+
bank_account.deposits { deposit(100).in_account(:super_bank_account).in_date('7/1/2011') }
|
325
|
+
super_account = Financial.account_manager.new_account(:super_bank_account)
|
326
|
+
Financial.account_manager.should_receive(:accounts).and_return([super_account, bank_account])
|
327
|
+
super_account.revenues_in_date(date).should == [bank_account.deposits.first]
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'should return an empty array when dont have costs' do
|
331
|
+
bank_account.revenues_in_date(date).should == []
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
describe '#events_in_date' do
|
336
|
+
let(:date) { Date.civil(2011, 7, 1) }
|
337
|
+
|
338
|
+
it 'should return all costs in date' do
|
339
|
+
bank_account.costs do
|
340
|
+
credit_card(400).in_date '7/1/2011'
|
341
|
+
end
|
342
|
+
bank_account.events_in_date(date).should == [bank_account.costs.first]
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'should return all revenues in date' do
|
346
|
+
bank_account.revenues do
|
347
|
+
service(500).in_date '7/1/2011'
|
348
|
+
end
|
349
|
+
bank_account.events_in_date(date).should == [bank_account.revenues.first]
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'should return all deposits in date' do
|
353
|
+
bank_account.deposits do
|
354
|
+
deposit(500).in_date('7/1/2011')
|
355
|
+
deposit(1000).in_date('7/1/2011')
|
356
|
+
end
|
357
|
+
bank_account.events_in_date(date).should == bank_account.deposits
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
describe '#last_balance_in_date' do
|
362
|
+
let(:date) { Date.civil(2011, 6, 14)}
|
363
|
+
|
364
|
+
it 'should return the toal when not have balances' do
|
365
|
+
bank_account.last_balance_in_date(date).should be(0)
|
366
|
+
end
|
367
|
+
|
368
|
+
it 'should return the last balance for the exactly date' do
|
369
|
+
bank_account.costs { a_cost(400).in_date '6/14/2011' }
|
370
|
+
bank_account.last_balance_in_date(date).should be -400
|
371
|
+
end
|
372
|
+
|
373
|
+
it 'should return the last balance that is less than date' do
|
374
|
+
bank_account.costs { other_cost(980).in_date '6/01/2011'}
|
375
|
+
bank_account.last_balance_in_date(date).should be -980
|
376
|
+
end
|
377
|
+
|
378
|
+
it 'should not return a old balance that is not the last balance for date' do
|
379
|
+
bank_account.costs do
|
380
|
+
a_cost(700).in_date '6/01/2011'
|
381
|
+
credit(300).in_date '6/12/2011'
|
382
|
+
end
|
383
|
+
bank_account.last_balance_in_date(date).should be -1000
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
describe '.find' do
|
388
|
+
it 'should find the reserved_bank account' do
|
389
|
+
bank_account
|
390
|
+
Account.find(:name => :reserved_bank).should == reserved_bank
|
391
|
+
end
|
392
|
+
|
393
|
+
it 'should find the reserved_bank account pass a stirng value' do
|
394
|
+
bank_account
|
395
|
+
Account.find(:name => 'reserved_bank').should == reserved_bank
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|