CSC/ECE 517 Fall 2013/oss E802 jst: Difference between revisions
(60 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
=E802: Refactoring and testing signup_sheet_controller= | =E802: Refactoring and testing signup_sheet_controller= | ||
__TOC__ | |||
==What does the controller do?== | ==What does the controller do?== | ||
Signup sheet controller | |||
Signup sheet controller handles all the responsibilities in Expertiza<ref> http://expertiza.ncsu.edu/</ref> related to managing sign up topics, assigning deadlines, creating microtask, managing waitlists, etc. | |||
==What are we supposed to do?== | ==What are we supposed to do?== | ||
* This controller contained 28 methods, which is way too many. Some of them did not follow the convention for method names (snake case). | * This [http://guides.rubyonrails.org/action_controller_overview.html| controller] contained 28 methods, which is way too many. Some of them did not follow the convention for method names (snake case). | ||
* This controller had many extraneous methods, including those dealing with team membership which were to be moved, and setting due dates for staggered deadline assignments which were a part of different project (E810). | * This controller had many extraneous methods, including those dealing with team membership which were to be moved, and setting due dates for staggered deadline assignments which were a part of different project (E810). | ||
Line 18: | Line 20: | ||
* This controller should be callable from the Topics tab on a New or Edit Assignment screen, not (just) from the popup menu for an assignment. This was dealt with, in another project and was skipped in view of avoiding redundancy. | * This controller should be callable from the Topics tab on a New or Edit Assignment screen, not (just) from the popup menu for an assignment. This was dealt with, in another project and was skipped in view of avoiding redundancy. | ||
* Integration tests need to be written. | * [http://6brand.com/rails-integration-testing-how-to-learn.html| Integration tests] need to be written. | ||
Hyperlink: | Hyperlink: http://152.46.20.88:5800/ | ||
Git repository: | Git repository: https://github.com/mdjayaprakash/expertiza/tree/sign_up_sheet_controller | ||
==Steps to set up Expertiza== | |||
==Steps to | |||
* Extract source code for Expertiza into RubyMine from the following URL: https://github.com/mdjayaprakash/expertiza/tree/sign_up_sheet_controller | * Extract source code for Expertiza into RubyMine from the following URL: https://github.com/mdjayaprakash/expertiza/tree/sign_up_sheet_controller | ||
Line 36: | Line 37: | ||
* Run - rake db:create:all | * Run - rake db:create:all | ||
* Run - rake db:migrate | * Run - rake [http://guides.rubyonrails.org/migrations.html| db:migrate ] | ||
* From the Expertiza folder(i.e. project root), execute the command “rails server” | * From the Expertiza folder(i.e. project root), execute the command “rails server” | ||
* This should start the Expertiza server at localhost:3000 in your browser. | * This should start the Expertiza server at localhost:3000 in your browser. | ||
==Files dealt with== | ==Files dealt with== | ||
Line 47: | Line 47: | ||
* signup_sheet controller | * signup_sheet controller | ||
* waitlist model | * waitlist [http://www.tutorialspoint.com/ruby-on-rails/rails-active-records.htm| model ] | ||
* signup_topic model | * signup_topic model | ||
* DueDate model | * DueDate model | ||
==Categories of code smells identified== | ==Categories of code smells identified== | ||
* ''Obvious Conditionals:'' Branches that check the conditions that are pretty obvious from the context hence increase the length of the overall code and leads to inefficient code. | * '''Obvious Conditionals:''' Branches that check the conditions that are pretty obvious from the context hence increase the length of the overall code and leads to inefficient code. | ||
* ''Meaningless Identifiers:'' The identifiers used to address some data whose meaning can’t be understood without going through the flow of code. | * '''Meaningless Identifiers:''' The identifiers used to address some data whose meaning can’t be understood without going through the flow of code. | ||
* ''Excessive Parameters:'' Making a method call with too many parameters makes the code pretty much error prone and reduces the code readability, understandability and simplicity. | * '''Excessive Parameters:''' Making a method call with too many parameters makes the code pretty much error prone and reduces the code readability, understandability and simplicity. | ||
* ''Lengthy | * '''Lengthy Definitions:''' These are the methods that have too many responsibilities and collaborators. As a result of which, their overall length has grown too long reducing the maintainability and readability. | ||
* ''Duplicated Code:'' These are those pieces of code that does almost the same functionality of some other piece of code leading to a bad design style. They are usually too error prone since not everyone identifies all the code responsible for the same task and does the changes whenever the need arises. | * '''Duplicated Code:''' These are those pieces of code that does almost the same functionality of some other piece of code leading to a bad design style. They are usually too error prone since not everyone identifies all the code responsible for the same task and does the changes whenever the need arises. | ||
* ''Bad method names:'' A good method name is expected to adhere to the Ruby style and design style guidelines. It is expected to convey a reasonable amount of responsibilities handled. A good method name in combination with good practices should resemble a user story. | * '''Bad method names:''' A good method name is expected to adhere to the Ruby style and design style guidelines. It is expected to convey a reasonable amount of responsibilities handled. A good method name in combination with good practices should resemble a user story. | ||
* ''Used and unnecessary methods:'' These are those methods that were useful when the code was first developed. But, they lost their functionality as the code got updated and new functionalities were added or existing ones were modified. | * '''Used and unnecessary methods:''' These are those methods that were useful when the code was first developed. But, they lost their functionality as the code got updated and new functionalities were added or existing ones were modified. | ||
* ''Bad Debug Statements:'' These statements are highly useful in development environment, but they spoil the software completeness if they’re not logged in the conventional way. | * '''Bad Debug Statements:''' These statements are highly useful in development environment, but they spoil the software completeness if they’re not logged in the conventional way. | ||
==Steps followed to eliminate code smells== | ==Steps followed to eliminate code smells== | ||
1. Definition renaming: | |||
1. '''Definition renaming:''' | |||
* confirmTopic() was refactored to confirm_topic() | * confirmTopic() was refactored to confirm_topic() | ||
This method follows the camel case which is a bad method naming style was renamed to a snake case style and its functionality was moved to waitlist controller since its functionality and association with waitlist controller is more prominent. | This method follows the [https://en.wikipedia.org/wiki/CamelCase| camel case] which is a bad method naming style was renamed to a snake case style and its functionality was moved to waitlist controller since its functionality and association with waitlist controller is more prominent. | ||
[[ File:1_Screenshot.png ]] | |||
* signup() was refactored to sign_up() | * signup() was refactored to sign_up() | ||
Even this method follows the camel case which is a bad method naming style was renamed to a snake case style just like the previous definition. The changes were done to the method heading along with all the code associated with this method like views/sign_up_sheet/_reserve_topic.html.erb and test/functional/SignUpControllerTest | Even this method follows the camel case which is a bad method naming style was renamed to a snake case style just like the previous definition. The changes were done to the method heading along with all the code associated with this method like views/sign_up_sheet/_reserve_topic.html.erb and test/functional/SignUpControllerTest | ||
[[ File:2_Screenshot.png ]] | |||
* teamdetails() was refactored to show_team() | * teamdetails() was refactored to show_team() | ||
Line 91: | Line 97: | ||
This definition does the job of fetching and showing a team. Hence, we changed its name to a word which describes the definition’s responsibility the closest. | This definition does the job of fetching and showing a team. Hence, we changed its name to a word which describes the definition’s responsibility the closest. | ||
This change had effects in views/sign_up_sheet/_table_line.html.erb | This change had effects in views/sign_up_sheet/_table_line.html.erb | ||
[[ File:3_Screenshot.png ]] | |||
* signup_topics() was refactored to list() | * signup_topics() was refactored to list() | ||
This definition’s responsibility can be best described by the word list since it lists all the topics for an assignment. The changes were reflected in signup_sheet_controller, views/student_task/view.html.erb, config/routes.rb and signupControllerTest in test/functional. | This definition’s responsibility can be best described by the word list since it lists all the topics for an assignment. The changes were reflected in signup_sheet_controller, views/student_task/view.html.erb, config/routes.rb and signupControllerTest in test/functional. | ||
[[ File:4_Screenshot.png ]] | |||
* create_default_for_microtask() was refactored to add_default_microtask() | * create_default_for_microtask() was refactored to add_default_microtask() | ||
This definition adds the default microtask as suggested by the new definition name. | This definition adds the default microtask as suggested by the new definition name. | ||
[[ File:Screenshot 5.png ]] | |||
* create_topic_deadline() was refactored to assign_topic_deadline() | * create_topic_deadline() was refactored to assign_topic_deadline() | ||
The responsibility of this definition is better described as assign_topic_deadline rather than create_topic_deadline since this method does both creating and assigning task. | The responsibility of this definition is better described as assign_topic_deadline rather than create_topic_deadline since this method does both creating and assigning task. | ||
[[ File:Screenshot 6.png ]] | |||
2. Several debug statements were present in various parts of the code which reflects bad programming style. Testing should have been used instead to identify the errors in code. For example, in sign_up: | 2. Several debug statements were present in various parts of the code which reflects bad programming style. Testing should have been used instead to identify the errors in code. For example, in sign_up: | ||
[[ File:Screenshot 7.png ]] | |||
Line 131: | Line 149: | ||
4. Redundancy is not a desirable feature in O-O style programming. The code in “save_topic_deadlines” had some duplication in the conditional if statement. This was carefully removed to adhere to good programming style and to increase readability. | 4. Redundancy is not a desirable feature in [https://en.wikipedia.org/wiki/Object-oriented_programming| O-O style programming]. The code in “save_topic_deadlines” had some duplication in the conditional if statement. This was carefully removed to adhere to good programming style and to increase readability. | ||
[[ File:Screenshot9.png ]] | |||
5. Wherever possible, the conditional if statement was replaced by the ternary operator ( ? : ) and if !(condition) was replaced with unless to enhance readability. These changes were made in almost all the definition. Like the one showed below: | 5. Wherever possible, the conditional if statement was replaced by the ternary operator ( ? : ) and if !(condition) was replaced with unless to enhance readability. These changes were made in almost all the definition. Like the one showed below: | ||
[[ File:Screenshot 8.png ]] | |||
6. Long definitions make it difficult to follow the flow of code and therefore, concise methods containing fewer lines of code are desired. In order to achieve the same, a new method “set_values_for_new_topic” was defined. | 6. Long definitions make it difficult to follow the flow of code and therefore, concise methods containing fewer lines of code are desired. In order to achieve the same, a new method “set_values_for_new_topic” was defined. | ||
[[ File:Screenshot 10.png ]] | |||
Line 154: | Line 177: | ||
==Testing== | ==Testing== | ||
Framework Used: Capybara | Framework Used: Capybara<ref>http://rubygems.org/gems/capybara </ref> | ||
Total Number of Tests: 7 | Total Number of Tests: 7 | ||
===Testing Scenarios=== | ===Testing Scenarios:=== | ||
# To login successfully. | # To login successfully. | ||
Line 167: | Line 190: | ||
# To login as a student and fail to choose another topic once a topic has already been selected. | # To login as a student and fail to choose another topic once a topic has already been selected. | ||
==References== | |||
<references/> | |||
Latest revision as of 22:15, 30 March 2014
E802: Refactoring and testing signup_sheet_controller
What does the controller do?
Signup sheet controller handles all the responsibilities in Expertiza<ref> http://expertiza.ncsu.edu/</ref> related to managing sign up topics, assigning deadlines, creating microtask, managing waitlists, etc.
What are we supposed to do?
- This controller contained 28 methods, which is way too many. Some of them did not follow the convention for method names (snake case).
- This controller had many extraneous methods, including those dealing with team membership which were to be moved, and setting due dates for staggered deadline assignments which were a part of different project (E810).
- One of the major functionalities of this class is dealing with deadlines for different topics. These functionalities should be moved to other classes, namely DueDate and DueDate controller.
- Code that deals with the behind-the-scenes working of signup sheets had to be moved to signup_topic model as project E803 is going to deal with it.
- Also, methods of this class refer to the now-removed resubmission & re-review deadlines (“resubmission” deadlines are now submission deadlines; “re-review” deadlines have been turned into review deadlines).
- This controller should be callable from the Topics tab on a New or Edit Assignment screen, not (just) from the popup menu for an assignment. This was dealt with, in another project and was skipped in view of avoiding redundancy.
- Integration tests need to be written.
Hyperlink: http://152.46.20.88:5800/
Git repository: https://github.com/mdjayaprakash/expertiza/tree/sign_up_sheet_controller
Steps to set up Expertiza
- Extract source code for Expertiza into RubyMine from the following URL: https://github.com/mdjayaprakash/expertiza/tree/sign_up_sheet_controller
- Confirm the SDK for RubyMine to Ruby1.9.3 using File -> Settings.
- Run - bundle install: This should install all the gems required for Expertiza in Ruby1.9.3.
- Run - rake db:create:all
- Run - rake db:migrate
- From the Expertiza folder(i.e. project root), execute the command “rails server”
- This should start the Expertiza server at localhost:3000 in your browser.
Files dealt with
- signup_sheet controller
- waitlist model
- signup_topic model
- DueDate model
Categories of code smells identified
- Obvious Conditionals: Branches that check the conditions that are pretty obvious from the context hence increase the length of the overall code and leads to inefficient code.
- Meaningless Identifiers: The identifiers used to address some data whose meaning can’t be understood without going through the flow of code.
- Excessive Parameters: Making a method call with too many parameters makes the code pretty much error prone and reduces the code readability, understandability and simplicity.
- Lengthy Definitions: These are the methods that have too many responsibilities and collaborators. As a result of which, their overall length has grown too long reducing the maintainability and readability.
- Duplicated Code: These are those pieces of code that does almost the same functionality of some other piece of code leading to a bad design style. They are usually too error prone since not everyone identifies all the code responsible for the same task and does the changes whenever the need arises.
- Bad method names: A good method name is expected to adhere to the Ruby style and design style guidelines. It is expected to convey a reasonable amount of responsibilities handled. A good method name in combination with good practices should resemble a user story.
- Used and unnecessary methods: These are those methods that were useful when the code was first developed. But, they lost their functionality as the code got updated and new functionalities were added or existing ones were modified.
- Bad Debug Statements: These statements are highly useful in development environment, but they spoil the software completeness if they’re not logged in the conventional way.
Steps followed to eliminate code smells
1. Definition renaming:
- confirmTopic() was refactored to confirm_topic()
This method follows the camel case which is a bad method naming style was renamed to a snake case style and its functionality was moved to waitlist controller since its functionality and association with waitlist controller is more prominent.
- signup() was refactored to sign_up()
Even this method follows the camel case which is a bad method naming style was renamed to a snake case style just like the previous definition. The changes were done to the method heading along with all the code associated with this method like views/sign_up_sheet/_reserve_topic.html.erb and test/functional/SignUpControllerTest
- teamdetails() was refactored to show_team()
This definition does the job of fetching and showing a team. Hence, we changed its name to a word which describes the definition’s responsibility the closest. This change had effects in views/sign_up_sheet/_table_line.html.erb
- signup_topics() was refactored to list()
This definition’s responsibility can be best described by the word list since it lists all the topics for an assignment. The changes were reflected in signup_sheet_controller, views/student_task/view.html.erb, config/routes.rb and signupControllerTest in test/functional.
- create_default_for_microtask() was refactored to add_default_microtask()
This definition adds the default microtask as suggested by the new definition name.
- create_topic_deadline() was refactored to assign_topic_deadline()
The responsibility of this definition is better described as assign_topic_deadline rather than create_topic_deadline since this method does both creating and assigning task.
2. Several debug statements were present in various parts of the code which reflects bad programming style. Testing should have been used instead to identify the errors in code. For example, in sign_up:
3. Several methods and parts of code that were associated with the signup_sheet_controller should be a part of other controller or model class. Such fragments of code were moved to the respective classes. The methods touched were:
- The method build_dependency_graph() was moved to sign_up_topic model
- The code in confirm_topic() was moved to waitlist_teams method in waitlist model.
- The code in create_topic_deadline was moved to DueDate.assign_topic_deadline
- The method set_start_due_date was moved to DueDate model
- The functionalities of delete_signup_for_topic was moved from sign_up_sheet_controller to reassign_topic method in sign_up_topic model
- The functionality of signup method from sign_up_sheet controller to signup_teams method in signup_sheet model.
4. Redundancy is not a desirable feature in O-O style programming. The code in “save_topic_deadlines” had some duplication in the conditional if statement. This was carefully removed to adhere to good programming style and to increase readability.
5. Wherever possible, the conditional if statement was replaced by the ternary operator ( ? : ) and if !(condition) was replaced with unless to enhance readability. These changes were made in almost all the definition. Like the one showed below:
6. Long definitions make it difficult to follow the flow of code and therefore, concise methods containing fewer lines of code are desired. In order to achieve the same, a new method “set_values_for_new_topic” was defined.
7. All the references to resubmission and re-review deadlines were removed and refactored. Since this functionality has already been removed, the references are redundant and useless.
8. The following redundant methods were removed since they’re redundant and were having duplicate code: find_team_members(team_id) and has_user(user, team_id)
Testing
Framework Used: Capybara<ref>http://rubygems.org/gems/capybara </ref> Total Number of Tests: 7
Testing Scenarios:
- To login successfully.
- To successfully login and create a private assignment with Topics and Available to Students options selected.
- To successfully login and create a Topic for the assignment created in the above test case.
- To login as a student who is enrolled for the same course as that of assignment created in scenario 2.
- To login as the same student in scenario 4 and reach the sign up sheet for the created assignment.
- To login as a student and successfully select the created topic under the created sample test_assignment.
- To login as a student and fail to choose another topic once a topic has already been selected.
References
<references/>