Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Luiza Airport Challenge #2502

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
145 changes: 145 additions & 0 deletions docs/user_stories.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# User story 1
As an air traffic controller
So I can get passengers to a destination
I want to instruct a plane to land at an airport

# Nouns
air traffic controller, passengers, destination, plane, airport

# Verbs
get, instruct, land

# Functional representation
Objects:
- plane
- airport

Messages:
- land

# Diagram
Airport <--land--> Plane


##################################
# User story 2
As an air traffic controller
So I can get passengers on the way to their destination
I want to instruct a plane to take off from an airport and confirm that it is no longer in the airport

# Nouns
air traffic controller, passengers, destination, plane, airport

# Verbs
get, instruct, take off, confirm

# Functional representation
Objects:
- Airport
- Plane

Messages:
- take_off
- left_airport?

# Diagrams
Airport <--take_off--> Plane

Plane <--left_airport?--> true


##################################
# User story 3
As an air traffic controller
To ensure safety
I want to prevent landing when the airport is full

# Nouns
air traffic controller, safety, airport, full

# Verbs
ensure, prevent, landing

# Functional representation
Objects:
- Airport
- Plane

Messages:
- landing
- full?

# Diagrams
Airport <--landing--> Plane

Airport <--full?--> true/false


##################################
# User story 4
As the system designer
So that the software can be used for many different airports
I would like a default airport capacity that can be overridden as appropriate

# Functional representation
Objects:
- Airport

Messages:
- set_capacity

Airport <--set_capacity--> num


##################################
# User story 5
As an air traffic controller
To ensure safety
I want to prevent takeoff when weather is stormy

# Functional representation
Objects:
- Airport
- Weather
- Plane

Messages:
- prevent_take_off

# Diagrams
Airport <--take_off--> Plane
Weather <--stormy?--> ture/false


##################################
# User story 6
As an air traffic controller
To ensure safety
I want to prevent landing when weather is stormy

# Functional representation
Objects:
- Airport
- Weather
- Plane

Messages:
- prevent_landing

# Diagrams
Airport <--land--> Plane
Weather <--stormy?--> true/false


##################################

# Edge cases
- planes can only take off from airports they are in;
# done
- planes that are already flying cannot take off and/or be in an airport;
(when plane lands left_airport? should be false)
# done
- planes that are landed cannot land again and must be in an airport
# done

##################################
42 changes: 42 additions & 0 deletions lib/airport.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require_relative 'plane'
require_relative 'weather'

class Airport

DEFAULT_CAPACITY = 5

attr_reader :planes, :capacity

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

def land(plane)
fail 'Airport full' if full?
fail 'Landing not allowed due to adverse weather' if stormy?
fail 'Plane already landed' if @planes.include?(plane)
plane.allowed_land
@planes << plane
plane
end

def take_off(plane)
fail 'Plane not in the airport' unless @planes.include?(plane)
fail 'Take-off not allowed due to adverse weather' if stormy?
plane.allowed_take_off
@planes.delete(plane)
end

private

def full?
@planes.length >= @capacity
end

def stormy?
weather = Weather.stormy?
weather
end

end
19 changes: 19 additions & 0 deletions lib/plane.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class Plane

def initialize
@left_airport = true
end

def allowed_take_off
@left_airport = true
end

def left_airport?
@left_airport
end

def allowed_land
@left_airport = false
end

end
10 changes: 10 additions & 0 deletions lib/weather.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class Weather

WEATHER = [:sunny, :rainy, :stormy, :windy]

def self.stormy?
current_weather = WEATHER.sample
current_weather == :stormy
end

end
133 changes: 133 additions & 0 deletions spec/airport_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
require './lib/airport'
require './lib/weather'

describe Airport do

# Capacity
describe '#capacity' do

it 'has a default value' do
expect(subject.capacity).to eq Airport::DEFAULT_CAPACITY
end

it 'can be set to a specific value' do
airport = Airport.new(10)
expect(airport.capacity).to eq 10
end

end

# Lands a plane
describe '#land' do

