Coding as a Craft Bootcamp Prep - v2.0
  • Introduction
  • Week 1 - Programming Basics - Ruby
    • Understanding the problem statement
    • User stories
    • Pair programming
    • The ATM challenge
      • Step 1 - Setting the stage
      • Step 2 - The core functionality
      • Step 3 - Interacting with objects
      • Step 4 - Refactoring
      • Step 5 - Testing the sad path
      • Step 6 - Cash is King
      • Step 7 - The Account
      • Step 8 - The Person
      • Step 9 - Making it all work together
    • Library Challenge
      • Important Topics
    • Extras
    • RSpec
      • RSpec introduction
      • Install and configure
      • RSpec Basics
      • How to write specs
      • So many Expectations...
      • Matchers
  • Week 2 -Programming Basics - JavaScript
  • Week 3 - TypeScript and Angular
  • Week 4 - Ruby on Rails Basics
  • Week 5 - Working With Legacy Code
  • Week 6 - Midcourse Project
  • Week 7 - Going Mobile
  • Week 8 & 9 - Advanced SaaS Applications
  • Week 10 - Expose and Consume API's
  • Configuring RSpec
Powered by GitBook
On this page
  1. Week 1 - Programming Basics - Ruby
  2. The ATM challenge

Step 9 - Making it all work together

Integrating all parts

Alright, at this stage we can create an Atm, we can create a Person that has an Account. ThePersoncan have cash in pocket or hold his money in his Account. All pretty straight forward.

Now we want to create a method that allows a person to withdraw funds from a specific atm and when he does that 3 things should happen:

  1. The balance of the account should DECREASE

  2. The funds in the ATM should DECREASE

  3. The cash in pocket should INCREASE

Consider these specs.

spec/person_spec.rb

describe 'can manage funds if an account been created' do

  [...]
  it 'funds are added to the account balance - deducted from cash' do
    subject.cash = 100
    subject.deposit(100)
    expect(subject.account.balance).to be 100
    expect(subject.cash).to be 0
  end


  it 'can withdraw funds' do
    command = lambda { subject.withdraw(amount: 100, pin: subject.account.pin_code, account: subject.account, atm: atm) }
    expect(command.call).to be_truthy
  end


  it 'withdraw is expected to raise error if no ATM is passed in' do
    command = lambda { subject.withdraw(amount: 100, pin: subject.account.pin_code, account: subject.account) }
    expect { command.call }.to raise_error 'An ATM is required'
  end


  it 'funds are added to cash - deducted from account balance' do
    subject.cash = 100
    subject.deposit(100)
    subject.withdraw(amount: 100, pin: subject.account.pin_code, account: subject.account, atm: atm)
    expect(subject.account.balance).to be 0
    expect(subject.cash).to be 100
  end
end

Note: There are some new commands and techniques in the code above. Google them, talk to your peers and figure out WHY we are using them so you get at good understanding of what we are doing. I will be going over some of them in my talks and break-out sessions, but it is up to you to find the best way of using them.

Now I will show you how I implemented the Person class - at least in the first development cycle (there are plenty of room for refactoring and I expect you to improve on this code).

lib/person.rb

require './lib/account'

class Person
 attr_accessor :name, :cash, :account

  def initialize(attrs = {})
    @name = set_name(attrs[:name])
    @cash = 0
    @account = nil
  end

  def create_account
    @account = Account.new(owner: self)
  end

  def deposit(amount)
    @account == nil ? missing_account : deposit_funds(amount)
  end

  def withdraw(args = {})
    @account == nil ? missing_account : withdraw_funds(args)
  end


  private

  def deposit_funds(amount)
    @cash -= amount
    @account.balance += amount
  end

  def withdraw_funds(args)
    args[:atm] == nil ? missing_atm : atm = args[:atm]
    account = @account
    amount = args[:amount]
    pin = args[:pin]
    response = atm.withdraw(amount, pin, account)
    response[:status] == true ? increase_cash(response) : response
  end

  def increase_cash(response)
    @cash += response[:amount]
  end

  def set_name(name)
    name == nil ? missing_name : name
  end

  def missing_name
    raise ArgumentError, 'A name is required'
  end

  def missing_account
    raise RuntimeError, 'No account present'
  end

  def missing_atm
    raise RuntimeError, 'An ATM is required'
  end
end
PreviousStep 8 - The PersonNextLibrary Challenge

Last updated 7 years ago