diff --git a/README_JL.md b/README_JL.md new file mode 100644 index 0000000000..b5f38794b3 --- /dev/null +++ b/README_JL.md @@ -0,0 +1,181 @@ +## Airport Weekend Challenge + +# How to install +Fork this repo, and clone to your local machine +Run the command gem install bundler (if you don't have bundler already) +When the installation completes, run bundle + +# How to Run +Open IRB +Require all .rb files. + +# How to test your code +Run RSpec from the Airport directory. + +# Introduction + +This project is the weekend task following the first week at Makers Academy. +The project comprises the simulation of an airport where the user is an air traffic controller. The main +methods available to the user are: + - land_plane, which adds a plane to the airport + - take_off(plane), which removes a specific plane from the airport + +The methods above have been written to react to further variables, such as capacity in the airport and +weather. + +# Motivation + +The motivation behind this project is to develop an understanding of how to Test Drive the writing of the +program. The general process when writing this code was to create feature and unit tests using IRB/ RSpec +and then write code that will satisfy the test, using error messages as guides. + +# Brief + +The following user stories were provided: + + As an air traffic controller + So I can get passengers to a destination + I want to instruct a plane to land at an airport + + 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 + + As an air traffic controller + To ensure safety + I want to prevent landing when the airport is full + + 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 + + As an air traffic controller + To ensure safety + I want to prevent takeoff when weather is stormy + + As an air traffic controller + To ensure safety + I want to prevent landing when weather is stormy + +# Brief Interpretation + +The following Classes and Mehtods were derrived from the user stories: + + Airport Controller (user) + Plane (Class) + Airport (Class) + land_plane + take_off + check_weather + Weather (Class) + +# Steps + +Several steps have been derrived from each of the user stories, to methodically build out tests and code. +These steps are written below with commentary and some example feature tests: + + 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 + + a. Create airport class + b. Pass plane into airport, using land_plane. Plane needs to be stored in airport (put inside instance + variable). + c. Create plane class + d. Update 'b' to accept instances of plane. - ended up writing this to create new instances of plane + rather than accepting it as an argument. + + 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 + + a. Create take_off method + + jimmylyons@Jimmys-MBP airport % irb + 3.0.2 :001 > require './lib/plane.rb' + => true + 3.0.2 :002 > require './lib/airport.rb' + => true + 3.0.2 :003 > airport = Airport.new + => # + 3.0.2 :004 > airport.land_plane + => # + 3.0.2 :005 > airport.planes_in_airport + => # + 3.0.2 :006 > airport.planes_in_airport.takeoff + (irb):6:in `
': undefined method `takeoff' for # (NoMethodError) + from /Users/jimmylyons/.rvm/rubies/ruby-3.0.2/lib/ruby/gems/3.0.0/gems/irb-1.3.5/exe/irb:11:in `' + from /Users/jimmylyons/.rvm/rubies/ruby-3.0.2/bin/irb:23:in `load' + from /Users/jimmylyons/.rvm/rubies/ruby-3.0.2/bin/irb:23:in `
' + 3.0.2 :007 > + + b. Ensure that plane leaves airport when plane takes off (instance variable should be empty) + c. Ensure that only specific instances of Plane that are in the airport can take off - not sure how to + do this + + 3) As an air traffic controller: To ensure safety; I want to prevent landing when the airport is full + + jimmylyons@Jimmys-MBP airport % irb + 3.0.2 :001 > require './lib/plane.rb' + => true + 3.0.2 :002 > require './lib/airport.rb' + => true + 3.0.2 :003 > airport = Airport.new + => # + 3.0.2 :004 > land_plane + (irb):4:in `
': undefined local variable or method `land_plane' for main:Object (NameError) + from /Users/jimmylyons/.rvm/rubies/ruby-3.0.2/lib/ruby/gems/3.0.0/gems/irb-1.3.5/exe/irb:11:in `' + from /Users/jimmylyons/.rvm/rubies/ruby-3.0.2/bin/irb:23:in `load' + from /Users/jimmylyons/.rvm/rubies/ruby-3.0.2/bin/irb:23:in `
' + 3.0.2 :005 > airport.land_plane + => # + 3.0.2 :006 > airport.land_plane + => # #--> keeps landing planes past capacity of 1 + + a. Ammend land_plane, so that when the airport (instance variable) is full, the plane cannot land + + 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 + + a. Ammend airport instance variable to array and set max capacity to a new instance variable - will + need to update previous tests + b. Add a method to change capacity + + 5) As an air traffic controller; To ensure safety; I want to prevent takeoff when weather is stormy + + a. Will need to create something like is_stormy? - Need to create random weather generator - should + this be new class Weather? + + jimmylyons@Jimmys-MBP airport % irb + 3.0.2 :001 > require './lib/weather' + => true + 3.0.2 :002 > weather = Weather.new + => # + 3.0.2 :003 > weather = Weather.new + => # + 3.0.2 :004 > weather = Weather.new + => # + 3.0.2 :005 > weather = Weather.new + => # + 3.0.2 :006 > weather = Weather.new + => # + 3.0.2 :007 > weather = Weather.new + => # + 3.0.2 :008 > weather = Weather.new + => # + 3.0.2 :009 > weather = Weather.new + => # + + b. Modify take_off so that if weather is stormy, then plane cannot take-off. + + 6) As an air traffic controller; To ensure safety; I want to prevent landing when weather is stormy + + a. Modify land_plane so that when weather is stormy, plan cannot land. + +# Key Thoughts and Issues + + • I can't get failure messages to work when I run RSpec. For some reason all the syntax I try keeps + failing. + • I think that take_off and land_plane should have check_weather as part of their methods, but then I + had no way to control the weather in my tests. I suppose that I can assume that the user will check + the weather before take off or landing. + I could probably refactor to get the above to work, but I think I would end up making my code less + concise. diff --git a/lib/airport.rb b/lib/airport.rb new file mode 100644 index 0000000000..83c000e4d4 --- /dev/null +++ b/lib/airport.rb @@ -0,0 +1,37 @@ +class Airport + + attr_accessor :planes_in_airport + attr_accessor :capacity + attr_accessor :current_weather + + def initialize + @planes_in_airport = [] + @capacity = 10 + @current_weather = check_weather + end + + def land_plane + check_for_storm + fail 'Airport is full' unless @planes_in_airport.length < @capacity + @planes_in_airport << Plane.new + @planes_in_airport.last + end + + def take_off(plane) + check_for_storm + @planes_in_airport.delete(plane) + plane + end + + def def_capacity(num) + @capacity = num + end + + def check_weather + @current_weather = Weather.new.weather + end + + def check_for_storm + fail 'Cannot fly when there is a storm' unless @current_weather != 'stormy' + end +end diff --git a/lib/plane.rb b/lib/plane.rb new file mode 100644 index 0000000000..4578b22819 --- /dev/null +++ b/lib/plane.rb @@ -0,0 +1,3 @@ +class Plane + +end diff --git a/lib/weather.rb b/lib/weather.rb new file mode 100644 index 0000000000..255fe25948 --- /dev/null +++ b/lib/weather.rb @@ -0,0 +1,7 @@ +class Weather + attr_accessor :weather + def initialize + rand_num = rand(10) + rand_num < 3 ? @weather = 'stormy' : @weather = 'sunny' + end +end diff --git a/spec/airport_spec.rb b/spec/airport_spec.rb new file mode 100644 index 0000000000..9d8a1f9839 --- /dev/null +++ b/spec/airport_spec.rb @@ -0,0 +1,70 @@ +require 'airport' + +describe Airport do + + subject(:airport) { described_class.new } + let(:plane) { Plane.new } + + it { is_expected.to be_kind_of Airport } + + describe '#land_plane' do + it 'allows plane to land in airport' do + airport.current_weather = 'sunny' + + expect(airport.land_plane).to be_kind_of Plane + end + + it 'does not allow planes to land when airport is full' do + airport.current_weather = 'sunny' + airport.capacity.times { airport.land_plane } + + expect { airport.land_plane }.to raise_error('Airport is full') + end + + it 'does not allow plane to land in airport when stormy' do + airport.current_weather = 'stormy' + + expect { airport.land_plane }.to raise_error('Cannot fly when there is a storm') + end + end + + describe '#take_off' do + context "when 'plane' is in 'planes_in_airport'" do + before(:each) { airport.planes_in_airport = [plane] } + + it 'does not let planes take off when stormy' do + airport.current_weather = 'stormy' + + expect { airport.take_off(plane) }.to raise_error('Cannot fly when there is a storm') + end + + context 'when the weather is sunny' do + before(:each) { allow(airport).to receive(:check_for_storm).and_return(nil) } + + it 'allows plane to leave airport' do + expect(airport.take_off(plane)).to eq plane + end + + it 'removes plane from airport' do + airport.take_off(plane) + + expect(airport.planes_in_airport).to eq([]) + end + end + end + end + + describe '#def_capacity' do + it 'allows you to change the capacity of the airport' do + airport.def_capacity(20) + + expect(airport.capacity).to eq(20) + end + end + + describe '#check_weather' do + it 'reports what if the weather is sunny or stormy' do + expect(airport.check_weather).to eq('sunny').or eq('stormy') + end + end +end diff --git a/spec/plane_spec.rb b/spec/plane_spec.rb new file mode 100644 index 0000000000..010edb2ca0 --- /dev/null +++ b/spec/plane_spec.rb @@ -0,0 +1,7 @@ +require 'plane' + +describe Plane do + + it { is_expected.to be_kind_of Plane } + +end diff --git a/spec/weather_spec.rb b/spec/weather_spec.rb new file mode 100644 index 0000000000..36c49052e0 --- /dev/null +++ b/spec/weather_spec.rb @@ -0,0 +1,12 @@ +require 'weather' + +describe Weather do + + it { is_expected.to be_kind_of Weather } + + it 'can be sunny or stormy' do + + expect(subject.weather).to eq('sunny').or eq('stormy') + end + +end