it 'airport responds to the method' do
expect(subject).to respond_to :land
end

it 'accepts one argument' do
expect(subject).to respond_to(:land).with(1).argument
end

it 'lands a plane' do
weather = class_double('Weather').as_stubbed_const
allow(weather).to receive(:stormy?).and_return(false)

plane = double (:plane)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding doubles to the top of the Airport spec would dry code a bit

allow(plane).to receive(:allowed_land)
expect(subject.land(plane)).to eq plane
end

it 'rasies an error when airport is full' do
weather = class_double('Weather').as_stubbed_const
allow(weather).to receive(:stormy?).and_return(false)

plane = double (:plane)
allow(plane).to receive(:allowed_land)
subject.capacity.times {subject.land(Plane.new)}
expect {subject.land(plane)}.to raise_error 'Airport full'
end

it 'raises an error when the weather is stormy' do
weather = class_double('Weather').as_stubbed_const
allow(weather).to receive(:stormy?).and_return(true)

plane = double (:plane)
allow(plane).to receive(:allowed_land)
expect{ subject.land(plane) }.to raise_error 'Landing not allowed due to adverse weather'
end

it 'raises an error when the plane has already landed' do
weather = class_double('Weather').as_stubbed_const
allow(weather).to receive(:stormy?).and_return(false)

plane = double (:plane)
allow(plane).to receive(:allowed_land)
subject.land(plane)
expect{ subject.land(plane) }.to raise_error 'Plane already landed'
end

it 'changes left_airport? to false' do
weather = class_double('Weather').as_stubbed_const
allow(weather).to receive(:stormy?).and_return(false)

plane = Plane.new
expect(subject.land(plane)).not_to be_left_airport
end

end

# Takes off a plane
describe '#take_off' do

it 'airport responds to the method' do
expect(subject).to respond_to :take_off
end

it 'accepts one argument' do
expect(subject).to respond_to(:take_off).with(1).argument
end

it 'raises an error when the weather is stormy' do
weather = class_double('Weather').as_stubbed_const
allow(weather).to receive(:stormy?).and_return(false)

plane = double (:plane)
allow(plane).to receive_messages(:allowed_land => nil, :allowed_take_off => nil)
subject.land(plane)

allow(weather).to receive(:stormy?).and_return(true)
expect{ subject.take_off(plane) }.to raise_error 'Take-off not allowed due to adverse weather'
end

it 'takes-off the plane when the weather is NOT stormy' do
weather = class_double('Weather').as_stubbed_const
allow(weather).to receive(:stormy?).and_return(false)

plane = double (:plane)
allow(plane).to receive_messages(:allowed_land => nil, :allowed_take_off => nil)
subject.land(plane)
expect(subject.take_off(plane)).to eq plane
end

it 'confirms the plane has left_airport?' do
weather = class_double('Weather').as_stubbed_const
allow(weather).to receive(:stormy?).and_return(false)

plane = Plane.new
subject.land(plane)
#expect(plane.left_airport?).to eq true
expect(subject.take_off(plane)).to be_left_airport
end

it 'raises an error when the plane is not in the airport' do
weather = class_double('Weather').as_stubbed_const
allow(weather).to receive(:stormy?).and_return(false)

plane = double (:plane)
allow(plane).to receive_messages(:allowed_land => nil, :allowed_take_off => nil)
expect{subject.take_off(plane)}.to raise_error 'Plane not in the airport'
end

end

end
27 changes: 27 additions & 0 deletions spec/plane_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'plane'

describe Plane do

it 'responds to allowed_take_off method' do
expect(subject).to respond_to :allowed_take_off
end

it 'responds to _left_airport? method' do
expect(subject).to respond_to :left_airport?
end

it 'after allowed_take_off returns true for left_airport?' do
subject.allowed_take_off
expect(subject).to be_left_airport
end

it 'responds to allowed_land method' do
expect(subject).to respond_to :allowed_land
end

it 'after allowed_land returns false for left_airport' do
subject.allowed_land
expect(subject).not_to be_left_airport
end

end
Loading