CSC/ECE 517 Spring 2024 - E2418. Reimplement of due date.rb (Phase 2)

From Expertiza_Wiki
Revision as of 21:30, 19 April 2024 by Dukolhat (talk | contribs)
Jump to navigation Jump to search

E2418. Reimplement due_date.rb (Phase 2)

This page provides a description of the Expertiza based OSS project.



About Expertiza

Expertiza is an open source project based on Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.

Introduction

We're refactoring the due_dates.rb in Expertiza, enhancing its codebase to adhere to DRY and design principles, improving readability, and reducing redundancy. Our focus includes changing class methods to instance methods and further testing.


Problem Statement

The reimplementation project entails:

  1. Refactoring due_date.rb: Enhancing code clarity, optimizing, and adding comments for unclear lines of code to improve maintainability and readability.
  2. Class to Instance Methods: Changing as many class methods to instance methods as possible.
  3. Testing with Rspec: Writing comprehensive tests using Rspec for each method to ensure functionality and integration, followed by a video demonstration showcasing the functionality of the reimplementation.


Plan for Reimplementation of DueDate

Refactoring due_date.rb:

  1. Our refactoring initiative encompassed specific actions to improve code clarity, optimize performance, and bolster maintainability across our application.
  2. Firstly, we embarked on adding descriptive comments throughout the codebase. For instance, within the teammate_review_allowed? method, we included comments explaining the logic behind determining whether teammate review is allowed, making it easier for developers to understand the function's purpose and behavior.
  3. Secondly, we focused on enhancing variable and method names. In the done_in_assignment_round method, we renamed variables like due_dates to assignment_due_dates for clarity. Additionally, we renamed the copy method to duplicate_due_dates to better convey its functionality. Breaking down complex methods into smaller, focused functions was another key aspect. For example, in the done_in_assignment_round method, we extracted the logic for sorting and filtering due dates into separate helper methods, improving readability and maintainability.
  4. Optimization efforts involved reviewing database queries for efficiency. In the get_next_due_date method, we optimized the query by using ActiveRecord query methods or adding appropriate database indexes to speed up retrieval of due dates, especially in cases where assignments had staggered deadlines or multiple topics.
  5. Robustness enhancements included refining error handling mechanisms. For instance, in the due_at_is_valid_datetime method, we provided more informative error messages to guide developers in identifying and resolving invalid datetime inputs.
  6. Adherence to Ruby and Rails best practices was ensured throughout the refactoring process. We leveraged Rails conventions and built-in functionalities wherever possible. For example, in the set_flag method, we utilized ActiveRecord's update method with attribute names instead of update_attribute for improved code clarity and safety.
  7. To mitigate against regressions, we implemented thorough unit tests using frameworks like RSpec or Minitest. For instance, we wrote tests to verify the behavior of the set_flag method and ensured it correctly updated the flag attribute.
  8. Lastly, we documented our progress and collaborated effectively using version control systems like Git. Code reviews provided valuable feedback on adherence to coding standards and best practices, ensuring consistency and quality across the codebase. By undertaking these specific actions, we aimed to transform our codebase into a more readable, efficient, and maintainable state, facilitating ongoing development and enhancement of our application.

Class Methods to Instance Methods:

  1. Our refactoring initiative encompassed specific actions to improve code clarity, optimize performance, and bolster maintainability across our application.
  2. Firstly, we embarked on adding descriptive comments throughout the codebase. For instance, within the teammate_review_allowed? method, we included comments explaining the logic behind determining whether teammate review is allowed, making it easier for developers to understand the function's purpose and behavior.
  3. Secondly, we focused on enhancing variable and method names. In the done_in_assignment_round method, we renamed variables like due_dates to assignment_due_dates for clarity. Additionally, we renamed the copy method to duplicate_due_dates to better convey its functionality. Breaking down complex methods into smaller, focused functions was another key aspect. For example, in the done_in_assignment_round method, we extracted the logic for sorting and filtering due dates into separate helper methods, improving readability and maintainability.
  4. Optimization efforts involved reviewing database queries for efficiency. In the get_next_due_date method, we optimized the query by using ActiveRecord query methods or adding appropriate database indexes to speed up retrieval of due dates, especially in cases where assignments have staggered deadlines or multiple topics.
  5. Robustness enhancements included refining error handling mechanisms. For instance, in the due_at_is_valid_datetime method, we provided more informative error messages to guide developers in identifying and resolving invalid datetime inputs.
  6. Adherence to Ruby and Rails best practices was ensured throughout the refactoring process. We leveraged Rails conventions and built-in functionalities wherever possible. For example, in the set_flag method, we utilized ActiveRecord's update method with attribute names instead of update_attribute for improved code clarity and safety.
  7. To mitigate against regressions, we implemented thorough unit tests using frameworks like RSpec or Minitest. For instance, we wrote tests to verify the behavior of the set_flag method and ensured it correctly updated the flag attribute.
  8. Lastly, we documented our progress and collaborated effectively using version control systems like Git. Code reviews provided valuable feedback on adherence to coding standards and best practices, ensuring consistency and quality across the codebase. By undertaking these specific actions, we aimed to transform our codebase into a more readable, efficient, and maintainable state, facilitating ongoing development and enhancement of our application.

