diff --git a/dummy_file.rb b/dummy_file.rb new file mode 100644 index 00000000..3a529ccc --- /dev/null +++ b/dummy_file.rb @@ -0,0 +1,16 @@ +# die.rb +module Bank + + class Die + def initialize + end + + def roll + return rand(1..6) + end + +end +end + +die = Die.new +puts die diff --git a/lib/account.rb b/lib/account.rb index e69de29b..c609681a 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -0,0 +1,70 @@ +require 'csv' +require 'date' +require_relative 'owner' + +module Bank + class Account + attr_reader :id, :balance , :open_date + attr_accessor :owner + + @@all_accounts = [] + + def initialize(id, balance, open_date='2010-12-21 12:21:12 -0800') + raise ArgumentError.new("balance must be >= 0") if balance < 0 + @id = id + @balance = balance + @open_date = open_date + @@all_accounts << self + end + + + def withdraw(withdrawal_amount) + raise ArgumentError.new("Withdrawal amount must be >= 0") if withdrawal_amount < 0 + if withdrawal_amount > @balance + puts "You don't have enough in your account to withdraw that amount!" + else @balance -= withdrawal_amount + end + return @balance + end + + def deposit(deposit_amount) + raise ArgumentError.new("Deposit amount must be >= 0") if deposit_amount < 0 + @balance += deposit_amount + end + + def self.reset_all_accounts_for_test + @@all_accounts = [] + end + + def self.read_csv + CSV.open("./support/accounts.csv").each do |acct| + acct_id = acct[0].to_i + acct_balance_dollars = acct[1].to_i / 100.0 + acct_date = DateTime.parse(acct[2]) + self.new(acct_id, acct_balance_dollars, acct_date) + end + end + + def self.all + @@all_accounts + end + + def self.find(id) + found_accounts = @@all_accounts.select {|acct| acct.id == id} + raise ArgumentError.new("That account doesn't exist!") if found_accounts[0]==nil + return found_accounts[0] + end + + def self.add_owners_to_all_accounts + self.read_csv + Bank::Owner.read_csv + + account_owners_csv = CSV.open("./support/account_owners.csv") + account_owners_csv.each {|pair| + account_id = pair[0].to_i + owner_id = pair[1].to_i + self.find(account_id).owner = Bank::Owner.find(owner_id) + } + end + end +end diff --git a/lib/checking_account.rb b/lib/checking_account.rb new file mode 100644 index 00000000..38fa3cbc --- /dev/null +++ b/lib/checking_account.rb @@ -0,0 +1,46 @@ +require 'csv' +require 'date' +require_relative 'account' + + +module Bank + + class CheckingAccount < Account + + def initialize(id, balance, open_date='2010-12-21 12:21:12 -0800') + super(id, balance, open_date) + @free_checks_used = 0 + end + + def withdraw(withdrawal_amount) + raise ArgumentError.new("Withdrawal amount must be >= 0") if withdrawal_amount < 0 + if withdrawal_amount > (@balance - 1) + puts "You don't have enough in your account to withdraw that amount!" + else @balance -= (withdrawal_amount + 1) + end + return @balance + end + + def withdraw_using_check(withdrawal_amount) + raise ArgumentError.new("Withdrawal amount must be >= 0") if withdrawal_amount < 0 + + if @free_checks_used < 3 + if withdrawal_amount > (@balance + 10) + puts "You don't have enough in your account to withdraw that amount, even with your $10 overdraft allowance!" + else @balance -= (withdrawal_amount) + @free_checks_used += 1 + end + else + if withdrawal_amount > (@balance + 10 - 2) + puts "You don't have enough in your account to withdraw that amount and pay the check fee, even with your $10 overdraft allowance!" + else @balance -= (withdrawal_amount + 2) + end + end + return @balance + end + + def reset_checks + @free_checks_used = 0 + end + end +end diff --git a/lib/money_market_account.rb b/lib/money_market_account.rb new file mode 100644 index 00000000..79fd8c80 --- /dev/null +++ b/lib/money_market_account.rb @@ -0,0 +1,69 @@ +require 'csv' +require 'date' +require_relative 'account' + +module Bank + + class MoneyMarketAccount < Account + + + def initialize(id, balance, open_date='2010-12-21 12:21:12 -0800') + super(id, balance, open_date) + raise ArgumentError.new("balance must be >= 10,000") if balance < 10000 + @transactions_used = 0 + @transactions_allowed = true + end + + def transaction_count + @transactions_used + end + + def reset_transactions + @transactions_used = 0 + end + + def withdraw(withdrawal_amount) + if @transactions_allowed + + if @transactions_used < 6 + @transactions_used += 1 + super(withdrawal_amount) + if @balance < 10000 + @balance -= 100 + @transactions_allowed = false + puts "Your account is now too low. You must make a deposit to allow more transactions." + return @balance + end + else + puts "You have already used all your transactions this month." + @balance + end + else + puts "Withdrawal not allowed. Account balance is too low. You must make a deposit to re-enable transactions. " + return @balance + end + end + + def deposit(deposit_amount) + if !(@transactions_allowed) + @transactions_allowed = true + super(deposit_amount) + else + if @transactions_used < 6 + @transactions_used += 1 + super(deposit_amount) + else puts "You have already used all your transactions this month." + @balance + end + end + end + + def add_interest(rate) + raise ArgumentError.new("Interest rate must be > 0") if rate <= 0 + interest = @balance * (rate/100) + @balance += interest + return interest + end + + end +end diff --git a/lib/owner.rb b/lib/owner.rb new file mode 100644 index 00000000..27c9a6a9 --- /dev/null +++ b/lib/owner.rb @@ -0,0 +1,46 @@ +require 'csv' + +module Bank + class Owner + attr_reader :id, :last_name, :first_name, :street_address, :city, :state + + @@all_owners = [] + + def initialize(owner_hash) + @id = owner_hash[:id] + @last_name = owner_hash[:last_name] + @first_name = owner_hash[:first_name] + @street_address = owner_hash[:street_address] + @city = owner_hash[:city] + @state = owner_hash[:state] + @@all_owners << self + end + + + def self.reset_all_owners_for_test + @@all_owners = [] + end + + def self.read_csv + CSV.open("./support/owners.csv").each do |owner| + owner_id = owner[0].to_i + owner_last_name = owner[1].to_s + owner_first_name = owner[2].to_s + owner_street_address = owner[3].to_s + owner_city = owner[4].to_s + owner_state = owner[5].to_s + self.new(id:owner_id, last_name:owner_last_name, first_name:owner_first_name, street_address:owner_street_address, city:owner_city, state:owner_state) + end + end + + def self.all + @@all_owners + end + + def self.find(id) + found_accounts = @@all_owners.select {|owner| owner.id.to_i == id.to_i} + raise ArgumentError.new("That account doesn't exist!") if found_accounts[0]==nil + return found_accounts[0] + end + end +end diff --git a/lib/savings_account.rb b/lib/savings_account.rb new file mode 100644 index 00000000..c283a8fc --- /dev/null +++ b/lib/savings_account.rb @@ -0,0 +1,30 @@ +require 'csv' +require 'date' +require_relative 'account' + + +module Bank + class SavingsAccount < Account + + def initialize(id, balance, open_date='2010-12-21 12:21:12 -0800') + super(id, balance, open_date) + raise ArgumentError.new("balance must be >= 10") if balance < 10 + end + + def withdraw(withdrawal_amount) + raise ArgumentError.new("Withdrawal amount must be >= 0") if withdrawal_amount < 0 + if withdrawal_amount > (@balance - 12) + puts "You don't have enough in your account to withdraw that amount!" + else @balance -= (withdrawal_amount + 2) + end + return @balance + end + + def add_interest(rate) + raise ArgumentError.new("Interest rate must be > 0") if rate <= 0 + interest = @balance * (rate/100) + @balance += interest + return interest + end + end +end diff --git a/specs/account_spec.rb b/specs/account_spec.rb index 6c399139..db9cfd9c 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -3,6 +3,8 @@ require 'minitest/skip_dsl' require_relative '../lib/account' +#Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + describe "Wave 1" do describe "Account#initialize" do it "Takes an ID and an initial balance" do @@ -28,7 +30,7 @@ end it "Can be created with a balance of 0" do - # If this raises, the test will fail. No 'must's needed! + #If this raises an error, the test will fail. No 'must's needed! Bank::Account.new(1337, 0) end end @@ -41,7 +43,7 @@ account.withdraw(withdrawal_amount) - expected_balance = start_balance - withdrawal_amount + expected_balance = start_balance - withdrawal_amount account.balance.must_equal expected_balance end @@ -67,7 +69,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 +138,90 @@ 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 + it "Returns an array" do + Bank::Account.reset_all_accounts_for_test + Bank::Account.read_csv + expect(Bank::Account.all).must_be_instance_of Array, "Not an array." + end + + it "Returns an array consisting only of accounts" do + Bank::Account.reset_all_accounts_for_test + Bank::Account.read_csv + Bank::Account.all.each do |account| + account.must_be_instance_of Bank::Account, "Not an instance of Account class." + end + end + + it "Returns an array with the correct number of accounts" do + Bank::Account.reset_all_accounts_for_test + Bank::Account.read_csv + expect(Bank::Account.all.length).must_equal 12, "Wrong number of accounts" + end + + + it "gives correct values for the ID and balance of the first and last + accounts match what's in the CSV file" do + Bank::Account.reset_all_accounts_for_test + Bank::Account.read_csv + expect(Bank::Account.all.first.id).must_equal 1212, "ID of first account is incorrect." + Bank::Account.reset_all_accounts_for_test + Bank::Account.read_csv + expect(Bank::Account.all.first.balance).must_equal 12356.67, "Balance of first account is incorrect." + Bank::Account.reset_all_accounts_for_test + Bank::Account.read_csv + expect(Bank::Account.all.last.id).must_equal 15156, "ID of second account is incorrect." + Bank::Account.reset_all_accounts_for_test + Bank::Account.read_csv + expect(Bank::Account.all.last.balance).must_equal 43567.72, "Balance of second account is incorrect." end +end - describe "Account.find" do - it "Returns an account that exists" do - # TODO: Your test code here! - end - it "Can find the first account from the CSV" do - # TODO: Your test code here! - end +describe "Account.find" do + it "Returns an Account that exists" do + Bank::Account.reset_all_accounts_for_test + Bank::Account.read_csv + expect(Bank::Account.find(15151)).must_be_instance_of Bank::Account, "Does not return account" + end - it "Can find the last account from the CSV" do - # TODO: Your test code here! + it "Can find the first account from the CSV" do + Bank::Account.reset_all_accounts_for_test + Bank::Account.read_csv + expect(Bank::Account.find(1212)).must_equal Bank::Account.all.first, "Cannot find first account" + end + + it "Can find the last account from the CSV" do + Bank::Account.reset_all_accounts_for_test + Bank::Account.read_csv + expect(Bank::Account.find(15156)).must_equal Bank::Account.all.last, "Cannot find last account" + end + + it "Raises an error for an account that doesn't exist" do + Bank::Account.reset_all_accounts_for_test + Bank::Account.read_csv + proc { + Bank::Account.find(9999999) + }.must_raise ArgumentError + end +end +end + +describe "Wave 2 optionals - linkage between acounts and owners" do + + describe "add_owners_to_all_accounts" do + it "adds an owner of type owner to each account" do + Bank::Account.add_owners_to_all_accounts + Bank::Account.find(15151).owner.must_be_instance_of Bank::Owner, "Does not associate an owner with an account" end - it "Raises an error for an account that doesn't exist" do - # TODO: Your test code here! + it "associates the correct owner with each account" do + Bank::Account.add_owners_to_all_accounts + Bank::Account.find(15151).owner.must_equal Bank::Owner.find(17), "Does not associate the correct owner with the tested account" end end + end diff --git a/specs/checking_account_spec.rb b/specs/checking_account_spec.rb index 7f95339e..d522ad7b 100644 --- a/specs/checking_account_spec.rb +++ b/specs/checking_account_spec.rb @@ -1,17 +1,18 @@ require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' +require_relative '../lib/checking_account' -# TODO: uncomment the next line once you start wave 3 and add lib/checking_account.rb -# require_relative '../lib/checking_account' +#Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new # 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 @@ -21,60 +22,149 @@ end describe "#withdraw" do + + #Since withdraw was overridden, must retest the basic functionality + it "Requires a positive withdrawal amount" do + start_balance = 100.0 + withdrawal_amount = -25.0 + account = Bank::CheckingAccount.new(1337, start_balance) + proc { + account.withdraw(withdrawal_amount) + }.must_raise ArgumentError + end + + it "Applies a $1 fee each time" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 25.0 + account = Bank::CheckingAccount.new(1337, start_balance) + account.withdraw(withdrawal_amount) + expected_balance = start_balance - withdrawal_amount - 1 + account.balance.must_equal expected_balance end + it "Doesn't modify the balance if the fee would put it negative" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 99.50 + account = Bank::CheckingAccount.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 end describe "#withdraw_using_check" do it "Reduces the balance" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 25.0 + account = Bank::CheckingAccount.new(1337, start_balance) + + account.withdraw_using_check(withdrawal_amount) + + expected_balance = start_balance - withdrawal_amount + account.balance.must_equal expected_balance end it "Returns the modified balance" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 25.0 + account = Bank::CheckingAccount.new(1337, start_balance) + + updated_balance = account.withdraw_using_check(withdrawal_amount) + + expected_balance = start_balance - withdrawal_amount + updated_balance.must_equal expected_balance end it "Allows the balance to go down to -$10" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 110.0 + account = Bank::CheckingAccount.new(1337, start_balance) + + updated_balance = account.withdraw_using_check(withdrawal_amount) + + expected_balance = start_balance - withdrawal_amount + updated_balance.must_equal expected_balance end it "Outputs a warning if the account would go below -$10" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 110.01 + account = Bank::CheckingAccount.new(1337, start_balance) + proc { + account.withdraw_using_check(withdrawal_amount) + }.must_output(/.+/) end it "Doesn't modify the balance if the account would go below -$10" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 110.01 + account = Bank::CheckingAccount.new(1337, start_balance) + updated_balance = account.withdraw_using_check(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 "Requires a positive withdrawal amount" do - # TODO: Your test code here! + proc { + Bank::Account.new(1337, -100.0) + }.must_raise ArgumentError end it "Allows 3 free uses" do - # TODO: Your test code here! + account = Bank::CheckingAccount.new(1337, 100) + withdrawal_amount = 10 + 3.times {account.withdraw_using_check(withdrawal_amount)} + + account.balance.must_equal 70 end it "Applies a $2 fee after the third use" do - # TODO: Your test code here! + account = Bank::CheckingAccount.new(1337, 100) + withdrawal_amount = 10 + 4.times {account.withdraw_using_check(withdrawal_amount)} + + account.balance.must_equal 58 end end describe "#reset_checks" do it "Can be called without error" do - # TODO: Your test code here! + account = Bank::CheckingAccount.new(1337, 100) + account.reset_checks end it "Makes the next three checks free if less than 3 checks had been used" do - # TODO: Your test code here! + account = Bank::CheckingAccount.new(1337, 100) + withdrawal_amount = 10 + 2.times {account.withdraw_using_check(withdrawal_amount)} + account.reset_checks + 3.times {account.withdraw_using_check(withdrawal_amount)} + account.balance.must_equal 50 end it "Makes the next three checks free if more than 3 checks had been used" do - # TODO: Your test code here! + account = Bank::CheckingAccount.new(1337, 100) + withdrawal_amount = 10 + 4.times {account.withdraw_using_check(withdrawal_amount)} + account.reset_checks + 3.times {account.withdraw_using_check(withdrawal_amount)} + account.balance.must_equal 28 + end + + it "Makes ONLY the next three checks free if more than 3 checks had been used" do + account = Bank::CheckingAccount.new(1337, 100) + withdrawal_amount = 10 + 4.times {account.withdraw_using_check(withdrawal_amount)} + account.reset_checks + 4.times {account.withdraw_using_check(withdrawal_amount)} + account.balance.must_equal 16 end + end end diff --git a/specs/money_market_account_spec.rb b/specs/money_market_account_spec.rb new file mode 100644 index 00000000..ec6a0d32 --- /dev/null +++ b/specs/money_market_account_spec.rb @@ -0,0 +1,159 @@ +require 'minitest/autorun' +require 'minitest/reporters' +require 'minitest/skip_dsl' +require_relative '../lib/money_market_account' + +#Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + + +describe "MoneyMarketAccount" do + + describe "#initialize" do + + # Check that a MoneyMarketAccount is in fact a kind of account + it "Is a kind of Account" do + account = Bank::MoneyMarketAccount.new(12345, 10000) + account.must_be_kind_of Bank::Account + end + + it "Requires an initial balance of at least $10,000" do + proc { + Bank::MoneyMarketAccount.new(1337, 9999) + }.must_raise ArgumentError + end + end + + describe "Maximum of 6 transacctions" do + + it "increases the transaction count when either a withdrawal or a deposit is made." do + account = Bank::MoneyMarketAccount.new(12345, 50000) + withdrawal_amount = 100 + deposit_amount = 300 + account.withdraw(withdrawal_amount) + account.deposit(deposit_amount) + account.transaction_count.must_equal 2 + end + + it "Outputs a message when a transaction is attempted after 6 transactions have been made." do + withdrawal_amount = 100 + deposit_amount = 300 + account = Bank::MoneyMarketAccount.new(1337, 50000) + 3.times {account.withdraw(withdrawal_amount)} + 3.times {account.deposit(deposit_amount)} + proc { + account.withdraw(withdrawal_amount) + }.must_output(/.+/) + proc { + account.deposit(deposit_amount) + }.must_output(/.+/) + end + + it "Does not implement a requested transaction or modify the balance after 6 transactions have been made." do + withdrawal_amount = 100 + deposit_amount = 300 + account = Bank::MoneyMarketAccount.new(1337, 50000) + 6.times {account.withdraw(withdrawal_amount)} + updated_balance = account.balance + account.deposit(deposit_amount) + account.withdraw(withdrawal_amount) + account.balance.must_equal updated_balance + end + + it "A deposit performed to reach or exceed the minimum balance of $10,000 is not counted as part of the 6 transactions" do + start_balance = 11050 + withdrawal_amount = 10 + account = Bank::MoneyMarketAccount.new(1337, start_balance) + 5.times {account.withdraw(withdrawal_amount)} + account.withdraw(2000) + updated_balance = account.balance + deposit_amount = 5000 + account.deposit(deposit_amount) + account.balance.must_equal (updated_balance + 5000) + end + end + + describe "#withdraw" do + + it "Deducts a $100 fee if the balance would go below $10000" do + start_balance = 11000 + withdrawal_amount = 2000 + account = Bank::MoneyMarketAccount.new(1337, start_balance) + account.withdraw(withdrawal_amount) + updated_balance = start_balance - withdrawal_amount - 100 + account.balance.must_equal updated_balance + end + + it "Outputs a 'disallowed' message if the balance has not been increased using a deposit transaction" do + start_balance = 11000 + withdrawal_amount = 2000 + account = Bank::MoneyMarketAccount.new(1337, start_balance) + account.withdraw(withdrawal_amount) + proc { + account.withdraw(10) + }.must_output(/.+/) + end + + it "Does not change balance upon withdrawal attempt if the balance has not been increased using a deposit transaction" do + start_balance = 11000 + withdrawal_amount = 2000 + account = Bank::MoneyMarketAccount.new(1337, start_balance) + account.withdraw(withdrawal_amount) + updated_balance = account.balance + + account.withdraw(10) + account.balance.must_equal updated_balance + end + + it "Implements new transactions once the balance has been increased using a deposit transaction" do + start_balance = 11000 + withdrawal_amount = 2000 + account = Bank::MoneyMarketAccount.new(1337, start_balance) + account.withdraw(withdrawal_amount) + deposit_amount = 5000 + account.deposit(deposit_amount) + updated_balance = account.balance + account.withdraw(100) + account.balance.must_equal (updated_balance - 100) + end + end + + describe "#reset_transactions" do + it "Can be called without error" do + account = Bank::MoneyMarketAccount.new(1337, 50000) + account.reset_transactions + end + + it "Re-enables transactions after they have been disabled dur to 6 transactions" do + withdrawal_amount = 100 + deposit_amount = 300 + account = Bank::MoneyMarketAccount.new(1337, 50000) + 3.times {account.withdraw(withdrawal_amount)} + 3.times {account.deposit(deposit_amount)} + account.reset_transactions + updated_balance = account.balance + account.withdraw(withdrawal_amount) + account.balance.must_equal (updated_balance - withdrawal_amount) + end + end + + describe "#add_interest" do + it "Returns the interest calculated" do + account = Bank::MoneyMarketAccount.new(1337, 10000) + account.add_interest(0.25).must_equal 25 + end + + it "Updates the balance with calculated interest" do + account = Bank::MoneyMarketAccount.new(1337, 10000) + account.add_interest(0.25) + account.balance.must_equal 10025 + end + + it "Requires a positive rate" do + account = Bank::MoneyMarketAccount.new(1337, 10000) + proc { + account.add_interest(-0.25) + }.must_raise ArgumentError + end + end + + end diff --git a/specs/owner_spec.rb b/specs/owner_spec.rb new file mode 100644 index 00000000..14b37896 --- /dev/null +++ b/specs/owner_spec.rb @@ -0,0 +1,120 @@ +require 'minitest/autorun' +require 'minitest/reporters' +require 'minitest/skip_dsl' +require_relative '../lib/owner' +require_relative '../lib/account' + +describe "Wave 1- optionals" do + + describe "Owner#initialize" do + it "Takes an owner hash" do + janice_hash={id:12345, last_name:'Lichtman', first_name:'Janice', street_address:'16-28 Radburn Rd', city:'Fair Lawn', state:'NJ'} + janice = Bank::Owner.new(janice_hash) + + janice.must_respond_to :id + janice.id.must_equal janice_hash[:id] + + janice.must_respond_to :last_name + janice.last_name.must_equal janice_hash[:last_name] + + janice.must_respond_to :first_name + janice.first_name.must_equal janice_hash[:first_name] + + janice.must_respond_to :street_address + janice.street_address.must_equal janice_hash[:street_address] + + janice.must_respond_to :city + janice.city.must_equal janice_hash[:city] + + janice.must_respond_to :state + janice.state.must_equal janice_hash[:state] + end + end + + describe "Adding owner to account" do + it "associates an owner, and the owner's details, with an account" do + janice = Bank::Owner.new(id:12345, first_name:"Janice") + janices_account=Bank::Account.new('jans_acct_id',100) + janices_account.owner = janice + + janices_account.owner.first_name.must_equal "Janice" + end + + it "has an owner of the Owner class" do + janice = Bank::Owner.new(id:12345, first_name:"Janice") + janices_account=Bank::Account.new('jans_acct_id',100) + janices_account.owner = janice + + janices_account.owner.must_be_instance_of Bank::Owner + end + end +end + +describe "Wave 2- optionals" do + + describe "Owner.all" do + it "Returns an array" do + Bank::Owner.reset_all_owners_for_test + Bank::Owner.read_csv + expect(Bank::Owner.all).must_be_instance_of Array, "Not an array." + end + + it "Returns an array consisting only of owners" do + Bank::Owner.reset_all_owners_for_test + Bank::Owner.read_csv + Bank::Owner.all.each do |owner| + owner.must_be_instance_of Bank::Owner, "Not an instance of Account class." + end + end + + it "Returns an array with the correct number of accounts" do + Bank::Owner.reset_all_owners_for_test + Bank::Owner.read_csv + expect(Bank::Owner.all.length).must_equal 12, "Wrong number of accounts" + end + + it "gives correct values for the ID and state of the first and last + accounts match what's in the CSV file" do + Bank::Owner.reset_all_owners_for_test + Bank::Owner.read_csv + expect(Bank::Owner.all.first.id).must_equal 14, "ID of first owner is incorrect." + Bank::Owner.reset_all_owners_for_test + Bank::Owner.read_csv + expect(Bank::Owner.all.first.state).must_equal "Hawaii", "State of first owner is incorrect." + Bank::Owner.reset_all_owners_for_test + Bank::Owner.read_csv + expect(Bank::Owner.all.last.id).must_equal 25, "ID of second owner is incorrect." + Bank::Owner.reset_all_owners_for_test + Bank::Owner.read_csv + expect(Bank::Owner.all.last.state).must_equal "New York", "ID of second owner is incorrect." + end +end + +describe "Owner.find" do + it "Returns an Owner that exists" do + Bank::Owner.reset_all_owners_for_test + Bank::Owner.read_csv + expect(Bank::Owner.find(20)).must_be_instance_of Bank::Owner, "Does not return account" + end + + it "Can find the first account from the CSV" do + Bank::Owner.reset_all_owners_for_test + Bank::Owner.read_csv + expect(Bank::Owner.find(14)).must_equal Bank::Owner.all.first, "Cannot find first account" + end + + it "Can find the last account from the CSV" do + Bank::Owner.reset_all_owners_for_test + Bank::Owner.read_csv + expect(Bank::Owner.find(25)).must_equal Bank::Owner.all.last, "Cannot find last account" + end + + it "Raises an error for an account that doesn't exist" do + Bank::Owner.reset_all_owners_for_test + Bank::Owner.read_csv + proc { + Bank::Owner.find(9999999) + }.must_raise ArgumentError + end +end +end diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index 3f4d1e4a..28f3216b 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -1,17 +1,14 @@ require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' - -# TODO: uncomment the next line once you start wave 3 and add lib/savings_account.rb -# require_relative '../lib/savings_account' +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 +17,84 @@ end it "Requires an initial balance of at least $10" do - # TODO: Your test code here! + proc { + Bank::SavingsAccount.new(1337, 9) + }.must_raise ArgumentError end end + describe "#withdraw" do + + #Since withdraw was overridden, must retest the basic functionality + it "Requires a positive withdrawal amount" do + start_balance = 100.0 + withdrawal_amount = -25.0 + account = Bank::SavingsAccount.new(1337, start_balance) + proc { + account.withdraw(withdrawal_amount) + }.must_raise ArgumentError + end + it "Applies a $2 fee each time" do - # TODO: Your test code here! + start_balance = 100.0 + withdrawal_amount = 25.0 + account = Bank::SavingsAccount.new(1337, start_balance) + account.withdraw(withdrawal_amount) + expected_balance = start_balance - withdrawal_amount - 2 + 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 = 89 + account = Bank::SavingsAccount.new(1337, start_balance) + 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 = 95 + account = Bank::SavingsAccount.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 "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 = 89 + account = Bank::SavingsAccount.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 end describe "#add_interest" do it "Returns the interest calculated" do - # TODO: Your test code here! + account = Bank::SavingsAccount.new(1337, 10000) + account.add_interest(0.25).must_equal 25 end it "Updates the balance with calculated interest" do - # TODO: Your test code here! + account = Bank::SavingsAccount.new(1337, 10000) + account.add_interest(0.25) + account.balance.must_equal 10025 end it "Requires a positive rate" do - # TODO: Your test code here! + account = Bank::SavingsAccount.new(1337, 10000) + proc { + account.add_interest(-0.25) + }.must_raise ArgumentError end end end