From ad56ad4950f3fd4e0c7d62d1b808066123df7f48 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Tue, 21 Feb 2017 15:16:25 -0800 Subject: [PATCH 01/22] Initial set up of Account class --- lib/account.rb | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/lib/account.rb b/lib/account.rb index e69de29b..f5f2aca3 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -0,0 +1,39 @@ +# Bank module contains Account class and any future bank account logic. +module Bank + class Account + # allows access to the current balance of an account at any time. + attr_accessor :account_balance + # only allow reader on unique account id + attr_reader :id + + # constructs a new Account object + def initialize(id, initial_balance) + # error handling for initial negative balance + if initial_balance >= 0 + @account_balance = initial_balance + else + raise ArgumentError.new "Inital balance cannot be a negetive value" + end + @id = id + + end + + # method that handles withdraw + def withdraw(money_amount) + # error handling for insufficient funds for a withdraw + if @account_balance >= money_amount + @account_balance -= money_amount + else + raise ArgumentError.new "You do not have sufficient funds to withdraw the entered amount" + end + return @account_balance + end + + # method that handles deposits + def deposit(money_amount) + @account_balance += money_amount + return @account_balance + end + + end +end From c1499be5b6951d207beb495db62eb926901f6b4e Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Tue, 21 Feb 2017 22:01:51 -0800 Subject: [PATCH 02/22] WIP: added owner class and added few tests for it --- lib/account.rb | 36 ++++++++++++++++++++++++++---------- lib/owner.rb | 21 +++++++++++++++++++++ specs/account_spec.rb | 38 +++++++++++++++++++++++++++++++++----- 3 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 lib/owner.rb diff --git a/lib/account.rb b/lib/account.rb index f5f2aca3..479d8e93 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -2,38 +2,54 @@ module Bank class Account # allows access to the current balance of an account at any time. - attr_accessor :account_balance + attr_accessor :balance, :owner # only allow reader on unique account id attr_reader :id # constructs a new Account object - def initialize(id, initial_balance) + # give a default value, in case the Owner class object is not passed + def initialize id, initial_balance, owner = nil # error handling for initial negative balance if initial_balance >= 0 - @account_balance = initial_balance + @balance = initial_balance else raise ArgumentError.new "Inital balance cannot be a negetive value" end @id = id + #note: in the future, consider account holder with multiple accounts + if owner.class == Bank::Owner + @owner = owner + else + @owner = Bank::Owner.new({name: "", address: {street: "", city: "", zipcode: ""}, phone: "" }) + end + end + + def update_owner_data(owner_hash) + # @owner = Bank::Owner.new(owner_hash) end # method that handles withdraw def withdraw(money_amount) # error handling for insufficient funds for a withdraw - if @account_balance >= money_amount - @account_balance -= money_amount + if @balance < money_amount + puts "You do not have sufficient funds to withdraw the entered amount" + elsif money_amount < 0 + raise ArgumentError.new "Withdraw amount cannot be a negetive value" else - raise ArgumentError.new "You do not have sufficient funds to withdraw the entered amount" + @balance -= money_amount end - return @account_balance + return @balance end # method that handles deposits def deposit(money_amount) - @account_balance += money_amount - return @account_balance + if money_amount < 0 + raise ArgumentError.new "Deposit amount cannot be a negetive value" + else + @balance += money_amount + return @balance + end end - end end diff --git a/lib/owner.rb b/lib/owner.rb new file mode 100644 index 00000000..2d0ea9a5 --- /dev/null +++ b/lib/owner.rb @@ -0,0 +1,21 @@ +module Bank + class Owner + attr_reader :customer_id, :first_name, :last_name, :street, :city, :zipcode, :address, :phone + def initialize owner_hash + # assumes that owner_hash structure is + # {customer_id: + name: "ginny smith", address => {street: "122 main st.", city: "seattle", zipcode: "98144"}, phone: "2065573099" } + # if owner_hash.class != Hash + # raise ArgumentError.new "Erroneous argument used for the constructor" + # else + @name = owner_hash[:name] + # @street = owner_hash[:address][:street] + # @city = owner_hash[:address][:city] + # @zipcode = owner_hash[:address][:zipcode] + # @address = { street: @street, city: @city, zipcode: @zipcode } + @address = owner_hash[:address] + @phone = owner_hash[:phone] + #end + end + end +end diff --git a/specs/account_spec.rb b/specs/account_spec.rb index 6c399139..1ef93d61 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -2,6 +2,9 @@ require 'minitest/reporters' require 'minitest/skip_dsl' require_relative '../lib/account' +require_relative '../lib/owner' + + describe "Wave 1" do describe "Account#initialize" do @@ -134,12 +137,37 @@ }.must_raise ArgumentError end end + + describe "Owner#added property to Account" do + it "Initializes account without owner property" do + id = 1337 + balance = 100.0 + owner = nil + account = Bank::Account.new(id, balance, owner) + + account.must_respond_to :owner + account.owner.class.must_equal Bank::Owner + end + + it "Initializes account with owner property" do + id = 1337 + balance = 100.0 + owner_hash = {name: "ginny smith", address: {street: "122 main st.", city: "seattle", zipcode: "98144"}, phone: "2065573099" } + owner = Bank::Owner.new(owner_hash) + account = Bank::Account.new(id, balance, owner) + + account.must_respond_to :owner + account.owner.class.must_equal Bank::Owner + end + + + 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 + it "Returns an array of all accounts" do skip # TODO: Your test code here! # Useful checks might include: # - Account.all returns an array @@ -152,19 +180,19 @@ end describe "Account.find" do - it "Returns an account that exists" do + it "Returns an account that exists" do skip # TODO: Your test code here! end - it "Can find the first account from the CSV" do + it "Can find the first account from the CSV" do skip # TODO: Your test code here! end - it "Can find the last account from the CSV" do + it "Can find the last account from the CSV" do skip # TODO: Your test code here! end - it "Raises an error for an account that doesn't exist" do + it "Raises an error for an account that doesn't exist" do skip # TODO: Your test code here! end end From ea721dc61a159c4496e2840569bf302a909b2d95 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Tue, 21 Feb 2017 22:26:36 -0800 Subject: [PATCH 03/22] Reduced the number of attributes in Owner class --- lib/owner.rb | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/lib/owner.rb b/lib/owner.rb index 2d0ea9a5..f7214430 100644 --- a/lib/owner.rb +++ b/lib/owner.rb @@ -1,21 +1,13 @@ module Bank class Owner - attr_reader :customer_id, :first_name, :last_name, :street, :city, :zipcode, :address, :phone + attr_reader :customer_id, :name, :address, :phone def initialize owner_hash # assumes that owner_hash structure is - # {customer_id: - name: "ginny smith", address => {street: "122 main st.", city: "seattle", zipcode: "98144"}, phone: "2065573099" } - # if owner_hash.class != Hash - # raise ArgumentError.new "Erroneous argument used for the constructor" - # else - @name = owner_hash[:name] - # @street = owner_hash[:address][:street] - # @city = owner_hash[:address][:city] - # @zipcode = owner_hash[:address][:zipcode] - # @address = { street: @street, city: @city, zipcode: @zipcode } - @address = owner_hash[:address] + # { customer_id: 1024, first_name: "ginny", last_name: "smith", address => {street: "123 main street", city: "seattle", state: "WA", zipcode: "12345"}, phone: "2065573099" } + @customer_id = owner_hash[:customer_id] + @name = "#{owner_hash[:first_name]} #{owner_hash[:last_name]}" + @address = "#{owner_hash[:address][:street]}, #{owner_hash[:address][:city]}, #{owner_hash[:address][:state]} #{owner_hash[:address][:zipcode]}" @phone = owner_hash[:phone] - #end end end end From f0cfdac877d7c71455c4431987017340d3e6411a Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Tue, 21 Feb 2017 23:26:33 -0800 Subject: [PATCH 04/22] Handles empty hash passed to the construtor --- lib/owner.rb | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/owner.rb b/lib/owner.rb index f7214430..3750d5d6 100644 --- a/lib/owner.rb +++ b/lib/owner.rb @@ -1,13 +1,18 @@ module Bank class Owner - attr_reader :customer_id, :name, :address, :phone - def initialize owner_hash - # assumes that owner_hash structure is - # { customer_id: 1024, first_name: "ginny", last_name: "smith", address => {street: "123 main street", city: "seattle", state: "WA", zipcode: "12345"}, phone: "2065573099" } - @customer_id = owner_hash[:customer_id] - @name = "#{owner_hash[:first_name]} #{owner_hash[:last_name]}" - @address = "#{owner_hash[:address][:street]}, #{owner_hash[:address][:city]}, #{owner_hash[:address][:state]} #{owner_hash[:address][:zipcode]}" - @phone = owner_hash[:phone] + attr_reader :customer_id + attr_accessor :name, :address, :phone + def initialize owner_hash = {} + if owner_hash != {} + # assumes that owner_hash structure is + # { customer_id: 1024, first_name: "ginny", last_name: "smith", address: {street: "123 main street", city: "seattle", state: "WA", zipcode: "12345"}, phone: "2065573099" } + @customer_id = owner_hash[:customer_id] + @name = "#{owner_hash[:first_name]} #{owner_hash[:last_name]}" + @address = "#{owner_hash[:address][:street]}, #{owner_hash[:address][:city]}, #{owner_hash[:address][:state]} #{owner_hash[:address][:zipcode]}" + @phone = owner_hash[:phone] + else + @customer_id = "0000" + end end end end From 83f1639404cf3feb0557a55a7ff80b3f7f4d8a1d Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Tue, 21 Feb 2017 23:30:11 -0800 Subject: [PATCH 05/22] Worked out updating account owner data --- lib/account.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/account.rb b/lib/account.rb index 479d8e93..0568c2df 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -21,12 +21,18 @@ def initialize id, initial_balance, owner = nil if owner.class == Bank::Owner @owner = owner else - @owner = Bank::Owner.new({name: "", address: {street: "", city: "", zipcode: ""}, phone: "" }) + @owner = Bank::Owner.new({}) end end + # method that overwrites existing empty @owner instance variable def update_owner_data(owner_hash) - # @owner = Bank::Owner.new(owner_hash) + #only overwrite if initially not added to account at the time of initializing account object + #note: in the future, consider being able to update names, addess, phone numbers + # individually for existing @owner + if @owner.customer_id == "0000" + @owner = Bank::Owner.new(owner_hash) + end end # method that handles withdraw From b1fdd0f76f6884b54c2fc6450938f327b387d207 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Tue, 21 Feb 2017 23:32:07 -0800 Subject: [PATCH 06/22] Added tests for the added owner property --- specs/account_spec.rb | 55 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/specs/account_spec.rb b/specs/account_spec.rb index 1ef93d61..d922b2d5 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -152,7 +152,18 @@ it "Initializes account with owner property" do id = 1337 balance = 100.0 - owner_hash = {name: "ginny smith", address: {street: "122 main st.", city: "seattle", zipcode: "98144"}, phone: "2065573099" } + owner_hash = { + customer_id: 1024, + first_name: "ginny", + last_name: "smith", + address: { + street: "123 main street", + city: "seattle", + state: "WA", + zipcode: "12345" + }, + phone: "2065573099" + } owner = Bank::Owner.new(owner_hash) account = Bank::Account.new(id, balance, owner) @@ -160,7 +171,47 @@ account.owner.class.must_equal Bank::Owner end - + it "Only accounts without initial owner property can be updated" do + owner_hash = { + customer_id: 1024, + first_name: "ginny", + last_name: "smith", + address: { + street: "123 main street", + city: "seattle", + state: "WA", + zipcode: "12345" + }, + phone: "2065573099" + } + test_hash = { + customer_id: 8888, + first_name: "sally", + last_name: "smith", + address: { + street: "456 1st street", + city: "columbus", + state: "OH", + zipcode: "54322" + }, + phone: "2234433099" + } + account_nil = Bank::Account.new(12345, 12, nil) + account = Bank::Account.new(12346, 0, Bank::Owner.new(test_hash)) + + account_nil.update_owner_data(owner_hash) + account.update_owner_data(owner_hash) + + account_nil.owner.customer_id.must_equal 1024 + account_nil.owner.name.must_equal "ginny smith" + account_nil.owner.phone.must_equal "2065573099" + account_nil.owner.address.must_equal "123 main street, seattle, WA 12345" + + account.owner.customer_id.must_equal 8888 + account.owner.name.must_equal "sally smith" + account.owner.phone.must_equal "2234433099" + account.owner.address.must_equal "456 1st street, columbus, OH 54322" + end end end From acf6fa0f878a936c6d5622ae80ced6c765838818 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Wed, 22 Feb 2017 22:35:17 -0800 Subject: [PATCH 07/22] Added test for .self.all class method --- specs/account_spec.rb | 70 +++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/specs/account_spec.rb b/specs/account_spec.rb index d922b2d5..e52fe8e4 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -11,28 +11,28 @@ it "Takes an ID and an initial balance" do id = 1337 balance = 100.0 - account = Bank::Account.new(id, balance) + open_date = "1999-03-27 11:30:09 -0800" + account = Bank::Account.new(id, balance, open_date) account.must_respond_to :id account.id.must_equal id account.must_respond_to :balance account.balance.must_equal balance + + account.must_respond_to :open_date + account.open_date.must_equal DateTime.parse(open_date) 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) + Bank::Account.new(1337, -100.0, "1999-03-27 11:30:09 -0800") }.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) + Bank::Account.new(1337, 0, "1999-03-27 11:30:09 -0800") end end @@ -40,7 +40,7 @@ it "Reduces the balance" do start_balance = 100.0 withdrawal_amount = 25.0 - account = Bank::Account.new(1337, start_balance) + account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") account.withdraw(withdrawal_amount) @@ -51,7 +51,7 @@ it "Returns the modified balance" do start_balance = 100.0 withdrawal_amount = 25.0 - account = Bank::Account.new(1337, start_balance) + account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") updated_balance = account.withdraw(withdrawal_amount) @@ -62,7 +62,7 @@ it "Outputs a warning if the account would go negative" do start_balance = 100.0 withdrawal_amount = 200.0 - account = Bank::Account.new(1337, start_balance) + account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") # Another proc! This test expects something to be printed # to the terminal, using 'must_output'. /.+/ is a regular @@ -76,7 +76,7 @@ it "Doesn't modify the balance if the account would go negative" do start_balance = 100.0 withdrawal_amount = 200.0 - account = Bank::Account.new(1337, start_balance) + account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") updated_balance = account.withdraw(withdrawal_amount) @@ -87,7 +87,7 @@ end it "Allows the balance to go to 0" do - account = Bank::Account.new(1337, 100.0) + account = Bank::Account.new(1337, 100.0, "1999-03-27 11:30:09 -0800") updated_balance = account.withdraw(account.balance) updated_balance.must_equal 0 account.balance.must_equal 0 @@ -96,7 +96,7 @@ it "Requires a positive withdrawal amount" do start_balance = 100.0 withdrawal_amount = -25.0 - account = Bank::Account.new(1337, start_balance) + account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") proc { account.withdraw(withdrawal_amount) @@ -108,7 +108,7 @@ it "Increases the balance" do start_balance = 100.0 deposit_amount = 25.0 - account = Bank::Account.new(1337, start_balance) + account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") account.deposit(deposit_amount) @@ -119,7 +119,7 @@ it "Returns the modified balance" do start_balance = 100.0 deposit_amount = 25.0 - account = Bank::Account.new(1337, start_balance) + account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") updated_balance = account.deposit(deposit_amount) @@ -130,7 +130,7 @@ it "Requires a positive deposit amount" do start_balance = 100.0 deposit_amount = -25.0 - account = Bank::Account.new(1337, start_balance) + account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") proc { account.deposit(deposit_amount) @@ -143,7 +143,7 @@ id = 1337 balance = 100.0 owner = nil - account = Bank::Account.new(id, balance, owner) + account = Bank::Account.new(id, balance, "1999-03-27 11:30:09 -0800", owner) account.must_respond_to :owner account.owner.class.must_equal Bank::Owner @@ -152,6 +152,7 @@ it "Initializes account with owner property" do id = 1337 balance = 100.0 + open_date = "1999-03-27 11:30:09 -0800" owner_hash = { customer_id: 1024, first_name: "ginny", @@ -165,7 +166,7 @@ phone: "2065573099" } owner = Bank::Owner.new(owner_hash) - account = Bank::Account.new(id, balance, owner) + account = Bank::Account.new(id, balance, open_date, owner) account.must_respond_to :owner account.owner.class.must_equal Bank::Owner @@ -196,8 +197,8 @@ }, phone: "2234433099" } - account_nil = Bank::Account.new(12345, 12, nil) - account = Bank::Account.new(12346, 0, Bank::Owner.new(test_hash)) + account_nil = Bank::Account.new(12345, 12, "1999-03-27 11:30:09 -0800") + account = Bank::Account.new(12346, 0, "1999-03-27 11:30:09 -0800", Bank::Owner.new(test_hash)) account_nil.update_owner_data(owner_hash) account.update_owner_data(owner_hash) @@ -216,16 +217,27 @@ 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 skip - # 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 + it "Returns an array of all accounts" do + # TODO + # everything in the array is an Account + all_array = Bank::Account.all + + all_array.each do |account| + account.class.must_equal Bank::Account + end + # the number of accounts is correct + all_array.length.must_equal 12 + + # the ID and balance of the first and last accounts match what's in the CSV file + all_array[0].id.must_equal 1212 + all_array[0].balance.must_equal 1235667 + all_array[0].open_date.must_equal DateTime.parse("1999-03-27 11:30:09 -0800") + all_array[-1].id.must_equal 15156 + all_array[-1].balance.must_equal 4356772 + all_array[-1].open_date.must_equal DateTime.parse("1994-11-17 14:04:56 -0800") + # Feel free to split this into multiple tests if needed end end From 9c0b3b76bdb77a4e393219b7208932c6422b4ee9 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Wed, 22 Feb 2017 22:37:31 -0800 Subject: [PATCH 08/22] updated Account class attributes --- lib/account.rb | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/lib/account.rb b/lib/account.rb index 0568c2df..ad88bbd1 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -1,22 +1,25 @@ +require 'csv' +require 'date' + # Bank module contains Account class and any future bank account logic. module Bank class Account # allows access to the current balance of an account at any time. attr_accessor :balance, :owner # only allow reader on unique account id - attr_reader :id + attr_reader :id, :open_date # constructs a new Account object # give a default value, in case the Owner class object is not passed - def initialize id, initial_balance, owner = nil + def initialize id, balance, open_date, owner = nil # error handling for initial negative balance - if initial_balance >= 0 - @balance = initial_balance + if balance >= 0 + @balance = balance else raise ArgumentError.new "Inital balance cannot be a negetive value" end @id = id - + @open_date = DateTime.parse(open_date) #note: in the future, consider account holder with multiple accounts if owner.class == Bank::Owner @owner = owner @@ -25,6 +28,32 @@ def initialize id, initial_balance, owner = nil end end + # method that returns a collection of Account instances, from data read in CSV + def self.all + all_accounts_array= [] + + CSV.read("../support/accounts.csv").each do |line| + all_accounts_array << Bank::Account.new( line[0].to_i, line[1].to_i, line[2] ) + end + + return all_accounts_array + end + + # method that returns an instance of an Account where the value of the id field + # in the CSV matches the passed parameter + def self.find(id) + raise ArgumentError.new ("Account id must be an positive integer value") if ( id.class != Integer || id < 1 ) + + CSV.read("./support/accounts.csv").each do |line| + if line[0].to_i == id + account = Bank::Account.new( line[0], line[1], line[2], nil ) + return account + end + end + raise ArgumentError.new "Account id does not exist in the database" + end + + # method that overwrites existing empty @owner instance variable def update_owner_data(owner_hash) #only overwrite if initially not added to account at the time of initializing account object From 39554cdf50eab0bc2a10be1ddb3364b4c406da93 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Wed, 22 Feb 2017 23:26:06 -0800 Subject: [PATCH 09/22] Working baseline --- lib/account.rb | 5 ++--- lib/owner.rb | 1 + specs/account_spec.rb | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/lib/account.rb b/lib/account.rb index ad88bbd1..6cc6f2fb 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -20,7 +20,6 @@ def initialize id, balance, open_date, owner = nil end @id = id @open_date = DateTime.parse(open_date) - #note: in the future, consider account holder with multiple accounts if owner.class == Bank::Owner @owner = owner else @@ -44,9 +43,9 @@ def self.all def self.find(id) raise ArgumentError.new ("Account id must be an positive integer value") if ( id.class != Integer || id < 1 ) - CSV.read("./support/accounts.csv").each do |line| + CSV.read("../support/accounts.csv").each do |line| if line[0].to_i == id - account = Bank::Account.new( line[0], line[1], line[2], nil ) + account = Bank::Account.new( line[0].to_i, line[1].to_i, line[2].to_s) return account end end diff --git a/lib/owner.rb b/lib/owner.rb index 3750d5d6..270be6f1 100644 --- a/lib/owner.rb +++ b/lib/owner.rb @@ -3,6 +3,7 @@ class Owner attr_reader :customer_id attr_accessor :name, :address, :phone def initialize owner_hash = {} + # assumes that the parameter value is either properly formatted hash or an empty hash if owner_hash != {} # assumes that owner_hash structure is # { customer_id: 1024, first_name: "ginny", last_name: "smith", address: {street: "123 main street", city: "seattle", state: "WA", zipcode: "12345"}, phone: "2065573099" } diff --git a/specs/account_spec.rb b/specs/account_spec.rb index e52fe8e4..1c0e5aa1 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -237,26 +237,52 @@ all_array[-1].id.must_equal 15156 all_array[-1].balance.must_equal 4356772 all_array[-1].open_date.must_equal DateTime.parse("1994-11-17 14:04:56 -0800") - - # Feel free to split this into multiple tests if needed end end describe "Account.find" do - it "Returns an account that exists" do skip + it "Returns an account that exists" do + # TODO: Your test code here! + account = Bank::Account.find(1213) + account.id.must_equal 1213 + account.balance.must_equal 66367 + account.open_date.must_equal DateTime.parse("2010-12-21 12:21:12 -0800") + end + + it "Can find the first account from the CSV" do # TODO: Your test code here! + account = Bank::Account.find(1212) + account.id.must_equal 1212 + account.balance.must_equal 1235667 + account.open_date.must_equal DateTime.parse("1999-03-27 11:30:09 -0800") end - it "Can find the first account from the CSV" do skip + it "Can find the last account from the CSV" do # TODO: Your test code here! + account = Bank::Account.find(15156) + account.id.must_equal 15156 + account.balance.must_equal 4356772 + account.open_date.must_equal DateTime.parse("1994-11-17 14:04:56 -0800") end - it "Can find the last account from the CSV" do skip + it "Raises an error for an account that doesn't exist" do # TODO: Your test code here! + proc { + Bank::Account.find(100233332223003) + }.must_raise ArgumentError end - it "Raises an error for an account that doesn't exist" do skip + it "Raises an error for an invalid input data type" do # TODO: Your test code here! + proc { + Bank::Account.find(0) + }.must_raise ArgumentError + proc { + Bank::Account.find(-1233) + }.must_raise ArgumentError + proc { + Bank::Account.find("happy dog") + }.must_raise ArgumentError end end end From 4787765440124d962beb22a038e415c38afbb2a4 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Thu, 23 Feb 2017 15:21:18 -0800 Subject: [PATCH 10/22] Working wave2 with completed optional and tests --- lib/account.rb | 20 +++-- lib/owner.rb | 89 ++++++++++++++++-- specs/account_spec.rb | 205 ++++++++++++++++++++++++++++++++---------- 3 files changed, 253 insertions(+), 61 deletions(-) diff --git a/lib/account.rb b/lib/account.rb index 6cc6f2fb..9d003ea7 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -20,6 +20,13 @@ def initialize id, balance, open_date, owner = nil end @id = id @open_date = DateTime.parse(open_date) + + CSV.read("support/account_owners.csv").each do |line| + if line[0].to_i == @id + @owner = Bank::Owner.find(line[1].to_i) + end + end + if owner.class == Bank::Owner @owner = owner else @@ -30,8 +37,8 @@ def initialize id, balance, open_date, owner = nil # method that returns a collection of Account instances, from data read in CSV def self.all all_accounts_array= [] - - CSV.read("../support/accounts.csv").each do |line| + #for efficiency, consider setting all_accounts_array to a class variable + CSV.read("support/accounts.csv").each do |line| all_accounts_array << Bank::Account.new( line[0].to_i, line[1].to_i, line[2] ) end @@ -43,9 +50,9 @@ def self.all def self.find(id) raise ArgumentError.new ("Account id must be an positive integer value") if ( id.class != Integer || id < 1 ) - CSV.read("../support/accounts.csv").each do |line| + CSV.read("support/accounts.csv").each do |line| if line[0].to_i == id - account = Bank::Account.new( line[0].to_i, line[1].to_i, line[2].to_s) + account = Bank::Account.new( line[0].to_i, line[1].to_i, line[2]) return account end end @@ -56,9 +63,8 @@ def self.find(id) # method that overwrites existing empty @owner instance variable def update_owner_data(owner_hash) #only overwrite if initially not added to account at the time of initializing account object - #note: in the future, consider being able to update names, addess, phone numbers - # individually for existing @owner - if @owner.customer_id == "0000" + #note: in the future, consider being able to update names, addess, phone number for existing @owners + if @owner.id == 0 @owner = Bank::Owner.new(owner_hash) end end diff --git a/lib/owner.rb b/lib/owner.rb index 270be6f1..858e19f0 100644 --- a/lib/owner.rb +++ b/lib/owner.rb @@ -1,19 +1,90 @@ +# module Bank +# class Owner +# attr_reader :id +# attr_accessor :name, :address, :phone +# def initialize owner_hash = {} +# # assumes that the parameter value is either properly formatted hash or an empty hash +# if owner_hash != {} +# # assumes that owner_hash structure is +# # { id: 1024, first_name: "ginny", last_name: "smith", address: {street: "123 main street", city: "seattle", state: "WA", zipcode: "12345"}, phone: "2065573099" } +# @id = owner_hash[:id] +# @name = "#{owner_hash[:first_name]} #{owner_hash[:last_name]}" +# @address = "#{owner_hash[:address][:street]}, #{owner_hash[:address][:city]}, #{owner_hash[:address][:state]} #{owner_hash[:address][:zipcode]}" +# @phone = owner_hash[:phone] +# else +# @id = "0000" +# end +# end +# end +# end + module Bank class Owner - attr_reader :customer_id - attr_accessor :name, :address, :phone + attr_reader :id + attr_accessor :last_name, :first_name, :street_address, :city, :state def initialize owner_hash = {} # assumes that the parameter value is either properly formatted hash or an empty hash + if owner_hash != {} - # assumes that owner_hash structure is - # { customer_id: 1024, first_name: "ginny", last_name: "smith", address: {street: "123 main street", city: "seattle", state: "WA", zipcode: "12345"}, phone: "2065573099" } - @customer_id = owner_hash[:customer_id] - @name = "#{owner_hash[:first_name]} #{owner_hash[:last_name]}" - @address = "#{owner_hash[:address][:street]}, #{owner_hash[:address][:city]}, #{owner_hash[:address][:state]} #{owner_hash[:address][:zipcode]}" - @phone = owner_hash[:phone] + [:id, :last_name, :first_name, :street_address, :city, :state].each do |expected_key| + if !owner_hash.has_key?(expected_key) + raise ArgumentError.new "Hey you are missing #{expected_key} information for the owner!" + end + end + + @id = owner_hash[:id] + @first_name = owner_hash[:first_name] + @last_name = owner_hash[:last_name] + @street_address = owner_hash[:street_address] + @city = owner_hash[:city] + @state = owner_hash[:state] else - @customer_id = "0000" + @id = 0 end end + + # method that returns a collection of Owner instances, from data read in CSV + def self.all + all_owners_array= [] + + CSV.read("support/owners.csv").each do |line| + all_owners_array << Bank::Owner.new( + { + id: line[0].to_i, + last_name: line[1], + first_name: line[2], + street_address: line[3], + city: line[4], + state: line[5] + } + ) + end + + return all_owners_array + end + + # method that returns an instance of an Owner where the value of the id field + # in the CSV matches the passed parameter + def self.find(id) + raise ArgumentError.new ("Account id must be an positive integer value") if ( id.class != Integer || id < 1 ) + + CSV.read("support/owners.csv").each do |line| + if line[0].to_i == id + owner = Bank::Owner.new( + { + id: line[0].to_i, + last_name: line[1], + first_name: line[2], + street_address: line[3], + city: line[4], + state: line[5] + } + ) + return owner + end + end + raise ArgumentError.new "Owner id does not exist in the database" + end + end end diff --git a/specs/account_spec.rb b/specs/account_spec.rb index 1c0e5aa1..5fc33bf6 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -142,29 +142,42 @@ it "Initializes account without owner property" do id = 1337 balance = 100.0 - owner = nil - account = Bank::Account.new(id, balance, "1999-03-27 11:30:09 -0800", owner) + account = Bank::Account.new(id, balance, "1999-03-27 11:30:09 -0800") account.must_respond_to :owner account.owner.class.must_equal Bank::Owner + account.owner.id.must_equal 0 end + it "Raise an error if the owner_hash is missing a key" do + # id = 1337 + # balance = 100.0 + # open_date = "1999-03-27 11:30:09 -0800" + owner_hash = { + id: 1024, + last_name: "smith", + street_address: "123 main street", + city: "seattle", + state: "WA" + } + proc { + Bank::Owner.new(owner_hash) + }.must_raise ArgumentError + end + + it "Initializes account with owner property" do id = 1337 balance = 100.0 open_date = "1999-03-27 11:30:09 -0800" owner_hash = { - customer_id: 1024, - first_name: "ginny", - last_name: "smith", - address: { - street: "123 main street", - city: "seattle", - state: "WA", - zipcode: "12345" - }, - phone: "2065573099" - } + id: 1024, + first_name: "ginny", + last_name: "smith", + street_address: "123 main street", + city: "seattle", + state: "WA" + } owner = Bank::Owner.new(owner_hash) account = Bank::Account.new(id, balance, open_date, owner) @@ -174,44 +187,42 @@ it "Only accounts without initial owner property can be updated" do owner_hash = { - customer_id: 1024, - first_name: "ginny", - last_name: "smith", - address: { - street: "123 main street", - city: "seattle", - state: "WA", - zipcode: "12345" - }, - phone: "2065573099" - } + id: 10, + first_name: "ginny", + last_name: "smith", + street_address: "123 main street", + city: "seattle", + state: "WA" + } + test_hash = { - customer_id: 8888, - first_name: "sally", - last_name: "smith", - address: { - street: "456 1st street", - city: "columbus", - state: "OH", - zipcode: "54322" - }, - phone: "2234433099" - } + id: 9, + first_name: "fran", + last_name: "swan", + street_address: "456 grand street", + city: "columbus", + state: "OH" + } + account_nil = Bank::Account.new(12345, 12, "1999-03-27 11:30:09 -0800") account = Bank::Account.new(12346, 0, "1999-03-27 11:30:09 -0800", Bank::Owner.new(test_hash)) account_nil.update_owner_data(owner_hash) account.update_owner_data(owner_hash) - account_nil.owner.customer_id.must_equal 1024 - account_nil.owner.name.must_equal "ginny smith" - account_nil.owner.phone.must_equal "2065573099" - account_nil.owner.address.must_equal "123 main street, seattle, WA 12345" - - account.owner.customer_id.must_equal 8888 - account.owner.name.must_equal "sally smith" - account.owner.phone.must_equal "2234433099" - account.owner.address.must_equal "456 1st street, columbus, OH 54322" + account_nil.owner.id.must_equal 10 + account_nil.owner.first_name.must_equal "ginny" + account_nil.owner.last_name.must_equal "smith" + account_nil.owner.street_address.must_equal "123 main street" + account_nil.owner.city.must_equal "seattle" + account_nil.owner.state.must_equal "WA" + + account.owner.id.must_equal 9 + account.owner.first_name.must_equal "fran" + account.owner.last_name.must_equal "swan" + account.owner.street_address.must_equal "456 grand street" + account.owner.city.must_equal "columbus" + account.owner.state.must_equal "OH" end end end @@ -227,8 +238,10 @@ all_array.each do |account| account.class.must_equal Bank::Account end + # the number of accounts is correct - all_array.length.must_equal 12 + #all_array.length.must_equal 12 + all_array.length.must_equal CSV.read("support/accounts.csv").length # the ID and balance of the first and last accounts match what's in the CSV file all_array[0].id.must_equal 1212 @@ -285,4 +298,106 @@ }.must_raise ArgumentError end end + + describe "Owner.all" do + it "Returns an array of all owners" do + # TODO + # everything in the array is an Owner + all_array = Bank::Owner.all + + all_array.each do |owner| + owner.class.must_equal Bank::Owner + end + + # the number of accounts is correct + #all_array.length.must_equal 12 + all_array.length.must_equal CSV.read("support/owners.csv").length + + # the ID, last_name, first_name, street_address, city, state of the first + # and last accounts match what's in the CSV file + all_array[0].id.must_equal 14 + all_array[0].last_name.must_equal "Morales" + all_array[0].first_name.must_equal "Wanda" + all_array[0].street_address.must_equal "9003 Gerald Hill" + all_array[0].city.must_equal "Honolulu" + all_array[0].state.must_equal "Hawaii" + + all_array[-1].id.must_equal 25 + all_array[-1].last_name.must_equal "Clark" + all_array[-1].first_name.must_equal "Kathleen" + all_array[-1].street_address.must_equal "72984 Chive Hill" + all_array[-1].city.must_equal "New York City" + all_array[-1].state.must_equal "New York" + end + end + + describe "Owner.find" do + it "Returns an owner that exists" do + owner = Bank::Owner.find(18) + owner.id.must_equal 18 + owner.last_name.must_equal "Gonzalez" + owner.first_name.must_equal "Laura" + owner.street_address.must_equal "310 Hauk Street" + owner.city.must_equal "Springfield" + owner.state.must_equal "Illinois" + end + + it "Can find the first owner from the CSV" do + owner = Bank::Owner.find(14) + owner.id.must_equal 14 + owner.last_name.must_equal "Morales" + owner.first_name.must_equal "Wanda" + owner.street_address.must_equal "9003 Gerald Hill" + owner.city.must_equal "Honolulu" + owner.state.must_equal "Hawaii" + end + + it "Can find the last account from the CSV" do + owner = Bank::Owner.find(25) + owner.id.must_equal 25 + owner.last_name.must_equal "Clark" + owner.first_name.must_equal "Kathleen" + owner.street_address.must_equal "72984 Chive Hill" + owner.city.must_equal "New York City" + owner.state.must_equal "New York" + end + + it "Raises an error for an owner that doesn't exist" do + # TODO: Your test code here! + proc { + Bank::Owner.find(100233332223003) + }.must_raise ArgumentError + end + + it "Raises an error for an invalid input data type" do + # TODO: Your test code here! + proc { + Bank::Owner.find(0) + }.must_raise ArgumentError + proc { + Bank::Owner.find(-1233) + }.must_raise ArgumentError + proc { + Bank::Owner.find("happy dog") + }.must_raise ArgumentError + end + end + describe "Use account_owners.csv to create owner property for existing " do + it "Makes account instance when account.id and owner.id pair doesn not exist within csv file" do + account = Bank::Account.new(1223222337, 0, "1999-03-27 11:30:09 -0800") + account.owner.id.must_equal 0 + + owner_hash = { + id: 1000000, + first_name: "ginny", + last_name: "smith", + street_address: "123 main street", + city: "seattle", + state: "WA" + } + account = Bank::Account.new(1223222337, 0, "1999-03-27 11:30:09 -0800", Bank::Owner.new(owner_hash)) + account.owner.id.must_equal 1000000 + + end + end end From cd7190de2e4dc289f6f1801061cb4610a568f3ec Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Thu, 23 Feb 2017 15:27:26 -0800 Subject: [PATCH 11/22] Created SavingsAccount and CheckingAccount file --- lib/CheckingAccount.rb | 0 lib/SavingsAccount.rb | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 lib/CheckingAccount.rb create mode 100644 lib/SavingsAccount.rb diff --git a/lib/CheckingAccount.rb b/lib/CheckingAccount.rb new file mode 100644 index 00000000..e69de29b diff --git a/lib/SavingsAccount.rb b/lib/SavingsAccount.rb new file mode 100644 index 00000000..e69de29b From 6eb336c20e3db31d4fc7537b45ffc7ba822dd9af Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Thu, 23 Feb 2017 16:00:49 -0800 Subject: [PATCH 12/22] Corrected file name --- lib/CheckingAccount.rb | 0 lib/SavingsAccount.rb | 0 lib/account.rb | 2 +- lib/checking_account.rb | 4 ++++ lib/savings_account.rb | 9 +++++++++ specs/savings_account_spec.rb | 21 ++++++++++++--------- 6 files changed, 26 insertions(+), 10 deletions(-) delete mode 100644 lib/CheckingAccount.rb delete mode 100644 lib/SavingsAccount.rb create mode 100644 lib/checking_account.rb create mode 100644 lib/savings_account.rb diff --git a/lib/CheckingAccount.rb b/lib/CheckingAccount.rb deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/SavingsAccount.rb b/lib/SavingsAccount.rb deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/account.rb b/lib/account.rb index 9d003ea7..9c96ff33 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -1,6 +1,6 @@ require 'csv' require 'date' - +require_relative 'owner' # Bank module contains Account class and any future bank account logic. module Bank class Account diff --git a/lib/checking_account.rb b/lib/checking_account.rb new file mode 100644 index 00000000..0a72db48 --- /dev/null +++ b/lib/checking_account.rb @@ -0,0 +1,4 @@ +class CheckingAccount < Bank::Account + + +end diff --git a/lib/savings_account.rb b/lib/savings_account.rb new file mode 100644 index 00000000..abe71616 --- /dev/null +++ b/lib/savings_account.rb @@ -0,0 +1,9 @@ +require_relative 'account' +module Bank + class SavingsAccount < Bank::Account + def initialize(id, balance, open_date) + raise ArgumentError.new("Your initial balance must be at least $10.00") if balance < 1000 + super(id, balance, open_date) + end + end +end diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index 3f4d1e4a..43b37ade 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -1,9 +1,7 @@ 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 @@ -11,20 +9,25 @@ # Here we'll only test things that are different. # TODO: change 'xdescribe' to 'describe' to run these tests -xdescribe "SavingsAccount" do +describe "SavingsAccount" do + before do + @account = Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + end + describe "#initialize" do it "Is a kind of Account" do # Check that a SavingsAccount is in fact a kind of account - account = Bank::SavingsAccount.new(12345, 100.0) - account.must_be_kind_of Bank::Account + @account.must_be_kind_of Bank::Account end it "Requires an initial balance of at least $10" do - # TODO: Your test code here! + proc { + Bank::SavingsAccount.new(12345, 100, "1999-03-27 11:30:09 -0800") + }.must_raise ArgumentError end end - describe "#withdraw" do + xdescribe "#withdraw" do it "Applies a $2 fee each time" do # TODO: Your test code here! end @@ -42,7 +45,7 @@ end end - describe "#add_interest" do + xdescribe "#add_interest" do it "Returns the interest calculated" do # TODO: Your test code here! end From 8e13e8da2dc12e677d959b5ff34e1ae2bfb4d850 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Thu, 23 Feb 2017 20:23:39 -0800 Subject: [PATCH 13/22] Withdraw method added to savings account, added working test --- lib/savings_account.rb | 21 +++++++++++++++++++++ specs/savings_account_spec.rb | 16 +++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib/savings_account.rb b/lib/savings_account.rb index abe71616..970479ed 100644 --- a/lib/savings_account.rb +++ b/lib/savings_account.rb @@ -5,5 +5,26 @@ def initialize(id, balance, open_date) raise ArgumentError.new("Your initial balance must be at least $10.00") if balance < 1000 super(id, balance, open_date) end + + # method that handles withdraw + def withdraw(withdraw_amount) + # raise error for non integer withdraw value + raise ArgumentError.new("Withdraw amount value must be a numerical value") if withdraw_amount.class != Integer + # raises error for negativd withdraw value + raise ArgumentError.new("Withdraw amount cannot be a negetive value") if withdraw_amount < 0 + + # error handling for insufficient funds for a withdraw + transaction_fee = 200 + minimum_balance = 1000 + # balance is insufficient + + if @balance <= (withdraw_amount + minimum_balance + transaction_fee) + puts "The amount you enetered for the withdraw will cause your balance to go below the $10.00 minimum balance required" + # ok to withdraw, update @balance + else + @balance -= (withdraw_amount + transaction_fee) + end + return @balance + end end end diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index 43b37ade..62a38191 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -10,38 +10,40 @@ # TODO: change 'xdescribe' to 'describe' to run these tests describe "SavingsAccount" do - before do - @account = Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") - end - describe "#initialize" do it "Is a kind of Account" do # Check that a SavingsAccount is in fact a kind of account - @account.must_be_kind_of Bank::Account + Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").must_be_kind_of Bank::Account end - it "Requires an initial balance of at least $10" do + it "Requires an initial balance of at least $10, raises error otherwise" do proc { Bank::SavingsAccount.new(12345, 100, "1999-03-27 11:30:09 -0800") }.must_raise ArgumentError end end - xdescribe "#withdraw" do + describe "#withdraw" do it "Applies a $2 fee each time" do # TODO: Your test code here! + Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(100).must_equal 9700 end it "Outputs a warning if the balance would go below $10" do # TODO: Your test code here! + proc { + Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(9500) + }.must_output (/.+/) end it "Doesn't modify the balance if it would go below $10" do # TODO: Your test code here! + Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(9100).must_equal 10000 end it "Doesn't modify the balance if the fee would put it below $10" do # TODO: Your test code here! + Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(9000).must_equal 10000 end end From 5819ab3e667937ff0cd496f7ae6672bdf3e0f0a6 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Thu, 23 Feb 2017 20:40:33 -0800 Subject: [PATCH 14/22] Added tests for add_interest method --- specs/savings_account_spec.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index 62a38191..f26619f9 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -47,17 +47,24 @@ end end - xdescribe "#add_interest" do + describe "#add_interest" do it "Returns the interest calculated" do # TODO: Your test code here! + Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").add_interest(0.25).must_equal 2500 end it "Updates the balance with calculated interest" do # TODO: Your test code here! + account = Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + account.add_interest(0.25) + account.balance.must_equal 12500 end it "Requires a positive rate" do # TODO: Your test code here! + proc { + Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").add_interest(-0.32) + }.must_raise ArgumentError end end end From 3d67d3b16dacebbec142ca0aafa22869e4574ee5 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Thu, 23 Feb 2017 21:08:36 -0800 Subject: [PATCH 15/22] Savings account working version for code and tests --- lib/savings_account.rb | 11 +++++++++++ specs/savings_account_spec.rb | 1 + 2 files changed, 12 insertions(+) diff --git a/lib/savings_account.rb b/lib/savings_account.rb index 970479ed..31ce10f5 100644 --- a/lib/savings_account.rb +++ b/lib/savings_account.rb @@ -26,5 +26,16 @@ def withdraw(withdraw_amount) end return @balance end + + #method that handles interest + def add_interest(rate) + raise ArgumentError.new("The interest rate must be a positive numerical value") if rate <= 0 + + interest = @balance * rate + @balance += interest + + return interest + end + end end diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index f26619f9..b3db3b32 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -66,5 +66,6 @@ Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").add_interest(-0.32) }.must_raise ArgumentError end + end end From e0ea43ba3e466953e85289200007676018b1fb59 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Fri, 24 Feb 2017 13:43:48 -0800 Subject: [PATCH 16/22] Finished Wave 3 baseline --- lib/account.rb | 27 +++++++++----- lib/checking_account.rb | 64 +++++++++++++++++++++++++++++++-- lib/owner.rb | 20 ----------- lib/savings_account.rb | 7 ++-- specs/account_spec.rb | 2 -- specs/checking_account_spec.rb | 66 ++++++++++++++++++++++++++++++---- specs/savings_account_spec.rb | 5 ++- 7 files changed, 146 insertions(+), 45 deletions(-) diff --git a/lib/account.rb b/lib/account.rb index 9c96ff33..21966210 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -1,26 +1,31 @@ require 'csv' require 'date' -require_relative 'owner' + + # Bank module contains Account class and any future bank account logic. module Bank class Account # allows access to the current balance of an account at any time. attr_accessor :balance, :owner - # only allow reader on unique account id + # only allow reader on unique account id, and opendate attr_reader :id, :open_date # constructs a new Account object # give a default value, in case the Owner class object is not passed + # assumes passed parameters are formated in their correct data type. def initialize id, balance, open_date, owner = nil + # error handling for initial negative balance if balance >= 0 @balance = balance else raise ArgumentError.new "Inital balance cannot be a negetive value" end + @id = id @open_date = DateTime.parse(open_date) + # assumes that required csv file is accesible CSV.read("support/account_owners.csv").each do |line| if line[0].to_i == @id @owner = Bank::Owner.find(line[1].to_i) @@ -30,6 +35,7 @@ def initialize id, balance, open_date, owner = nil if owner.class == Bank::Owner @owner = owner else + # default instance of the Owner class initialized with empty hash @owner = Bank::Owner.new({}) end end @@ -45,10 +51,10 @@ def self.all return all_accounts_array end - # method that returns an instance of an Account where the value of the id field + # method that returns an instance of an Account class, where the value of the id field # in the CSV matches the passed parameter def self.find(id) - raise ArgumentError.new ("Account id must be an positive integer value") if ( id.class != Integer || id < 1 ) + raise ArgumentError.new ("Account id must be a positive integer value") if ( id.class != Integer || id < 1 ) CSV.read("support/accounts.csv").each do |line| if line[0].to_i == id @@ -70,20 +76,25 @@ def update_owner_data(owner_hash) end # method that handles withdraw - def withdraw(money_amount) + def withdraw(withdraw_amount) # error handling for insufficient funds for a withdraw - if @balance < money_amount + raise ArgumentError.new ("Withdraw amount must be a positive numericla value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) + # insufficient funds + if @balance < withdraw_amount puts "You do not have sufficient funds to withdraw the entered amount" - elsif money_amount < 0 + # negative withdraw amount, invalid + elsif withdraw_amount < 0 raise ArgumentError.new "Withdraw amount cannot be a negetive value" + # allow withdraw else - @balance -= money_amount + @balance -= withdraw_amount end return @balance end # method that handles deposits def deposit(money_amount) + # negative deposit amount, invalid if money_amount < 0 raise ArgumentError.new "Deposit amount cannot be a negetive value" else diff --git a/lib/checking_account.rb b/lib/checking_account.rb index 0a72db48..29d85b7b 100644 --- a/lib/checking_account.rb +++ b/lib/checking_account.rb @@ -1,4 +1,64 @@ -class CheckingAccount < Bank::Account - +require 'csv' +require_relative 'account' +module Bank + class CheckingAccount < Bank::Account + attr_accessor :new_month + attr_reader :num_checks_used + def initialize(id, balance, open_date) + super(id, balance, open_date) + @num_checks_used = 0 + @new_month = false + end + # method that handles withdraw + def withdraw(withdraw_amount) + # raise error for erroneous withdraw value + raise ArgumentError.new ("Withdraw amount must be a positive numericla value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) + + # error handling for insufficient funds for a withdraw + transaction_fee = 100 + + # balance is insufficient + if @balance <= (withdraw_amount + transaction_fee) + puts "The amount you enetered for the withdraw will cause the balance to go below the $0.00" + # ok to withdraw, update @balance + else + @balance -= (withdraw_amount + transaction_fee) + end + return @balance + end + + # method that handles withdraw_using_check + def withdraw_using_check(withdraw_amount) + # raise error for non integer withdraw value + raise ArgumentError.new ("Withdraw amount must be a positive numericla value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) + + # error handling for insufficient funds for a withdraw + transaction_fee = 100 + allotted_negative_balance = -1000 + check_fee = 0 + + if @num_checks_used >= 3 + check_fee = 200 + end + # balance is insufficient + if @balance < (withdraw_amount + transaction_fee + check_fee + allotted_negative_balance) + puts "The amount you enetered for the withdraw will cause the balance to go over the allotted_negative_balance of -$10.00" + # ok to withdraw, update @balance + else + @balance -= (withdraw_amount + transaction_fee + check_fee) + @num_checks_used += 1 + end + return @balance + end + + # Resets the number of checks used to zero + def reset_checks() + if @new_month + @num_checks_used = 0 + @new_month = false + end + end + + end end diff --git a/lib/owner.rb b/lib/owner.rb index 858e19f0..c6bbcb30 100644 --- a/lib/owner.rb +++ b/lib/owner.rb @@ -1,23 +1,3 @@ -# module Bank -# class Owner -# attr_reader :id -# attr_accessor :name, :address, :phone -# def initialize owner_hash = {} -# # assumes that the parameter value is either properly formatted hash or an empty hash -# if owner_hash != {} -# # assumes that owner_hash structure is -# # { id: 1024, first_name: "ginny", last_name: "smith", address: {street: "123 main street", city: "seattle", state: "WA", zipcode: "12345"}, phone: "2065573099" } -# @id = owner_hash[:id] -# @name = "#{owner_hash[:first_name]} #{owner_hash[:last_name]}" -# @address = "#{owner_hash[:address][:street]}, #{owner_hash[:address][:city]}, #{owner_hash[:address][:state]} #{owner_hash[:address][:zipcode]}" -# @phone = owner_hash[:phone] -# else -# @id = "0000" -# end -# end -# end -# end - module Bank class Owner attr_reader :id diff --git a/lib/savings_account.rb b/lib/savings_account.rb index 31ce10f5..f8b06877 100644 --- a/lib/savings_account.rb +++ b/lib/savings_account.rb @@ -1,3 +1,4 @@ +require 'csv' require_relative 'account' module Bank class SavingsAccount < Bank::Account @@ -9,15 +10,15 @@ def initialize(id, balance, open_date) # method that handles withdraw def withdraw(withdraw_amount) # raise error for non integer withdraw value - raise ArgumentError.new("Withdraw amount value must be a numerical value") if withdraw_amount.class != Integer + raise ArgumentError.new ("Withdraw amount must be a positive numericla value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) # raises error for negativd withdraw value raise ArgumentError.new("Withdraw amount cannot be a negetive value") if withdraw_amount < 0 # error handling for insufficient funds for a withdraw transaction_fee = 200 minimum_balance = 1000 - # balance is insufficient + # balance is insufficient if @balance <= (withdraw_amount + minimum_balance + transaction_fee) puts "The amount you enetered for the withdraw will cause your balance to go below the $10.00 minimum balance required" # ok to withdraw, update @balance @@ -30,12 +31,10 @@ def withdraw(withdraw_amount) #method that handles interest def add_interest(rate) raise ArgumentError.new("The interest rate must be a positive numerical value") if rate <= 0 - interest = @balance * rate @balance += interest return interest end - end end diff --git a/specs/account_spec.rb b/specs/account_spec.rb index 5fc33bf6..7522272a 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -4,8 +4,6 @@ require_relative '../lib/account' require_relative '../lib/owner' - - describe "Wave 1" do describe "Account#initialize" do it "Takes an ID and an initial balance" do diff --git a/specs/checking_account_spec.rb b/specs/checking_account_spec.rb index 7f95339e..c059651d 100644 --- a/specs/checking_account_spec.rb +++ b/specs/checking_account_spec.rb @@ -1,9 +1,7 @@ require 'minitest/autorun' require 'minitest/reporters' 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,11 +9,11 @@ # 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 = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") account.must_be_kind_of Bank::Account end end @@ -23,58 +21,114 @@ describe "#withdraw" do it "Applies a $1 fee each time" do # TODO: Your test code here! + Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(100).must_equal 9800 end it "Doesn't modify the balance if the fee would put it negative" do # TODO: Your test code here! + proc { + Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(10100) + }.must_output (/.+/) + end + + it "Doesn't modify the balance if the fee would put it below $0.00" do + # TODO: Your test code here! + Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(100000).must_equal 10000 end end describe "#withdraw_using_check" do it "Reduces the balance" do # TODO: Your test code here! + account =Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + account.withdraw_using_check(1000) + account.balance.must_equal 8900 end it "Returns the modified balance" do # TODO: Your test code here! + Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw_using_check(100).must_equal 9800 end it "Allows the balance to go down to -$10" do # TODO: Your test code here! + Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw_using_check(10900).must_equal (-1000) end it "Outputs a warning if the account would go below -$10" do # TODO: Your test code here! + proc { + Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw_using_check(11000) + }.must_output (/.+/) end it "Doesn't modify the balance if the account would go below -$10" do # TODO: Your test code here! + account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + account.withdraw_using_check(11000) + account.balance.must_equal (10000) end it "Requires a positive withdrawal amount" do # TODO: Your test code here! + account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + proc { + account.withdraw_using_check(-1000) + }.must_raise ArgumentError end it "Allows 3 free uses" do # TODO: Your test code here! + account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + 3.times do + account.withdraw_using_check(1000) + end + account.balance.must_equal (6700) end it "Applies a $2 fee after the third use" do # TODO: Your test code here! + account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + 4.times do + account.withdraw_using_check(1000) + end + account.balance.must_equal (5400) end end describe "#reset_checks" do it "Can be called without error" do # TODO: Your test code here! + account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + 3.times do + account.withdraw_using_check(1000) + end + account.new_month = true + account.reset_checks + account.withdraw_using_check(1000) + account.balance.must_equal (5600) 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(12345, 10000, "1999-03-27 11:30:09 -0800") + account.withdraw_using_check(1000) + account.new_month = true + account.reset_checks + account.withdraw_using_check(1000) + account.balance.must_equal (7800) 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(12345, 10000, "1999-03-27 11:30:09 -0800") + 5.times do + account.withdraw_using_check(1000) + end + account.new_month = true + account.reset_checks + account.num_checks_used.must_equal 0 + # account.withdraw_using_check(1000) + # account.balance.must_equal (3000) end end end diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index b3db3b32..4dce3bf2 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -23,7 +23,7 @@ end end - describe "#withdraw" do + xdescribe "#withdraw" do it "Applies a $2 fee each time" do # TODO: Your test code here! Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(100).must_equal 9700 @@ -47,7 +47,7 @@ end end - describe "#add_interest" do + xdescribe "#add_interest" do it "Returns the interest calculated" do # TODO: Your test code here! Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").add_interest(0.25).must_equal 2500 @@ -66,6 +66,5 @@ Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").add_interest(-0.32) }.must_raise ArgumentError end - end end From 1c1022d8a5bba93215487ceb842eefc259241b08 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Fri, 24 Feb 2017 13:48:38 -0800 Subject: [PATCH 17/22] removed xdescribe --- specs/savings_account_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index 4dce3bf2..f26619f9 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -23,7 +23,7 @@ end end - xdescribe "#withdraw" do + describe "#withdraw" do it "Applies a $2 fee each time" do # TODO: Your test code here! Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(100).must_equal 9700 @@ -47,7 +47,7 @@ end end - xdescribe "#add_interest" do + describe "#add_interest" do it "Returns the interest calculated" do # TODO: Your test code here! Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").add_interest(0.25).must_equal 2500 From f0ecccf9b2a6ad723c28ab5348b1810133ff2183 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Fri, 24 Feb 2017 13:56:54 -0800 Subject: [PATCH 18/22] Added files for optional wave 3 --- lib/money_market_account.rb | 0 specs/checking_account_spec.rb | 2 -- specs/money_market_account_spec.rb | 0 3 files changed, 2 deletions(-) create mode 100644 lib/money_market_account.rb create mode 100644 specs/money_market_account_spec.rb diff --git a/lib/money_market_account.rb b/lib/money_market_account.rb new file mode 100644 index 00000000..e69de29b diff --git a/specs/checking_account_spec.rb b/specs/checking_account_spec.rb index c059651d..e2b9bfb9 100644 --- a/specs/checking_account_spec.rb +++ b/specs/checking_account_spec.rb @@ -127,8 +127,6 @@ account.new_month = true account.reset_checks account.num_checks_used.must_equal 0 - # account.withdraw_using_check(1000) - # account.balance.must_equal (3000) 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..e69de29b From 5d02ae6819e7952e746cccbe645fd18fbd8bd5dc Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Fri, 24 Feb 2017 15:49:41 -0800 Subject: [PATCH 19/22] Added tests for MoneyMarketAccount --- lib/money_market_account.rb | 16 +++ specs/money_market_account_spec.rb | 156 +++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) diff --git a/lib/money_market_account.rb b/lib/money_market_account.rb index e69de29b..79604362 100644 --- a/lib/money_market_account.rb +++ b/lib/money_market_account.rb @@ -0,0 +1,16 @@ +require 'csv' +require_relative 'account' + +module Bank + class MoneyMarketAccount < Bank::Account + attr_accessor :new_month + attr_reader :num_transaction + def initialize(id, balance, open_date) + raise ArgumentError.new("Your initial balance must be at least $10,000.00") if balance < 1000000 + super(id, balance, open_date) + @num_transaction = 0 + @new_month = false + end + + end +end diff --git a/specs/money_market_account_spec.rb b/specs/money_market_account_spec.rb index e69de29b..8a9e4d5d 100644 --- a/specs/money_market_account_spec.rb +++ b/specs/money_market_account_spec.rb @@ -0,0 +1,156 @@ +require 'minitest/autorun' +require 'minitest/reporters' +require 'minitest/skip_dsl' +require_relative '../lib/money_market_account' + +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, 1000000, "1999-03-27 11:30:09 -0800") + account.must_be_kind_of Bank::Account + end + + # Raises an error when attemted to initialize MoneyMarketAccount with initial balance less than $10,000 + it "Invalid initial balance" do + proc { + Bank::MoneyMarketAccount.new(12345, 900000, "1999-03-27 11:30:09 -0800") + }.must_raise ArgumentError + end + end + + describe "#withdraw" do + # Raises error when an erroneous withdrawal amount is entered + it "Requires a positive withdrawal amount" do + account = Bank::MoneyMarketAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + proc { + account.withdraw(-1000) + }.must_raise ArgumentError + end + + # Withdraw method will reduce accout balance, if there are no conflicts + it "Reduces the balance" do + account =Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") + account.withdraw(1000) + account.balance.must_equal 999000 + end + + # If a withdrawal causes the balance to go below $10,000, a fee of $100 is imposed + it "Applies a $100 fee when withdrawal causes the balance to go below $10,000" do + account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") + account.withdraw(1100000) + account.must_equal 890000 + end + + # If the balance is below $10,000, balance does not change + it "Doesn't modify balance if the withdrawal causes the balance to be less than $10,000.00" do + account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") + account.withdraw(1100000) + account.withdraw(10000).must_equal 890000 + end + + # With each withdrawal, the num_transaction count goes up by 1 + it "Each withdraw transaction will be counted against the maximum number of transactions" do + account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") + account.withdraw(1100) + account.withdraw(1100) + account.num_transaction.must_equal 2 + end + + # transaction is not allowed when the num_transaction is greater than equal to 6 + it "Doesn't modify the balance if the num_transaction is greater than equal to 6" do + account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") + account.num_transaction = 6 + account.withdraw(1100000).must_equal 2000000 + end + end + + describe "#deposit" do + # Raises error when an erroneous deposit amount is entered + it "Requires a positive deposit amount" do + account = Bank::MoneyMarketAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + proc { + account.deposit(-1000) + }.must_raise ArgumentError + end + + # Deposit method will increase accout balance, if there are no conflicts + it "Increase the balance" do + account =Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") + account.deposit(1000) + account.balance.must_equal 1001000 + end + + # If a deposit causes the balance to be greater than equal to $10,000, a fee of $100 is removed + it "Removes $100 fee when deposit causes the balance to be greater than equal to $10,000" do + account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") + account.withdraw(1100000) + account.deposit(1100000) + account.withdraw(1000000).must_equal 1000000 + end + + # If a deposit causes the balance to be greater than equal to $10,000, that deposit does not add to num_transaction + it "Does not increase num_transaction, when deposit causes the balance to be greater than equal to $10,000" do + account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") + account.withdraw(1100000) + account.deposit(1100000) + account.num_transaction.must_equal 1 + end + + # With each deposit, the num_transaction count goes up by 1 + it "Each deposit transaction will be counted against the maximum number of transactions" do + account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") + account.deposit(1100) + account.deposit(1100) + account.num_transaction.must_equal 2 + end + + # transaction is not allowed when the num_transaction is greater than equal to 6 + it "Doesn't modify the balance if the num_transaction is greater than equal to 6" do + account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") + account.num_transaction = 6 + account.deposit(1100000).must_equal 2000000 + end + end + + describe "#add_interest" do + # Only the actual interest amount added is returned + it "Returns the interest calculated" do + Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800").add_interest(0.25).must_equal 250000 + end + # Balance is updated + it "Updates the balance with calculated interest" do + account = Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800").add_interest(0.25).must_equal 250000 + account.add_interest(0.25) + account.balance.must_equal 1250000 + end + # Checks against erroneous rate value inputs + it "Requires a positive rate" do + proc { + Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800").add_interest(-0.32) + }.must_raise ArgumentError + end + end + + describe "#reset_transactions" do + # Resets the number of transactions to zero + it "Resets the num_transaction to 0" do + account = Bank::CheckingAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") + 5.times do + account.deposit(100000) + end + account.new_month = true + account.reset_transactions + account.num_transaction.must_equal 0 + end + + # When the num_transaction is zero, calling this method outputs a message + it "Outputs a message when the num_transaction is already 0" do + account = Bank::CheckingAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") + account.new_month = true + proc { + account.reset_transactions + }.must_output /.+/ + end + end +end From 7af41f66c56a0fef04ec36fab16ac6a3ddd4784e Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Sat, 25 Feb 2017 22:12:08 -0800 Subject: [PATCH 20/22] Finished tests and cleaned up comments --- lib/account.rb | 43 ++--- lib/checking_account.rb | 20 +- lib/money_market_account.rb | 40 ++++ lib/owner.rb | 43 ++--- lib/savings_account.rb | 17 +- specs/account_spec.rb | 296 ++++++++++++++--------------- specs/checking_account_spec.rb | 46 +++-- specs/money_market_account_spec.rb | 41 ++-- specs/savings_account_spec.rb | 25 +-- 9 files changed, 305 insertions(+), 266 deletions(-) diff --git a/lib/account.rb b/lib/account.rb index 21966210..57833b92 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -1,20 +1,18 @@ require 'csv' require 'date' - # Bank module contains Account class and any future bank account logic. module Bank class Account - # allows access to the current balance of an account at any time. + # Allows access to the current balance of an account at any time. attr_accessor :balance, :owner - # only allow reader on unique account id, and opendate + # Only allow reader on unique account id, and opendate attr_reader :id, :open_date - # constructs a new Account object - # give a default value, in case the Owner class object is not passed - # assumes passed parameters are formated in their correct data type. + # Constructs a new Account object + # Give a default value, in case the Owner class object is not passed + # Assumes passed parameters are formated in their correct data type. def initialize id, balance, open_date, owner = nil - # error handling for initial negative balance if balance >= 0 @balance = balance @@ -25,7 +23,7 @@ def initialize id, balance, open_date, owner = nil @id = id @open_date = DateTime.parse(open_date) - # assumes that required csv file is accesible + # Assumes that required csv file is accesible CSV.read("support/account_owners.csv").each do |line| if line[0].to_i == @id @owner = Bank::Owner.find(line[1].to_i) @@ -35,24 +33,22 @@ def initialize id, balance, open_date, owner = nil if owner.class == Bank::Owner @owner = owner else - # default instance of the Owner class initialized with empty hash + # Default instance of the Owner class initialized with empty hash @owner = Bank::Owner.new({}) end end - # method that returns a collection of Account instances, from data read in CSV + # Method that returns a collection of Account instances, from data read in CSV def self.all all_accounts_array= [] - #for efficiency, consider setting all_accounts_array to a class variable + CSV.read("support/accounts.csv").each do |line| all_accounts_array << Bank::Account.new( line[0].to_i, line[1].to_i, line[2] ) end - return all_accounts_array end - # method that returns an instance of an Account class, where the value of the id field - # in the CSV matches the passed parameter + # Method that returns an instance of an Account class, where the value of the id field in the CSV matches the passed parameter def self.find(id) raise ArgumentError.new ("Account id must be a positive integer value") if ( id.class != Integer || id < 1 ) @@ -66,35 +62,34 @@ def self.find(id) end - # method that overwrites existing empty @owner instance variable + # Method that overwrites existing empty @owner instance variable def update_owner_data(owner_hash) - #only overwrite if initially not added to account at the time of initializing account object - #note: in the future, consider being able to update names, addess, phone number for existing @owners + # Only overwrite if initially not added to account at the time of initializing account object if @owner.id == 0 @owner = Bank::Owner.new(owner_hash) end end - # method that handles withdraw + # Method that handles withdraw def withdraw(withdraw_amount) - # error handling for insufficient funds for a withdraw + # Error handling for insufficient funds for a withdraw raise ArgumentError.new ("Withdraw amount must be a positive numericla value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) - # insufficient funds + # Insufficient funds if @balance < withdraw_amount puts "You do not have sufficient funds to withdraw the entered amount" - # negative withdraw amount, invalid + # Negative withdraw amount, invalid elsif withdraw_amount < 0 raise ArgumentError.new "Withdraw amount cannot be a negetive value" - # allow withdraw + # Allow withdraw and update the balance else @balance -= withdraw_amount end return @balance end - # method that handles deposits + # Method that handles deposits def deposit(money_amount) - # negative deposit amount, invalid + # Negative deposit amount, invalid if money_amount < 0 raise ArgumentError.new "Deposit amount cannot be a negetive value" else diff --git a/lib/checking_account.rb b/lib/checking_account.rb index 29d85b7b..4365c13d 100644 --- a/lib/checking_account.rb +++ b/lib/checking_account.rb @@ -1,39 +1,41 @@ require 'csv' require_relative 'account' + module Bank class CheckingAccount < Bank::Account attr_accessor :new_month attr_reader :num_checks_used + def initialize(id, balance, open_date) super(id, balance, open_date) @num_checks_used = 0 @new_month = false end - # method that handles withdraw + # Method that handles withdraw def withdraw(withdraw_amount) # raise error for erroneous withdraw value raise ArgumentError.new ("Withdraw amount must be a positive numericla value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) - # error handling for insufficient funds for a withdraw + # Error handling for insufficient funds for a withdraw transaction_fee = 100 - # balance is insufficient + # Balance is insufficient if @balance <= (withdraw_amount + transaction_fee) puts "The amount you enetered for the withdraw will cause the balance to go below the $0.00" - # ok to withdraw, update @balance + # Ok to withdraw, updates the balance else @balance -= (withdraw_amount + transaction_fee) end return @balance end - # method that handles withdraw_using_check + # Method that handles withdraw_using_check def withdraw_using_check(withdraw_amount) # raise error for non integer withdraw value - raise ArgumentError.new ("Withdraw amount must be a positive numericla value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) + raise ArgumentError.new ("Withdraw amount must be a positive numerical value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) - # error handling for insufficient funds for a withdraw + # Error handling for insufficient funds for a withdraw transaction_fee = 100 allotted_negative_balance = -1000 check_fee = 0 @@ -41,10 +43,10 @@ def withdraw_using_check(withdraw_amount) if @num_checks_used >= 3 check_fee = 200 end - # balance is insufficient + # Balance is insufficient if @balance < (withdraw_amount + transaction_fee + check_fee + allotted_negative_balance) puts "The amount you enetered for the withdraw will cause the balance to go over the allotted_negative_balance of -$10.00" - # ok to withdraw, update @balance + # Ok to withdraw, update @balance else @balance -= (withdraw_amount + transaction_fee + check_fee) @num_checks_used += 1 diff --git a/lib/money_market_account.rb b/lib/money_market_account.rb index 79604362..d55cb532 100644 --- a/lib/money_market_account.rb +++ b/lib/money_market_account.rb @@ -12,5 +12,45 @@ def initialize(id, balance, open_date) @new_month = false end + def withdraw(withdraw_amount) + # Raise error for non integer withdraw value + raise ArgumentError.new ("Withdraw amount must be a positive numerical value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) + minimum_balance = 1000000 + penalty_fee = 0 + + # Withdraw allowed only if num_transaction is less than 6 AND balance is above minimum_balance + if @num_transaction < 6 && @balance >= minimum_balance + # Withdraw_amount will cause balance to go below minimum_balance + if @balance < withdraw_amount + minimum_balance + penalty_fee = 10000 + end + @balance -= (withdraw_amount + penalty_fee) + @num_transaction += 1 + end + return @balance + end + + # Resets the number of checks used to zero + def reset_transactions() + if @new_month + if @num_transaction == 0 + puts "You haven't made any transactions yet." + else + @num_transaction = 0 + end + @new_month = false + end + end + + + + + + + + + + + end end diff --git a/lib/owner.rb b/lib/owner.rb index c6bbcb30..a38eca44 100644 --- a/lib/owner.rb +++ b/lib/owner.rb @@ -2,16 +2,15 @@ module Bank class Owner attr_reader :id attr_accessor :last_name, :first_name, :street_address, :city, :state - def initialize owner_hash = {} - # assumes that the parameter value is either properly formatted hash or an empty hash + def initialize owner_hash = {} + # Assumes that the parameter value is either properly formatted hash or an empty hash if owner_hash != {} [:id, :last_name, :first_name, :street_address, :city, :state].each do |expected_key| if !owner_hash.has_key?(expected_key) raise ArgumentError.new "Hey you are missing #{expected_key} information for the owner!" end end - @id = owner_hash[:id] @first_name = owner_hash[:first_name] @last_name = owner_hash[:last_name] @@ -23,48 +22,46 @@ def initialize owner_hash = {} end end - # method that returns a collection of Owner instances, from data read in CSV + # Method that returns a collection of Owner instances, from data read in CSV def self.all all_owners_array= [] CSV.read("support/owners.csv").each do |line| all_owners_array << Bank::Owner.new( - { - id: line[0].to_i, - last_name: line[1], - first_name: line[2], - street_address: line[3], - city: line[4], - state: line[5] - } + { + id: line[0].to_i, + last_name: line[1], + first_name: line[2], + street_address: line[3], + city: line[4], + state: line[5] + } ) end return all_owners_array end - # method that returns an instance of an Owner where the value of the id field - # in the CSV matches the passed parameter + # Method that returns an instance of an Owner where the value of the id field in the CSV matches the passed parameter def self.find(id) raise ArgumentError.new ("Account id must be an positive integer value") if ( id.class != Integer || id < 1 ) CSV.read("support/owners.csv").each do |line| if line[0].to_i == id owner = Bank::Owner.new( - { - id: line[0].to_i, - last_name: line[1], - first_name: line[2], - street_address: line[3], - city: line[4], - state: line[5] - } + { + id: line[0].to_i, + last_name: line[1], + first_name: line[2], + street_address: line[3], + city: line[4], + state: line[5] + } ) return owner end end raise ArgumentError.new "Owner id does not exist in the database" end - end end diff --git a/lib/savings_account.rb b/lib/savings_account.rb index f8b06877..9a10e4bd 100644 --- a/lib/savings_account.rb +++ b/lib/savings_account.rb @@ -1,39 +1,40 @@ require 'csv' require_relative 'account' + module Bank class SavingsAccount < Bank::Account + def initialize(id, balance, open_date) raise ArgumentError.new("Your initial balance must be at least $10.00") if balance < 1000 super(id, balance, open_date) end - # method that handles withdraw + # Method that handles withdraw def withdraw(withdraw_amount) - # raise error for non integer withdraw value + # Raise error for non integer withdraw value raise ArgumentError.new ("Withdraw amount must be a positive numericla value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) - # raises error for negativd withdraw value + # Raises error for negativd withdraw value raise ArgumentError.new("Withdraw amount cannot be a negetive value") if withdraw_amount < 0 - # error handling for insufficient funds for a withdraw + # Error handling for insufficient funds for a withdraw transaction_fee = 200 minimum_balance = 1000 - # balance is insufficient + # Balance is insufficient if @balance <= (withdraw_amount + minimum_balance + transaction_fee) puts "The amount you enetered for the withdraw will cause your balance to go below the $10.00 minimum balance required" - # ok to withdraw, update @balance + # Allows withdraw, update @balance else @balance -= (withdraw_amount + transaction_fee) end return @balance end - #method that handles interest + # Method that handles interest def add_interest(rate) raise ArgumentError.new("The interest rate must be a positive numerical value") if rate <= 0 interest = @balance * rate @balance += interest - return interest end end diff --git a/specs/account_spec.rb b/specs/account_spec.rb index 7522272a..570699d0 100644 --- a/specs/account_spec.rb +++ b/specs/account_spec.rb @@ -6,6 +6,7 @@ describe "Wave 1" do describe "Account#initialize" do + # Checks for instance variables it "Takes an ID and an initial balance" do id = 1337 balance = 100.0 @@ -22,6 +23,7 @@ account.open_date.must_equal DateTime.parse(open_date) end + # Checks for erroneous values used for instance variables it "Raises an ArgumentError when created with a negative balance" do proc { Bank::Account.new(1337, -100.0, "1999-03-27 11:30:09 -0800") @@ -35,6 +37,7 @@ end describe "Account#withdraw" do + # Updates the balance, given there are no conflicts it "Reduces the balance" do start_balance = 100.0 withdrawal_amount = 25.0 @@ -57,33 +60,28 @@ updated_balance.must_equal expected_balance end + # Outputs a warning message it "Outputs a warning if the account would go negative" do start_balance = 100.0 withdrawal_amount = 200.0 account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") - # 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 /.+/ + }.must_output (/.+/) end + # Both the value returned and the balance in the account must be un-modified. it "Doesn't modify the balance if the account would go negative" do start_balance = 100.0 withdrawal_amount = 200.0 account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") - 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 + # User can withdraw all of the money in the account it "Allows the balance to go to 0" do account = Bank::Account.new(1337, 100.0, "1999-03-27 11:30:09 -0800") updated_balance = account.withdraw(account.balance) @@ -91,6 +89,7 @@ account.balance.must_equal 0 end + # Checks for erroneous amount inout it "Requires a positive withdrawal amount" do start_balance = 100.0 withdrawal_amount = -25.0 @@ -103,28 +102,27 @@ end describe "Account#deposit" do + # Updates the balance, given there are no conflicts it "Increases the balance" do start_balance = 100.0 deposit_amount = 25.0 account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") - + prev_balance = account.balance account.deposit(deposit_amount) - - expected_balance = start_balance + deposit_amount - account.balance.must_equal expected_balance + (prev_balance <= account.balance).must_equal true end + # Method returns te balance it "Returns the modified balance" do start_balance = 100.0 deposit_amount = 25.0 account = Bank::Account.new(1337, start_balance, "1999-03-27 11:30:09 -0800") - updated_balance = account.deposit(deposit_amount) - expected_balance = start_balance + deposit_amount updated_balance.must_equal expected_balance end + # Checks for erroneous amount inout it "Requires a positive deposit amount" do start_balance = 100.0 deposit_amount = -25.0 @@ -137,6 +135,7 @@ end describe "Owner#added property to Account" do + # Handles missing owner parameter at initialization. it "Initializes account without owner property" do id = 1337 balance = 100.0 @@ -147,10 +146,8 @@ account.owner.id.must_equal 0 end + # Handles incomplete or erroneous owner_hash it "Raise an error if the owner_hash is missing a key" do - # id = 1337 - # balance = 100.0 - # open_date = "1999-03-27 11:30:09 -0800" owner_hash = { id: 1024, last_name: "smith", @@ -163,7 +160,7 @@ }.must_raise ArgumentError end - + # Initializes using the passed instance of the Owner class it "Initializes account with owner property" do id = 1337 balance = 100.0 @@ -183,6 +180,7 @@ account.owner.class.must_equal Bank::Owner end + # Adds owner property to accounts without existing owner info it "Only accounts without initial owner property can be updated" do owner_hash = { id: 10, @@ -225,20 +223,17 @@ end end -# TODO: change 'xdescribe' to 'describe' to run these tests describe "Wave 2" do describe "Account.all" do it "Returns an array of all accounts" do - # TODO - # everything in the array is an Account + # Everything in the array is an Account all_array = Bank::Account.all all_array.each do |account| account.class.must_equal Bank::Account end - # the number of accounts is correct - #all_array.length.must_equal 12 + # The number of accounts is correct all_array.length.must_equal CSV.read("support/accounts.csv").length # the ID and balance of the first and last accounts match what's in the CSV file @@ -249,153 +244,144 @@ all_array[-1].balance.must_equal 4356772 all_array[-1].open_date.must_equal DateTime.parse("1994-11-17 14:04:56 -0800") end - end - - describe "Account.find" do - it "Returns an account that exists" do - # TODO: Your test code here! - account = Bank::Account.find(1213) - account.id.must_equal 1213 - account.balance.must_equal 66367 - account.open_date.must_equal DateTime.parse("2010-12-21 12:21:12 -0800") - end - it "Can find the first account from the CSV" do - # TODO: Your test code here! - account = Bank::Account.find(1212) - account.id.must_equal 1212 - account.balance.must_equal 1235667 - account.open_date.must_equal DateTime.parse("1999-03-27 11:30:09 -0800") - end - - it "Can find the last account from the CSV" do - # TODO: Your test code here! - account = Bank::Account.find(15156) - account.id.must_equal 15156 - account.balance.must_equal 4356772 - account.open_date.must_equal DateTime.parse("1994-11-17 14:04:56 -0800") - end - it "Raises an error for an account that doesn't exist" do - # TODO: Your test code here! - proc { - Bank::Account.find(100233332223003) - }.must_raise ArgumentError - end + describe "Account.find" do + it "Returns an account that exists" do + account = Bank::Account.find(1213) + account.id.must_equal 1213 + account.balance.must_equal 66367 + account.open_date.must_equal DateTime.parse("2010-12-21 12:21:12 -0800") + end - it "Raises an error for an invalid input data type" do - # TODO: Your test code here! - proc { - Bank::Account.find(0) - }.must_raise ArgumentError - proc { - Bank::Account.find(-1233) - }.must_raise ArgumentError - proc { - Bank::Account.find("happy dog") - }.must_raise ArgumentError - end - end + it "Can find the first account from the CSV" do + account = Bank::Account.find(1212) + account.id.must_equal 1212 + account.balance.must_equal 1235667 + account.open_date.must_equal DateTime.parse("1999-03-27 11:30:09 -0800") + end - describe "Owner.all" do - it "Returns an array of all owners" do - # TODO - # everything in the array is an Owner - all_array = Bank::Owner.all + it "Can find the last account from the CSV" do + account = Bank::Account.find(15156) + account.id.must_equal 15156 + account.balance.must_equal 4356772 + account.open_date.must_equal DateTime.parse("1994-11-17 14:04:56 -0800") + end - all_array.each do |owner| - owner.class.must_equal Bank::Owner + it "Raises an error for an account that doesn't exist" do + proc { + Bank::Account.find(100233332223003) + }.must_raise ArgumentError end - # the number of accounts is correct - #all_array.length.must_equal 12 - all_array.length.must_equal CSV.read("support/owners.csv").length - - # the ID, last_name, first_name, street_address, city, state of the first - # and last accounts match what's in the CSV file - all_array[0].id.must_equal 14 - all_array[0].last_name.must_equal "Morales" - all_array[0].first_name.must_equal "Wanda" - all_array[0].street_address.must_equal "9003 Gerald Hill" - all_array[0].city.must_equal "Honolulu" - all_array[0].state.must_equal "Hawaii" - - all_array[-1].id.must_equal 25 - all_array[-1].last_name.must_equal "Clark" - all_array[-1].first_name.must_equal "Kathleen" - all_array[-1].street_address.must_equal "72984 Chive Hill" - all_array[-1].city.must_equal "New York City" - all_array[-1].state.must_equal "New York" + it "Raises an error for an invalid input data type" do + proc { + Bank::Account.find(0) + }.must_raise ArgumentError + proc { + Bank::Account.find(-1233) + }.must_raise ArgumentError + proc { + Bank::Account.find("happy dog") + }.must_raise ArgumentError + end end - end - describe "Owner.find" do - it "Returns an owner that exists" do - owner = Bank::Owner.find(18) - owner.id.must_equal 18 - owner.last_name.must_equal "Gonzalez" - owner.first_name.must_equal "Laura" - owner.street_address.must_equal "310 Hauk Street" - owner.city.must_equal "Springfield" - owner.state.must_equal "Illinois" + describe "Owner.all" do + it "Returns an array of all owners" do + # Everything in the array is an Owner + all_array = Bank::Owner.all + all_array.class.must_equal Array + + all_array.each do |owner| + owner.class.must_equal Bank::Owner + end + + # The number of accounts is correct + all_array.length.must_equal CSV.read("support/owners.csv").length + + # The ID, last_name, first_name, street_address, city, state of the first and last accounts match what's in the CSV file + all_array[0].id.must_equal 14 + all_array[0].last_name.must_equal "Morales" + all_array[0].first_name.must_equal "Wanda" + all_array[0].street_address.must_equal "9003 Gerald Hill" + all_array[0].city.must_equal "Honolulu" + all_array[0].state.must_equal "Hawaii" + + all_array[-1].id.must_equal 25 + all_array[-1].last_name.must_equal "Clark" + all_array[-1].first_name.must_equal "Kathleen" + all_array[-1].street_address.must_equal "72984 Chive Hill" + all_array[-1].city.must_equal "New York City" + all_array[-1].state.must_equal "New York" + end end - it "Can find the first owner from the CSV" do - owner = Bank::Owner.find(14) - owner.id.must_equal 14 - owner.last_name.must_equal "Morales" - owner.first_name.must_equal "Wanda" - owner.street_address.must_equal "9003 Gerald Hill" - owner.city.must_equal "Honolulu" - owner.state.must_equal "Hawaii" - end + describe "Owner.find" do + it "Returns an owner that exists" do + owner = Bank::Owner.find(18) + owner.id.must_equal 18 + owner.last_name.must_equal "Gonzalez" + owner.first_name.must_equal "Laura" + owner.street_address.must_equal "310 Hauk Street" + owner.city.must_equal "Springfield" + owner.state.must_equal "Illinois" + end - it "Can find the last account from the CSV" do - owner = Bank::Owner.find(25) - owner.id.must_equal 25 - owner.last_name.must_equal "Clark" - owner.first_name.must_equal "Kathleen" - owner.street_address.must_equal "72984 Chive Hill" - owner.city.must_equal "New York City" - owner.state.must_equal "New York" - end + it "Can find the first owner from the CSV" do + owner = Bank::Owner.find(14) + owner.id.must_equal 14 + owner.last_name.must_equal "Morales" + owner.first_name.must_equal "Wanda" + owner.street_address.must_equal "9003 Gerald Hill" + owner.city.must_equal "Honolulu" + owner.state.must_equal "Hawaii" + end - it "Raises an error for an owner that doesn't exist" do - # TODO: Your test code here! - proc { - Bank::Owner.find(100233332223003) - }.must_raise ArgumentError - end + it "Can find the last account from the CSV" do + owner = Bank::Owner.find(25) + owner.id.must_equal 25 + owner.last_name.must_equal "Clark" + owner.first_name.must_equal "Kathleen" + owner.street_address.must_equal "72984 Chive Hill" + owner.city.must_equal "New York City" + owner.state.must_equal "New York" + end - it "Raises an error for an invalid input data type" do - # TODO: Your test code here! - proc { - Bank::Owner.find(0) - }.must_raise ArgumentError - proc { - Bank::Owner.find(-1233) - }.must_raise ArgumentError - proc { - Bank::Owner.find("happy dog") - }.must_raise ArgumentError - end - end - describe "Use account_owners.csv to create owner property for existing " do - it "Makes account instance when account.id and owner.id pair doesn not exist within csv file" do - account = Bank::Account.new(1223222337, 0, "1999-03-27 11:30:09 -0800") - account.owner.id.must_equal 0 + it "Raises an error for an owner that doesn't exist" do + proc { + Bank::Owner.find(100233332223003) + }.must_raise ArgumentError + end - owner_hash = { - id: 1000000, - first_name: "ginny", - last_name: "smith", - street_address: "123 main street", - city: "seattle", - state: "WA" - } - account = Bank::Account.new(1223222337, 0, "1999-03-27 11:30:09 -0800", Bank::Owner.new(owner_hash)) - account.owner.id.must_equal 1000000 + it "Raises an error for an invalid input data type" do + proc { + Bank::Owner.find(0) + }.must_raise ArgumentError + proc { + Bank::Owner.find(-1233) + }.must_raise ArgumentError + proc { + Bank::Owner.find("happy dog") + }.must_raise ArgumentError + end + end + describe "Use account_owners.csv to create owner property for existing " do + it "Makes account instance when account.id and owner.id pair doesn not exist within csv file" do + account = Bank::Account.new(1223222337, 0, "1999-03-27 11:30:09 -0800") + account.owner.id.must_equal 0 + owner_hash = { + id: 1000000, + first_name: "ginny", + last_name: "smith", + street_address: "123 main street", + city: "seattle", + state: "WA" + } + account = Bank::Account.new(1223222337, 0, "1999-03-27 11:30:09 -0800", Bank::Owner.new(owner_hash)) + account.owner.id.must_equal 1000000 + end end end end diff --git a/specs/checking_account_spec.rb b/specs/checking_account_spec.rb index e2b9bfb9..85eddbff 100644 --- a/specs/checking_account_spec.rb +++ b/specs/checking_account_spec.rb @@ -3,80 +3,88 @@ require 'minitest/skip_dsl' 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 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, 10000, "1999-03-27 11:30:09 -0800") account.must_be_kind_of Bank::Account + account.must_respond_to :num_checks_used + account.num_checks_used.must_equal 0 + account.must_respond_to :new_month + account.new_month.must_equal false + end + + # Checks for instance variables + it "Initial value for instance variable are set" do + account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + account.must_respond_to :num_checks_used + account.num_checks_used.must_equal 0 + account.must_respond_to :new_month + account.new_month.must_equal false end end + # Decreases balance in decreased by the withdrawal amount, including $1 fee describe "#withdraw" do it "Applies a $1 fee each time" do - # TODO: Your test code here! Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(100).must_equal 9800 end + # Balance does not change, returns amount it "Doesn't modify the balance if the fee would put it negative" do - # TODO: Your test code here! proc { Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(10100) }.must_output (/.+/) end + # Balance does not change, returns amount it "Doesn't modify the balance if the fee would put it below $0.00" do - # TODO: Your test code here! - Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(100000).must_equal 10000 + Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(100000).must_equal 10000 end end describe "#withdraw_using_check" do + # Withdraw the amount entered, if theres no conflict it "Reduces the balance" do - # TODO: Your test code here! account =Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") account.withdraw_using_check(1000) account.balance.must_equal 8900 end + # Checks that the method returns the updated balance it "Returns the modified balance" do - # TODO: Your test code here! Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw_using_check(100).must_equal 9800 end + # Checks that user can overdraft upto -$10.00, when using withdraw_using_check it "Allows the balance to go down to -$10" do - # TODO: Your test code here! Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw_using_check(10900).must_equal (-1000) end + # Outputs an error message when the account will be overdraft by more than $10.00 it "Outputs a warning if the account would go below -$10" do - # TODO: Your test code here! proc { Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw_using_check(11000) }.must_output (/.+/) end + # Checks that the method returns an unchanged balance. it "Doesn't modify the balance if the account would go below -$10" do - # TODO: Your test code here! account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") account.withdraw_using_check(11000) account.balance.must_equal (10000) end + # Checks that a negative check amount will raise an error. it "Requires a positive withdrawal amount" do - # TODO: Your test code here! account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") proc { account.withdraw_using_check(-1000) }.must_raise ArgumentError end + # Account owner gets 3 free checks per month it "Allows 3 free uses" do # TODO: Your test code here! account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") @@ -86,7 +94,8 @@ account.balance.must_equal (6700) end - it "Applies a $2 fee after the third use" do + # Account owner is charged $2.00 fee for + it "Applies a $2 fee after the third check" do # TODO: Your test code here! account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") 4.times do @@ -97,6 +106,7 @@ end describe "#reset_checks" do + # Calls the method without error it "Can be called without error" do # TODO: Your test code here! account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") @@ -109,6 +119,7 @@ account.balance.must_equal (5600) end + # Resets used check count to 0 it "Makes the next three checks free if less than 3 checks had been used" do account = Bank::CheckingAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") account.withdraw_using_check(1000) @@ -118,6 +129,7 @@ account.balance.must_equal (7800) end + # Resets used check count to 0 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(12345, 10000, "1999-03-27 11:30:09 -0800") diff --git a/specs/money_market_account_spec.rb b/specs/money_market_account_spec.rb index 8a9e4d5d..3ad74674 100644 --- a/specs/money_market_account_spec.rb +++ b/specs/money_market_account_spec.rb @@ -11,6 +11,15 @@ account.must_be_kind_of Bank::Account end + # Checks for instance variables + it "Initial value for instance variable are set" do + account = Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") + account.must_respond_to :num_transaction + account.num_transaction.must_equal 0 + account.must_respond_to :new_month + account.new_month.must_equal false + end + # Raises an error when attemted to initialize MoneyMarketAccount with initial balance less than $10,000 it "Invalid initial balance" do proc { @@ -22,7 +31,7 @@ describe "#withdraw" do # Raises error when an erroneous withdrawal amount is entered it "Requires a positive withdrawal amount" do - account = Bank::MoneyMarketAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + account = Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") proc { account.withdraw(-1000) }.must_raise ArgumentError @@ -31,15 +40,15 @@ # Withdraw method will reduce accout balance, if there are no conflicts it "Reduces the balance" do account =Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") - account.withdraw(1000) - account.balance.must_equal 999000 + account.withdraw(100000) + account.balance.must_equal 890000 end # If a withdrawal causes the balance to go below $10,000, a fee of $100 is imposed it "Applies a $100 fee when withdrawal causes the balance to go below $10,000" do account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") - account.withdraw(1100000) - account.must_equal 890000 + account.withdraw(1500000) + account.balance.must_equal 490000 end # If the balance is below $10,000, balance does not change @@ -57,15 +66,17 @@ account.num_transaction.must_equal 2 end - # transaction is not allowed when the num_transaction is greater than equal to 6 + # Transaction is not allowed when the num_transaction is greater than equal to 6 it "Doesn't modify the balance if the num_transaction is greater than equal to 6" do account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") - account.num_transaction = 6 - account.withdraw(1100000).must_equal 2000000 + 6.times do + account.withdraw(0) + end + account.withdraw(11000).must_equal 2000000 end end - describe "#deposit" do + xdescribe "#deposit" do # Raises error when an erroneous deposit amount is entered it "Requires a positive deposit amount" do account = Bank::MoneyMarketAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") @@ -105,7 +116,7 @@ account.num_transaction.must_equal 2 end - # transaction is not allowed when the num_transaction is greater than equal to 6 + # Transaction is not allowed when the num_transaction is greater than equal to 6 it "Doesn't modify the balance if the num_transaction is greater than equal to 6" do account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") account.num_transaction = 6 @@ -113,7 +124,7 @@ end end - describe "#add_interest" do + xdescribe "#add_interest" do # Only the actual interest amount added is returned it "Returns the interest calculated" do Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800").add_interest(0.25).must_equal 250000 @@ -135,9 +146,9 @@ describe "#reset_transactions" do # Resets the number of transactions to zero it "Resets the num_transaction to 0" do - account = Bank::CheckingAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") + account = Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") 5.times do - account.deposit(100000) + account.withdraw(1000) end account.new_month = true account.reset_transactions @@ -146,11 +157,11 @@ # When the num_transaction is zero, calling this method outputs a message it "Outputs a message when the num_transaction is already 0" do - account = Bank::CheckingAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") + account = Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") account.new_month = true proc { account.reset_transactions - }.must_output /.+/ + }.must_output (/.+/) end end end diff --git a/specs/savings_account_spec.rb b/specs/savings_account_spec.rb index f26619f9..a76e0ca2 100644 --- a/specs/savings_account_spec.rb +++ b/specs/savings_account_spec.rb @@ -3,19 +3,14 @@ require 'minitest/skip_dsl' 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 describe "SavingsAccount" do describe "#initialize" do + # Check that a SavingsAccount is in fact a kind of account it "Is a kind of Account" do - # Check that a SavingsAccount is in fact a kind of account Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").must_be_kind_of Bank::Account end + # Check that the initial balance is at least $10.00 it "Requires an initial balance of at least $10, raises error otherwise" do proc { Bank::SavingsAccount.new(12345, 100, "1999-03-27 11:30:09 -0800") @@ -24,44 +19,44 @@ end describe "#withdraw" do + # Decreases balance in decreased by the withdrawal amount, including $2 fee it "Applies a $2 fee each time" do - # TODO: Your test code here! Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(100).must_equal 9700 end + # Outputs a message warning the user it "Outputs a warning if the balance would go below $10" do - # TODO: Your test code here! proc { Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(9500) }.must_output (/.+/) end + # Withdrawal amonut causes balance to go below $10 it "Doesn't modify the balance if it would go below $10" do - # TODO: Your test code here! Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(9100).must_equal 10000 end + # Withdrawal amonut and the fee causes balance to go below $10 it "Doesn't modify the balance if the fee would put it below $10" do - # TODO: Your test code here! - Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(9000).must_equal 10000 + Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").withdraw(9000).must_equal 10000 end end describe "#add_interest" do + # Returns the actual interest amount it "Returns the interest calculated" do - # TODO: Your test code here! Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").add_interest(0.25).must_equal 2500 end + # Checks that the balance is updated it "Updates the balance with calculated interest" do - # TODO: Your test code here! account = Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") account.add_interest(0.25) account.balance.must_equal 12500 end + # Checks that the rate passed is valid data type it "Requires a positive rate" do - # TODO: Your test code here! proc { Bank::SavingsAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800").add_interest(-0.32) }.must_raise ArgumentError From 085dc8ae2161a586de6df2d6626f8f4052dfd872 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Sat, 25 Feb 2017 22:29:09 -0800 Subject: [PATCH 21/22] Edited indentations and spellings --- lib/account.rb | 1 - lib/money_market_account.rb | 12 +----------- lib/savings_account.rb | 2 +- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/lib/account.rb b/lib/account.rb index 57833b92..7466ffdd 100644 --- a/lib/account.rb +++ b/lib/account.rb @@ -1,7 +1,6 @@ require 'csv' require 'date' -# Bank module contains Account class and any future bank account logic. module Bank class Account # Allows access to the current balance of an account at any time. diff --git a/lib/money_market_account.rb b/lib/money_market_account.rb index d55cb532..6421ffdd 100644 --- a/lib/money_market_account.rb +++ b/lib/money_market_account.rb @@ -5,6 +5,7 @@ module Bank class MoneyMarketAccount < Bank::Account attr_accessor :new_month attr_reader :num_transaction + def initialize(id, balance, open_date) raise ArgumentError.new("Your initial balance must be at least $10,000.00") if balance < 1000000 super(id, balance, open_date) @@ -41,16 +42,5 @@ def reset_transactions() @new_month = false end end - - - - - - - - - - - end end diff --git a/lib/savings_account.rb b/lib/savings_account.rb index 9a10e4bd..fbf75385 100644 --- a/lib/savings_account.rb +++ b/lib/savings_account.rb @@ -12,7 +12,7 @@ def initialize(id, balance, open_date) # Method that handles withdraw def withdraw(withdraw_amount) # Raise error for non integer withdraw value - raise ArgumentError.new ("Withdraw amount must be a positive numericla value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) + raise ArgumentError.new ("Withdraw amount must be a positive numerical value") if ( !(withdraw_amount.class == Integer || withdraw_amount.class == Float) || withdraw_amount < 0 ) # Raises error for negativd withdraw value raise ArgumentError.new("Withdraw amount cannot be a negetive value") if withdraw_amount < 0 From 6f15881cca0fe9c456abed23894da5324318c742 Mon Sep 17 00:00:00 2001 From: Bo Trethewey Date: Mon, 27 Feb 2017 00:07:21 -0800 Subject: [PATCH 22/22] Updated Money Market account --- lib/money_market_account.rb | 26 ++++++++++++++++++++++---- specs/money_market_account_spec.rb | 26 ++++++++++++++------------ 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/lib/money_market_account.rb b/lib/money_market_account.rb index 6421ffdd..1c62b348 100644 --- a/lib/money_market_account.rb +++ b/lib/money_market_account.rb @@ -1,10 +1,9 @@ require 'csv' -require_relative 'account' +require_relative 'savings_account' module Bank - class MoneyMarketAccount < Bank::Account - attr_accessor :new_month - attr_reader :num_transaction + class MoneyMarketAccount < Bank::SavingsAccount + attr_accessor :new_month, :num_transaction def initialize(id, balance, open_date) raise ArgumentError.new("Your initial balance must be at least $10,000.00") if balance < 1000000 @@ -31,6 +30,25 @@ def withdraw(withdraw_amount) return @balance end + # Method that handles interest + def add_interest(rate) + super(rate) + end + + # Method that handles deposits + def deposit(money_amount) + # Negative deposit amount, invalid + if money_amount < 0 + raise ArgumentError.new "Deposit amount cannot be a negetive value" + elsif @num_transaction < 6 + if @balance >= 1000000 + @num_transaction += 1 + end + @balance += money_amount + end + return @balance + end + # Resets the number of checks used to zero def reset_transactions() if @new_month diff --git a/specs/money_market_account_spec.rb b/specs/money_market_account_spec.rb index 3ad74674..e68e638f 100644 --- a/specs/money_market_account_spec.rb +++ b/specs/money_market_account_spec.rb @@ -6,9 +6,9 @@ describe "MoneyMarketAccount" do describe "#initialize" do # Check that a MoneyMarketAccount is in fact a kind of account - it "Is a kind of Account" do + it "Is a kind of SavingsAccount" do account = Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") - account.must_be_kind_of Bank::Account + account.must_be_kind_of Bank::SavingsAccount end # Checks for instance variables @@ -76,10 +76,10 @@ end end - xdescribe "#deposit" do + describe "#deposit" do # Raises error when an erroneous deposit amount is entered it "Requires a positive deposit amount" do - account = Bank::MoneyMarketAccount.new(12345, 10000, "1999-03-27 11:30:09 -0800") + account = Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") proc { account.deposit(-1000) }.must_raise ArgumentError @@ -95,8 +95,8 @@ # If a deposit causes the balance to be greater than equal to $10,000, a fee of $100 is removed it "Removes $100 fee when deposit causes the balance to be greater than equal to $10,000" do account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") - account.withdraw(1100000) - account.deposit(1100000) + account.withdraw(1500000) + account.deposit(1510000) account.withdraw(1000000).must_equal 1000000 end @@ -111,27 +111,29 @@ # With each deposit, the num_transaction count goes up by 1 it "Each deposit transaction will be counted against the maximum number of transactions" do account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") - account.deposit(1100) - account.deposit(1100) + 2.times do + account.deposit(1100) + end account.num_transaction.must_equal 2 end # Transaction is not allowed when the num_transaction is greater than equal to 6 it "Doesn't modify the balance if the num_transaction is greater than equal to 6" do account = Bank::MoneyMarketAccount.new(12345, 2000000, "1999-03-27 11:30:09 -0800") - account.num_transaction = 6 + account.num_transaction = 10 account.deposit(1100000).must_equal 2000000 end end - xdescribe "#add_interest" do + describe "#add_interest" do # Only the actual interest amount added is returned it "Returns the interest calculated" do - Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800").add_interest(0.25).must_equal 250000 + account = Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") + account.add_interest(0.25).must_equal 250000 end # Balance is updated it "Updates the balance with calculated interest" do - account = Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800").add_interest(0.25).must_equal 250000 + account = Bank::MoneyMarketAccount.new(12345, 1000000, "1999-03-27 11:30:09 -0800") account.add_interest(0.25) account.balance.must_equal 1250000 end