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

Baljit's branch for airport_challenge #2495

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 23 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,35 @@ Airport Challenge
= ===(_________)

```
# Airport Challenge

Instructions
---------
This Airport challenge allows users to instruct a plane to land and take off from an airport, but only if the weather is sunny!

* Feel free to use google, your notes, books, etc. but work on your own
* If you refer to the solution of another coach or student, please put a link to that in your README
* If you have a partial solution, **still check in a partial solution**
* You must submit a pull request to this repo with your code by 10am Monday morning
## Getting started

Steps
-------
- First step - Fork this repo and clone it to your local machine
- Second step - Run the command gem install bundler (if you don't have bundler already)
- Third step - When the installation completes, run bundle

1. Fork this repo, and clone to your local machine
2. Run the command `gem install bundler` (if you don't have bundler already)
3. When the installation completes, run `bundle`
4. Complete the following task:

Task
-----
## How to use

We have a request from a client to write the software to control the flow of planes at an airport. The planes can land and take off provided that the weather is sunny. Occasionally it may be stormy, in which case no planes can land or take off. Here are the user stories that we worked out in collaboration with the client:
Now, I know you're excited to get your pilot's hat on, but please read these instructions first, which will walk you through how to test my program.

- Open your terminal and navigate to the Airport_challenge directory
- Run irb and require './lib/airport.rb'
- You can create plane instances (plane = Plane.new) and airport instances (airport = Airport.new).
- To instruct a plane to take off from an airport you can use the 'takeoff' method (airport.takeoff(plane))
- To instruct a plane to land you can use the 'land' method (airport.land(plane))
## Some things to note
- The airport's default capacity is set to 10 planes, so if you would like to change the airports default capacity, you can pass your desired capacity as an integer to the airport instance eg (airport = Airport.new(20))
- You will only be able to land and take-off planes if the weather is sunny. Luckily, the weather is sunny 75% of the time, and stormy the other 25%.

## Running tests

- If you would like to run my unit tests, run rspec in the Airport_challenge directory.

## User stories

```
As an air traffic controller
Expand All @@ -59,31 +67,3 @@ As an air traffic controller
To ensure safety
I want to prevent landing when weather is stormy
```

Your task is to test drive the creation of a set of classes/modules to satisfy all the above user stories. You will need to use a random number generator to set the weather (it is normally sunny but on rare occasions it may be stormy). In your tests, you'll need to use a stub to override random weather to ensure consistent test behaviour.

Your code should defend against [edge cases](http://programmers.stackexchange.com/questions/125587/what-are-the-difference-between-an-edge-case-a-corner-case-a-base-case-and-a-b) such as inconsistent states of the system ensuring that planes can only take off from airports they are in; planes that are already flying cannot take off and/or be in an airport; planes that are landed cannot land again and must be in an airport, etc.

For overriding random weather behaviour, please read the documentation to learn how to use test doubles: https://www.relishapp.com/rspec/rspec-mocks/docs . There’s an example of using a test double to test a die that’s relevant to testing random weather in the test.

Please create separate files for every class, module and test suite.

In code review we'll be hoping to see:

* All tests passing
* High [Test coverage](https://github.com/makersacademy/course/blob/main/pills/test_coverage.md) (>95% is good)
* The code is elegant: every class has a clear responsibility, methods are short etc.

Reviewers will potentially be using this [code review rubric](docs/review.md). Referring to this rubric in advance will make the challenge somewhat easier. You should be the judge of how much challenge you want this at this moment.

**BONUS**

* Write an RSpec **feature** test that lands and takes off a number of planes

Note that is a practice 'tech test' of the kinds that employers use to screen developer applicants. More detailed submission requirements/guidelines are in [CONTRIBUTING.md](CONTRIBUTING.md)

Finally, don’t overcomplicate things. This task isn’t as hard as it may seem at first.

* **Submit a pull request early.**

* Finally, please submit a pull request before Monday at 10am with your solution or partial solution. However much or little amount of code you wrote please please please submit a pull request before Monday at 10am.
33 changes: 33 additions & 0 deletions lib/airport.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require_relative '../lib/weather.rb'
require_relative '../lib/plane.rb'

class Airport
attr_reader :planes, :capacity
DEFAULT_CAPACITY = 10

def initialize(capacity = DEFAULT_CAPACITY, weather: Weather.new)
@planes = []
@capacity = capacity
@weather = weather
end

def land(plane)
fail "Plane is not in the air" if plane.in_flight?
fail 'Due to stormy weather no landing allowed' if stormy?
fail 'Airport is full no landing allowed' if @planes.count >= DEFAULT_CAPACITY
plane.in_flight = false
@planes << plane
end

def takeoff(plane)
fail 'Due to stormy weather no landing allowed' if stormy?
fail 'Plane is not at the airport' if plane.in_flight?
plane.in_flight = true
@planes.delete(plane)
'plane has taken off'
end

def stormy?
@weather.stormy
end
end
11 changes: 11 additions & 0 deletions lib/plane.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Plane
attr_accessor :in_flight

def initialize(in_flight = false)
@in_flight = in_flight
end

def in_flight?
@in_flight
end
end
13 changes: 13 additions & 0 deletions lib/weather.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Weather
def stormy
random_outlook == :stormy
end

private

OUTLOOKS = [:stormy, :fine, :fine, :fine]

def random_outlook
OUTLOOKS.sample
end
end
66 changes: 66 additions & 0 deletions spec/airport_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
require_relative '../lib/airport.rb'

describe Airport do
let(:plane) { Plane.new }
let(:airport) { Airport.new }
let(:weather) { Weather.new }


describe '# landing' do

it 'has a Default capcity' do
Copy link

Choose a reason for hiding this comment

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

small typo, capacity

expect(airport.capacity).to eq(Airport::DEFAULT_CAPACITY)
end

it '--to be prevented when airport is full' do
allow(airport).to receive(:stormy?).and_return false
Airport::DEFAULT_CAPACITY.times { airport.land Plane.new }
expect { airport.land Plane.new }.to raise_error 'Airport is full no landing allowed'
end

it 'is prevented due to stormy weather' do
allow(airport).to receive(:stormy?).and_return true
expect { airport.land plane }.to raise_error "Due to stormy weather no landing allowed"
end

it 'raise an error when plane is not in the air before landing' do
allow(airport).to receive(:stormy?).and_return false
plane = Plane.new(true)
expect { airport.land plane }.to raise_error "Plane is not in the air"
end
it 'lands multiple planes' do # bonus points
allow(airport).to receive(:stormy?).and_return false
5.times { airport.land Plane.new }
expect { airport.land Plane.new }.not_to raise_error
end
end
baljitrakhra marked this conversation as resolved.
Show resolved Hide resolved

describe '#take-offs' do
it { is_expected.to respond_to(:takeoff).with(1).argument }

it 'informs that the plane has taken off' do
allow(airport).to receive(:stormy?).and_return false
airport.planes << plane
expect(airport.takeoff plane).to eq 'plane has taken off'
end
it 'gets weather status' do
allow(airport).to receive(:stormy?).and_return false
expect(weather.stormy).to be(true).or be(false)
end
it 'is prevented due to stormy weather' do
allow(airport).to receive(:stormy?).and_return true
expect { airport.takeoff plane }.to raise_error "Due to stormy weather no landing allowed"
end

it 'raise an error when plane is not in the airport before taking off' do
allow(airport).to receive(:stormy?).and_return false
plane.in_flight = true
expect { airport.takeoff plane }.to raise_error "Plane is not at the airport"
end
it 'multiple planes' do # bonus points
allow(airport).to receive(:stormy?).and_return false
5.times { airport.land Plane.new }
expect { airport.takeoff plane }.not_to raise_error
end
end
end
4 changes: 4 additions & 0 deletions spec/plane_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require_relative '../lib/plane.rb'

describe Plane do
end
19 changes: 19 additions & 0 deletions spec/weather_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require_relative '../lib/weather.rb'

describe Weather do
let(:weather) { Weather.new }

it { is_expected.to respond_to(:stormy) }

describe '#tells the weather condition' do
it "is sunny" do
allow(weather).to receive(:random_outlook).and_return(:fine)
expect(weather.stormy).to eq false
end

it "is stormy" do
allow(weather).to receive(:random_outlook).and_return(:stormy)
expect(weather.stormy).to eq true
end
end
end