CSCI142: Computer Science 2
Lab 2 - RIT Parking

Introduction

Parking and Transportation Services (PATS) is responsible for administering parking and transportation services at RIT. Parking regulations require that all vehicles operated on campus by students, faculty and staff must be registered. Permits for general and reserved parking are available for purchase and must be displayed on the rearview mirror of the vehicle. Routinely, Campus Safety has parking officers who patrol the parking lots and check each parked vehcile's permit. Tickets are issued for cars that have no permit, or for cars that have have a general permit but are parked in a reserved parking spot.

For this lab you will be implementing a system that simulates this parking service. Recall from lecture that objects are the fundamental component in object oriented programming. A class defines the various behaviors and state of a particular object. Thus, an object can be viewed as a specific instance of a class, with real data that is encapsulated inside the object and restricted from direct access to objects of other class types.

Test Driven Development

This lab is going to have you follow a development process known as Test Driven Development (TDD). The goal is to get you thinking about how you can write proper test cases for a class before you fully implement them. The idea is that you will take the documentation for a class and stub out a compilable skeleton. Next, you will implement a test method that exercises all those stubbed methods and tests what their expected behavior/s should be. Initially, most if not all of the test cases will fail. Finally, you will incrementally implement each method and verify the tests case/s that exercise the method now gives the expected result.

Design

Class Diagram

The syntax used in this class diagram is slightly different than the formal UML you saw in lecture. It was generated using IntelliJ's class diagram generator (from the Ultimate edition). The major difference is that in the IntelliJ version it has the behavior (methods) section before the state (data member) section. It also uses fancier icons to display the scope.

Documentation

For full documentation on all the classes, their methods, and state (including private) refer to the main documentation page.

Implementation

Starter Code

You can download a zip file containing all the supplied code for this lab here. Do not copy them into your project until you are instructed to do so. Because we are providing you with the main class, RITParking, it will not compile until you have implemented all the required classes. We also want you to develop sufficient tests for these classes you have to write, so that when you eventually do add in the main program it should run smoothly.

To begin with, you should create an IntelliJ project and copy all of the provided source files into it, excluding ParkingException.java and RITParking.java. Your project source folder should look like the following:

Part 1: Vehicle

The first class you worked with during the in-lab activity was the Vehicle class. For this part, we provided you with the main test method. For the remaining classes you have to write, you must write your own test cases.

Understanding Testing

Take a moment to look over the main test method. Here is an example test case in code:

    System.out.println("v1 plate is 10? " + (10 == v1.getPlate() ? "OK" :
        "FAIL, got: " + v1.getPlate()));

What this test is doing is checking that a previously created vehicle, referenced by v1, has a plate number of 10. The first string in the print statement tells the user what we are expecting to see when we check the plate number. The remaining part of the print statement checks that the plate number is 10. If it is correct, it would print out:

    v1 plate is 10? OK

If the plate number was not 10, it would print out a failure message, along with what it observed the plate number to be. For example, if the plate number the test saw was 20 it would print out:

    v1 plate is 10? FAIL, got: 20

You can use this visually verify that the class passes all the tests. If you ever see a FAIL messsage, you know that there is either an issue with your test case, or how you implemented what the test case is testing.

It does this in code by using a ternary operator - a condensed if/else statement. There are three parts to the ternary - a test condition, the part to include if the test is true, and the part to include if the test is false. Here it is written out with separate lines, with comments after that show how it is treated as an if/else statement:

    10 == v1.getPlate() ?                 // if (10 == v1.getPlate()) {
        "OK"                              //     "OK"
    :                                     // } else {
        "FAIL, got: " + v1.getPlate()     //     ""FAIL, got: " + v1.getPlate()
                                          // }

Here is an example of an if/else statement:

    if (fee == true) {
        System.out.println("The fee is $2");
    } else {
        System.out.println("The fee is $0");
    }

And here it is again as a ternary operator:

    System.out.println("The fee is $" + (fee == true) ? "2" : "0");

Look over all the test cases in this class and make sure you can adapt them for the remaining classes you need to write. Part of your grade is based on how thorough you make your test cases.

Part 2: ParkingSpot

