rodger 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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +38 -0
- data/Rakefile +1 -0
- data/lib/rodger.rb +123 -0
- data/lib/rodger/version.rb +3 -0
- data/rodger.gemspec +27 -0
- data/spec/demo.ledger.txt +579 -0
- data/spec/lib/rodger_spec.rb +333 -0
- data/spec/rodger_spec.rb +333 -0
- data/spec/spec.dat +8 -0
- metadata +118 -0
@@ -0,0 +1,333 @@
|
|
1
|
+
require './lib/rodger.rb'
|
2
|
+
|
3
|
+
describe Rodger do
|
4
|
+
|
5
|
+
[:filename, :report_type, :current, :begin, :end, :period, :period_sort, :cleared, :dc, :uncleared,
|
6
|
+
:real, :actual, :related, :budget, :add_budget, :unbudgeted, :forecast, :limit, :amount, :total].each do |a|
|
7
|
+
it {should respond_to a}
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
describe "accounts" do
|
12
|
+
describe "small file" do
|
13
|
+
before :all do
|
14
|
+
@r = Rodger.new(:file => 'spec/spec.dat', :bin => 'ledger')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return an AccountTree" do
|
18
|
+
@r.accounts.should be_a AccountTree
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should give correct AccountTree" do
|
22
|
+
@r.accounts.should == {
|
23
|
+
"Assets" => {
|
24
|
+
"Checking" => {
|
25
|
+
:name => "Assets:Checking", :balance => {:amount => 110.0, :currency => nil},
|
26
|
+
"Jumping" => {
|
27
|
+
:name => "Assets:Checking:Jumping", :balance => {:amount => 100.0, :currency => nil}
|
28
|
+
}
|
29
|
+
},
|
30
|
+
:name => "Assets", :balance => {:amount => 110.0, :currency => nil},
|
31
|
+
},
|
32
|
+
"Liabilities" => {
|
33
|
+
"Saving" => {
|
34
|
+
:name => "Liabilities:Saving", :balance => {:amount => -110.0, :currency => nil},
|
35
|
+
"Sleeping" => {
|
36
|
+
:name => "Liabilities:Saving:Sleeping", :balance => {:amount => -100.0, :currency => nil}
|
37
|
+
}
|
38
|
+
},
|
39
|
+
:name => "Liabilities", :balance => {:amount => -110.0, :currency => nil}
|
40
|
+
|
41
|
+
}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
describe "big file" do
|
46
|
+
before :all do
|
47
|
+
@r = Rodger.new(:file => 'spec/demo.ledger.txt', :bin => 'ledger')
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should give correct list of accounts" do
|
51
|
+
@r.accounts["Assets"].should == {
|
52
|
+
"AccountsReceivable" => {
|
53
|
+
:name => "Assets:AccountsReceivable", :balance => {:amount => 0, :currency => nil},
|
54
|
+
},
|
55
|
+
"Current" => {
|
56
|
+
"BestBank" => {
|
57
|
+
"Checking" => {
|
58
|
+
:name => "Assets:Current:BestBank:Checking", :balance => { :amount => 2206.56, :currency => "USD"},
|
59
|
+
},
|
60
|
+
:name => "Assets:Current:BestBank", :balance => {:amount => -8382.17,:currency => "USD"},
|
61
|
+
"Savings" => {
|
62
|
+
:name => "Assets:Current:BestBank:Savings", :balance => {:amount => -10588.73, :currency => "USD"}
|
63
|
+
},
|
64
|
+
},
|
65
|
+
:name => "Assets:Current", :balance => { :amount => -9699.84, :currency => "USD"},
|
66
|
+
"Cash" => {
|
67
|
+
:name => "Assets:Current:Cash", :balance => {:amount => -1317.67, :currency => "USD"},
|
68
|
+
}
|
69
|
+
|
70
|
+
},
|
71
|
+
"Investments" => {
|
72
|
+
"UTrade" => {
|
73
|
+
"Account" => {
|
74
|
+
:name => "Assets:Investments:UTrade:Account", :balance => {:amount => 9980.78, :currency => "USD"},
|
75
|
+
"AAPL" => {
|
76
|
+
:name => "Assets:Investments:UTrade:Account:AAPL", :balance => {:amount => 185.40, :currency => "USD" },
|
77
|
+
},"EWJ" => {
|
78
|
+
:name => "Assets:Investments:UTrade:Account:EWJ", :balance => {:amount => 13.34, :currency => "USD"},
|
79
|
+
}
|
80
|
+
},
|
81
|
+
:name => "Assets:Investments:UTrade", :balance => {:amount => 9980.78, :currency => "USD"}
|
82
|
+
|
83
|
+
},
|
84
|
+
:name => "Assets:Investments", :balance => {:amount => 9980.78, :currency => "USD"}
|
85
|
+
|
86
|
+
},
|
87
|
+
:name => "Assets", :balance => { :amount => 280.94,:currency => "USD"}
|
88
|
+
|
89
|
+
}
|
90
|
+
|
91
|
+
# "Equity" => {
|
92
|
+
# :name => "Equity", :balance => {:currency => "USD", :amount => -4407.06},
|
93
|
+
# "Opening-Balances" => {
|
94
|
+
# :name => "Equity:Opening-Balances", :balance => {:currency => "USD", :amount => -4407.06},
|
95
|
+
# }},
|
96
|
+
# "Expenses" => {
|
97
|
+
# :name => "Expenses", :balance => {:currency => "USD", :amount => 10647.66},
|
98
|
+
# "Books" => {
|
99
|
+
# :name => "Expenses:Books", :balance => {:currency => "USD", :amount => 74.43},
|
100
|
+
# },
|
101
|
+
# "Car" => {
|
102
|
+
# :name => "Expenses:Car", :balance => {:currency => "USD", :amount => 40.00},
|
103
|
+
# "Gas" => {
|
104
|
+
# :name => "Expenses:Car:Gas", :balance => {:currency => "USD", :amount => 40.00},
|
105
|
+
# }
|
106
|
+
# },
|
107
|
+
# "Charity" => {
|
108
|
+
# :name => "Expenses:Charity", :balance => {:currency => "USD", :amount => 50.00},
|
109
|
+
# },
|
110
|
+
# "Clothes" => {
|
111
|
+
# :name => "Expenses:Clothes", :balance => {:currency => "USD", :amount => 161.22},
|
112
|
+
# },
|
113
|
+
# "Communications" => {
|
114
|
+
# :name => "Expenses:Communications", :balance => {:currency => "USD", :amount => 126.39},
|
115
|
+
# "Mail" => {
|
116
|
+
# :name => "Expenses:Communications:Mail", :balance => {:currency => "USD", :amount => 4.43},
|
117
|
+
# },
|
118
|
+
# "Phone" => {
|
119
|
+
# :name => "Expenses:Communications:Phone", :balance => {:currency => "USD", :amount => 121.96},
|
120
|
+
# },
|
121
|
+
# },
|
122
|
+
# "Financial" => {
|
123
|
+
# :name => "Expenses:Financial", :balance => {:currency => "USD", :amount => 28.40},
|
124
|
+
# "Commissions" => {
|
125
|
+
# :name => "Expenses:Financial:Commissions", :balance => {:currency => "USD", :amount => 19.90},
|
126
|
+
# },
|
127
|
+
# "Fees" => {
|
128
|
+
# :name => "Expenses:Financial:Fees", :balance => {:currency => "USD", :amount => 8.50},
|
129
|
+
# }
|
130
|
+
# },
|
131
|
+
# "Food" => {
|
132
|
+
# :name => "Expenses:Food", :balance => {:currency => "USD", :amount => 2625.76},
|
133
|
+
# "Alcool" => {
|
134
|
+
# :name => "Expenses:Food:Alcool", :balance => {:currency => "USD", :amount => 600.00},
|
135
|
+
# },
|
136
|
+
# "Grocery" => {
|
137
|
+
# :name => "Expenses:Food:Grocery", :balance => {:currency => "USD", :amount => 54.03},
|
138
|
+
# },
|
139
|
+
# "Restaurant" => {
|
140
|
+
# :name => "Expenses:Food:Restaurant", :balance => {:currency => "USD", :amount => 1971.73},
|
141
|
+
# }
|
142
|
+
# },
|
143
|
+
# "Fun" => {
|
144
|
+
# :name => "Expenses:Fun", :balance => {:currency => "USD", :amount => 24.00},
|
145
|
+
# "Movie" => {
|
146
|
+
# :name => "Expenses:Fun:Movie", :balance => {:currency => "USD", :amount => 24.00},
|
147
|
+
# },
|
148
|
+
# },
|
149
|
+
# "Govt-Services" => {
|
150
|
+
# :name => "Expenses:Govt-Services", :balance => {:currency => "USD", :amount => 110.00},
|
151
|
+
# },
|
152
|
+
# "Home" => {
|
153
|
+
# :name => "Expenses:Home", :balance => {:currency => "USD", :amount => 2459.78},
|
154
|
+
# "Monthly" => {
|
155
|
+
# :name => "Expenses:Home:Monthly", :balance => {:currency => "USD", :amount => 2459.78},
|
156
|
+
# "Condo-Fees" => {
|
157
|
+
# :name => "Expenses:Home:Monthly:Condo-Fees", :balance => {:currency => "USD", :amount => 699.08},
|
158
|
+
# },
|
159
|
+
# "Loan-Interest" => {
|
160
|
+
# :name => "Expenses:Home:Monthly:Loan-Interest", :balance => {:currency => "USD", :amount => 1760.70},
|
161
|
+
# },
|
162
|
+
# }
|
163
|
+
# },
|
164
|
+
# "Insurance" => {
|
165
|
+
# :name => "Expenses:Insurance", :balance => {:currency => "USD", :amount => 4492.44},
|
166
|
+
# "Life" => {
|
167
|
+
# :name => "Expenses:Insurance:Life", :balance => {:currency => "USD", :amount => 4492.44},
|
168
|
+
# }
|
169
|
+
# },
|
170
|
+
# "Medical" => {
|
171
|
+
# :name => "Expenses:Medical", :balance => {:currency => "USD", :amount => 312.00},
|
172
|
+
# },
|
173
|
+
# "Sports" => {
|
174
|
+
# :name => "Expenses:Sports", :balance => {:currency => "USD", :amount => 209.00},
|
175
|
+
# "Gear" => {
|
176
|
+
# :name => "Expenses:Sports:Gear", :balance => {:currency => "USD", :amount => 89.00},
|
177
|
+
# }
|
178
|
+
# },
|
179
|
+
# "Taxes" => {
|
180
|
+
# :name => "Expenses:Taxes", :balance => {:currency => "USD", :amount => -77.76},
|
181
|
+
# "US-Federal" => {
|
182
|
+
# :name => "Expenses:Taxes:US-Federal", :balance => {:currency => "USD", :amount => -77.76},
|
183
|
+
# }
|
184
|
+
# },
|
185
|
+
# "Transportation" => {
|
186
|
+
# :name => "Expenses:Transportation", :balance => {:currency => "USD", :amount => 12.00},
|
187
|
+
# "Taxi" => {
|
188
|
+
# :name => "Expenses:Transportation:Taxi", :balance => {:currency => "USD", :amount => 12.00},}
|
189
|
+
# }
|
190
|
+
# },
|
191
|
+
# "Income" => {
|
192
|
+
# :name => "Income", :balance => {:currency => "USD", :amount => -8198.73},
|
193
|
+
# "Investments" => {
|
194
|
+
# :name => "Income:Investments", :balance => {:currency => "USD", :amount => -198.73},
|
195
|
+
# "Dividends" => {
|
196
|
+
# :name => "Income:Investments:Divdends", :balance => {:currency => "USD", :amount => -0.68},
|
197
|
+
# },
|
198
|
+
# "Interest" => {
|
199
|
+
# :name => "Income:Interest", :balance => {:currency => "USD", :amount => -198.05},
|
200
|
+
# "Checking" => {
|
201
|
+
# :name => "Income:Interest:Checking", :balance => {:currency => "USD", :amount => -0.02},
|
202
|
+
# },
|
203
|
+
# "Savings" => {
|
204
|
+
# :name => "Income:Interest:Savings", :balance => {:currency => "USD", :amount => -198.03},
|
205
|
+
# }
|
206
|
+
# }
|
207
|
+
# },
|
208
|
+
# "Salary" => {
|
209
|
+
# :name => "Income:Salary", :balance => {:currency => "USD", :amount => -8000.00},
|
210
|
+
# "AcmeCo" => {
|
211
|
+
# :name => "Income:Salary:AcmeCo", :balance => {:currency => "USD", :amount => -8000.00},
|
212
|
+
# }
|
213
|
+
# }
|
214
|
+
# },
|
215
|
+
@r.accounts["Liabilities"].should == {
|
216
|
+
:name => "Liabilities", :balance => {:currency => "USD", :amount => 1677.19},
|
217
|
+
"BestBank" => {
|
218
|
+
:name => "Liabilities:BestBank", :balance => {:currency => "USD", :amount => 1026.06},
|
219
|
+
"Mortgage" => {
|
220
|
+
:name => "Liabilities:BestBank:Mortgage", :balance => {:currency => "USD", :amount => 1026.06},
|
221
|
+
"Loan" => {
|
222
|
+
:name => "Liabilities:BestBank:Mortgage:Loan", :balance => {:currency => "USD", :amount => 1026.06},
|
223
|
+
}
|
224
|
+
}
|
225
|
+
},
|
226
|
+
"Condo-Management" => {
|
227
|
+
:name => "Liabilities:Condo-Management", :balance => {:currency => "USD", :amount => 100.92},
|
228
|
+
},
|
229
|
+
"Credit-Card" => {
|
230
|
+
:name => "Liabilities:Credit-Card", :balance => {:currency => "USD", :amount => 550.21},
|
231
|
+
"VISA" => {
|
232
|
+
:name => "Liabilities:Credit-Card:VISA", :balance => {:currency => "USD", :amount => 550.21},
|
233
|
+
}
|
234
|
+
}
|
235
|
+
}
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should give correct names" do
|
239
|
+
@r.accounts["Liabilities"]["Credit-Card"]["VISA"][:name].should == "Liabilities:Credit-Card:VISA"
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should give correct balance" do
|
243
|
+
@r.accounts["Liabilities"]["Credit-Card"]["VISA"][:balance].should == {:amount => 550.21, :currency => "USD"}
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "balance" do
|
247
|
+
it "should give correct balance" do
|
248
|
+
@r.balance("Liabilities:Credit-Card:VISA").should == {:amount => 550.21, :currency => "USD"}
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
describe "private functions" do
|
258
|
+
before :all do
|
259
|
+
@r = Rodger.new
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should recurse accounts properly" do
|
263
|
+
@r.send(:recurse_accounts,["a","b","c","d"]).should == {
|
264
|
+
"a" =>
|
265
|
+
{
|
266
|
+
:name => "a",
|
267
|
+
:balance => {
|
268
|
+
:amount => 0,
|
269
|
+
:currency => nil,
|
270
|
+
},
|
271
|
+
"b" =>
|
272
|
+
{
|
273
|
+
:name => "a:b",
|
274
|
+
:balance => {
|
275
|
+
:amount => 0,
|
276
|
+
:currency => nil
|
277
|
+
},
|
278
|
+
"c" =>
|
279
|
+
{
|
280
|
+
:name => "a:b:c",
|
281
|
+
:balance => {
|
282
|
+
:amount => 0,
|
283
|
+
:currency => nil
|
284
|
+
},
|
285
|
+
"d" => {
|
286
|
+
:name => "a:b:c:d",
|
287
|
+
:balance => {
|
288
|
+
:amount => 0, :currency => nil
|
289
|
+
}
|
290
|
+
}
|
291
|
+
}
|
292
|
+
}
|
293
|
+
}
|
294
|
+
}
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
describe AccountTree do
|
300
|
+
describe "initialize" do
|
301
|
+
before :all do
|
302
|
+
@a = AccountTree.new(:a => {:b => {:c => 2}})
|
303
|
+
end
|
304
|
+
it "should return correct values" do
|
305
|
+
@a[:a].should == {:b => {:c => 2}}
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
describe "deep merge" do
|
310
|
+
let(:x) { AccountTree.new(:a => {:b => 1, :d => 3}) }
|
311
|
+
let(:y) { AccountTree.new(:a => {:c => 1, :d => 4}) }
|
312
|
+
it "should deep merge properly" do
|
313
|
+
x.deep_merge(y).should == {:a => {:b => 1, :c => 1, :d => 4}}
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
|
318
|
+
|
319
|
+
it "should have a name on each node" do
|
320
|
+
@a = AccountTree.new(:a => AccountTree.new({:name => "abc", :b => {:c => AccountTree.new({:a => 2, :name => "def"})}}))
|
321
|
+
@a[:a][:name].should == "abc"
|
322
|
+
@a[:a][:b][:c][:name].should == "def"
|
323
|
+
end
|
324
|
+
|
325
|
+
it "should recognise leaf accounts properly" do
|
326
|
+
AT = AccountTree
|
327
|
+
@a = AccountTree.new(:a => AT.new({:b => AT.new({:c => AT.new({})})}))
|
328
|
+
@a[:a].leaf?.should == false
|
329
|
+
@a[:a][:b].leaf?.should == false
|
330
|
+
@a[:a][:b][:c].leaf?.should == true
|
331
|
+
end
|
332
|
+
|
333
|
+
end
|
data/spec/rodger_spec.rb
ADDED
@@ -0,0 +1,333 @@
|
|
1
|
+
require './lib/rodger.rb'
|
2
|
+
|
3
|
+
describe Rodger do
|
4
|
+
|
5
|
+
[:filename, :report_type, :current, :begin, :end, :period, :period_sort, :cleared, :dc, :uncleared,
|
6
|
+
:real, :actual, :related, :budget, :add_budget, :unbudgeted, :forecast, :limit, :amount, :total].each do |a|
|
7
|
+
it {should respond_to a}
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
describe "accounts" do
|
12
|
+
describe "small file" do
|
13
|
+
before :all do
|
14
|
+
@r = Rodger.new(:file => 'spec/spec.dat', :bin => 'ledger')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return an AccountTree" do
|
18
|
+
@r.accounts.should be_a AccountTree
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should give correct AccountTree" do
|
22
|
+
@r.accounts.should == {
|
23
|
+
"Assets" => {
|
24
|
+
"Checking" => {
|
25
|
+
:name => "Assets:Checking", :balance => {:amount => 110.0, :currency => nil},
|
26
|
+
"Jumping" => {
|
27
|
+
:name => "Assets:Checking:Jumping", :balance => {:amount => 100.0, :currency => nil}
|
28
|
+
}
|
29
|
+
},
|
30
|
+
:name => "Assets", :balance => {:amount => 110.0, :currency => nil},
|
31
|
+
},
|
32
|
+
"Liabilities" => {
|
33
|
+
"Saving" => {
|
34
|
+
:name => "Liabilities:Saving", :balance => {:amount => -110.0, :currency => nil},
|
35
|
+
"Sleeping" => {
|
36
|
+
:name => "Liabilities:Saving:Sleeping", :balance => {:amount => -100.0, :currency => nil}
|
37
|
+
}
|
38
|
+
},
|
39
|
+
:name => "Liabilities", :balance => {:amount => -110.0, :currency => nil}
|
40
|
+
|
41
|
+
}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
describe "big file" do
|
46
|
+
before :all do
|
47
|
+
@r = Rodger.new(:file => 'spec/demo.ledger.txt', :bin => 'ledger')
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should give correct list of accounts" do
|
51
|
+
@r.accounts["Assets"].should == {
|
52
|
+
"AccountsReceivable" => {
|
53
|
+
:name => "Assets:AccountsReceivable", :balance => {:amount => 0, :currency => nil},
|
54
|
+
},
|
55
|
+
"Current" => {
|
56
|
+
"BestBank" => {
|
57
|
+
"Checking" => {
|
58
|
+
:name => "Assets:Current:BestBank:Checking", :balance => { :amount => 2206.56, :currency => "USD"},
|
59
|
+
},
|
60
|
+
:name => "Assets:Current:BestBank", :balance => {:amount => -8382.17,:currency => "USD"},
|
61
|
+
"Savings" => {
|
62
|
+
:name => "Assets:Current:BestBank:Savings", :balance => {:amount => -10588.73, :currency => "USD"}
|
63
|
+
},
|
64
|
+
},
|
65
|
+
:name => "Assets:Current", :balance => { :amount => -9699.84, :currency => "USD"},
|
66
|
+
"Cash" => {
|
67
|
+
:name => "Assets:Current:Cash", :balance => {:amount => -1317.67, :currency => "USD"},
|
68
|
+
}
|
69
|
+
|
70
|
+
},
|
71
|
+
"Investments" => {
|
72
|
+
"UTrade" => {
|
73
|
+
"Account" => {
|
74
|
+
:name => "Assets:Investments:UTrade:Account", :balance => {:amount => 9980.78, :currency => "USD"},
|
75
|
+
"AAPL" => {
|
76
|
+
:name => "Assets:Investments:UTrade:Account:AAPL", :balance => {:amount => 185.40, :currency => "USD" },
|
77
|
+
},"EWJ" => {
|
78
|
+
:name => "Assets:Investments:UTrade:Account:EWJ", :balance => {:amount => 13.34, :currency => "USD"},
|
79
|
+
}
|
80
|
+
},
|
81
|
+
:name => "Assets:Investments:UTrade", :balance => {:amount => 9980.78, :currency => "USD"}
|
82
|
+
|
83
|
+
},
|
84
|
+
:name => "Assets:Investments", :balance => {:amount => 9980.78, :currency => "USD"}
|
85
|
+
|
86
|
+
},
|
87
|
+
:name => "Assets", :balance => { :amount => 280.94,:currency => "USD"}
|
88
|
+
|
89
|
+
}
|
90
|
+
|
91
|
+
# "Equity" => {
|
92
|
+
# :name => "Equity", :balance => {:currency => "USD", :amount => -4407.06},
|
93
|
+
# "Opening-Balances" => {
|
94
|
+
# :name => "Equity:Opening-Balances", :balance => {:currency => "USD", :amount => -4407.06},
|
95
|
+
# }},
|
96
|
+
# "Expenses" => {
|
97
|
+
# :name => "Expenses", :balance => {:currency => "USD", :amount => 10647.66},
|
98
|
+
# "Books" => {
|
99
|
+
# :name => "Expenses:Books", :balance => {:currency => "USD", :amount => 74.43},
|
100
|
+
# },
|
101
|
+
# "Car" => {
|
102
|
+
# :name => "Expenses:Car", :balance => {:currency => "USD", :amount => 40.00},
|
103
|
+
# "Gas" => {
|
104
|
+
# :name => "Expenses:Car:Gas", :balance => {:currency => "USD", :amount => 40.00},
|
105
|
+
# }
|
106
|
+
# },
|
107
|
+
# "Charity" => {
|
108
|
+
# :name => "Expenses:Charity", :balance => {:currency => "USD", :amount => 50.00},
|
109
|
+
# },
|
110
|
+
# "Clothes" => {
|
111
|
+
# :name => "Expenses:Clothes", :balance => {:currency => "USD", :amount => 161.22},
|
112
|
+
# },
|
113
|
+
# "Communications" => {
|
114
|
+
# :name => "Expenses:Communications", :balance => {:currency => "USD", :amount => 126.39},
|
115
|
+
# "Mail" => {
|
116
|
+
# :name => "Expenses:Communications:Mail", :balance => {:currency => "USD", :amount => 4.43},
|
117
|
+
# },
|
118
|
+
# "Phone" => {
|
119
|
+
# :name => "Expenses:Communications:Phone", :balance => {:currency => "USD", :amount => 121.96},
|
120
|
+
# },
|
121
|
+
# },
|
122
|
+
# "Financial" => {
|
123
|
+
# :name => "Expenses:Financial", :balance => {:currency => "USD", :amount => 28.40},
|
124
|
+
# "Commissions" => {
|
125
|
+
# :name => "Expenses:Financial:Commissions", :balance => {:currency => "USD", :amount => 19.90},
|
126
|
+
# },
|
127
|
+
# "Fees" => {
|
128
|
+
# :name => "Expenses:Financial:Fees", :balance => {:currency => "USD", :amount => 8.50},
|
129
|
+
# }
|
130
|
+
# },
|
131
|
+
# "Food" => {
|
132
|
+
# :name => "Expenses:Food", :balance => {:currency => "USD", :amount => 2625.76},
|
133
|
+
# "Alcool" => {
|
134
|
+
# :name => "Expenses:Food:Alcool", :balance => {:currency => "USD", :amount => 600.00},
|
135
|
+
# },
|
136
|
+
# "Grocery" => {
|
137
|
+
# :name => "Expenses:Food:Grocery", :balance => {:currency => "USD", :amount => 54.03},
|
138
|
+
# },
|
139
|
+
# "Restaurant" => {
|
140
|
+
# :name => "Expenses:Food:Restaurant", :balance => {:currency => "USD", :amount => 1971.73},
|
141
|
+
# }
|
142
|
+
# },
|
143
|
+
# "Fun" => {
|
144
|
+
# :name => "Expenses:Fun", :balance => {:currency => "USD", :amount => 24.00},
|
145
|
+
# "Movie" => {
|
146
|
+
# :name => "Expenses:Fun:Movie", :balance => {:currency => "USD", :amount => 24.00},
|
147
|
+
# },
|
148
|
+
# },
|
149
|
+
# "Govt-Services" => {
|
150
|
+
# :name => "Expenses:Govt-Services", :balance => {:currency => "USD", :amount => 110.00},
|
151
|
+
# },
|
152
|
+
# "Home" => {
|
153
|
+
# :name => "Expenses:Home", :balance => {:currency => "USD", :amount => 2459.78},
|
154
|
+
# "Monthly" => {
|
155
|
+
# :name => "Expenses:Home:Monthly", :balance => {:currency => "USD", :amount => 2459.78},
|
156
|
+
# "Condo-Fees" => {
|
157
|
+
# :name => "Expenses:Home:Monthly:Condo-Fees", :balance => {:currency => "USD", :amount => 699.08},
|
158
|
+
# },
|
159
|
+
# "Loan-Interest" => {
|
160
|
+
# :name => "Expenses:Home:Monthly:Loan-Interest", :balance => {:currency => "USD", :amount => 1760.70},
|
161
|
+
# },
|
162
|
+
# }
|
163
|
+
# },
|
164
|
+
# "Insurance" => {
|
165
|
+
# :name => "Expenses:Insurance", :balance => {:currency => "USD", :amount => 4492.44},
|
166
|
+
# "Life" => {
|
167
|
+
# :name => "Expenses:Insurance:Life", :balance => {:currency => "USD", :amount => 4492.44},
|
168
|
+
# }
|
169
|
+
# },
|
170
|
+
# "Medical" => {
|
171
|
+
# :name => "Expenses:Medical", :balance => {:currency => "USD", :amount => 312.00},
|
172
|
+
# },
|
173
|
+
# "Sports" => {
|
174
|
+
# :name => "Expenses:Sports", :balance => {:currency => "USD", :amount => 209.00},
|
175
|
+
# "Gear" => {
|
176
|
+
# :name => "Expenses:Sports:Gear", :balance => {:currency => "USD", :amount => 89.00},
|
177
|
+
# }
|
178
|
+
# },
|
179
|
+
# "Taxes" => {
|
180
|
+
# :name => "Expenses:Taxes", :balance => {:currency => "USD", :amount => -77.76},
|
181
|
+
# "US-Federal" => {
|
182
|
+
# :name => "Expenses:Taxes:US-Federal", :balance => {:currency => "USD", :amount => -77.76},
|
183
|
+
# }
|
184
|
+
# },
|
185
|
+
# "Transportation" => {
|
186
|
+
# :name => "Expenses:Transportation", :balance => {:currency => "USD", :amount => 12.00},
|
187
|
+
# "Taxi" => {
|
188
|
+
# :name => "Expenses:Transportation:Taxi", :balance => {:currency => "USD", :amount => 12.00},}
|
189
|
+
# }
|
190
|
+
# },
|
191
|
+
# "Income" => {
|
192
|
+
# :name => "Income", :balance => {:currency => "USD", :amount => -8198.73},
|
193
|
+
# "Investments" => {
|
194
|
+
# :name => "Income:Investments", :balance => {:currency => "USD", :amount => -198.73},
|
195
|
+
# "Dividends" => {
|
196
|
+
# :name => "Income:Investments:Divdends", :balance => {:currency => "USD", :amount => -0.68},
|
197
|
+
# },
|
198
|
+
# "Interest" => {
|
199
|
+
# :name => "Income:Interest", :balance => {:currency => "USD", :amount => -198.05},
|
200
|
+
# "Checking" => {
|
201
|
+
# :name => "Income:Interest:Checking", :balance => {:currency => "USD", :amount => -0.02},
|
202
|
+
# },
|
203
|
+
# "Savings" => {
|
204
|
+
# :name => "Income:Interest:Savings", :balance => {:currency => "USD", :amount => -198.03},
|
205
|
+
# }
|
206
|
+
# }
|
207
|
+
# },
|
208
|
+
# "Salary" => {
|
209
|
+
# :name => "Income:Salary", :balance => {:currency => "USD", :amount => -8000.00},
|
210
|
+
# "AcmeCo" => {
|
211
|
+
# :name => "Income:Salary:AcmeCo", :balance => {:currency => "USD", :amount => -8000.00},
|
212
|
+
# }
|
213
|
+
# }
|
214
|
+
# },
|
215
|
+
@r.accounts["Liabilities"].should == {
|
216
|
+
:name => "Liabilities", :balance => {:currency => "USD", :amount => 1677.19},
|
217
|
+
"BestBank" => {
|
218
|
+
:name => "Liabilities:BestBank", :balance => {:currency => "USD", :amount => 1026.06},
|
219
|
+
"Mortgage" => {
|
220
|
+
:name => "Liabilities:BestBank:Mortgage", :balance => {:currency => "USD", :amount => 1026.06},
|
221
|
+
"Loan" => {
|
222
|
+
:name => "Liabilities:BestBank:Mortgage:Loan", :balance => {:currency => "USD", :amount => 1026.06},
|
223
|
+
}
|
224
|
+
}
|
225
|
+
},
|
226
|
+
"Condo-Management" => {
|
227
|
+
:name => "Liabilities:Condo-Management", :balance => {:currency => "USD", :amount => 100.92},
|
228
|
+
},
|
229
|
+
"Credit-Card" => {
|
230
|
+
:name => "Liabilities:Credit-Card", :balance => {:currency => "USD", :amount => 550.21},
|
231
|
+
"VISA" => {
|
232
|
+
:name => "Liabilities:Credit-Card:VISA", :balance => {:currency => "USD", :amount => 550.21},
|
233
|
+
}
|
234
|
+
}
|
235
|
+
}
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should give correct names" do
|
239
|
+
@r.accounts["Liabilities"]["Credit-Card"]["VISA"][:name].should == "Liabilities:Credit-Card:VISA"
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should give correct balance" do
|
243
|
+
@r.accounts["Liabilities"]["Credit-Card"]["VISA"][:balance].should == {:amount => 550.21, :currency => "USD"}
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "balance" do
|
247
|
+
it "should give correct balance" do
|
248
|
+
@r.balance("Liabilities:Credit-Card:VISA").should == {:amount => 550.21, :currency => "USD"}
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
describe "private functions" do
|
258
|
+
before :all do
|
259
|
+
@r = Rodger.new
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should recurse accounts properly" do
|
263
|
+
@r.send(:recurse_accounts,["a","b","c","d"]).should == {
|
264
|
+
"a" =>
|
265
|
+
{
|
266
|
+
:name => "a",
|
267
|
+
:balance => {
|
268
|
+
:amount => 0,
|
269
|
+
:currency => nil,
|
270
|
+
},
|
271
|
+
"b" =>
|
272
|
+
{
|
273
|
+
:name => "a:b",
|
274
|
+
:balance => {
|
275
|
+
:amount => 0,
|
276
|
+
:currency => nil
|
277
|
+
},
|
278
|
+
"c" =>
|
279
|
+
{
|
280
|
+
:name => "a:b:c",
|
281
|
+
:balance => {
|
282
|
+
:amount => 0,
|
283
|
+
:currency => nil
|
284
|
+
},
|
285
|
+
"d" => {
|
286
|
+
:name => "a:b:c:d",
|
287
|
+
:balance => {
|
288
|
+
:amount => 0, :currency => nil
|
289
|
+
}
|
290
|
+
}
|
291
|
+
}
|
292
|
+
}
|
293
|
+
}
|
294
|
+
}
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
describe AccountTree do
|
300
|
+
describe "initialize" do
|
301
|
+
before :all do
|
302
|
+
@a = AccountTree.new(:a => {:b => {:c => 2}})
|
303
|
+
end
|
304
|
+
it "should return correct values" do
|
305
|
+
@a[:a].should == {:b => {:c => 2}}
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
describe "deep merge" do
|
310
|
+
let(:x) { AccountTree.new(:a => {:b => 1, :d => 3}) }
|
311
|
+
let(:y) { AccountTree.new(:a => {:c => 1, :d => 4}) }
|
312
|
+
it "should deep merge properly" do
|
313
|
+
x.deep_merge(y).should == {:a => {:b => 1, :c => 1, :d => 4}}
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
|
318
|
+
|
319
|
+
it "should have a name on each node" do
|
320
|
+
@a = AccountTree.new(:a => AccountTree.new({:name => "abc", :b => {:c => AccountTree.new({:a => 2, :name => "def"})}}))
|
321
|
+
@a[:a][:name].should == "abc"
|
322
|
+
@a[:a][:b][:c][:name].should == "def"
|
323
|
+
end
|
324
|
+
|
325
|
+
it "should recognise leaf accounts properly" do
|
326
|
+
AT = AccountTree
|
327
|
+
@a = AccountTree.new(:a => AT.new({:b => AT.new({:c => AT.new({})})}))
|
328
|
+
@a[:a].leaf?.should == false
|
329
|
+
@a[:a][:b].leaf?.should == false
|
330
|
+
@a[:a][:b][:c].leaf?.should == true
|
331
|
+
end
|
332
|
+
|
333
|
+
end
|