diff --git a/lib/account.rb b/lib/account.rb index e69de29b..0f70dc6f 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -0,0 +1,73 @@ +require 'csv' +require 'date' + +module Bank + class Account + attr_reader :id, :balance, :date_opened + + def initialize(id = "", balance = "", date_opened = "") + @id = id.to_i + @balance = balance.to_f + @date_opened = date_opened + + raise ArgumentError.new("balance must be >= 0") if @balance < 0 + if @balance < 0 + then + puts "balance must be >= 0" + end + + end + + def self.all + array =[] + CSV.open("support/accounts.csv").each do |line| + array << self.new(line[0], line[1], DateTime.parse(line[2])) + end + return array + end + + def self.find(id) + self.all.each do |account| + if account.id == id then return account + end + end + raise ArgumentError.new("You must select a valid account") + end + + def withdraw(amount, limit = 0) + if amount > 0 + if (@balance - amount) >= limit + @balance -= amount + else + puts "You have insufficient funds" + end + else + puts "You must withraw an amount greater than $0.00 dollars" + raise ArgumentError.new("you must withdraw an amount greater than $0.00") + end + return @balance + end + + def deposit(amount) + if amount >= 0 + @balance += amount + else + puts "You must deposit an amount greater than $0.00 dollars" + raise ArgumentError.new("you must deposit an amount greater than $0.00") + end + return @balance + end + + def reset_checks + @count = 0 + end + + end +end + # + # start_balance = 100.0 + # withdrawal_amount = 91.0 + # account = Bank::Account.new(1337, start_balance) + # + # account.withdraw(withdrawal_amount) + # puts account.balance diff --git a/lib/account2.rb b/lib/account2.rb new file mode 100644 index 00000000..4210b3fa --- /dev/null +++ b/lib/account2.rb @@ -0,0 +1,65 @@ +require 'csv' +require 'date' + +module Bank + class Account + attr_reader :id, :balance, :date_opened + + def initialize(id = "", balance = "", date_opened = "") + @id = id.to_i + @balance = balance.to_i + @date_opened = date_opened + + raise ArgumentError.new("balance must be >= 0") if @balance < 0 + if @balance < 0 + then + puts "balance must be >= 0" + end + + end + + def self.all + array =[] + CSV.open("../support/accounts.csv").each do |line| + array << self.new(line[0], line[1], line[2]) + end + return array + end + + def self.find(id) + self.all.each do |account| + if account.id == id then puts account.id + return account.id + end + end + raise ArgumentError.new("You must select a valid account") + end + + def withdraw(amount) + if amount > 0 + if (@balance - amount) >= 0 + @balance -= amount + else + puts "You have insufficient funds" + end + else + puts "You must withraw an amount greater than $0.00 dollars" + raise ArgumentError.new("you must withdraw an amount greater than $0.00") + end + return @balance + end + + def deposit(amount) + if amount >= 0 + @balance += amount + else + puts "You must deposit an amount greater than $0.00 dollars" + raise ArgumentError.new("you must deposit an amount greater than $0.00") + end + return @balance + + end + end +end + + Bank::Account.find(122) diff --git a/lib/checkingaccount.rb b/lib/checkingaccount.rb new file mode 100644 index 00000000..bcb159eb --- /dev/null +++ b/lib/checkingaccount.rb @@ -0,0 +1,38 @@ +require_relative 'account.rb' +module Bank + class CheckingAccount < Account + attr_reader :count + + def initialize(id = "", balance = 10, date_opened = "" ) + @count = 0 + super(id, balance, date_opened) + if balance < 10 + raise ArgumentError.new("balance must be >= 10") + puts "balance must be >= 10" + end + end + + def withdraw(amount,limit= 10) + total_withdrawl = amount + 1 + super(total_withdrawl, -10) + return @balance + end + + + def withdraw_using_check(amount,limit= -10) + if count <= 3 + withdraw((amount - 1)) + @count += 1 + elsif count >= 4 + withdraw((amount + 1)) + @count += 1 + end + return balance + end + + end +end +opening_balance = 100 +withdrawal_amount = 10 +account = Bank::CheckingAccount.new(12345, opening_balance) +puts account.withdraw_using_check(withdrawal_amount) diff --git a/lib/savingsaccount.rb b/lib/savingsaccount.rb new file mode 100644 index 00000000..16955a18 --- /dev/null +++ b/lib/savingsaccount.rb @@ -0,0 +1,28 @@ +require_relative 'account.rb' +module Bank + class SavingsAccount < Account + def initialize(id = "", balance = 10, date_opened = "" ) + super(id, balance, date_opened) + + raise ArgumentError.new("balance must be >= 10") if balance < 10 + + + end + + def withdraw(amount) + total_withdrawl = amount + 2 + super(total_withdrawl, 10) + #end + return @balance + end + + + def add_interest(rate) + + if rate > 0 then @balance = balance * (1 + (rate/100)) + else puts "Rate must be greater than 0" + end + return @balance + end + end +end diff --git a/specs/account_spec.rb b/specs/account_spec.rb index 6c399139..efd75d6e 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -2,6 +2,7 @@ require 'minitest/reporters' require 'minitest/skip_dsl' require_relative '../lib/account' +require 'date' describe "Wave 1" do describe "Account#initialize" do @@ -67,7 +68,7 @@ # anything at all is printed out the test will pass. proc { account.withdraw(withdrawal_amount) - }.must_output /.+/ + }.must_output (/.+/) end it "Doesn't modify the balance if the account would go negative" do @@ -136,36 +137,58 @@ end end -# TODO: change 'xdescribe' to 'describe' to run these tests -xdescribe "Wave 2" do - describe "Account.all" do - it "Returns an array of all accounts" do - # TODO: Your test code here! - # Useful checks might include: - # - Account.all returns an array - # - Everything in the array is an Account - # - The number of accounts is correct - # - The ID and balance of the first and last - # accounts match what's in the CSV file - # Feel free to split this into multiple tests if needed + + +describe "Account.all" do + it "Returns an array of all accounts" do + Bank::Account.all.must_be_kind_of Array, "Must be an array" + + end +end + +describe "Test that each account has the correct number of items" do + it "Fits the template for an account" do + Bank::Account.all.each do |account| + account.must_be_kind_of Bank::Account, "This should be an account" end end +end + +describe "Tests that the number of accounts is correct" do +it "Account.all should be same length as CSV file" do + file_size = CSV.readlines("support/accounts.csv").size + Bank::Account.all.length.must_equal file_size + end +end +# +describe "Tests that ID/Balance of 1st/nth account match whats in the CSV" do + it "Matches the opening and closing of the .csv file" do +CSV.readlines("support/accounts.csv")[0][0].to_i.must_equal Bank::Account.all[0].id.to_i, "the first item's ids should be the same" +CSV.readlines("support/accounts.csv")[-1][0].to_i.must_equal Bank::Account.all[-1].id.to_i, "the last items's ids should be the same" + +CSV.readlines("support/accounts.csv")[0][1].to_i.must_equal Bank::Account.all[0].balance.to_i, "the first item's balance should be the same" +CSV.readlines("support/accounts.csv")[-1][1].to_i.must_equal Bank::Account.all[-1].balance.to_i, "the last items's balance should be the same" +end +end describe "Account.find" do it "Returns an account that exists" do - # TODO: Your test code here! + Bank::Account.find(1217).must_be_kind_of Bank::Account, "This should be a valid account #{}" end - it "Can find the first account from the CSV" do - # TODO: Your test code here! + it "Can find the first acount in the CSV" do + Bank::Account.find(1212).must_be_kind_of Bank::Account, "This should show account #1212" end - +end +describe "Account.find the last" do it "Can find the last account from the CSV" do - # TODO: Your test code here! - end + Bank::Account.find(15153).must_be_kind_of Bank::Account, "This should show account #15156" + end + it "Raises an error for an account that doesn't exist" do - # TODO: Your test code here! + proc { + Bank::Account.find(5) + }.must_raise ArgumentError end end -end diff --git a/specs/checking_account_spec.rb b/specs/checking_account_spec.rb index 7f95339e..9e500529 100644 --- a/specs/checking_account_spec.rb +++ b/specs/checking_account_spec.rb @@ -1,80 +1,153 @@ require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' +require_relative '../lib/checkingaccount' +require 'date' -# TODO: uncomment the next line once you start wave 3 and add lib/checking_account.rb -# require_relative '../lib/checking_account' -# Because a CheckingAccount is a kind -# of Account, and we've already tested a bunch of functionality -# on Account, we effectively get all that testing for free! -# Here we'll only test things that are different. # TODO: change 'xdescribe' to 'describe' to run these tests -xdescribe "CheckingAccount" do - describe "#initialize" do - # Check that a CheckingAccount is in fact a kind of account - it "Is a kind of Account" do - account = Bank::CheckingAccount.new(12345, 100.0) - account.must_be_kind_of Bank::Account - end + +describe "#initialize" do + # Check that a CheckingAccount is in fact a kind of account + it "Is a kind of Account" do + account = Bank::CheckingAccount.new(12345, 100.0) + account.must_be_kind_of Bank::Account end +end - describe "#withdraw" do - it "Applies a $1 fee each time" do - # TODO: Your test code here! - end +describe "#withdraw" do + it "Applies a $1 fee each time" do + opening_balance = 100 + withdrawal_amount = 90 + total_withdrawl = withdrawal_amount + 1 + account = Bank::CheckingAccount.new(12345,opening_balance) + account.withdraw(withdrawal_amount).must_equal opening_balance - total_withdrawl - it "Doesn't modify the balance if the fee would put it negative" do - # TODO: Your test code here! - end end + it "Doesn't modify the balance if the fee would put it negative" do + opening_balance = 100 + withdrawal_amount = 111 - describe "#withdraw_using_check" do - it "Reduces the balance" do - # TODO: Your test code here! - end + account = Bank::CheckingAccount.new(12345,opening_balance) + account.withdraw(withdrawal_amount).must_equal opening_balance + end +end - it "Returns the modified balance" do - # TODO: Your test code here! - end - it "Allows the balance to go down to -$10" do - # TODO: Your test code here! - end +describe "#withdraw_using_check" do + it "Reduces the balance" do + opening_balance = 100 + withdrawal_amount = 10 - it "Outputs a warning if the account would go below -$10" do - # TODO: Your test code here! - end + account = Bank::CheckingAccount.new(12345, opening_balance) + account.withdraw_using_check(withdrawal_amount).wont_equal opening_balance + end - it "Doesn't modify the balance if the account would go below -$10" do - # TODO: Your test code here! + it "Returns the modified balance" do + opening_balance = 100 + withdrawal_amount = 10 + account = Bank::CheckingAccount.new(12345, opening_balance) + 3.times{account.withdraw_using_check(10)} + account.withdraw_using_check(1) + new_balance = account.balance + + if account.count <= 3 + account.withdraw_using_check(withdrawal_amount).must_equal new_balance - withdrawal_amount + elsif account.count >= 4 + account.withdraw_using_check(withdrawal_amount).must_equal new_balance - (withdrawal_amount + 2) end + end - it "Requires a positive withdrawal amount" do - # TODO: Your test code here! - end + it "Allows the balance to go down to -$10" do + opening_balance = 100 + withdrawal_amount = 109 + account = Bank::CheckingAccount.new(12345, opening_balance) + account.withdraw_using_check(withdrawal_amount).must_equal opening_balance - withdrawal_amount + end - it "Allows 3 free uses" do - # TODO: Your test code here! - end + it "Outputs a warning if the account would go below -$10" do + start_balance = 100.0 + withdrawal_amount = 111.0 + account = Bank::CheckingAccount.new(1337, start_balance) + #This is a proc with a regex that requires a string in order for the test to pass + proc { + account.withdraw_using_check(withdrawal_amount) + }.must_output (/.+/) + end - it "Applies a $2 fee after the third use" do - # TODO: Your test code here! - end + it "Doesn't modify the balance if the account would go below -$10" do + start_balance = 100.0 + withdrawal_amount = 111.0 + account = Bank::CheckingAccount.new(1337, start_balance) + account.withdraw_using_check(withdrawal_amount).must_equal start_balance end - describe "#reset_checks" do - it "Can be called without error" do - # TODO: Your test code here! - end + it "Requires a positive withdrawal amount" do + start_balance = 100.0 + withdrawal_amount = -111.0 + account = Bank::CheckingAccount.new(1337, start_balance) + # This is a proc with a rexex that requires a string in order for the test to passed + proc { + account.withdraw_using_check(withdrawal_amount) + }.must_raise ArgumentError + end + + it "Allows 3 free uses" do + opening_balance = 100 + withdrawal_amount = 10 + account = Bank::CheckingAccount.new(12345, opening_balance) + 3.times{account.withdraw_using_check(10)} + new_balance = account.balance - it "Makes the next three checks free if less than 3 checks had been used" do - # TODO: Your test code here! + if account.count <= 3 + account.withdraw_using_check(withdrawal_amount).must_equal new_balance - withdrawal_amount end + end + + it "Applies a $2 fee after the third use" do + opening_balance = 100 + withdrawal_amount = 10 + account = Bank::CheckingAccount.new(12345, opening_balance) + 4.times{account.withdraw_using_check(10)} + new_balance = account.balance - it "Makes the next three checks free if more than 3 checks had been used" do - # TODO: Your test code here! + if account.count <= 3 + account.withdraw_using_check(withdrawal_amount).must_equal new_balance - (withdrawal_amount + 2) end end end + + +describe "#reset_checks" do + it "Can be called without error" do + account = Bank::CheckingAccount.new(1234, 1000) + end + + +it "Makes the next three checks free if less than 3 checks had been used" do + opening_balance = 100 + withdrawal_amount = 10 + account = Bank::CheckingAccount.new(12345, opening_balance) + 2.times{account.withdraw_using_check(10)} + new_balance = account.balance + account.reset_checks + + if account.count <= 3 + account.withdraw_using_check(withdrawal_amount).must_equal new_balance - (withdrawal_amount) + end +end + +it "Makes the next three checks free if more than 3 checks had been used" do + opening_balance = 100 + withdrawal_amount = 10 + account = Bank::CheckingAccount.new(12345, opening_balance) + 4.times{account.withdraw_using_check(10)} + new_balance = account.balance + account.reset_checks + + if account.count <= 3 + account.withdraw_using_check(withdrawal_amount).must_equal new_balance - (withdrawal_amount) + end +end +end diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index 3f4d1e4a..8c902157 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -1,17 +1,10 @@ require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' +require_relative '../lib/savingsaccount' +require 'date' -# TODO: uncomment the next line once you start wave 3 and add lib/savings_account.rb -# require_relative '../lib/savings_account' -# Because a SavingsAccount is a kind -# of Account, and we've already tested a bunch of functionality -# on Account, we effectively get all that testing for free! -# Here we'll only test things that are different. - -# TODO: change 'xdescribe' to 'describe' to run these tests -xdescribe "SavingsAccount" do describe "#initialize" do it "Is a kind of Account" do # Check that a SavingsAccount is in fact a kind of account @@ -20,39 +13,75 @@ end it "Requires an initial balance of at least $10" do - # TODO: Your test code here! + proc { + Bank::SavingsAccount.new(1337, 9.99) + }.must_raise ArgumentError end end describe "#withdraw" do it "Applies a $2 fee each time" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 25.0 + total_withdrawl = withdrawal_amount + 2 + account = Bank::SavingsAccount.new(1337, start_balance) + account.withdraw(withdrawal_amount) + + expected_balance = start_balance - total_withdrawl + account.balance.must_equal expected_balance end it "Outputs a warning if the balance would go below $10" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 91.0 + account = Bank::SavingsAccount.new(1337, start_balance) + #This is a proc with a regex that requires a string in order for the test to pass + proc { + account.withdraw(withdrawal_amount) + }.must_output (/.+/) end it "Doesn't modify the balance if it would go below $10" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 91.0 + account = Bank::SavingsAccount.new(1337, start_balance) + if account.balance - withdrawal_amount < 10 + account.withdraw(withdrawal_amount).must_equal start_balance + end end it "Doesn't modify the balance if the fee would put it below $10" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 91.0 + total_withdrawl = withdrawal_amount + 2 + account = Bank::SavingsAccount.new(1337, start_balance) + if account.balance - total_withdrawl < 10 + account.withdraw(withdrawal_amount).must_equal start_balance + end end end describe "#add_interest" do it "Returns the interest calculated" do - # TODO: Your test code here! + start_balance = 10000.0 + account = Bank::SavingsAccount.new(1337, start_balance) + account.add_interest(0.25).must_equal start_balance * 1.0025 end it "Updates the balance with calculated interest" do - # TODO: Your test code here! + start_balance = 10000.00 + account = Bank::SavingsAccount.new(1337,start_balance) + account.add_interest(0.25).must_equal 10025 end it "Requires a positive rate" do - # TODO: Your test code here! + start_balance = 10000.0 + rate = -0.2 + account = Bank::SavingsAccount.new(1337, start_balance) + account.add_interest(rate) + + proc { + account.add_interest(rate) + }.must_output (/.+/) end end -end