Skip to content

Instantly share code, notes, and snippets.

@mjseaman
Last active December 20, 2015 17:18
Show Gist options
  • Save mjseaman/6167372 to your computer and use it in GitHub Desktop.
Save mjseaman/6167372 to your computer and use it in GitHub Desktop.
class Account
class InvalidAccountNumberError < StandardError; end
class NegativeDepositError < StandardError; end
class OverdraftError < StandardError; end
attr_reader :transactions
def initialize(acct_number, starting_balance = 0)
validate_number(acct_number)
@acct_number = acct_number
@transactions = [ starting_balance ]
end
def balance
transactions.inject(:+)
end
def acct_number
hidden_length = @acct_number.length - 4
@acct_number.sub(Regexp.new("^.{#{hidden_length}}"), "*" * hidden_length)
end
def deposit!(amount)
raise NegativeDepositError if amount < 0
add_transaction(amount)
balance
end
def withdraw!(amount)
amount = -amount if amount > 0
add_transaction(amount)
balance
end
private
def validate_number(number)
unless valid_number?(number)
raise InvalidAccountNumberError
end
end
def valid_number?(number)
number.match /^\d{10}$/
end
def add_transaction(amount)
raise OverdraftError if balance + amount < 0
transactions << amount
self
end
end
require "rspec"
require_relative "account"
describe Account do
let(:account_number){ '1234567890' }
let(:account) { Account.new(account_number) }
subject{ account }
describe "new" do
context "when given an invalid account number" do
let(:account_number){ '12' }
it "should raise error" do
expect{ account }.to raise_error
end
end
it "should return an instance of Account" do
expect(Account.new(account_number)).to be_a Account
end
end
describe "defaults" do
describe "transactions" do
subject{ account.transactions }
it{ should eq [0]}
end
end
describe "#acct_number" do
subject{ account.acct_number }
context "when the given account number is 0123456789" do
let(:account) { Account.new('0123456789') }
it{ should eq "******6789" }
end
context "when the given account number is 5555555555" do
let(:account) { Account.new('5555555555') }
it{ should eq "******5555" }
end
context "when the given account number is 2314" do
let(:account) { Account.new('2314') }
it "should raise error" do
expect{ subject }.to raise_error
end
end
end
describe "#transactions" do
subject{ account.transactions }
context "when an account started with 0 and deposited $100" do
before do
account.instance_variable_set(:@transactions, [0,100])
end
context "when I deposit $12" do
before do
account.deposit!(12)
end
it { should eq [0,100,12] }
end
end
end
describe "#balance" do
context "when I deposit to an empty account" do
subject{ account.balance }
before do
account.deposit!(1)
end
it { should eq(1) }
end
end
describe "#deposit!" do
context "when the amount deposited is negative" do
subject{ account.deposit!(-3) }
it "should raise NegativeDepositError" do
expect{ subject }.to raise_error(Account::NegativeDepositError)
end
end
context "when we deposit money the balance increases" do
subject{ account.deposit!(3000000000) }
before do
account.instance_variable_set(:@transactions, [5000000000])
end
it { should eq(8000000000) }
end
end
describe "#withdraw!" do
context "when I withdraw more money than the balance" do
subject{ account.withdraw!(120) }
it "should raise OverdraftError" do
expect{ subject }.to raise_error(Account::OverdraftError)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment