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

Iteration 2 features - Qory Pull Request # 2 #572

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0151b08
Updated Gemfile.lock after running bundle install
qoryhanisagal Oct 18, 2024
bf9eeeb
Added documentation for Iteration 1: Exploring the existing codebase,…
qoryhanisagal Oct 18, 2024
26ae234
Added documentation for Iteration 2: Created Registrant class and det…
qoryhanisagal Oct 18, 2024
40dbe33
Added documentation for Iteration 3: Implemented missing functionalit…
qoryhanisagal Oct 18, 2024
f76f1ae
Added documentation for Iteration 2: Created Registrant class and det…
qoryhanisagal Oct 18, 2024
a3487f3
Added documentation for Iteration 3: Implemented missing functionalit…
qoryhanisagal Oct 18, 2024
efeb4e5
Added documentation for Iteration 4: Final refactoring and testing re…
qoryhanisagal Oct 18, 2024
3e8a4b6
Detailed message describing all changes
qoryhanisagal Oct 18, 2024
4d0f93d
Ran initial tests, identifying failing tests in the existing codebase.
qoryhanisagal Oct 18, 2024
b1cccd8
Updated the Iteration_1.md to reflect my step by TDD process
qoryhanisagal Oct 18, 2024
3d2fcf9
Fix Facility class to allow the initalize method to accept the hash …
qoryhanisagal Oct 18, 2024
1b8b77d
Fixed Facility class to accept hash for initialization and corrected …
qoryhanisagal Oct 18, 2024
65afa1e
Added detailed comments to Dmv class and fixed facilities access
qoryhanisagal Oct 18, 2024
263a484
Added detailed comments to Dmv class and fixed facilities access
qoryhanisagal Oct 18, 2024
48ea784
Added registration_date attribute to Vehicle class and updated tests
qoryhanisagal Oct 18, 2024
a8725f2
Completed initial_debugging
qoryhanisagal Oct 18, 2024
dd596b8
Implemented Registrant class and added tests for initialization and p…
qoryhanisagal Oct 18, 2024
1158654
Updated Iteration_1.md to reflect logic and implementation of Registr…
qoryhanisagal Oct 18, 2024
be9c9dc
Updated Iteration_1.md to reflect logic and implementation of Registr…
qoryhanisagal Oct 18, 2024
d86c86f
Added and passed all tests for Registrant class, including edge cases
qoryhanisagal Oct 18, 2024
c6dc8b6
Added vehicle registration functionality to Facility class, including…
qoryhanisagal Oct 18, 2024
4348ba4
Updated Vehicle class with plate_type and registration_date attribute…
qoryhanisagal Oct 18, 2024
2cd6bd0
Added test for registrant to check if registrant has a permit
qoryhanisagal Oct 18, 2024
2c91c47
Completed reflection for Iteration 1 and double checked Registrant cl…
qoryhanisagal Oct 22, 2024
8a8031b
Added vehicle registration functionality and tested vehicle registrat…
qoryhanisagal Oct 22, 2024
5e53950
Updated Iteration 2 documentation
qoryhanisagal Oct 22, 2024
b29e808
Added written test administration functionality and tested eligibilit…
qoryhanisagal Oct 22, 2024
2f3a53f
Added road test administration functionality and tested eligibility b…
qoryhanisagal Oct 22, 2024
a44985f
Added edge case tests for vehicle registration: missing service, miss…
qoryhanisagal Oct 22, 2024
bd48f4a
Updated Iteration 2 documentation
qoryhanisagal Oct 22, 2024
cad881f
Added renew_drivers_license method and tests for license renewal func…
qoryhanisagal Oct 22, 2024
1eee568
Completed Iteration 2: Added vehicle registration, testing, and exter…
qoryhanisagal Oct 23, 2024
7964125
Completed Iteration 2: Added external data integration and vehicle cr…
qoryhanisagal Oct 23, 2024
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
1 change: 1 addition & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ GEM
PLATFORMS
arm64-darwin-20
arm64-darwin-21
arm64-darwin-24

DEPENDENCIES
faraday
Expand Down
57 changes: 57 additions & 0 deletions Iteration_1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Iteration 1 - Learning the Existing Codebase

## Overview
In this iteration, I explored the existing codebase and familiarized ourselves with the classes, methods, and tests already in place. The goal was to identify any bugs in the application code and debug the project until all tests passed.

# Iteration 1 - Learning an Existing Codebase

## Logic and Implementation of the Registrant Class

In this iteration, I implemented the `Registrant` class to represent a user of the DMV system. The class has the following key features:

- **Attributes**: `name`, `age`, `permit`, and `license_data`.
- **Permit** defaults to `false` if not provided.
- **License Data** is initialized as a hash with three keys: `:written`, `:license`, and `:renewed`, all defaulting to `false`.

- **Methods**:
- `permit?`: Checks if the registrant currently holds a permit.
- `earn_permit`: Allows the registrant to earn a permit, updating the `permit` attribute from `false` to `true`.

---

## Test-Driven Development (TDD) Process

1. **Step 1: Write Tests for Initialization**:
I started by writing tests to verify that the `Registrant` class correctly initializes with a name, age, and optional permit. The default values for the `license_data` hash were also tested.

2. **Step 2: Implement the Class**:
After writing the tests, I implemented the class to make the tests pass. This included:
- Defining an initializer method that accepts `name`, `age`, and `permit` (with a default value of `false`).
- Initializing the `license_data` hash to track the registrant’s progress through the DMV process.

3. **Step 3: Write Tests for Permit Functionality**:
I added tests to verify the behavior of the `permit?` and `earn_permit` methods. These methods control whether a registrant has earned their permit and allow this status to be updated.

4. **Step 4: Implement Permit Logic**:
I implemented the `permit?` method to return the status of the permit and the `earn_permit` method to update the `permit` attribute to `true`.

---

## Test Failures and Fixes

1. **Test: Initialization**
- **Failure Reason**: Missing attributes during initialization.
- **Fix**: Added the required parameters (`name`, `age`, and `permit`) to the `Registrant` class initializer.

2. **Test: Permit Status**
- **Failure Reason**: Initially, the `permit` attribute was not correctly initialized as `false`.
- **Fix**: Set `permit` to default to `false` unless otherwise provided in the initializer.

3. **Test: License Data**
- **Failure Reason**: The `license_data` hash was not initialized correctly.
- **Fix**: Ensured the `license_data` hash is always initialized with default values (`false` for `:written`, `:license`, and `:renewed`).

## Reflection
- **Steps to Explore Codebase**: To explore the codebase, I first reviewed the structure of the provided classes and methods, focusing on how the Facility and Vehicle classes interacted. I read through the initial tests to understand the expected behavior. Using binding.pry, I paused execution at key points to inspect objects and variables, which helped me visualize how data flowed through the code. Finally, I worked through any failing tests one by one, debugging and adjusting the application logic to make them pass.
- **Challenges**: One challenge was getting familiar with the code that I didn’t write myself, especially when it came to understanding how different methods and objects were interacting. Some logic wasn’t immediately clear, so I had to spend extra time debugging. It was also challenging to extend the functionality without breaking the existing structure.
- **What was Easier**: It was easier than expected to work with the tests once I understood how the existing structure was built. The well-structured nature of the tests helped me see where new functionality needed to be added. Using binding.pry also made it easier to debug by allowing real-time inspection of object states, which gave quick feedback when something wasn’t working as expected.
40 changes: 40 additions & 0 deletions Iteration_2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Iteration 2 - Adding Features and Creating Objects from Data Sources

## Overview
In this iteration, I extended the **Facility** class to administer a variety of DMV services such as **vehicle registration**, **written tests**, **road tests**, and **driver’s license renewals**. The registration logic applies different fees based on vehicle types, and each service requires the facility to offer the relevant service before it can be performed. I also focused on integrating external data for creating vehicle objects using a service class.

## New Classes and Methods
### Methods Added:
1. **register_vehicle**:
- Registers a vehicle, sets the registration date, and applies appropriate fees based on the vehicle type (regular, antique, electric).

2. **administer_written_test**:
- Administers a written test to eligible registrants (age 16+, with a permit).

3. **administer_road_test**:
- Administers a road test if the registrant has passed the written test.

4. **renew_drivers_license**:
- Renews a license if the registrant has a valid license.

## Test Failures and Fixes
1. **Test: Written Test Eligibility**
- **Failure Reason**: Registrants without a permit or under age 16 were incorrectly allowed to take the test.
- **Fix**: Added condition checks in the `administer_written_test` method to restrict access to eligible registrants only.

2. **Test: Road Test**
- **Failure Reason**: Registrants who had not passed the written test were able to take the road test.
- **Fix**: Updated the `administer_road_test` method to check the status of the written test in the registrant's `license_data` hash.

## TDD Process
1. **Start with Writing Tests**: I first wrote unit tests for each new service: vehicle registration, written test, road test, and license renewal.
2. **Implementation**: After each test was written, I implemented the corresponding method in the `Facility` class.
3. **Refinement and Debugging**: As we ran the tests, I fixed any issues or failures, ensuring that all methods adhered to the expected behavior.
4. **Final Testing**: After completing the functionality, I ensured all edge cases were covered and tests passed successfully.

## Reflection
- **Steps to Add Classes**: The process involved carefully understanding the requirements for each service, adding them one by one, and ensuring that they adhered to the rules (e.g., age and permit requirements for tests). Each method was added incrementally after writing the corresponding test.

- **Challenges**: One of the challenges was handling edge cases such as attempting to administer a road test when the written test had not been passed, and ensuring that only facilities offering a service could perform it.

- **What was Easier**: Adding the vehicle registration logic was straightforward since the different fees and conditions could easily be mapped to vehicle attributes such as `year` and `engine type`.
22 changes: 22 additions & 0 deletions Iteration_3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Iteration 3 - Implementing Missing Functionality

## Overview
In this iteration, the focus was on completing the missing functionality from the project. New features were added to improve the system's capabilities.

## New Features Implemented
- [Feature 1]
- [Feature 2]

## Test Failures and Fixes
- No major test failures encountered during this iteration.

## TDD Process
- Followed TDD by writing tests for new features first, then implementing the functionality.

## Reflection
- **Challenges**: [What was challenging about building the new functionality].
- **Successes**: [What worked well].


# DMVdata will come as potentially 1,000 arrays.
#### The challenge here is to organize the data. Assign arrays to class objects
14 changes: 14 additions & 0 deletions Iteration_4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Iteration 4 - Refactoring and Final Testing

## Overview
This iteration was about optimizing the project, refactoring the code for better clarity and performance, and ensuring all tests passed.

## Refactoring Details
- Refactored [method/class] to improve readability and performance.

## Final Test Results
- All tests pass successfully, confirming that the system works as expected.

## Reflection
- **Challenges in Refactoring**: [What challenges did you encounter?]
- **Final Thoughts on Project**: [Overall experience and lessons learned].
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# The DMV

This is the starter repo for the BE Mod1 DMV project.
Repo for the SE Mod1 DMV project.
By Qoiree
240 changes: 240 additions & 0 deletions initial_debugging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
## Test Failures and Fixes

### 1. Test: Facility#initialize can initialize
- **Failure Reason**: The `Facility` class was expecting three separate arguments (`name`, `address`, `phone`), but the test was passing a hash.
- **Fix**: Updated the `Facility` class to accept a hash (`facility_details`) and extract the `name`, `address`, and `phone` keys from it. This aligns with the way the test is structured.

### 2. Test: Facility#add service can add available services
- **Failure Reason**: The `add_service` method name in the class was pluralized (`add_services`), but the test was calling it in singular form.
- **Fix**: Changed the method name from `add_services` to `add_service` to align with the test.

### 3. Test: Dmv#initialize can initialize
- **Failure Reason**: The `@facilities` instance variable was being initialized correctly, but there was no getter method (`facilities`) to access it in the test.
- **Fix**: Added `attr_reader :facilities` to provide access to the `@facilities` array. This allowed the test to properly access and verify the initialized empty array.

### 4. Test: Dmv#add facilities can add available facilities
- **Failure Reason**: The method was working but not accessible without a getter method.
- **Fix**: After adding `attr_reader`, the facilities array could be accessed and validated.

## Successes
- Successfully explored and understood the relationships between `Facility`, `Dmv`, and `Vehicle` classes.
- All existing tests pass after resolving bugs in the application code.

## Application Logic
- The `Dmv` class handles facilities and their services.
- The `Vehicle` class defines vehicle properties and implements methods such as `antique?` and `electric_vehicle?`.

# TDD Process
- Refactored code in small steps, ensuring tests passed after each refactor.
- Used test failures to guide debugging.
## Error 1:
```` ruby
ArgumentError: wrong number of arguments (given 1, expected 3)
````
### Test 1: Facility Initialization
- Test is tring to intilalize the Facility class with a hash, the class expects three separate arguement (name, address, phone).
#### Step 1: Analyze the Current Code
#### **Facility Class:**
- The initialize method expects three separate arguments (name, address, phone), but your test is passing a **hash** instead.
#### **facility_spec.rb:**
- Here, the test is passing a hash with keys (name, address, phone) to the Facility.new method, which is inconsistent with the initialize method.
#### Step 2: Write the Correct Initialization (TDD Process)
#### Fix:
- I need to modify the initialize method in the Facility class to accept a hash instead of individual arguments.
##### Modify the Facility Class:
```` ruby
class Facility
attr_reader :name, :address, :phone, :services

def initialize(facility_details)
@name = facility_details[:name]
@address = facility_details[:address]
@phone = facility_details[:phone]
@services = []
end

def add_services(service)
@services << service
end
end
````
#### Key Notes:
- This change allows the initialize method to accept a hash and extract name, address, and phone from the hash, aligning with the way it’s being called in the test file.
#### Step 3: Update the add_service Method
- There’s also a small typo in the method name. In the test, you’re calling add_service (singular), but in the Facility class, it’s named add_services (plural).
```` ruby
class Facility
attr_reader :name, :address, :phone, :services

def initialize(facility_details)
@name = facility_details[:name]
@address = facility_details[:address]
@phone = facility_details[:phone]
@services = []
end

def add_service(service)
@services << service
end
end
````
#### Step 4: Rerun the Tests
```` ruby
rspec
````
#### Step 5: Commit Changes
- Commit changes add high-level message.

## Error 2:
```` ruby
NoMethodError: undefined method `facilities' for #<Dmv:0x0000000105a63960 @facilities=[]>
````
- The test is trying to call a method called facilities on an instance of the Dmv class, but the method is not defined.
### Test 1:
- Looks I am trying to access an instance variable @facilities using expect(@dmv.facilities).to eq([]). However, the Dmv class does not have a method to access @facilities.
#### Step 1: Add an accessor for @facilities:
#### ** Accessor for Facilities:**
- In order to make @facilities accessible outside the class, I need to either define an accessor method for it or use attr_reader to expose the @facilities instance variable.
#### Step 2: Write the Correct Initialization (TDD Process)
#### Fix:
```` ruby
class Dmv
# This creates a getter method for facilities so it can be accessed outside the class
attr_reader :facilities

def initialize
@facilities = [] # Initializes an empty array to hold facilities
end

# This method allows adding a facility to the list
def add_facility(facility)
@facilities << facility
end
end
````
- Adding attr_reader :facilities, I created a getter method for @facilities, which allows the facilities method to be called on an instance of Dmv in the test.

#### Step 3: Rerun the Tests
```` ruby
rspec
````
#### Step 5: Commit Changes
- Commit changes add high-level message.
## Reflection
1. **attr_reader :facilities:**
- This line creates a getter method for the @facilities instance variable, allowing it to be accessed from outside the class. However, this variable cannot be directly modified from the outside (i.e., there’s no setter method), which enforces encapsulation.
2. **initialize method:**
- The initialize method is called when a new instance of the Dmv class is created. It sets up an empty array for @facilities, which will later hold the list of DMV facilities.
- This ensures that each instance of the Dmv class starts with its own unique list of facilities.
3. **add_facility method:**
- This method takes a facility object as a parameter and adds it to the @facilities array.
- This allows the Dmv class to manage a collection of facilities dynamically, which can later be retrieved using the facilities getter method.

## Error 3:
```` ruby
NoMethodError: undefined method `facilities' for #<Dmv:0x0000000105a63960 @facilities=[]>
````
- The test is trying to call this method to return a list of facilities that offer a specified service, but the method hasn’t been defined yet.

### Test 1:Add facilities_offering_service in Dmv class.
-
#### Step 1: Implement method facilities_offering_service in the Dmv class
#### ** Accessor for Facilities:**
-I need to implement the facilities_offering_service method in the Dmv class. This method will iterate over the list of facilities and return only those that offer the requested service.
#### Fix:
```` ruby
class Dmv
attr_reader :facilities # Getter method for facilities

def initialize
@facilities = [] # Initialize an empty array for storing facilities
end

# This method adds a facility to the @facilities array
def add_facility(facility)
@facilities << facility # Add the given facility to the @facilities array
end

# This method returns a list of facilities that offer the specified service.
# It iterates over the @facilities array and selects facilities that include the requested service.
#
# @param service [String] the name of the service to search for in the facilities.
# @return [Array] an array of facilities that offer the specified service.
def facilities_offering_service(service)
@facilities.select do |facility|
facility.services.include?(service) # Check if the facility offers the specified service
end
end
end
````

#### Step 3: Rerun the Tests
```` ruby
rspec
````
#### Step 5: Commit Changes
- Commit changes add high-level message.
## Reflection
1. **facilities_offering_service Method:**
- This method takes a service parameter (e.g., ‘Road Test’) and checks each facility in the @facilities array to see if it offers that service.
- It uses select to iterate over the array and return a new array containing only the facilities that offer the specified service.
2. **Key Points:**
- **facility.services.include?(service):** This line checks whether the services array of each facility contains the service being searched for.

## Error 4:
```` ruby
Failure/Error: expect(@cruz.registration_date).to eq(nil)

NoMethodError:
undefined method `registration_date' for #<Vehicle:0x0000000108539388 @vin="123456789abcdefgh", @year=2012, @make="Chevrolet", @model="Cruz", @engine=:ice>
# ./spec/vehicle_spec.rb:17:in `block (3 levels) in <top (required)>'

````
- The Vehicle class is missing the registration_date attribute, which the test is expecting to be initialized to nil. I should be able to resolve this issue by adding a registration_date attribute to the Vehicle class and ensuring it’s initialized correctly.
### Test 1: Update Vehicle Class
- Add registration_date as an instance variable and initialize it to nil in the initialize method.
- Also, add attr_reader :registration_date so that it can be accessed outside the class.
#### Step 1: Add `attr_reader`
#### **`attr_reader :registration_date`**
- This creates a getter method for the `@registration_date` instance variable, allowing it to be accessed outside the class (e.g., in the test file).
#### Step 2:Add **`registration_date = nil`**
- The initialize method sets the `@registration_date` to `nil` when a new Vehicle instance is created, as the vehicle isn’t registered initially.

#### Fix:
```` ruby
class Vehicle
# These attributes are readable from outside the class.
attr_reader :vin, :year, :make, :model, :engine, :registration_date

# The initialize method takes a hash of vehicle details and assigns them to instance variables.
# It also initializes @registration_date to nil, indicating the vehicle is not yet registered.
def initialize(vehicle_details)
@vin = vehicle_details[:vin] # Vehicle Identification Number
@year = vehicle_details[:year] # Year of manufacture
@make = vehicle_details[:make] # Vehicle's make (e.g., Chevrolet)
@model = vehicle_details[:model] # Vehicle's model (e.g., Cruz)
@engine = vehicle_details[:engine] # Type of engine (e.g., :ice for internal combustion engine)
@registration_date = nil # Initially, the vehicle is unregistered, so set to nil
end

# This method determines if the vehicle is considered an antique, which is true if the car is older than 25 years.
def antique?
Date.today.year - @year > 25
end

# This method checks if the vehicle is an electric vehicle (EV) by comparing the engine type.
def electric_vehicle?
@engine == :ev
end
end
````
-

#### Step 3: Write the Correct Initialization (TDD Process)
#### Step 4: Rerun the Tests
```` ruby
rspec
````
#### Step 5: Commit Changes
- Commit changes add high-level message.
## Reflection
Loading