budget 1.0.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/lib/budget.rb +98 -0
- data/test/test_budget.rb +56 -0
- metadata +48 -0
data/lib/budget.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
class Budget
|
2
|
+
attr_reader :income, :expense, :remaining, :total_income, :total_expenses, :month, :year
|
3
|
+
# Your code goes here...
|
4
|
+
def initialize
|
5
|
+
@income = Array.new
|
6
|
+
@expense = Array.new
|
7
|
+
@remaining = 0
|
8
|
+
@total_income = 0
|
9
|
+
@total_expenses = 0
|
10
|
+
@month = Time.now.month
|
11
|
+
@year = Time.now.year
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_month(liMonth, liYear)
|
15
|
+
raise RangeError, 'Month must be an integer 1 - 12' if ((!liMonth.is_a? Integer) || liMonth < 1 || liMonth > 12)
|
16
|
+
raise RangeError, 'Year must be an integer' if (!liYear.is_a? Integer)
|
17
|
+
@month = liMonth
|
18
|
+
@year = liYear
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_income(pfIncome, psMemo = "Income Item #{self.income.count + 1}", pdDate = Time.now)
|
22
|
+
raise TypeError, 'Amount parameter must be numeric' if !is_numeric?(pfIncome)
|
23
|
+
lhIncome = Hash.new
|
24
|
+
lhIncome["amount"] = pfIncome.round(2)
|
25
|
+
lhIncome["memo"] = psMemo.to_s
|
26
|
+
lhIncome["date"] = pdDate
|
27
|
+
@income << lhIncome
|
28
|
+
set_total_income()
|
29
|
+
set_difference()
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_total_income
|
33
|
+
lfIncome = get_income()
|
34
|
+
@total_income = lfIncome.round(2)
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_expense(pfAmount, psMemo = "Expense Item #{self.expense.count + 1}", pdDate = Time.now)
|
38
|
+
raise TypeError, 'Amount parameter must be numeric' if !is_numeric?(pfAmount)
|
39
|
+
lhExpense = Hash.new
|
40
|
+
lhExpense["amount"] = pfAmount.round(2)
|
41
|
+
lhExpense["memo"] = psMemo.to_s
|
42
|
+
lhExpense["date"] = pdDate
|
43
|
+
@expense << lhExpense
|
44
|
+
set_total_expenses()
|
45
|
+
set_difference()
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_total_expenses
|
49
|
+
lfTotalExpenses = get_expenses()
|
50
|
+
@total_expenses = lfTotalExpenses.round(2)
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_income
|
54
|
+
lfTotalIncome = 0
|
55
|
+
@income.each do |i|
|
56
|
+
lfTotalIncome = lfTotalIncome + i["amount"].round(2)
|
57
|
+
end
|
58
|
+
return lfTotalIncome
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_expenses
|
62
|
+
lfTotalExpenses = 0
|
63
|
+
@expense.each do |i|
|
64
|
+
lfTotalExpenses = lfTotalExpenses + i["amount"].round(2)
|
65
|
+
end
|
66
|
+
return lfTotalExpenses
|
67
|
+
end
|
68
|
+
|
69
|
+
def set_difference
|
70
|
+
lfIncome = get_income()
|
71
|
+
lfExpenses = get_expenses()
|
72
|
+
lfDifference = lfIncome - lfExpenses
|
73
|
+
@remaining = lfDifference
|
74
|
+
end
|
75
|
+
|
76
|
+
def delete_income(piIndex)
|
77
|
+
@income.delete_at(piIndex)
|
78
|
+
set_total_income()
|
79
|
+
set_difference()
|
80
|
+
end
|
81
|
+
|
82
|
+
def delete_expense(piIndex)
|
83
|
+
@expense.delete_at(piIndex)
|
84
|
+
set_total_expenses()
|
85
|
+
set_difference()
|
86
|
+
end
|
87
|
+
|
88
|
+
def complete?
|
89
|
+
if @total_expenses == @total_income
|
90
|
+
return true
|
91
|
+
end
|
92
|
+
return false
|
93
|
+
end
|
94
|
+
|
95
|
+
def is_numeric?(obj)
|
96
|
+
obj.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
|
97
|
+
end
|
98
|
+
end
|
data/test/test_budget.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'budget'
|
3
|
+
|
4
|
+
class BudgetTest < Test::Unit::TestCase
|
5
|
+
def test_budget
|
6
|
+
foo = Budget.new
|
7
|
+
# Test the inital month and year is the current month and year
|
8
|
+
assert_equal Time.now.month, foo.month
|
9
|
+
assert_equal Time.now.year, foo.year
|
10
|
+
# Test we can change month to May 2015
|
11
|
+
foo.set_month(5,2015)
|
12
|
+
assert_equal 5, foo.month
|
13
|
+
assert_equal 2015, foo.year
|
14
|
+
# Test we can add $500 income
|
15
|
+
foo.add_income(500)
|
16
|
+
assert_equal 500, foo.total_income
|
17
|
+
assert_equal 500, foo.remaining
|
18
|
+
assert_equal 0, foo.total_expenses
|
19
|
+
foo.add_income(500)
|
20
|
+
assert_equal 1000, foo.total_income
|
21
|
+
assert_equal 1000, foo.remaining
|
22
|
+
assert_equal 0, foo.total_expenses
|
23
|
+
# Test to make sure memo is set to default with the right number
|
24
|
+
assert_equal 'Income Item 1', foo.income[0]["memo"]
|
25
|
+
assert_equal 'Income Item 2', foo.income[1]["memo"]
|
26
|
+
foo.add_income(500, 'Paycheck 3')
|
27
|
+
assert_equal 'Paycheck 3', foo.income[2]["memo"]
|
28
|
+
# Test to make sure budget is not complete at the moment
|
29
|
+
assert !foo.complete?
|
30
|
+
# Add a few expenses
|
31
|
+
foo.add_expense(200)
|
32
|
+
foo.add_expense(400)
|
33
|
+
assert_equal 600, foo.total_expenses
|
34
|
+
assert_equal 200, foo.expense[0]["amount"]
|
35
|
+
assert_equal 400, foo.expense[1]["amount"]
|
36
|
+
# Make sure budget still is not complete
|
37
|
+
assert !foo.complete?
|
38
|
+
foo.add_expense(900, 'Mortgage')
|
39
|
+
assert_equal 1500, foo.total_expenses
|
40
|
+
assert foo.complete?
|
41
|
+
assert_equal 0, foo.remaining
|
42
|
+
# Remove last first expense
|
43
|
+
foo.delete_expense(0)
|
44
|
+
assert !foo.complete?
|
45
|
+
assert_equal 1300, foo.total_expenses
|
46
|
+
assert_equal 200, foo.remaining
|
47
|
+
foo.add_expense(200)
|
48
|
+
assert_equal 'Expense Item 3', foo.expense[2]["memo"]
|
49
|
+
foo.delete_income(2)
|
50
|
+
assert !foo.complete?
|
51
|
+
assert_equal -500, foo.remaining
|
52
|
+
assert_equal 1000, foo.total_income
|
53
|
+
foo.add_income(500)
|
54
|
+
assert foo.complete?
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: budget
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- DrSayre
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-09-08 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A class to create a budget
|
15
|
+
email:
|
16
|
+
- DrSayre2002@yahoo.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/budget.rb
|
22
|
+
- test/test_budget.rb
|
23
|
+
homepage: https://github.com/DrSayre/budget
|
24
|
+
licenses: []
|
25
|
+
post_install_message:
|
26
|
+
rdoc_options: []
|
27
|
+
require_paths:
|
28
|
+
- lib
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 1.8.24
|
44
|
+
signing_key:
|
45
|
+
specification_version: 3
|
46
|
+
summary: A class to create a budget
|
47
|
+
test_files:
|
48
|
+
- test/test_budget.rb
|