diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4c209dde8f..db60678887 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -2,7 +2,7 @@ Please write your full name here to make it easier to find your pull request. -# User stories +# User stories Please list which user stories you've implemented (delete the ones that don't apply). @@ -21,4 +21,4 @@ Does your README contains instructions for - [ ] how to run, - [ ] and how to test your code? -[Here is a pill](https://github.com/makersacademy/course/blob/main/pills/readmes.md) that can help you write a great README! \ No newline at end of file +[Here is a pill](https://github.com/makersacademy/course/blob/main/pills/readmes.md) that can help you write a great README! diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9adc651647..2273408796 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,21 +1,18 @@ -Tech Test Submission Requirements/Guidelines -====== +# Tech Test Submission Requirements/Guidelines Before submitting your test, please review the requirements/guidelines below. Note that the requirements are mandatory and if you do not satisfy them we won't review your code (we don't mean to be harsh but this is based on the minimum expectations that our hiring partners require when you submit code for tech tests). -Requirements ------- +## Requirements -* Make sure you have written your own README that briefly explains your approach to solving the challenge. -* If your code isn't finished it's not ideal but acceptable as long as you explain in your README where you got to and how you would plan to finish the challenge. -* All code must be written test-first - we're looking for 100% test coverage or as near as possible to that figure. - * The test coverage statistics `SimpleCov` generates after your tests will show you what your coverage is like and where it's lacking. -* Ensure all your tests are passing. -* Check your code conforms to the [Rubocop](https://github.com/bbatsov/rubocop) style guide. Run `rubocop`, read and digest what it says, fix the violations and then run `rubocop` again to check. When you're done, commit and push. - * Advanced mode: run `rubocop` before every commit you make and fix mistakes before you even commit! +- Make sure you have written your own README that briefly explains your approach to solving the challenge. +- If your code isn't finished it's not ideal but acceptable as long as you explain in your README where you got to and how you would plan to finish the challenge. +- All code must be written test-first - we're looking for 100% test coverage or as near as possible to that figure. + - The test coverage statistics `SimpleCov` generates after your tests will show you what your coverage is like and where it's lacking. +- Ensure all your tests are passing. +- Check your code conforms to the [Rubocop](https://github.com/bbatsov/rubocop) style guide. Run `rubocop`, read and digest what it says, fix the violations and then run `rubocop` again to check. When you're done, commit and push. + - Advanced mode: run `rubocop` before every commit you make and fix mistakes before you even commit! -Guidelines -------- +## Guidelines -* Ensure you've understood the specification and built the code according to the challenge guidelines. -* Read through [Code Reviews :pill:](https://github.com/makersacademy/course/blob/main/pills/code_reviews.md) to understand what we're looking for in your code. +- Ensure you've understood the specification and built the code according to the challenge guidelines. +- Read through [Code Reviews :pill:](https://github.com/makersacademy/course/blob/main/pills/code_reviews.md) to understand what we're looking for in your code. diff --git a/README.md b/README.md index 6dd4fa6bc9..320506fcf4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -Airport Challenge -================= +**_Please scroll to bottom to see my notes_** -``` +# Airport Challenge + +`````` ______ _\____\___ = = ==(____MA____) @@ -11,53 +12,50 @@ Airport Challenge `---~~\___________/------------````` = ===(_________) -``` +`````` -Instructions ---------- +## Instructions -* 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 +- 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 -Steps -------- +## Steps 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 ------ +## Task -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: +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: ``` -As an air traffic controller -So I can get passengers to a destination +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 +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 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 takeoff when weather is stormy -As an air traffic controller -To ensure safety -I want to prevent landing when weather is stormy +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. @@ -70,20 +68,27 @@ 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. +- 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. +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 +- 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) +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.** +- **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. + +Student notes: -* 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. +- I needed to spend some time practising on Boris Bikes to get my head around this one, and as a result I wasn't able to completely finish. Planes can take off and land, default capacity can be overridden by passing the airport an argument when instantiating it, and exceptions are raised according to the weather, but I was didn't have time to learn about stubbing to ensure regular testing, and didn't have time to work out how to defend against all edge cases. Consequently, it's possible to land the same plane into two different airports, or into the same airport twice etc. Though at least planes can only take off from airports that they're in, as far as I can tell. I'll look more into how to guard against these errors - I'm assuming some kind of exception? - but will need to submit it in its current state for now. +- If you run the rspec, you'll get different errors according to what weather you get, but the lowest number of errors is 2, which seems to be to do with a single plane being returned in an array... +- Also, I had planned to create a weather generator as a separate file but was struggling to call this so had to just use a constant. +- In terms of outside help, I took a quick look at this https://medium.com/@charlottebrf/makers-academy-day-5-8dc1c792cda5, which I stumbled upon while googling how to create a random weather generator, and which gave me the idea of using a constant for the capacity (and subsequently for the weather, as I never got onto making a generator in a separate class). Other than that, I also reached out to my mentor, Nico Cortese, Gawain Hewitt, and Jimmy Lyons. \ No newline at end of file diff --git a/docs/review.md b/docs/review.md index e957ccca16..24919bfa59 100644 --- a/docs/review.md +++ b/docs/review.md @@ -8,7 +8,6 @@ You'll be using this to review someone else's code. Help them improve by looking Also, there's a tonne of stuff here. Pace yourself, take on the improvements that feel most powerful to you and keep the rest in mind for future. - ## Does it pass the tests? Please checkout your reviewee's code and run their tests. Read the code and try some manual feature tests in IRB. How easy is it to understand the structure of their code? How readable is their code? Did you need to make any cognitive leaps to 'get it'? @@ -18,14 +17,16 @@ Please checkout your reviewee's code and run their tests. Read the code and try ### README is updated Please do update your README following the [contribution notes](https://github.com/makersacademy/airport_challenge/blob/main/CONTRIBUTING.md), i.e. -* Make sure you have written your own README that briefly explains your approach to solving the challenge. -* If your code isn't finished it's not ideal but acceptable as long as you explain in your README where you got to and how you would plan to finish the challenge. + +- Make sure you have written your own README that briefly explains your approach to solving the challenge. +- If your code isn't finished it's not ideal but acceptable as long as you explain in your README where you got to and how you would plan to finish the challenge. The above is a relatively straightforward thing to do that doesn't involve much programming - I'll often get it done while thinking about other problems in the back of my mind :-) -* http://stackoverflow.com/questions/2304863/how-to-write-a-good-readme +- http://stackoverflow.com/questions/2304863/how-to-write-a-good-readme ### Instructions in README + It's a great idea to show the full story of how your app is used (from a user's perspective) in the README, i.e. a code example or irb transcript ``` @@ -43,7 +44,7 @@ $ irb ### Use `context` and `describe` blocks to create test scopes -If a group of tests share the same setup or are related logically, group them in a `context` block or a `describe` block. Use `describe` when the tests are related by a subset of behaviour (e.g 'landing') and use `context` when the tests are related by program state (e.g. 'when it is stormy'). +If a group of tests share the same setup or are related logically, group them in a `context` block or a `describe` block. Use `describe` when the tests are related by a subset of behaviour (e.g 'landing') and use `context` when the tests are related by program state (e.g. 'when it is stormy'). `let`, `subject` and `before` statements inside a context or describe block will only run for tests inside the block and will override similar statements in an outer block. @@ -64,7 +65,7 @@ it 'is in the airport after landing' do end ``` -All this does is test the stubbing behaviour of the `airport` double - it's not testing any of the actual application code. This is often caused by a test being in the wrong place. Since the expectation is on the state of `airport`, this is a strong indication that this test should be in `airport_spec.rb`: +All this does is test the stubbing behaviour of the `airport` double - it's not testing any of the actual application code. This is often caused by a test being in the wrong place. Since the expectation is on the state of `airport`, this is a strong indication that this test should be in `airport_spec.rb`: ```ruby # airport_spec.rb @@ -109,7 +110,7 @@ describe Airport do end ``` -We are not testing that the `land` method of `plane` is called. This should be included in a further test: +We are not testing that the `land` method of `plane` is called. This should be included in a further test: ```ruby describe 'landing planes' do @@ -126,7 +127,7 @@ describe 'landing planes' do end ``` -Does every implementation in the code have associated unit tests? For example, if you take off a specific plane: +Does every implementation in the code have associated unit tests? For example, if you take off a specific plane: ```ruby def take_off(plane) @@ -148,7 +149,7 @@ it 'instructs the plane to land and then has the plane' do end ``` -Also, avoid additional `expect`s when stubbing. Prefer `allow`. Avoid the following double expect: +Also, avoid additional `expect`s when stubbing. Prefer `allow`. Avoid the following double expect: ```ruby it 'does not allow plane to take off' do @@ -192,6 +193,7 @@ it 'can land a plane' do is_expected.to respond_to(:land).with(1).argument end ``` + can be collapsed to one liners like this ```ruby @@ -208,7 +210,7 @@ it 'fails when the airport is full' do end ``` -The `respond_to` tests are an initial step you go through using the tests to drive the creation of an objects public interface, and can safely be deleted once you have more sophisticated tests that check both the interface methods and their responses (and associated changes in state) +The `respond_to` tests are an initial step you go through using the tests to drive the creation of an objects public interface, and can safely be deleted once you have more sophisticated tests that check both the interface methods and their responses (and associated changes in state) ### Breaking over multiple lines redundancy @@ -221,7 +223,7 @@ Note that by breaking some long lines (to go below 80 chars) in: end ``` -creates two separate lines that are interpreted separately. The expect now checks for any error (regardless of message) and the single string 'The plane is not currently landed at this airport' on the following line is effectively discarded. Prefer something like the following: +creates two separate lines that are interpreted separately. The expect now checks for any error (regardless of message) and the single string 'The plane is not currently landed at this airport' on the following line is effectively discarded. Prefer something like the following: ```ruby it 'a plane can only take off from an airport it is at' do @@ -230,12 +232,11 @@ creates two separate lines that are interpreted separately. The expect now chec end ``` - ## Is the application code well-written? ### Naming Convention Matching the Domain Model -In general it's critical for maintainability that code is readable. We want to ensure that other developers (and ourself in the future) can come to the codebase and make sense of what's going on. That's supported by having the naming conventions match that of the ruby community and of the domain model (in this case 'air traffic control'). +In general it's critical for maintainability that code is readable. We want to ensure that other developers (and ourself in the future) can come to the codebase and make sense of what's going on. That's supported by having the naming conventions match that of the ruby community and of the domain model (in this case 'air traffic control'). So for example we might have the following: @@ -248,7 +249,7 @@ class air_port end ``` -This breaks several [ruby coding conventions](https://github.com/bbatsov/ruby-style-guide). If we don't follow these we will confuse other Ruby programmers. Critical fails in the above are that in Ruby class names should be in CamelCase and method names should be in snake_case, and that variables (such as method parameters) can't start with a sequence of numbers. We also have domain model issues here, in that `747-400` is too specific, and `ExtractEntityFromSky` is a convoluted way to say `land`. So we would prefer the following: +This breaks several [ruby coding conventions](https://github.com/bbatsov/ruby-style-guide). If we don't follow these we will confuse other Ruby programmers. Critical fails in the above are that in Ruby class names should be in CamelCase and method names should be in snake_case, and that variables (such as method parameters) can't start with a sequence of numbers. We also have domain model issues here, in that `747-400` is too specific, and `ExtractEntityFromSky` is a convoluted way to say `land`. So we would prefer the following: ```ruby class Plane @@ -266,12 +267,12 @@ $ airport = Airport.new $ airport.land(plane) ``` -* [Ruby Style Guide: CamelCase for classes and modules](https://github.com/bbatsov/ruby-style-guide#camelcase-classes) -* [Ruby Style Guide: snake_case for symbols, methods and variables](https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars) +- [Ruby Style Guide: CamelCase for classes and modules](https://github.com/bbatsov/ruby-style-guide#camelcase-classes) +- [Ruby Style Guide: snake_case for symbols, methods and variables](https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars) ### Remove all Commented-out code -When submitting delete all "commented out" code. You may not yet trust git to store all your old code, and you might not feel confident about rolling back to old commits to see that code, but that shouldn't be an excuse for leaving big chunks of commented out code in your files. Make sure you commit to git (and push to GitHub) regularly, and start to get familiar with how to check out previous versions of your code. If you are still worried store old versions of code in other files that you don't check in. What we're trying to get you into the habit of, is polishing your submission so that it would be acceptable as a submission to a company as a technical test. So we don't want to see any of this: +When submitting delete all "commented out" code. You may not yet trust git to store all your old code, and you might not feel confident about rolling back to old commits to see that code, but that shouldn't be an excuse for leaving big chunks of commented out code in your files. Make sure you commit to git (and push to GitHub) regularly, and start to get familiar with how to check out previous versions of your code. If you are still worried store old versions of code in other files that you don't check in. What we're trying to get you into the habit of, is polishing your submission so that it would be acceptable as a submission to a company as a technical test. So we don't want to see any of this: ```ruby def initialize(capacity: 1, weather: Weather.new) @@ -282,7 +283,7 @@ def initialize(capacity: 1, weather: Weather.new) end ``` -Just delete commented out lines in your final submission. Descriptive comments are just about okay, but please prefer to try and make the code describe itself, e.g. +Just delete commented out lines in your final submission. Descriptive comments are just about okay, but please prefer to try and make the code describe itself, e.g. ```ruby def land(plane) # this lands the plane at the airport @@ -293,7 +294,7 @@ def land(plane) # this lands the plane at the airport end ``` -Are the above comments really necessary? Comments like this aren't tested, and so can easily go out of date. Prefer to name your methods so they describe exactly what they do. +Are the above comments really necessary? Comments like this aren't tested, and so can easily go out of date. Prefer to name your methods so they describe exactly what they do. ### Use guard clause to improve readability and unrelated conditionals: @@ -317,8 +318,8 @@ fail 'Airport full' if full? planes << plane ``` -* [Style Guide: No Nested Conditionals](https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals) -* [Style Guide: If as a modifier](https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier) +- [Style Guide: No Nested Conditionals](https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals) +- [Style Guide: If as a modifier](https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier) ### Use Implicit Return of Booleans @@ -352,7 +353,7 @@ end ### Do not Expose Internal Implementation -Be careful not to give 'public' access to objects and methods that are should only be accessed internally. E.g.: +Be careful not to give 'public' access to objects and methods that are should only be accessed internally. E.g.: ```ruby class Airport @@ -364,7 +365,7 @@ class Airport end ``` -The `planes` method exposes the internal array of planes and so should not be publicly accessible. Use the `private` keyword to prevent this: +The `planes` method exposes the internal array of planes and so should not be publicly accessible. Use the `private` keyword to prevent this: ```ruby class Airport @@ -382,7 +383,7 @@ end #### Classes -A class should have one responsibility. An airport is responsible for the coming and going of airplanes. It needs access to weather information to make decisions, but it _should not be responsible for determining the weather_. Weather information should be provided by a separate class and injected into airport as a dependency. E.g.: +A class should have one responsibility. An airport is responsible for the coming and going of airplanes. It needs access to weather information to make decisions, but it _should not be responsible for determining the weather_. Weather information should be provided by a separate class and injected into airport as a dependency. E.g.: ```ruby class Weather @@ -406,10 +407,9 @@ class Airport end ``` - #### Methods -A method also should have only one responsibility. E.g _the following method is too long_: +A method also should have only one responsibility. E.g _the following method is too long_: ```ruby def stormy? @@ -421,12 +421,12 @@ end Although there are clearly several other issues with this method, the example is intended to show a method with too many responsibilities: -* It defines the outlooks, -* it handles the random number selection, -* it extracts an outlook from the outlooks array and -* it translates the random selection to a boolean to indicate `stormy?` +- It defines the outlooks, +- it handles the random number selection, +- it extracts an outlook from the outlooks array and +- it translates the random selection to a boolean to indicate `stormy?` -It can be refactored to have only one responsibility. Although this introduces more code, the goal is _readability_ and reducing cognitive overload when scanning the code: +It can be refactored to have only one responsibility. Although this introduces more code, the goal is _readability_ and reducing cognitive overload when scanning the code: ```ruby def stormy? @@ -441,6 +441,7 @@ def random_outlook OUTLOOKS.sample end ``` + Note: Ruby already handles the responsibility of choosing randomly from and array with the `sample` method. ### Avoid Magic Numbers (e.g. on capacity) @@ -451,7 +452,7 @@ def initialize end ``` -`6` is a numeric literal and its purpose in this statement is unclear. Encapsulate in a constant: +`6` is a numeric literal and its purpose in this statement is unclear. Encapsulate in a constant: ```ruby DEFAULT_CAPACITY = 6 @@ -463,11 +464,11 @@ end ### Prefer Symbols over Strings -Each time a string literal (e.g. `'flying'`) is interpreted by Ruby, a new string object is created in memory. Therefore, every time a method is called that contains a string literal (e.g. `'sunny'`) a new object is created. This can lead to lots of unnecessary objects being created when we're not interested in the _object identity_ of a string, just its _value_. To overcome this, use symbols instead e.g.: `:flying`, `:sunny`. +Each time a string literal (e.g. `'flying'`) is interpreted by Ruby, a new string object is created in memory. Therefore, every time a method is called that contains a string literal (e.g. `'sunny'`) a new object is created. This can lead to lots of unnecessary objects being created when we're not interested in the _object identity_ of a string, just its _value_. To overcome this, use symbols instead e.g.: `:flying`, `:sunny`. ### Separately name Command and Query methods -Methods should be _either_ **commands** or **queries**, not both. As a general rule: +Methods should be _either_ **commands** or **queries**, not both. As a general rule: - Command method names should start with a verb: _what does the method do?_ - Query method names should be nounal. @@ -490,8 +491,7 @@ Prefer delegating to the reader method (`planes.count >= capacity`) if it is def ### Prefer `attr_reader` over `attr_accessor` -`attr_accessor` allows a caller to change the attribute to any object they like. In general, `attr_accessor` is a code smell. - +`attr_accessor` allows a caller to change the attribute to any object they like. In general, `attr_accessor` is a code smell. ### Avoid using `attr_accessor` and then defining another mutator (do one or the other) @@ -516,11 +516,12 @@ or ```ruby plane.land ``` -*Prefer the custom method (`land`) for more control over the value of `@landed` and use `attr_reader` instead.* + +_Prefer the custom method (`land`) for more control over the value of `@landed` and use `attr_reader` instead._ ### Avoid Redundant lines of code -It's easy to have redundant lines of code hanging around. Anything you think might be redundant can be checked by deleting it and re-running your tests. If still green you didn't need that code. If you think you really did then you need a test to match it - and you should have written that first before writing the code. +It's easy to have redundant lines of code hanging around. Anything you think might be redundant can be checked by deleting it and re-running your tests. If still green you didn't need that code. If you think you really did then you need a test to match it - and you should have written that first before writing the code. Some examples of redundancy: diff --git a/lib/airport.rb b/lib/airport.rb new file mode 100644 index 0000000000..ff383dee62 --- /dev/null +++ b/lib/airport.rb @@ -0,0 +1,30 @@ +require_relative 'plane' + +class Airport + + CAPACITY = 5 + WEATHER = { 0 => "stormy", 1 => "fine", 2 => "fine", 3 => "fine" } + + def initialize(capacity = CAPACITY, weather = WEATHER[rand(4)]) + @planes = [] + @capacity = capacity + @weather = weather + end + + def release_plane(_plane) + fail 'weather too stormy for take-off' unless @weather != "stormy" + @planes.pop + end + + def land_plane(plane) + + fail 'airport full' if @planes.length == @capacity + fail 'weather too stormy for landing' unless @weather != "stormy" + @planes << plane + end + + attr_accessor :planes + attr_accessor :capacity + attr_accessor :weather + +end diff --git a/lib/plane.rb b/lib/plane.rb new file mode 100644 index 0000000000..115da6033d --- /dev/null +++ b/lib/plane.rb @@ -0,0 +1,5 @@ +class Plane + # def working? + # true + # end +end diff --git a/lib/weather_generator.rb b/lib/weather_generator.rb new file mode 100644 index 0000000000..c6715945a9 --- /dev/null +++ b/lib/weather_generator.rb @@ -0,0 +1,5 @@ +class WeatherGenerator + def generate_weather + weather = { 0 => "sunny", 1 => "stormy" } + end +end diff --git a/spec/airport_spec.rb b/spec/airport_spec.rb new file mode 100644 index 0000000000..6bce7ee821 --- /dev/null +++ b/spec/airport_spec.rb @@ -0,0 +1,57 @@ +require 'airport' + +describe Airport do + + it 'responds to planes' do + expect(subject).to respond_to(:planes) + end + + it 'responds to release_plane' do + expect(subject).to respond_to(:release_plane) + end + + describe '#release_plane' do + it 'releases a plane' do + plane = Plane.new + subject.land_plane(plane) + expect(subject.release_plane(plane)).to eq plane + end + end + + it 'responds to land_plane with one argument' do + expect(subject).to respond_to(:land_plane).with(1).argument + end + + describe '#land_plane' do + it 'prevents landing when airport is full' do + 5.times { subject.land_plane Plane.new } + expect { subject.land_plane Plane.new }.to raise_error 'airport full' + end + end + + it 'has a default capacity that can be overridden' do + expect(subject.capacity).to eq 5 + end + + it 'lands something' do + plane = Plane.new + expect(subject.land_plane(plane)).to eq plane + end + + it 'returns landed planes' do + plane = Plane.new + subject.land_plane(plane) + expect(subject.planes).to eq plane + end + + it 'prevents landing if weather is stormy' do + subject.weather = "stormy" + expect { subject.land_plane(Plane.new) }.to raise_error 'weather too stormy for landing' + end + + it 'prevents takeoff if weather is stormy' do + subject.weather = "stormy" + expect { subject.release_plane(Plane.new) }.to raise_error 'weather too stormy for take-off' + end + +end diff --git a/spec/plane_spec.rb b/spec/plane_spec.rb new file mode 100644 index 0000000000..100d260f94 --- /dev/null +++ b/spec/plane_spec.rb @@ -0,0 +1,6 @@ +require 'plane' +describe Plane do + # it 'responds to working' do + # expect(subject).to respond_to(:working?) + # end +end diff --git a/spec/weather_generator_spec.rb b/spec/weather_generator_spec.rb new file mode 100644 index 0000000000..6a557e767e --- /dev/null +++ b/spec/weather_generator_spec.rb @@ -0,0 +1,7 @@ +require 'weather_generator' + +describe WeatherGenerator do + it 'responds to generate_weather' do + expect(subject).to respond_to(:generate_weather) + end +end