diff --git a/lib/account.rb b/lib/account.rb index e69de29b..8f1f080f 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -0,0 +1,56 @@ +require 'csv' + +module Bank + class Account + attr_reader :id, :balance + def initialize(id, balance) + raise ArgumentError.new("balance must be >= 0") if balance < 0 + @id = id + @balance = balance + end + + def withdraw(amount) + raise ArgumentError.new("withdrawal amount must be >= 0") if amount < 0 + if amount > @balance + raise ArgumentError.new("withdrawal amount must be > 0") if @balance < 0 + puts "Account would go negative." + elsif amount <= @balance + @balance = @balance - amount + end + return @balance + end + + def deposit(amount) + raise ArgumentError.new("deposit amount must be >= 0") if amount < 0 + @balance = @balance + amount + return @balance + end + + def self.all + accounts_array = [] + + read_file = CSV.read('support/accounts.csv') + + read_file.each do |line| + id = line[0].to_i + balance = line[1].to_i + account = Bank::Account.new(id, balance) + accounts_array << account + end + + return accounts_array + end + + def self.find(id) + accounts = Bank::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..fd9c2734 --- /dev/null +++ b/lib/checking_account.rb @@ -0,0 +1,75 @@ +require_relative './account' +require 'csv' + +module Bank + class MoneyMarketAccount < Bank::Account + def initialize(id, balance) + super(id, balance) + @counter = 0 + end + + def withdraw(amount) + amount += 1 + + if (@balance - amount) < 0 + return @balance + raise ArgumentError.new("account must be > 0") if (@balance - amount) < 0 + else + @balance = @balance - amount + return @balance + end + end + + #Note: In the video for Wave 3 it was mentioned that we could + #forgo counting by month. I did not account for the month. + def withdraw_using_check(amount) + # @counter = 0 + fee = 2 + test_balance = @balance - amount + raise ArgumentError.new("needs a positive withdrawal amount") if amount < 0 + + if @counter <= 3 && test_balance < -10 + return @balance + raise ArgumentError.new("account will go below -10") if (@balance - amount) < -10 + elsif @counter <= 3 && test_balance >= -10 + @balance = @balance - amount + return @balance + @counter += 1 + elsif @counter > 3 && test_balance >= -10 + @balance = @balance - amount - fee + @counter += 1 + elsif @counter > 3 && test_balance < -10 + raise ArgumentError.new("account will go below -10") if (@balance - amount) < -10 + return @balance + end + end + + end +end + +test_1 = Bank::MoneyMarketAccount.new(666, 100) +# puts test_1.withdraw_using_check(2) + + +4.times do + # test_1.withdraw_using_check(2) + puts test_1.withdraw_using_check(2) + puts @counter.class +end + + + +# if @counter <= 3 && test_balance < -10 +# return @balance +# raise ArgumentError.new("account will go below -10") if (@balance - amount) < -10 +# elsif @counter <= 3 && test_balance >= -10 +# @balance = @balance - amount +# return @balance +# @counter += 1 +# elsif @counter > 3 && test_balance >= -10 +# @balance = @balance - amount - fee +# @counter += 1 +# elsif @counter > 3 && test_balance < -10 +# raise ArgumentError.new("account will go below -10") if (@balance - amount) < -10 +# return @balance +# end diff --git a/lib/savings_account.rb b/lib/savings_account.rb new file mode 100644 index 00000000..e3b83d93 --- /dev/null +++ b/lib/savings_account.rb @@ -0,0 +1,38 @@ +require_relative './account' +require 'csv' + +module Bank + class SavingsAccount < Bank::Account + def initialize(id, balance) + super(id, balance) + raise ArgumentError.new("balance must be > 10") if balance < 10 + @interest = 0 + end + + def withdraw(amount) + amount += 2 + + if (@balance - amount) < 10 + return @balance + raise ArgumentError.new("account must be > 10") if (@balance - amount) < 10 + else + @balance = @balance - amount + return @balance + end + end + + def add_interest(rate) + raise ArgumentError.new("interest must be > 0") if rate < 0 + + @interest = @balance * (rate / 100) + + @balance = @balance + @interest + return @interest + end + + end +end + +# test_1 = Bank::SavingsAccount.new(666, 10_000) +# puts test_1.withdraw(2) +# puts test_1.add_interest(0.25) diff --git a/specs/account_spec.rb b/specs/account_spec.rb index 6c399139..d84d7f0f 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -1,8 +1,11 @@ +require 'csv' require 'minitest/autorun' require 'minitest/reporters' 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 @@ -18,10 +21,6 @@ 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 @@ -61,10 +60,6 @@ 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 /.+/ @@ -77,8 +72,6 @@ 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 @@ -136,36 +129,73 @@ end end -# TODO: change 'xdescribe' to 'describe' to run these tests -xdescribe "Wave 2" do +describe "Wave 2" do describe "Account.all" do + + before do + @accounts = Bank::Account.all + end + 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 + @accounts.must_be_instance_of Array + end + it "Everything in the array is an Account" do + @accounts.each do |account| + account.must_be_instance_of Bank::Account + end + end + it "Number of accounts is correct" do + @accounts.length.must_equal 12 + end + + it "Match elements in file" do + CSV.read('support/accounts.csv') do |line| + counter = 0 + @accounts[counter].id.must_equal line[0].to_i + @accounts[counter].balance.must_equal line[1].to_i + counter += 1 + end end - end + + it "ID and balance match the first and last element" do + @accounts.first.id.must_equal 1212 + @accounts.first.balance.must_equal 1235667 + + @accounts.last.id.must_equal 15156 + @accounts.last.balance.must_equal 4356772 + end + end + describe "Account.find" do it "Returns an account that exists" do - # TODO: Your test code here! + account = Bank::Account.find(1216) + + account.must_be_instance_of Bank::Account + account.id.must_equal 1216 + account.balance.must_equal 100022 end it "Can find the first account from the CSV" do - # TODO: Your test code here! + account = Bank::Account.find(1212) + + account.must_be_instance_of Bank::Account + account.id.must_equal 1212 + account.balance.must_equal 1235667 end it "Can find the last account from the CSV" do - # TODO: Your test code here! + account = Bank::Account.find(15156) + + account.must_be_instance_of Bank::Account + account.id.must_equal 15156 + account.balance.must_equal 4356772 end it "Raises an error for an account that doesn't exist" do - # TODO: Your test code here! + proc { + Bank::Account.find(666) + }.must_raise ArgumentError end end end diff --git a/specs/checking_account_spec.rb b/specs/checking_account_spec.rb index 7f95339e..c32f6ad8 100644 --- a/specs/checking_account_spec.rb +++ b/specs/checking_account_spec.rb @@ -3,7 +3,7 @@ require 'minitest/skip_dsl' # 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,69 +11,152 @@ # 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) + # skip + account = Bank::MoneyMarketAccount.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! + # skip + start_balance = 100.0 + withdraw_amount = 50.0 + account = Bank::MoneyMarketAccount.new(666, start_balance) + + account.withdraw(withdraw_amount) + + expected_balance = start_balance - withdraw_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! + it "Doesn't modify the balance if the fee would put negative" do + # skip + start_balance = 10.0 + withdraw_amount = 10.0 + account = Bank::MoneyMarketAccount.new(666, start_balance) + + account.withdraw(withdraw_amount) + + expected_balance = start_balance - withdraw_amount - 1 + account.balance.must_equal start_balance end end describe "#withdraw_using_check" do it "Reduces the balance" do - # TODO: Your test code here! + # skip + start_balance = 100.0 + check_withdraw_amount = 50.0 + account = Bank::MoneyMarketAccount.new(666, start_balance) + + account.withdraw_using_check(check_withdraw_amount) + + expected_balance = start_balance - check_withdraw_amount + account.balance.must_equal expected_balance end it "Returns the modified balance" do - # TODO: Your test code here! + # skip + start_balance = 100.0 + check_withdraw_amount = 50.0 + account = Bank::MoneyMarketAccount.new(666, start_balance) + + account.withdraw_using_check(check_withdraw_amount) + + expected_balance = start_balance - check_withdraw_amount + account.balance.must_equal expected_balance end it "Allows the balance to go down to -$10" do - # TODO: Your test code here! + # skip + start_balance = 100.0 + check_withdraw_amount = 110.0 + account = Bank::MoneyMarketAccount.new(666, start_balance) + + account.withdraw_using_check(check_withdraw_amount) + + expected_balance = start_balance - check_withdraw_amount + account.balance.must_equal expected_balance end it "Outputs a warning if the account would go below -$10" do - # TODO: Your test code here! + # skip + proc { + Bank::MoneyMarketAccount.new(666, -11) + }.must_raise ArgumentError end it "Doesn't modify the balance if the account would go below -$10" do - # TODO: Your test code here! + # skip + start_balance = 100.0 + check_withdraw_amount = 111.0 + account = Bank::MoneyMarketAccount.new(666, start_balance) + + account.withdraw_using_check(check_withdraw_amount) + + # expected_balance = start_balance - check_withdraw_amount + account.balance.must_equal start_balance end it "Requires a positive withdrawal amount" do - # TODO: Your test code here! + # skip + start_balance = 100.0 + withdrawal_amount = -50.0 + account = Bank::MoneyMarketAccount.new(666, start_balance) + + proc { + account.withdraw_using_check(withdrawal_amount) + }.must_raise ArgumentError end it "Allows 3 free uses" do - # TODO: Your test code here! + # skip + start_balance = 100.0 + withdrawal_amount = 2.0 + account = Bank::MoneyMarketAccount.new(666, start_balance) + + 3.times do + account.withdraw_using_check(withdrawal_amount) + end + + expected_balance = start_balance - (3 * withdrawal_amount) + + account.balance.must_equal expected_balance end it "Applies a $2 fee after the third use" do - # TODO: Your test code here! + skip + start_balance = 100.0 + withdrawal_amount = 2.0 + account = Bank::MoneyMarketAccount.new(666, start_balance) + + 4.times do + account.withdraw_using_check(withdrawal_amount) + end + + expected_balance = (start_balance - (4 * withdrawal_amount)) - 2 + + account.balance.must_equal expected_balance end end describe "#reset_checks" do it "Can be called without error" do + skip # TODO: Your test code here! end it "Makes the next three checks free if less than 3 checks had been used" do + skip # TODO: Your test code here! end it "Makes the next three checks free if more than 3 checks had been used" do + skip # TODO: Your test code here! end end diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index 3f4d1e4a..d3eff72a 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -3,7 +3,7 @@ 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 @@ -11,48 +11,106 @@ # 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 + # skip # Check that a SavingsAccount is in fact a kind of account - account = Bank::SavingsAccount.new(12345, 100.0) + account = Bank::SavingsAccount.new(666, 100.0) account.must_be_kind_of Bank::Account end it "Requires an initial balance of at least $10" do - # TODO: Your test code here! + # skip + proc { + Bank::SavingsAccount.new(666, 1) + }.must_raise ArgumentError end end describe "#withdraw" do it "Applies a $2 fee each time" do - # TODO: Your test code here! + # skip + start_balance = 100.0 + withdraw_amount = 50.0 + account = Bank::SavingsAccount.new(666, start_balance) + + account.withdraw(withdraw_amount) + + expected_balance = start_balance - withdraw_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! + # skip + proc { + Bank::SavingsAccount.new(666, 1) + }.must_raise ArgumentError end it "Doesn't modify the balance if it would go below $10" do - # TODO: Your test code here! + # skip + start_balance = 20 + withdraw_amount = 21 + account = Bank::SavingsAccount.new(666, start_balance) + + account.withdraw(withdraw_amount) + + 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! + skip + start_balance = 11 + withdraw_amount = 2 + account = Bank::SavingsAccount.new(666, start_balance) + + account.withdraw(withdraw_amount) + + account.balance.must_equal start_balance end end describe "#add_interest" do it "Returns the interest calculated" do - # TODO: Your test code here! + # skip + start_balance = 100.0 + withdraw_amount = 25.0 + interest_rate = 0.25 + account = Bank::SavingsAccount.new(666, start_balance) + + account.add_interest(interest_rate) + + expected_interest = start_balance + (interest_rate / 100.0) + account.interest.must_equal expected_interest end it "Updates the balance with calculated interest" do - # TODO: Your test code here! + # skip + start_balance = 100 + withdraw_amount = 25.0 + interest_rate = 0.25 + account = Bank::SavingsAccount.new(666, start_balance) + + account.add_interest(interest_rate) + + expected_balance = start_balance + (start_balance * (interest_rate / 100.0)) + account.balance.must_equal expected_balance end - it "Requires a positive rate" do - # TODO: Your test code here! + #This test wasn't mentioned in the requirements so I wasn't + #sure what y'all were looking for. + it "Requires a positive interest rate" do + # skip + start_balance = 100 + withdraw_amount = 25.0 + interest_rate = -0.25 + account = Bank::SavingsAccount.new(666, start_balance) + + proc { + account.add_interest(interest_rate) + }.must_raise ArgumentError + end end end diff --git a/support/account.csv b/support/account.csv new file mode 100644 index 00000000..e69de29b