OLD CODE:

def self.teammate_review_allowed?(student)
	# time when teammate review is allowed
	due_date = current(student.assignment.due_dates)
	..

NEW CODE:

def teammate_review_allowed?(student)
	# time when teammate review is allowed
    	due_date = self.class.current(student.assignment.due_dates)

Design Principles

Single Responsibility Principle (SRP):

Each method in the DueDate class was responsible for a specific task related to managing due dates. Methods were refactored to separate concerns such as setting due dates, retrieving due dates, and performing operations on due dates. For example, the set_duedate method focused solely on setting the due date for a task.

Don't Repeat Yourself (DRY) Principle:

Code duplication in the DueDate class was eliminated by extracting common functionality into helper methods or modules. Repetitive logic, such as date calculations or formatting, was refactored to promote code reusability and maintainability.

Encapsulation:

Data and behavior within the DueDate class were encapsulated within appropriate instance methods and attributes to minimize dependencies. Access to instance variables and methods was limited, promoting encapsulation and separation of concerns.

Dependency Inversion Principle (DIP):

The DueDate class depended on abstractions, interfaces, or higher-level modules instead of concrete implementations. Dependency injection or inversion of control was used to decouple the class from specific date manipulation implementations, allowing for flexibility and easier testing.

Testing

Testing with Rspec:

At our last testing iteration, we enhanced the readability, maintainability, and coverage of our DueDate model tests using RSpec. We achieved this by implementing several key strategies.

  1. Firstly, we organized our tests into contextual groupings using descriptive describe blocks. Each block encapsulated different aspects of the model's functionality, such as validation, manipulation, and behavior under specific conditions. This approach improved the readability of our test suite by providing clear and logical groupings. Additionally, we employed helper methods within the before(:each) block to streamline setup logic. These methods handled common setup tasks, such as creating due dates with various attributes, reducing repetition, and making the test setup more concise and understandable.
  2. To ensure test efficiency and isolation, we leveraged mocking techniques to simulate dependencies where necessary. For methods relying on complex associations or external data, we mocked the required dependencies rather than relying on real database records. This approach sped up tests and isolated the behavior under test.
  3. Furthermore, we paid attention to edge cases, ensuring comprehensive test coverage by including scenarios such as nil due dates, absence of response maps, and staggered deadline variations. By testing these edge cases, we ensured the robustness of our model and handled unexpected scenarios gracefully.
  4. Our test assertions were reviewed to ensure clarity and completeness. We verified that each test covered all expected outcomes and that assertions were clear and concise. For instance, in tests like copying due dates to a new assignment, we not only checked the count but also verified that due dates in the new assignment matched the originals.
  5. We also focused on error handling, testing both error and success paths thoroughly. For methods like due_at_is_valid_datetime, we ensured that error handling scenarios were covered comprehensively, guaranteeing robustness in the face of unexpected inputs. As our test suite grew, we monitored test performance using RSpec's profiling tools and optimized slow tests as needed. Additionally, we documented our tests with comments or descriptions to clarify the purpose of each test, aiding understanding for future maintainers and contributing to overall code quality.
  6. By implementing these strategies, we created a comprehensive, maintainable, and efficient test suite for our DueDate model using RSpec.

Team

Mentor
  • Kalyan Karnatı
Members
  • Atharva Patil (aspatil2@ncsu.edu)
  • Deepika Choudhary Patibandla (@ncsu.edu)
  • Dhruv Kolhatkar (dukolhat@ncsu.edu)

References

  1. Expertiza on GitHub
  2. GitHub Project Repository Fork
  3. The live Expertiza website
  4. Expertiza project documentation wiki
  5. Rspec Documentation
  6. Clean Code: A handbook of agile software craftsmanship. Author: Robert C Martin