A ParkingSpot represents a single space in a parking lot. It can either hold an existing vehicle, or if the spot is empty the vehicle will be null. This is a relatively simple class for you to develop. Unlike the previous part, you will develop a main method for it that fully tests the class. These are the steps you should follow:

  1. Using the javadocs, write the class with no data members and stub out each method, e.g. a void method is blank, a method that returns a boolean returns false, a method that returns an integer returns 0, and a method that returns an object returns null.
  2. Implement the tester helper method, verifySpot. This method will be re-used by the main method for most of the test cases you will develop there. It should do the following, using the testing method described in the previous section:
  3. Now implement the constructor, accessors and toString method.
  4. You can now implement your first test case in the main method. Create a handicapped parking spot (number 1). Use your verify method to make sure everything is as you expect it. Create a new run configuration for this class.
  5. Now implement occupySpot. This is how a vehicle occupies an empty spot.
  6. Implement a second test case where you create a vehicle, and have the vehicle occupy the spot you created in the first test case. Use your helper test method to verify things, e.g. the vehicle is now parked.
  7. Now implement vacateSpot. This is how a parking spot becomes empty again.
  8. Implement a third test case where you vacate the spot you occupied in the previous test. Use your helper method to verify things, e.g. the vehicle is now unparked.
  9. You can be even more thorough by creating spots with different ids, and different types, and making sure those are correct using your helper test method.

Also note that due to the formatting of the parking spot's toString(), it is guaranteed there will never be more than 100 spots to park in.

Part 3: ParkingLot

The ParkingLot holds a collection of parking spots. You should be comfortable with and follow the test driven format you've been using in the prior two parts. Make a new run configuration for this class that calls the main methods and tests your class.

Part 4: ParkingOfficer

The final class to implement is the ParkingOfficer. They are responsible for patroling the parking lot and issuing tickets to vehicles that violate the parking rules. Again you should follow the test driven development from the previous parts. Make a new run configuration for this class that calls the main methods and tests your class.

Make note that for patrolLot that you will not be able to do one thing until the main class is tied in during the next part. You won't be able to pause the officer as they patrol the lot and issue tickets. Either comment out this line, or leave it to be implemented once you've added in the main class.

Part 5: RITParking

You can now add the final two classes from the zip file into your project's source directory. Warning, do not modify the contents of either of these files!:

Since you incrementally developed all the other classes, these new classes should plug in with no errors. If you see any errors, make sure you first go back and verify that you followed the exact documentation for each class and method.

The main program runs the parking simulation. It can be run two ways:

  1. $ java RITParking
  2. $ java RITParking filename

With the first way, the user must enter all the commands for the simulation program from standard input. Since this can be quite laborious and time consuming, the second way allows you to put all the commands into a file and then use it instead. It is suggested that you make a top level directory called data where you can put your test files. In this case, when you run the main program you need to specify the file argument as data/filename.

The help command reveals the full list of commands the system accepts:

    - create lot #handicapped #reserved #general
        create a new lot with the different spots
    - create permit # HANDICAPPED|RESERVED|GENERAL
        create a new lot with the different spots
    - display lot
        print out the lot
    - display vehicles
    	print out all vehicles created
    - get spot #
    	get the vehicle in spot (if one exists)
    - help
    	this help message
    - issue permit # vehicle #
    	issue a previously created permit by id to a vehicle by plate
    - make vehicle #
    	create a new vehicle by plate
    - park vehicle # spot #
    	park a vehicle by plate in a spot by id
    - patrol lot
    	have officer patrol lot and issue tickets
    - remove vehicle #
	remove parked vehicle from lot by plate
    - quit
	end the simulation

We are providing you with one test file that exercises the majority of the system, test1.txt. The expected output should match our supplied output1.txt , except for the timestamp information. If you run this and you don't get the same output, it most likely means you did not do a thorough enough job of testing the individual classes you wrote. For any problems you find, you should go back to your test methods and improve them (part of your grade is based on how well your tests cases exercise the classes you wrote).

Submission

You should zip all of the Java source files in the src directory into a file named lab2.zip and submit it to the dropbox on MyCourses by the due date.

Grading

The grade breakdown for this lab is as follows: