diff --git a/lib/account.rb b/lib/account.rb index e69de29b..69754c6b 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -0,0 +1,51 @@ +require 'csv' +module Bank + class Account + attr_reader :id, :balance, :open_date, :accounts + def initialize(id, balance, open_date = "1999-03-27 11:30:09 -0800") + raise ArgumentError.new("balance must be >= 0") if balance < 0 + + @id = id + @balance = balance + @open_date = open_date + end + + def withdraw(amount) + if amount < 0 + raise ArgumentError.new("withdrawal can't be negative number.") + end + + if amount > @balance + puts "Overdrawn" + @balance + else + @balance -= amount + end + end + + def deposit(amount) + if amount < 0 + raise ArgumentError.new("withdrawal can't be negative number.") + end + @balance += amount + end + + def self.all + @accounts = [] + CSV.open("./support/accounts.csv", "r").each do |line| + @accounts << self.new(line[0].to_i, line[1].to_f, line[2].to_s) + end + return @accounts + end + + def self.find(id) + @accounts = Account.all + @accounts.each do |account| + if account.id == id + return account + end + end + raise ArgumentError.new('Account does not exist') + end + end +end diff --git a/lib/checking_account.rb b/lib/checking_account.rb new file mode 100644 index 00000000..d839f3a3 --- /dev/null +++ b/lib/checking_account.rb @@ -0,0 +1,42 @@ +require_relative 'account' + +module Bank + class CheckingAccount < Account + attr_reader :balance + def initialize(id, balance, open_date = "1999-03-27 11:30:09 -0800") + super(id, balance, open_date) + @check_count = 1 + end + + def withdraw(amount) + if @balance < amount + 1 + raise ArgumentError.new("Insufficient funds") + end + @balance = super(amount + 1) + end + + def withdraw_using_check(amount) + + if amount < 0 + raise ArgumentError.new("withdrawal can't be negative number.") + end + + if @balance - amount < -10 + raise ArgumentError.new ("Negative balance cannot exceed -$10") + end + if @check_count > 3 + @balance -= (amount + 2) + @check_count += 1 + elsif + @balance -= amount + @check_count += 1 + return @balance + end + end + + def reset_checks + return @check_count = 1 + end + + end +end diff --git a/lib/savings_account.rb b/lib/savings_account.rb new file mode 100644 index 00000000..97f07407 --- /dev/null +++ b/lib/savings_account.rb @@ -0,0 +1,28 @@ +require_relative 'account' + +module Bank + class SavingsAccount < Account + attr_reader :interest + def initialize(id, balance, open_date = "1999-03-27 11:30:09 -0800") + super(id, balance, open_date) + raise ArgumentError.new("balance must be >= 10") if balance < 10 + end + + def withdraw(amount) + if @balance - amount - 2 < 10.0 + raise ArgumentError.new("Withdrawal amount requested will bring balance below $10.00") + end + @balance = super(amount + 2) + return @balance + end + + def add_interest(rate) + if rate < 0 + raise ArgumentError.new("Interest rate cannot be negative value.") + end + 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..f94b9bf3 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -67,7 +67,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 +136,70 @@ 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 + Bank::Account.all.must_be_instance_of Array, "This is not an array" end - end - describe "Account.find" do - it "Returns an account that exists" do - # TODO: Your test code here! + it "Everything in the array is an Account" do + Bank::Account.all.each do |account| + if account.class != Bank::Account + puts "These are not accounts" + else + puts "These are accounts" + end + end + end + + it "The number of accounts is correct" do + Bank::Account.all.length.must_equal 12 + end + + it "The ID and balance of the first and last accounts match what's in the CSV file." do + accounts_array = Bank::Account.all + accounts_array[0].id.must_equal(1212) + accounts_array[0].balance.must_equal(1235667) + + accounts_array[11].id.must_equal(15156) + accounts_array[11].balance.must_equal(4356772) + end + end +end - it "Can find the first account from the CSV" do - # TODO: Your test code here! +describe "Account.find" do + it "Returns an account that exists" do + if Bank::Account.all[6].id == 15151 + Bank::Account.find(15151).balance.must_equal 9844567 + puts "Account found" + else + raise ArgumentError.new('Account not found') end + 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 + if Bank::Account.all[0].id == 1212 + Bank::Account.find(1212).open_date.must_equal "1999-03-27 11:30:09 -0800" + puts "First Account found" + else + raise ArgumentError.new('First Account not found') end + end - it "Raises an error for an account that doesn't exist" do - # TODO: Your test code here! + it "Can find the last account from the CSV" do + if Bank::Account.all[-1].id == 15156 + Bank::Account.find(15156).open_date.must_equal "1994-11-17 14:04:56 -0800" + puts "Last Account found" + else + raise ArgumentError.new('Last Account not found') end end + + it "Raises an error for an account that doesn't exist" do + proc { + Bank::Account.find(54321) + }.must_raise ArgumentError + end end diff --git a/specs/checking_account_spec.rb b/specs/checking_account_spec.rb index 7f95339e..3d8a1384 100644 --- a/specs/checking_account_spec.rb +++ b/specs/checking_account_spec.rb @@ -1,9 +1,10 @@ require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new # TODO: uncomment the next line once you start wave 3 and add lib/checking_account.rb -# require_relative '../lib/checking_account' +require_relative '../lib/checking_account' # Because a CheckingAccount is a kind # of Account, and we've already tested a bunch of functionality @@ -11,7 +12,7 @@ # 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 @@ -22,59 +23,122 @@ describe "#withdraw" do it "Applies a $1 fee each time" do - # TODO: Your test code here! + account = Bank::CheckingAccount.new(12345, 100.0) + account.withdraw(10) + account.balance.must_equal 89 end it "Doesn't modify the balance if the fee would put it negative" do - # TODO: Your test code here! + # skip + account = Bank::CheckingAccount.new(12345, 100.0) + proc { + account.withdraw(100) + }.must_raise ArgumentError end end describe "#withdraw_using_check" do it "Reduces the balance" do - # TODO: Your test code here! + # skip + account = Bank::CheckingAccount.new(12345, 100.0) + account.withdraw_using_check(50) + account.balance.must_equal 50 end it "Returns the modified balance" do - # TODO: Your test code here! + # skip + account = Bank::CheckingAccount.new(12345, 100.0) + new_balance = account.withdraw_using_check(50) + new_balance.must_equal 50 end it "Allows the balance to go down to -$10" do - # TODO: Your test code here! + # skip + account = Bank::CheckingAccount.new(12345, 100.0) + neg_balance = account.withdraw_using_check(110) + neg_balance.must_equal -10 end it "Outputs a warning if the account would go below -$10" do - # TODO: Your test code here! + # skip + account = Bank::CheckingAccount.new(12345, 100.0) + proc { + account.withdraw_using_check(111) + }.must_raise ArgumentError end it "Doesn't modify the balance if the account would go below -$10" do - # TODO: Your test code here! + # skip + account = Bank::CheckingAccount.new(12345, 100) + proc { + account.withdraw_using_check(111) + }.must_raise ArgumentError + account.balance.must_equal 100 + end it "Requires a positive withdrawal amount" do - # TODO: Your test code here! + # skip + account = Bank::CheckingAccount.new(12345, 100) + proc { + account.withdraw_using_check(-25) + }.must_raise ArgumentError + account.balance.must_equal 100 end it "Allows 3 free uses" do - # TODO: Your test code here! + # skip + account = Bank::CheckingAccount.new(12345, 100) + 3.times do + account.withdraw_using_check(10) + end + account.balance.must_equal 70 end it "Applies a $2 fee after the third use" do - # TODO: Your test code here! + # skip + account = Bank::CheckingAccount.new(12345, 100) + 4.times do + account.withdraw_using_check(10) + end + account.balance.must_equal 58 end end describe "#reset_checks" do it "Can be called without error" do - # TODO: Your test code here! + # skip + account = Bank::CheckingAccount.new(12345, 100) + proc { + account.reset_checks + }.must_be_silent end it "Makes the next three checks free if less than 3 checks had been used" do - # TODO: Your test code here! + # skip + account = Bank::CheckingAccount.new(12345, 100) + 2.times do + account.withdraw_using_check(10) + end + account.reset_checks + 3.times do + account.withdraw_using_check(10) + end + 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! + # skip + account = Bank::CheckingAccount.new(12345, 100) + 4.times do + account.withdraw_using_check(10) + end + account.balance.must_equal 58 + account.reset_checks + 3.times do + account.withdraw_using_check(10) + end + account.balance.must_equal 28 end end end diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index 3f4d1e4a..708e6f47 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -1,9 +1,10 @@ require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new # 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 @@ -11,7 +12,7 @@ # 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 +21,69 @@ end it "Requires an initial balance of at least $10" do - # TODO: Your test code here! + # skip + proc { + account = Bank::SavingsAccount.new(12345, 5.0) + }.must_raise ArgumentError end end describe "#withdraw" do it "Applies a $2 fee each time" do - # TODO: Your test code here! + # skip + account = Bank::SavingsAccount.new(12345, 100.0) + account.withdraw(5).must_equal 95 - 2 + end it "Outputs a warning if the balance would go below $10" do - # TODO: Your test code here! + # skip + + proc { + account = Bank::SavingsAccount.new(12345, 20.0) + account.withdraw(15) + }.must_raise ArgumentError end it "Doesn't modify the balance if it would go below $10" do - # TODO: Your test code here! + # skip + account = Bank::SavingsAccount.new(12345, 20.0) + proc { + account.withdraw(15) + }.must_raise ArgumentError + account.balance.must_equal 20 end it "Doesn't modify the balance if the fee would put it below $10" do - # TODO: Your test code here! + # skip + account = Bank::SavingsAccount.new(12345, 20.0) + proc { + account.withdraw(9) + }.must_raise ArgumentError + account.balance.must_equal 20 end end describe "#add_interest" do it "Returns the interest calculated" do - # TODO: Your test code here! + # skip + account = Bank::SavingsAccount.new(12345, 10000.0) + account.add_interest(0.25).must_equal 25 end it "Updates the balance with calculated interest" do - # TODO: Your test code here! + # skip + account = Bank::SavingsAccount.new(12345, 10000.0) + account.add_interest(0.25) + account.balance.must_equal 10025 end it "Requires a positive rate" do - # TODO: Your test code here! + # skip + account = Bank::SavingsAccount.new(12345, 10000.0) + proc { + account.add_interest(-25) + }.must_raise ArgumentError end end end