TS 60 Refactoring3
Refactoring Test Specification for
Author: Milan Kubec, Jiri Prox
Version: Revision: 1.1
Last update: Date: 2006/05/23 05:52:48
Introduction:
This document is test specification for several kinds of refactoring provided by NetBeans IDE. Refactoring is an action changing inner structure of the code without influencing behaviour of the whole application. It's used above all for simplifying and reorganization of the code. This testspec concerns following types of refactoring:
- Pull Up
- Push Down
- Move Inner to Outer Level
- Convert Anonymous Class to Inner
- Use Supertype Where Possible
Comments:
Specifications:
Pull Up, Push Down, Move Inner to Outer Level, Convert Anonymous Class to Inner, Use Supertype Where Possible.
Contents |
Test suite: Pull Up
Purpose: Pull Up moves elements of the class to the super class. Moved elements can be fields, methods, inner classes and implemented interfaces. When moving private elements its modifier must be changed to protected in order to be accessible from original class.
Setup: Unzip and open project PushPull.
- Pull Up Availability
- Check presence of Pull Up item in menu Refactor
- Select package pull in the project windows and check in Pull Up is disabled both in Refactor | Pull Up and context menu.
- Select node corresponding to VIPCustomer.java in project view and call Pull Up
- Open VIPCustomer class in editor and call Pull Up .
- {{result|EXPECTED RESULT: Pull Up is present in the menu and is disabled for package scope. When called in the class scope and in editor the dialog is opened. It has correct title and provides all inner elements which can be pulled up.
- Pull Up basic
- Invoke Refactor | Pull Up for VIPCustomer class
- Select class Customer as a target
- Select all elements and press Preview
- Review all changes and click Do Refactoring
- EXPECTED RESULT: In the dialog, there are listed all pull-able elements. Methods have extra checkbox Make abstract. After confirming action, all elements are moved to the superclass. (There is error in RegularCustomer class after the refactoring - invalid method overriding)
- Pull Up two and more levels
- Invoke Refactor
- Invoke Refactor
Test suite: Push Down
Purpose: Push down moves selected elements lower to the subclasses. If the actual class has more subclasses the elements are propagated to all of them. All elements such fields, methods, inner classes and implemented interfaces can be pulled down, regardless of their modificators.
Setup: Unzip and open project PushPull
- Push Down basic
- Invoke Refactor | Push Down for SuperBaseClass class
- Select all elements and press Preview
- Review all changes and click Do Refactoring
- EXPECTED RESULT: All elements should be moved to all subclasses. Note that there is warning about field fieldString , which already exists in one of the subclasses. When refactoring is performed, the declaration of fieldString is doubled in one of the subclasses. Necessary imports are added to all subclasses.
- Push Down selected element
- Open SuperBaseClass in editor
- Put caret on element which can be pushed down (note: this doesn't work for elements with further inner elements such as classes, inner ifaces etc..)
- Call Refactor | Push Down
- EXPECTED RESULT: When caret is located in pushable element the relevant checkbox is checked in the refactoring dialog
- Push Down implemented interface
- Invoke Refactor
- Invoke Refactor
Test suite: Inner to Outer
Purpose: This type of refactoring moves inner class one level up. If it was originally in the top level class it is moved to separate file. The problem with accessing elements in the original outer class is solved by adding parameter to constructor passing instance of outer class.
Setup: Unzip and open project ConvertClasses
- Inner to Outer - basic
- Put caret in the body of class Inner1 located in OuterClass
- Call Move Inner to Outer Level
- In the dialog change Class Name to Rename,Field Name to orig
- Click Preview, inspect all changes and confirm by Do Refactoring
- EXPECTED RESULT: New file with class Renamed is created. Its constructor has one parameter orig of type OuterClass . The occurrences of Inner1 is replaced with the new name. The modifiers of field and privMethod are changed to package public. The getInner() method of the original outer class contains return new Renamed(this); . Class User has correct reference to new class.
- Inner to Outer - static class
- Call Move Inner to Outer Level for class Inner2 located in OuterClass
- Keep all options as default
- Click Preview, review all changes and confirm by Do Refactoring
- EXPECTED RESULT: The class is moved into new file as top-level class. Class User has correct reference to moved class. Filed referring to original class is not generated.
- Inner to Outer - interfaces
- Call Move Inner to Outer Level for class InnerIface located in OuterClass
- In the dialog change Class Name
- Click Preview, review all changes and confirm by Do Refactoring
- EXPECTED RESULT: Interface is moved to separate file. Reference in class User is updated
- Inner to Outer - enum
- Call Move Inner to Outer Level for enum InnerEnum located in OuterClass
- In the dialog change Class Name
- Click Preview, review all changes and confirm by Do Refactoring
- EXPECTED RESULT: Enum is moved to separate file. Reference in class User is updated
- Inner to Outer - annotations
- Call Move Inner to Outer Level for class InnerAnot located in OuterClass
- In the dialog change Class Name
- Click Preview, review all changes and confirm by Do Refactoring
- EXPECTED RESULT: Annotation is moved to separate file. Reference in class User is updated
- Inner to Outer - fix imports
- Call Move Inner to Outer Level for class FileHandler located in Wrapper class
- Keep all defaults and perform refactoring
- EXPECTED RESULT: Class is moved to a separate file with all necessary imports.
- Inner to Outer - constructors
- Call Move Inner to Outer Level for class InnerClass located in Wrapper class
- In the dialog, leave all options as default
- Click Preview, review all changes and confirm by Do Refactoring
- EXPECTED RESULT: New separate file with class Inner is created. All constructors are updated to accept reference to outer class as additional parameter.
- Inner to Outer - two levels
- Call Move Inner to Outer Level for class InnerInnerClass located in Wrapper class
- Keep all as default, perform refactoring
- Call Move Inner to Outer Level for class InnerInnerClass again
- Keep all as default, perform refactoring
- EXPECTED RESULT: The InnerInnerClass class is step by step propagated to outer level. The reference to previous outer classes are added to constructor.
- Inner to Outer - w/o preview
- Call Move Inner to Outer Level for class Inner1 located in OuterClass
- In the dialog uncheck Preview All Changes
- Click Refactor
- EXPECTED RESULT: Action is performed w/o preview
- Inner to Outer - cancel
- Call Move Inner to Outer Level for class Inner1 located in OuterClass
- Click Preview
- In preview click Cancel
- EXPECTED RESULT: There are no changes in the code
- Inner to Outer - refresh
- Call Move Inner to Outer Level for class Inner1 located in OuterClass
- In the dialog change Class Name and Field Name
- Click Preview
- In preview click Refresh (button with the green arrow)
- EXPECTED RESULT: The refactoring dialog is reopened, all values are restored
Test suite: Anonymous to Inner
Purpose: This refactoring converts selected anonymous class to regular inner class.
Comments: This is implemented in Java/hints module.
Setup: Unzip and open project [[../data/ConvertClasses_TS_60_Refactoring3.zip| ConvertClasses]]
- Anon to Inner availability
- Check presence of Convert Anonymous Class to Inner item in menu Refactor
- Select package node and class node and check that menu item is disabled
- Open some java file and put carent into it -> the menu item is enabled
- Place cursor over identifier of supertype in anonymous class declaration (e.g. over second word Runnable in "Runnable r = new Runnable() { ... }") -> hint Convert anonymous ... is provided
- EXPECTED RESULT: The menu item is avaiable and it's enable/disable status follow previous description.
- Anon to Inner - basic
- Open ClassA in editor and call refactoring for its anonymous class.
- Type new name
- Use editor undo for taking the changes back
- EXPECTED RESULT: New inner class is created. It's name is derived from original name by appending "Impl", the body of anonymous class is move to the newly introduced class and at original place, there is call of its constructor. The instant-rename for name of new class is on, so when the user is typing the new class is beeing renamed. Enter ends the renaming. Undo reverts all changes.
- Anon to Inner - constructor
- Open ClassB in editor and call refactoring for its anonymous class.
- EXPECTED RESULT: The new inner class is created. It's constructor accepts one parameter and delegates is to super class.
- Anon to Inner - static
- Open ClassD in editor and call refactoring for its anonymous class.
- EXPECTED RESULT: The new class is declared as static, since it used in static context
Test suite: Use Supertype
Purpose: This kind of refactoring tries to use selected supertype where possible, e.g. changes the type of variable to the supertype if it doesn't use methods or fields of any its subtype.
Setup: Unzip and open project [[../data/ConvertClasses_TS_60_Refactoring3.zip| ConvertClasses]]
- Use Supertype - availability
- Check presence of Use Supertype Where Possible item in menu Refactor
- Browse through the structure of class usesupertype.Sub in projects window, call Use Supertype Where Possible for each type of element.
- Open Sub in editor and call refactoring from various position in the class
- EXPECTED RESULT: Use Supertype Where Possible is enabled available for classes, e.g form node corresponding to java file and form node corresponding directly to the class.
- Use Supertype - basic
- Call Use Supertype Where Possible for class Sub
- Select java.lang.Object from the list and check Preview All Changes
- Click Preview, review all changes and confirm by Do Refactoring
- EXPECTED RESULT: Occurrence is found, check the class User , there should be s6 retyped to Object .
- Use Supertype - select type
- Call Use Supertype Where Possible for class Sub
- Select one item form the list
- Click Preview, review all changes and confirm by Do Refactoring
- EXPECTED RESULT: The identifiers s? should be typed according to the selected type
- Use Supertype - w/o preview
- Call Use Supertype Where Possible for class Sub
- Select one item from the list, uncheck Preview All Changes
- Click Refactor
- EXPECTED RESULT: The action is performed w/o preview
- Use Supertype - cancel
- Call Use Supertype Where Possible for class Sub
- Select one item from the list,
- Click Preview.
- In the preview click Cancel
- EXPECTED RESULT: Refactoring is canceled, no changes are made to the code.
- Use Supertype - refresh
- Call Use Supertype Where Possible for class Sub
- Select one item from the list
- Click Preview
- In preview click Refresh (button with the green arrow)
- EXPECTED RESULT: Dialog is reopened, previous selection is restored

