/boris-bikes-1

Week 1 - Pair Programming Project

Primary LanguageRuby

Boris Bikes

Technologies: Ruby, Rspec

Makers Academy - Week 1 Pair Programming Project

User Story | DockingStation Rspec File | Bike Rspec File | DockingStation Ruby Code | Bike Ruby Code

Outline

Let's go back several years, to the days when there were no Boris Bikes. Imagine that you're a junior developer (that was easy). Transport for London, the body responsible for delivery of a new bike system, come to you with a plan: a network of docking stations and bikes that anyone can use. They want you to build a program that will emulate all the docking stations, bikes, and infrastructure (repair staff, and so on) required to make their dream a reality.

The Task

Throughout the course of the project we we’re given several User Stories which are listed below. We started to determine which parts of the User Story are Objects and which are Methods. As in all TDD we created a test for a feature that we wanted to manipulate and then wrote the code to pass those tests.

User Story

As a person,
So that I can use a bike,
I'd like a docking station to release a bike.

As a person,
So that I can use a good bike,
I'd like to see if a bike is working

As a person,
So that I can use a bike,
I'd like to get a bike from a docking station.

As a person,
So that I can use a good bike,
I'd like to see if a bike is working

As a member of the public
So I can return bikes I've hired
I want to dock my bike at the docking station

As a member of the public
So I can decide whether to use the docking station
I want to see a bike that has been docked

As a member of the public,
So that I am not confused and charged unnecessarily,
I'd like docking stations not to release bikes when there are none available.

As a maintainer of the system,
So that I can control the distribution of bikes,
I'd like docking stations not to accept more bikes than their capacity.

As a system maintainer,
So that I can plan the distribution of bikes,
I want a docking station to have a default capacity of 20 bikes.

As a system maintainer,
So that busy areas can be served more effectively,
I want to be able to specify a larger capacity when necessary.

As a member of the public,
So that I reduce the chance of getting a broken bike in future,
I'd like to report a bike as broken when I return it.

As a maintainer of the system,
So that I can manage broken bikes and not disappoint users,
I'd like docking stations not to release broken bikes.

As a maintainer of the system,
So that I can manage broken bikes and not disappoint users,
I'd like docking stations to accept returning bikes (broken or not).

DockingStation Rspec File

require "docking_station"

describe DockingStation do
  # Create bike double and allow it to access variable "working"
  let(:bike) { double :bike, :working= => true, working?: false}

  # TEST: Release a bike
  it { is_expected.to respond_to :release_bike }

  # TEST: Release only a working bike
  it 'releases a bike if working' do
    allow(bike).to receive(:working?).and_return(true)
    subject.dock_bike(bike)
    expect(subject.release_bike).to be_working
  end

  # TEST: Check method dock_bike responds to 1 argument
  it { is_expected.to respond_to(:dock_bike).with(1).argument }

  # TEST: Dock a bike successfully
  it 'docks something' do
    allow(bike).to receive(:working?)
    expect(subject.dock_bike(bike)).to eq [bike]
  end

  # TEST: Fill docking station up and check for full error
  it "gives an error when docking station is full" do
    DockingStation::DEFAULT_CAPACITY.times { subject.dock_bike(bike) }
    expect{subject.dock_bike(bike)}.to raise_error 'Full dock'
  end

  # TEST: Dock a bike then release the same bike
  it 'releases a bike' do
    allow(bike).to receive(:working?).and_return(true)
    subject.dock_bike(bike)
    expect(subject.release_bike).to eq bike
  end

  # TEST: Test for error if docking station is empty
  it 'raises an error if dock empty' do
    expect {subject.release_bike}.to raise_error 'Empty dock'
  end

  # Test different size docking stations
  it 'Allow user to set capacity of docking station' do
    # Create a new station with 50 bikes and test
    num = 50
    station = DockingStation.new(num)
    expect(station.capacity).to eq num

    # Create a default station using the DEFAULT_CAPACITY constant
    station = DockingStation.new
    expect(station.capacity).to eq DockingStation::DEFAULT_CAPACITY
  end
end

Bike Rspec File

require 'bike'

describe Bike do
  # TEST: check to see if we can respond to method working?
  it {is_expected.to respond_to :working?}
end

DockingStation Ruby Code

require_relative 'bike'

class DockingStation

  DEFAULT_CAPACITY = 20

  attr_reader :capacity

  def initialize(capacity=DEFAULT_CAPACITY)
      @docked = []
      @capacity = capacity
  end

  def release_bike
    raise "Empty dock" if empty?
    docked.each_with_index {|bike,index| docked.delete_at(index) ; return bike if bike.working? }
    raise "All bikes broken!"
  end

  def dock_bike(bike, working = true)
    raise "Full dock" if full?
    bike.working = false if !working
    docked << bike
  end

  private

  attr_reader :docked
  def full?
    docked.count >= capacity
  end

  def empty?
    docked.empty?
  end
end

Bike Ruby Code

class Bike

  attr_accessor :working

  def initialize(work=true)
    @working = work
  end

  def working?
    working
  end
end