diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..4ad951ed Binary files /dev/null and b/.DS_Store differ diff --git a/Rakefile b/Rakefile index deb52f2c..f4f704fc 100644 --- a/Rakefile +++ b/Rakefile @@ -2,7 +2,7 @@ require 'rake/testtask' Rake::TestTask.new do |t| t.libs = ["lib"] - t.warning = true + t.warning = false t.test_files = FileList['specs/*_spec.rb'] end diff --git a/lib/account.rb b/lib/account.rb index e69de29b..44faaddc 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -0,0 +1,58 @@ +require 'csv' +module Bank + + + class Account + + def self.all + account = [] + CSV.open("/Users/habsr/ada/projects/BankAccounts/support/accounts.csv", "r").each do |file| + id = Integer(file[0]) + balance = Integer(file[1]) + open_date = file[2] + new_account = Account.new(id, balance, open_date) + account << new_account + end + return account + end + + def self.find(id) + Account.all.each do |account| + if account.id == id + return account + end + end + puts "That account Does Not Exist" + end + + attr_reader :id, :balance + def initialize(id, balance, open_date = nil) + @id = id + @balance = balance + @open_date = open_date + if @balance < 0 + raise ArgumentError.new "The starting balance cannot be negative" + end + end + + def withdraw(withdrawal_amount) + if withdrawal_amount > @balance + puts "Warning, the balance cannot be negative" + @balance = @balance + elsif withdrawal_amount < 0 + raise ArgumentError.new "You cannot withdraw a negative amount" + else + @balance -= withdrawal_amount + end + end + + def deposit(deposit_amount) + #raise ArgumentError.new("amount must be >= 0") if amount < 0 + if deposit_amount < 0 + raise ArgumentError.new "The deposit must be greater than 0" + else + @balance += deposit_amount + end + end + end +end diff --git a/lib/checking_account.rb b/lib/checking_account.rb new file mode 100644 index 00000000..1fcd968c --- /dev/null +++ b/lib/checking_account.rb @@ -0,0 +1,47 @@ +require 'csv' +require_relative '../lib/account' + +module Bank + + class CheckingAccount < Account + attr_reader :id, :balance + def initialize(id, balance) + @id = id + @balance = balance + @check_num = 3 + + def withdraw(withdrawal_amount) + check_balance = @balance - (withdrawal_amount + 1) + if check_balance < 0 + puts "Warning, this will be below 0 , " + (@balance.to_s) + else + super + (-1) + end + end + + def withdraw_with_check(withdrawal_amount) + if withdrawal_amount < 0 + raise ArgumentError.new "You cannot withdraw a negative amount" + elsif (@balance - withdrawal_amount) <= -11 + puts "Warning, the balance cannot be negative " + return @balance + else + withdrawal_fee = 0 + @balance -= withdrawal_amount + withdrawal_fee + @check_num -= 1 + if @check_num < 0 + withdrawal_fee = 2 + @balance -= withdrawal_fee + end + end + end + end + + def reset_checks + if @check_num <= 0 + @check_num = 3 + end + end + + end +end diff --git a/lib/owner.rb b/lib/owner.rb new file mode 100644 index 00000000..8eb0ee81 --- /dev/null +++ b/lib/owner.rb @@ -0,0 +1,10 @@ +module Bank + class Owner + + def initialize(owner_hash) + @name = owner_hash[:name] + @address = owner_hash[:address] + @account_number = owner_hash[:account_number] + end + end +end diff --git a/lib/savings_account.rb b/lib/savings_account.rb new file mode 100644 index 00000000..f7825f0c --- /dev/null +++ b/lib/savings_account.rb @@ -0,0 +1,36 @@ +require 'csv' +require_relative '../lib/account' + +module Bank + + class SavingsAccount < Account + attr_reader :id, :balance, :interest + + def initialize(id, balance) + + raise ArgumentError.new "Balance must be at least $10" unless balance >= 10 + @id = id + @balance = balance + end + + def withdraw(withdrawal_amount) + temp_balance = @balance - (withdrawal_amount + 2) + if temp_balance < 10 + puts "Warning, this will make your balance below your mininum , the current balance is " + (@balance.to_s) + @balance + else + super + (-2) + end + end + + def add_interest(rate) + if rate < 0 + raise ArgumentError.new "The interest rate cannot be negative" + else + interest = @balance * (rate / 100).to_f + @balance += interest + return interest + end + end + end +end diff --git a/specs/account_spec.rb b/specs/account_spec.rb index 6c399139..ce305ec4 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -4,6 +4,7 @@ require_relative '../lib/account' describe "Wave 1" do + describe "Account#initialize" do it "Takes an ID and an initial balance" do id = 1337 @@ -12,23 +13,18 @@ account.must_respond_to :id account.id.must_equal id - + account.must_respond_to :balance account.balance.must_equal balance end it "Raises an ArgumentError when created with a negative balance" do - # Note: we haven't talked about procs yet. You can think - # of them like blocks that sit by themselves. - # This code checks that, when the proc is executed, it - # raises an ArgumentError. proc { Bank::Account.new(1337, -100.0) }.must_raise ArgumentError end it "Can be created with a balance of 0" do - # If this raises, the test will fail. No 'must's needed! Bank::Account.new(1337, 0) end end @@ -38,9 +34,7 @@ start_balance = 100.0 withdrawal_amount = 25.0 account = Bank::Account.new(1337, start_balance) - account.withdraw(withdrawal_amount) - expected_balance = start_balance - withdrawal_amount account.balance.must_equal expected_balance end @@ -51,7 +45,6 @@ account = Bank::Account.new(1337, start_balance) updated_balance = account.withdraw(withdrawal_amount) - expected_balance = start_balance - withdrawal_amount updated_balance.must_equal expected_balance end @@ -61,13 +54,8 @@ withdrawal_amount = 200.0 account = Bank::Account.new(1337, start_balance) - # Another proc! This test expects something to be printed - # to the terminal, using 'must_output'. /.+/ is a regular - # expression matching one or more characters - as long as - # anything at all is printed out the test will pass. - proc { - account.withdraw(withdrawal_amount) - }.must_output /.+/ + proc { account.withdraw(withdrawal_amount) + }.must_output(/.+/) end it "Doesn't modify the balance if the account would go negative" do @@ -76,15 +64,13 @@ account = Bank::Account.new(1337, start_balance) updated_balance = account.withdraw(withdrawal_amount) - - # Both the value returned and the balance in the account - # must be un-modified. updated_balance.must_equal start_balance account.balance.must_equal start_balance end it "Allows the balance to go to 0" do account = Bank::Account.new(1337, 100.0) + updated_balance = account.withdraw(account.balance) updated_balance.must_equal 0 account.balance.must_equal 0 @@ -108,7 +94,6 @@ account = Bank::Account.new(1337, start_balance) account.deposit(deposit_amount) - expected_balance = start_balance + deposit_amount account.balance.must_equal expected_balance end @@ -119,7 +104,6 @@ account = Bank::Account.new(1337, start_balance) updated_balance = account.deposit(deposit_amount) - expected_balance = start_balance + deposit_amount updated_balance.must_equal expected_balance end @@ -136,36 +120,51 @@ end end -# TODO: change 'xdescribe' to 'describe' to run these tests -xdescribe "Wave 2" do +describe "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 - end - end - describe "Account.find" do - it "Returns an account that exists" do - # TODO: Your test code here! - end + account = Bank::Account.all - it "Can find the first account from the CSV" do - # TODO: Your test code here! - end + account.must_be_instance_of Array - it "Can find the last account from the CSV" do - # TODO: Your test code here! + # - Everything in the array is an Account + account.each do |element| + element.must_be_instance_of Bank::Account + end + # - The number of accounts is correct account.length = 12 + account.length.must_equal 12 #CSV.read("support/accounts.csv").length + # - The ID and balance of the first and last ...pull out indexes, id must be equal to + # accounts match what's in the CSV file + account[0].id.must_equal 1212 + account[-1].id.must_equal 15156 + account[0].balance.must_equal 1235667 + account[-1].balance.must_equal 4356772 + # Feel free to split this into multiple tests if needed end - it "Raises an error for an account that doesn't exist" do - # TODO: Your test code here! + describe "Account.find" do + it "Returns an account that exists" do + account = Bank::Account.find(1212) + account.must_be_instance_of Bank::Account + end + + it "Can find the first account from the CSV" do + accounts = Bank::Account.all + account = Bank::Account.find(1212) + account.id.must_equal accounts[0].id + end + + it "Can find the last account from the CSV" do + accounts = Bank::Account.all + account = Bank::Account.find(15156) + account.id.must_equal accounts[-1].id + end + + it "Raises an error for an account that doesn't exist" do + proc { Bank::Account.find(111111) + }.must_output(/.+/) + end end end end diff --git a/specs/checking_account_spec.rb b/specs/checking_account_spec.rb index 7f95339e..0144b2d3 100644 --- a/specs/checking_account_spec.rb +++ b/specs/checking_account_spec.rb @@ -1,19 +1,12 @@ require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' +require_relative '../lib/checking_account' +require_relative '../lib/account' -# 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 "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 @@ -22,59 +15,114 @@ describe "#withdraw" do it "Applies a $1 fee each time" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 200) + + new_balance = checking_account.withdraw(10) + new_balance.must_equal 189 end it "Doesn't modify the balance if the fee would put it negative" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 200) + + proc { checking_account.withdraw(200)}.must_output(/.+/) + checking_account.balance.must_equal 200 end end describe "#withdraw_using_check" do it "Reduces the balance" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 200) + + checking_account.balance.must_equal 200 + checking_account.withdraw_with_check(10) + checking_account.balance.must_equal 190 end it "Returns the modified balance" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 200) + + checking_account.balance.must_equal 200 + checking_account.withdraw_with_check(10) + checking_account.balance.must_equal 190 end it "Allows the balance to go down to -$10" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 200) + + checking_account.withdraw_with_check(210) + checking_account.balance.must_equal(-10) end it "Outputs a warning if the account would go below -$10" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 200) + + checking_account.withdraw_with_check(211) + checking_account.balance.must_equal 200 + + proc { checking_account.withdraw_with_check(211)}.must_output(/.+/) end it "Doesn't modify the balance if the account would go below -$10" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 200) + + checking_account.withdraw_with_check(211) + checking_account.balance.must_equal 200 end it "Requires a positive withdrawal amount" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = -25.0 + checking_account = Bank::CheckingAccount.new(11, start_balance) + + proc { + checking_account.withdraw_with_check(withdrawal_amount) + }.must_raise(ArgumentError) end it "Allows 3 free uses" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 80) + + 3.times do checking_account.withdraw_with_check(20) + end + checking_account.balance.must_equal 20 end it "Applies a $2 fee after the third use" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 100) + + 4.times do checking_account.withdraw_with_check(20) + end + checking_account.balance.must_equal 18 end end describe "#reset_checks" do it "Can be called without error" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 200) + + 4.times do checking_account.withdraw_with_check(20) + end + checking_account.reset_checks + checking_account.withdraw_with_check(20) + checking_account.balance.must_equal 98 end it "Makes the next three checks free if less than 3 checks had been used" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 200) + + 3.times do checking_account.withdraw_with_check(20) + end + checking_account.balance.must_equal 140 end it "Makes the next three checks free if more than 3 checks had been used" do - # TODO: Your test code here! + checking_account = Bank::CheckingAccount.new(11, 200) + + 4.times do checking_account.withdraw_with_check(20) + end + checking_account.reset_checks + checking_account.withdraw_with_check(20) + checking_account.balance.must_equal 98 end end end diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index 3f4d1e4a..1078da83 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -1,17 +1,9 @@ require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' +require_relative '../lib/savings_account' -# 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 "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 +12,56 @@ end it "Requires an initial balance of at least $10" do - # TODO: Your test code here! + proc{ account = Bank::SavingsAccount.new(1212, 9) + }.must_raise(ArgumentError) end end - + describe "#withdraw" do it "Applies a $2 fee each time" do - # TODO: Your test code here! + savings_account = Bank::SavingsAccount.new(11, 200) + new_balance = savings_account.withdraw(10) + new_balance.must_equal 188 end it "Outputs a warning if the balance would go below $10" do - # TODO: Your test code here! + savings_account = Bank::SavingsAccount.new(11, 200) + savings_account.balance.must_equal 200 + savings_account.withdraw(191) + proc { savings_account.withdraw(191)}.must_output(/.+/) end it "Doesn't modify the balance if it would go below $10" do - # TODO: Your test code here! + savings_account = Bank::SavingsAccount.new(1212, 200) + # savings_account.balance.must_equal 200 + savings_account.withdraw(191) + savings_account.balance.must_equal 200 end it "Doesn't modify the balance if the fee would put it below $10" do - # TODO: Your test code here! + savings_account = Bank::SavingsAccount.new(1212, 200) + savings_account.withdraw(189) + savings_account.balance.must_equal 200 end end describe "#add_interest" do it "Returns the interest calculated" do - # TODO: Your test code here! + savings_account = Bank::SavingsAccount.new(11, 10000) + interest = savings_account.add_interest(0.25) + interest.must_equal 25.0 end it "Updates the balance with calculated interest" do - # TODO: Your test code here! + savings_account = Bank::SavingsAccount.new(11, 10000) + savings_account.add_interest(0.25) + savings_account.balance.must_equal 10025.0 end it "Requires a positive rate" do - # TODO: Your test code here! + savings_account = Bank::SavingsAccount.new(11, 10000) + proc{ savings_account.add_interest(-1) + }.must_raise(ArgumentError) end end end diff --git a/support/.DS_Store b/support/.DS_Store new file mode 100644 index 00000000..1594eef0 Binary files /dev/null and b/support/.DS_Store differ