/*
* Copyright (c) 2013, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.dart.engine.services.internal.refactoring;
import com.google.dart.engine.services.assist.AssistContext;
import com.google.dart.engine.services.change.Change;
import com.google.dart.engine.services.refactoring.ExtractMethodRefactoring;
import com.google.dart.engine.services.refactoring.Parameter;
import com.google.dart.engine.services.status.RefactoringStatus;
import com.google.dart.engine.services.status.RefactoringStatusSeverity;
import org.apache.commons.lang3.ArrayUtils;
import static org.fest.assertions.Assertions.assertThat;
/**
* Test for {@link ExtractMethodRefactoringImpl}.
*/
public class ExtractMethodRefactoringImplTest extends RefactoringImplTest {
private ExtractMethodRefactoringImpl refactoring;
private int selectionStart = -1;
private int selectionEnd = -1;
private String methodName = "res";
private boolean replaceAllOccurences = true;
private boolean keepGetterFlag = false;
private RefactoringStatus refactoringStatus;
public void test_bad_assignmentLeftHandSide() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int aaa;",
"// start",
" aaa ",
"// end",
" = 0;",
"}",
"");
setSelectionString("aaa ");
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract the left-hand side of an assignment.");
}
public void test_bad_comment_selectionEndsInside() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" print(0);",
"/*",
"// end",
"*/",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Selection ends inside a comment.");
}
public void test_bad_comment_selectionStartsInside() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"/*",
"// start",
"*/",
" print(0);",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Selection begins inside a comment.");
}
public void test_bad_conflict_method_alreadyDeclaresMethod() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" void res() {}",
" main() {",
"// start",
" print(0);",
"// end",
" }",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.ERROR,
"Class 'A' already declares method with name 'res'.",
findRangeIdentifier("res() {}"));
}
public void test_bad_conflict_method_shadowsSuperDeclaration() throws Exception {
indexTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" void res() {} // marker",
"}",
"class B extends A {",
" main() {",
" res();",
"// start",
" print(0);",
"// end",
" }",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.ERROR,
"Created method will shadow method 'A.res'.",
findRangeIdentifier("res() {} // marker"));
}
public void test_bad_conflict_topLevel_alreadyDeclaresFunction() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"void res() {}",
"main() {",
"// start",
" print(0);",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.ERROR,
"Library already declares function with name 'res'.",
findRangeIdentifier("res() {}"));
}
// TODO(scheglov) waiting for "library namespace" in Engine
// public void test_bad_conflict_method_willHideTopLevel() throws Exception {
// indexTestUnit(
// "// filler filler filler filler filler filler filler filler filler filler",
// "void res() {} // marker",
// "class B {",
// " main() {",
// "// start",
// " print(0);",
// "// end",
// " }",
// " foo() {",
// " res();",
// " }",
// "}",
// "");
// setSelectionFromStartEndComments();
// createRefactoring();
// // check conditions
// assertRefactoringStatus(
// refactoringStatus,
// RefactoringStatusSeverity.ERROR,
// "Created method will shadow method 'A.res'.",
// findRangeIdentifier("res() {} // marker"));
//// assertTrue(refactoringStatus.hasError());
//// {
//// String msg = refactoringStatus.getMessageMatchingSeverity(RefactoringStatus.ERROR);
//// assertEquals(
//// "Usage of function 'res' in file 'Test/Test.dart' in library 'Test' will be shadowed by created function",
//// msg);
//// }
// }
public void test_bad_conflict_topLevel_willHideInheritedMemberUsage() throws Exception {
indexTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" void res() {}",
"}",
"class B extends A {",
" foo() {",
" res(); // marker",
" }",
"}",
"main() {",
"// start",
" print(0);",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.ERROR,
"Created function will shadow method 'A.res'.",
findRangeIdentifier("res(); // marker"));
}
public void test_bad_constructor_initializer() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" int f;",
" A() :",
"// start",
" f = 0",
"// end",
" {}",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract a constructor initializer. Select expression part of initializer.");
}
public void test_bad_constructor_redirectingConstructor() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" A() :",
"// start",
" this.named()",
"// end",
" ;",
" A.named() {}",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract a constructor initializer. Select expression part of initializer.");
}
public void test_bad_constructor_superConstructor() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class B {}",
"class A extends B {",
" A() :",
"// start",
" super()",
"// end",
" {}",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract a constructor initializer. Select expression part of initializer.");
}
public void test_bad_doWhile_body() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" do ",
"// start",
" { ",
" }",
"// end",
" while (true);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Operation not applicable to a 'do' statement's body and expression.");
}
public void test_bad_emptySelection() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
"// end",
" int v = 1 + 2;",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Can only extract a single expression or a set of statements.");
}
public void test_bad_forLoop_conditionAndUpdaters() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" for ( ",
" int i = 0;",
"// start",
" i < 10; ",
" i++",
"// end",
" ) {}",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Operation not applicable to a 'for' statement's condition and updaters.");
}
public void test_bad_forLoop_init() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" for ( ",
"// start",
" int i = 0",
"// end",
" ; i < 10; ",
" i++",
" ) {}",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract initialization part of a 'for' statement.");
}
public void test_bad_forLoop_initAndCondition() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" for ( ",
"// start",
" int i = 0;",
" i < 10; ",
"// end",
" i++",
" ) {}",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Operation not applicable to a 'for' statement's initializer and condition.");
}
public void test_bad_forLoop_updaters() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" for ( ",
" int i = 0;",
" i < 10; ",
"// start",
" i++",
"// end",
" ) {}",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract increment part of a 'for' statement.");
}
public void test_bad_forLoop_updatersAndBody() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" for ( ",
" int i = 0;",
" i < 10; ",
"// start",
" i++",
" ) {}",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Operation not applicable to a 'for' statement's updaters and body.");
}
public void test_bad_methodName_reference() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" main();",
"}",
"");
selectionStart = findOffset("main();");
selectionEnd = selectionStart + "main".length();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract a single method name.");
}
public void test_bad_namePartOfDeclaration_function() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a;",
"}",
"");
selectionStart = findOffset("main() {");
selectionEnd = selectionStart + "main".length();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract the name part of a declaration.");
}
public void test_bad_namePartOfDeclaration_variable() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int vvv = 0;",
"}",
"");
selectionStart = findOffset("vvv =");
selectionEnd = selectionStart + "vvv".length();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract the name part of a declaration.");
}
public void test_bad_namePartOfQualified() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" var fff;",
"}",
"main() {",
" A a;",
" a.fff = 1;",
"}",
"");
selectionStart = findOffset("fff =");
selectionEnd = selectionStart + "fff".length();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Can not extract name part of a property access.");
}
public void test_bad_newMethodName_notIdentifier() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" print(0);",
"// end",
"}",
"");
setSelectionFromStartEndComments();
methodName = "bad-name";
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Method name must not contain '-'.");
}
public void test_bad_notSameParent() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" while (false) ",
"// start",
" { ",
" } ",
" print(0);",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Not all selected statements are enclosed by the same parent statement.");
}
public void test_bad_parameterName_duplicate() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
"// start",
" int a = v1 + v2; // marker",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// update parameters
{
Parameter[] parameters = refactoring.getParameters();
assertThat(parameters).hasSize(2);
parameters[0].setNewName("dup");
parameters[1].setNewName("dup");
refactoring.setParameters(parameters);
}
// check conditions
refactoringStatus = refactoring.checkFinalConditions(pm);
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.ERROR,
"Parameter 'dup' already exists");
}
public void test_bad_parameterName_inUse() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
"// start",
" int a = v1 + v2; // marker",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// update parameters
{
Parameter[] parameters = refactoring.getParameters();
assertThat(parameters).hasSize(2);
parameters[0].setNewName("a");
refactoring.setParameters(parameters);
}
// check conditions
refactoringStatus = refactoring.checkFinalConditions(pm);
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.ERROR,
"'a' is already used as a name in the selected code");
}
public void test_bad_selectionEndsInSomeNode() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" print(0);",
" print(1);",
"// end",
"}",
"");
setSelectionFromStartEndComments();
selectionEnd = findOffset("print(1)") + "pri".length();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"The selection does not cover a set of statements or an expression. Extend selection to a valid range.");
}
public void test_bad_statements_return_andAssignsVariable() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" var v = 0;",
" return 42;",
"// end",
" print(v);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Ambiguous return value: "
+ "Selected block contains assignment(s) to local variables and return statement.");
}
public void test_bad_switchCase() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" switch (1) { ",
"// start",
" case 0: break;",
"// end",
" }",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Selection must either cover whole switch statement or parts of a single case block.");
}
public void test_bad_tokensBetweenLastNodeAndSelectionEnd() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" print(0);",
" print(1);",
"}",
"// end",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"The end of the selection contains characters that do not belong to a statement.");
}
public void test_bad_tokensBetweenSelectionStartAndFirstNode() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" print(0); // marker",
" print(1);",
"// end",
"}",
"");
setSelectionFromStartEndComments();
selectionStart = findOffset("// marker") - "); ".length();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"The beginning of the selection contains characters that do not belong to a statement.");
}
public void test_bad_try_catchBlock_block() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" try",
" {} ",
" catch (e)",
"// start",
" {}",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Selection must either cover whole try statement or parts of try, catch, or finally block.");
}
public void test_bad_try_catchBlock_complete() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" try",
" {} ",
"// start",
" catch (e)",
" {}",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Selection must either cover whole try statement or parts of try, catch, or finally block.");
}
public void test_bad_try_catchBlock_exception() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" try",
" {} ",
" catch (",
"// start",
" e",
"// end",
" )",
" {}",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract the name part of a declaration.");
}
public void test_bad_try_finallyBlock() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" try",
" {} ",
" finally",
"// start",
" {}",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Selection must either cover whole try statement or parts of try, catch, or finally block.");
}
public void test_bad_try_tryBlock() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" try",
"// start",
" {} ",
"// end",
" finally",
" {}",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Selection must either cover whole try statement or parts of try, catch, or finally block.");
}
public void test_bad_typeReference() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a;",
"}",
"");
selectionStart = findOffset("int");
selectionEnd = selectionStart + "int".length();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract a single type reference.");
}
public void test_bad_variableDeclarationFragment() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int ",
"// start",
" a = 1",
"// end",
" ,b = 2;",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract a variable declaration fragment. Select whole declaration statement.");
}
public void test_bad_while_conditionAndBody() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" while ",
"// start",
" (false) ",
" { ",
" } ",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Operation not applicable to a while statement's expression and body.");
}
public void test_canExtractGetter_false_fieldAssignment() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" var f;",
" main() {",
"// start",
" f = 1;",
"// end",
" }",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
//
assertFalse(refactoring.canExtractGetter());
assertFalse(refactoring.getExtractGetter());
}
public void test_canExtractGetter_false_hasParameters() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"f(int p) {",
" int a = p + 1;",
"}",
"");
setSelectionString("p + 1");
createRefactoring();
//
assertFalse(refactoring.canExtractGetter());
assertFalse(refactoring.getExtractGetter());
}
public void test_canExtractGetter_false_returnNotUsed_assignment() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"var topVar = 0;",
"f(int p) {",
" topVar = 5;",
"}",
"");
setSelectionString("topVar = 5");
createRefactoring();
//
assertFalse(refactoring.canExtractGetter());
assertFalse(refactoring.getExtractGetter());
}
public void test_canExtractGetter_false_returnNotUsed_noReturn() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"var topVar = 0;",
"main() {",
"// start",
" int a = 1;",
" int b = 2;",
" topVar = a + b;",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
//
assertFalse(refactoring.canExtractGetter());
assertFalse(refactoring.getExtractGetter());
}
public void test_canExtractGetter_true() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a = 1 + 2;",
"}",
"");
setSelectionString("1 + 2");
createRefactoring();
// no parameters
assertTrue(refactoring.canExtractGetter());
assertTrue(refactoring.getExtractGetter());
}
public void test_checkMethodName() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" print(1 + 2);",
"}");
setSelectionString("1 + 2");
methodName = "bad-name";
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoring.checkMethodName(),
RefactoringStatusSeverity.ERROR,
"Method name must not contain '-'.");
}
public void test_closure_asFunction_singleExpression() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"process(f(x)) {}",
"main() {",
" process((x) => x * 2);",
"}");
setSelectionString("(x) => x * 2");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"process(f(x)) {}",
"main() {",
" process(res);",
"}",
"",
"res(x) => x * 2;");
}
public void test_closure_asFunction_statements() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"process(f(x)) {}",
"main() {",
" process((x) {",
" print(x);",
" return x * 2;",
" }); // marker",
"}");
selectionStart = findOffset("(x) {");
selectionEnd = findOffset("); // marker");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"process(f(x)) {}",
"main() {",
" process(res); // marker",
"}",
"",
"res(x) {",
" print(x);",
" return x * 2;",
"}");
}
public void test_closure_asMethod_statements() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"process(f(x)) {}",
"class A {",
" int k = 2;",
" main() {",
" process((x) {",
" print(x);",
" return x * k;",
" }); // marker",
" }",
"}");
selectionStart = findOffset("(x) {");
selectionEnd = findOffset("); // marker");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"process(f(x)) {}",
"class A {",
" int k = 2;",
" main() {",
" process(res); // marker",
" }",
"",
" res(x) {",
" print(x);",
" return x * k;",
" }",
"}");
}
public void test_closure_bad_referencesLocalVariable() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"process(f(x)) {}",
"main() {",
" int k = 2;",
" process((x) => x * k);",
"}");
setSelectionString("(x) => x * k");
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract closure as method, it references 1 external variable(s).");
}
public void test_closure_bad_referencesParameter() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"process(f(x)) {}",
"foo(int k) {",
" process((x) => x * k);",
"}");
setSelectionString("(x) => x * k");
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Cannot extract closure as method, it references 1 external variable(s).");
}
public void test_fromTopLevelVariableInitializerClosure() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"var X = 1;",
"",
"var Y = () {",
" return 1 + X;",
"};");
setSelectionString("1 + X");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"var X = 1;",
"",
"var Y = () {",
" return res();",
"};",
"",
"num res() => 1 + X;");
}
public void test_getExtractGetter_false_do() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" int v = 0;",
" do {",
" v++;",
" } while (v < 10);",
"// end",
" print(v);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
//
assertFalse(refactoring.getExtractGetter());
}
public void test_getExtractGetter_false_for() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" int v = 0;",
" for (int i = 0; i < 10; i++) {",
" v += i;",
" }",
"// end",
" print(v);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
//
assertFalse(refactoring.getExtractGetter());
}
public void test_getExtractGetter_false_forEach() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"List<int> L = [];",
"main() {",
"// start",
" int v = 0;",
" for (int i in L) {",
" v += i;",
" }",
"// end",
" print(v);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
//
assertFalse(refactoring.getExtractGetter());
}
public void test_getExtractGetter_false_methodInvocation_expression() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"List<int> L = [];",
"main() {",
" int v = calculateSomething() + 5;",
"}",
"int calculateSomething() => 42;",
"");
setSelectionString("calculateSomething() + 5");
createRefactoring();
//
assertFalse(refactoring.getExtractGetter());
}
public void test_getExtractGetter_false_methodInvocation_statements() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"List<int> L = [];",
"main() {",
"// start",
" int v = calculateSomething();",
"// end",
" print(v);",
"}",
"int calculateSomething() => 42;",
"");
setSelectionFromStartEndComments();
createRefactoring();
//
assertFalse(refactoring.getExtractGetter());
}
public void test_getExtractGetter_false_while() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" int v = 0;",
" while (v < 10) {",
" v++;",
" }",
"// end",
" print(v);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
//
assertFalse(refactoring.getExtractGetter());
}
public void test_getExtractGetter_true_simpleBlock() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" int v = 1 + 2;",
"// end",
" print(v);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
//
assertTrue(refactoring.getExtractGetter());
}
public void test_getExtractGetter_true_singleExpression() throws Exception {
keepGetterFlag = true;
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a = 1 + 2;",
"}",
"");
setSelectionString("1 + 2");
createRefactoring();
//
assertTrue(refactoring.getExtractGetter());
}
public void test_getRefactoringName_function() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" print(1 + 2);",
"}");
// create refactoring
setSelectionString("1 + 2");
createRefactoring();
// access
assertEquals("Extract Function", refactoring.getRefactoringName());
}
public void test_getRefactoringName_method() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" main() {",
" print(1 + 2);",
" }",
"}");
// create refactoring
setSelectionString("1 + 2");
createRefactoring();
// access
assertEquals("Extract Method", refactoring.getRefactoringName());
}
public void test_setExtractGetter() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a = 1 + 2;",
"}",
"");
setSelectionString("1 + 2");
createRefactoring();
// false
refactoring.setExtractGetter(false);
assertEquals(false, refactoring.getExtractGetter());
// true
refactoring.setExtractGetter(true);
assertEquals(true, refactoring.getExtractGetter());
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a = res;",
"}",
"",
"int get res => 1 + 2;",
"");
}
public void test_singleExpression() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a = 1 + 2;",
"}",
"");
setSelectionString("1 + 2");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a = res();",
"}",
"",
"int res() => 1 + 2;",
"");
}
public void test_singleExpression_cascade() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"dynaFunction() {}",
"main() {",
" String s = '';",
" var v = s..length;",
"}",
"");
setSelectionString("s..length");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"dynaFunction() {}",
"main() {",
" String s = '';",
" var v = res(s);",
"}",
"",
"String res(String s) => s..length;",
"");
}
public void test_singleExpression_Dynamic() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"dynaFunction() {}",
"main() {",
" int a = dynaFunction(); // marker",
"}",
"");
selectionStart = findOffset("dynaFunction();");
selectionEnd = findOffset("; // marker");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"dynaFunction() {}",
"main() {",
" int a = res(); // marker",
"}",
"",
"res() => dynaFunction();",
"");
}
public void test_singleExpression_ignore_assignmentLeftHandSize() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" getButton().text = 'txt';",
" print(getButton().text); // marker",
"}",
"getButton() {}",
"");
selectionStart = findOffset("getButton().text); // marker");
selectionEnd = findOffset("); // marker");
createRefactoring();
// check number of occurrences
assertEquals(1, refactoring.getNumberOfOccurrences());
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" getButton().text = 'txt';",
" print(res()); // marker",
"}",
"",
"res() => getButton().text;",
"getButton() {}",
"");
}
public void test_singleExpression_occurrences() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int v3 = 3;",
" int positiveA = v1 + v2; // marker",
" int positiveB = v2 + v3;",
" int positiveC = v1 + v2;",
" int positiveD = v1/*abc*/ + v2;",
" int negA = 1 + 2;",
" int negB = 1 + v2;",
" int negC = v1 + 2;",
" int negD = v1 * v2;",
"}",
"");
selectionStart = findOffset("v1 +");
selectionEnd = findOffset("; // marker");
createRefactoring();
// check number of occurrences
assertEquals(4, refactoring.getNumberOfOccurrences());
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int v3 = 3;",
" int positiveA = res(v1, v2); // marker",
" int positiveB = res(v2, v3);",
" int positiveC = res(v1, v2);",
" int positiveD = res(v1, v2);",
" int negA = 1 + 2;",
" int negB = 1 + v2;",
" int negC = v1 + 2;",
" int negD = v1 * v2;",
"}",
"",
"int res(int v1, int v2) => v1 + v2;",
"");
}
public void test_singleExpression_occurrences_disabled() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int v3 = 3;",
" int a = v1 + v2; // marker",
" int b = v2 + v3;",
"}",
"");
selectionStart = findOffset("v1 +");
selectionEnd = findOffset("; // marker");
replaceAllOccurences = false;
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int v3 = 3;",
" int a = res(v1, v2); // marker",
" int b = v2 + v3;",
"}",
"",
"int res(int v1, int v2) => v1 + v2;",
"");
}
public void test_singleExpression_occurrences_inClassOnly() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" myMethod() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = v1 + v2; // marker",
" }",
"}",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int negA = v1 + v2;",
"}",
"");
selectionStart = findOffset("v1 +");
selectionEnd = findOffset("; // marker");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" myMethod() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = res(v1, v2); // marker",
" }",
"",
" int res(int v1, int v2) => v1 + v2;",
"}",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int negA = v1 + v2;",
"}",
"");
}
public void test_singleExpression_occurrences_inWholeUnit() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = v1 + v2; // marker",
"}",
"class A {",
" myMethod() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveB = v1 + v2;",
" }",
"}",
"");
selectionStart = findOffset("v1 +");
selectionEnd = findOffset("; // marker");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = res(v1, v2); // marker",
"}",
"",
"int res(int v1, int v2) => v1 + v2;",
"class A {",
" myMethod() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveB = res(v1, v2);",
" }",
"}",
"");
}
public void test_singleExpression_returnTypeGeneric() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" var v = new List<String>();",
"}",
"");
setSelectionString("new List<String>()");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" var v = res();",
"}",
"",
"List<String> res() => new List<String>();",
"");
}
public void test_singleExpression_returnTypePrefix() throws Exception {
setFileContent(
"MyLib.dart",
makeSource(
"// filler filler filler filler filler filler filler filler filler filler",
"library my_lib;",
"class A {}",
""));
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"import 'MyLib.dart' as ml;",
"main() {",
" var a = new ml.A();",
"}",
"");
setSelectionString("new ml.A()");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"import 'MyLib.dart' as ml;",
"main() {",
" var a = res();",
"}",
"",
"ml.A res() => new ml.A();",
"");
}
public void test_singleExpression_staticContext_extractFromInitializer() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" A(int v) {}",
"}",
"class B extends A {",
" B() : super(1 + 2) {}",
"}",
"");
selectionStart = findOffset("1 + 2");
selectionEnd = findOffset("2) {}") + 1;
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" A(int v) {}",
"}",
"class B extends A {",
" B() : super(res()) {}",
"",
" static int res() => 1 + 2;",
"}",
"");
}
public void test_singleExpression_staticContext_extractFromInstance() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" instanceMethodA() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = v1 + v2; // marker",
" }",
" instanceMethodB() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveB = v1 + v2;",
" }",
" static staticMethodA() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = v1 + v2;",
" }",
"}",
"");
selectionStart = findOffset("v1 +");
selectionEnd = findOffset("; // marker");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" instanceMethodA() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = res(v1, v2); // marker",
" }",
"",
" static int res(int v1, int v2) => v1 + v2;",
" instanceMethodB() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveB = res(v1, v2);",
" }",
" static staticMethodA() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = res(v1, v2);",
" }",
"}",
"");
}
public void test_singleExpression_staticContext_extractFromStatic() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" static staticMethodA() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = v1 + v2; // marker",
" }",
" static staticMethodB() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveB = v1 + v2;",
" }",
" instanceMethodA() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = v1 + v2;",
" }",
"}",
"");
selectionStart = findOffset("v1 +");
selectionEnd = findOffset("; // marker");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" static staticMethodA() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = res(v1, v2); // marker",
" }",
"",
" static int res(int v1, int v2) => v1 + v2;",
" static staticMethodB() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveB = res(v1, v2);",
" }",
" instanceMethodA() {",
" int v1 = 1;",
" int v2 = 2;",
" int positiveA = res(v1, v2);",
" }",
"}",
"");
}
public void test_singleExpression_staticContext_hasInInitializer() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" A(int v) {}",
"}",
"class B extends A {",
" B() : super(1 + 2) {}",
" foo() {",
" print(1 + 2); // marker",
" }",
"}",
"");
selectionStart = findOffset("1 + 2); // marker");
selectionEnd = findOffset("2); // marker") + 1;
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" A(int v) {}",
"}",
"class B extends A {",
" B() : super(res()) {}",
" foo() {",
" print(res()); // marker",
" }",
"",
" static int res() => 1 + 2;",
"}",
"");
}
public void test_singleExpression_usesParameter() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"fooA(int a1) {",
" int a2 = 2;",
" int a = a1 + a2; // marker",
"}",
"fooB(int b1) {",
" int b2 = 2;",
" int b = b1 + b2;",
"}",
"");
selectionStart = findOffset("a1 +");
selectionEnd = findOffset("; // marker");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"fooA(int a1) {",
" int a2 = 2;",
" int a = res(a1, a2); // marker",
"}",
"",
"int res(int a1, int a2) => a1 + a2;",
"fooB(int b1) {",
" int b2 = 2;",
" int b = res(b1, b2);",
"}",
"");
}
public void test_singleExpression_withVariables() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int a = v1 + v2 + v1; // marker",
"}",
"");
selectionStart = findOffset("v1 +");
selectionEnd = findOffset("; // marker");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int a = res(v1, v2); // marker",
"}",
"",
"int res(int v1, int v2) => v1 + v2 + v1;",
"");
}
public void test_singleExpression_withVariables_doRename() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int v3 = 3;",
" int a = v1 + v2 + v1; // marker",
" int b = v2 + v3 + v2;",
"}",
"");
selectionStart = findOffset("v1 +");
selectionEnd = findOffset("; // marker");
createRefactoring();
// update parameters
{
Parameter[] parameters = refactoring.getParameters();
assertThat(parameters).hasSize(2);
parameters[0].setNewName("par1");
parameters[1].setNewName("param2");
refactoring.setParameters(parameters);
}
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int v3 = 3;",
" int a = res(v1, v2); // marker",
" int b = res(v2, v3);",
"}",
"",
"int res(int par1, int param2) => par1 + param2 + par1;",
"");
}
public void test_singleExpression_withVariables_doReorder() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int v3 = 3;",
" int a = v1 + v2; // marker",
" int b = v2 + v3;",
"}",
"");
selectionStart = findOffset("v1 +");
selectionEnd = findOffset("; // marker");
createRefactoring();
// update parameters
{
Parameter[] parameters = refactoring.getParameters();
assertThat(parameters).hasSize(2);
Parameter p = parameters[1];
parameters = ArrayUtils.remove(parameters, 1);
parameters = ArrayUtils.add(parameters, 0, p);
refactoring.setParameters(parameters);
}
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int v3 = 3;",
" int a = res(v2, v1); // marker",
" int b = res(v3, v2);",
"}",
"",
"int res(int v2, int v1) => v1 + v2;",
"");
}
/**
* <p>
* https://code.google.com/p/dart/issues/detail?id=10942
*/
public void test_singleExpression_withVariables_namedExpression() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int a = process(arg: v1 + v2); // marker",
"}",
"process({arg}) {}");
setSelectionString("process(arg: v1 + v2)");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int a = res(v1, v2); // marker",
"}",
"",
"res(int v1, int v2) => process(arg: v1 + v2);",
"process({arg}) {}");
}
public void test_singleExpression_withVariables_newType() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int v3 = 3;",
" int a = v1 + v2 + v3; // marker",
"}",
"");
selectionStart = findOffset("v1 +");
selectionEnd = findOffset("; // marker");
createRefactoring();
// update parameters
{
Parameter[] parameters = refactoring.getParameters();
assertThat(parameters).hasSize(3);
parameters[0].setNewTypeName("num");
parameters[1].setNewTypeName("dynamic");
parameters[2].setNewTypeName("");
refactoring.setParameters(parameters);
}
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v1 = 1;",
" int v2 = 2;",
" int v3 = 3;",
" int a = res(v1, v2, v3); // marker",
"}",
"",
"int res(num v1, v2, v3) => v1 + v2 + v3;",
"");
}
public void test_singleExpression_withVariables_useBestType() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" var v1 = 1;",
" var v2 = 2;",
" var a = v1 + v2 + v1; // marker",
"}",
"");
selectionStart = findOffset("v1 +");
selectionEnd = findOffset("; // marker");
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" var v1 = 1;",
" var v2 = 2;",
" var a = res(v1, v2); // marker",
"}",
"",
"num res(int v1, int v2) => v1 + v2 + v1;",
"");
}
public void test_statements_assignment() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v;",
"// start",
" v = 5;",
"// end",
" print(v);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int v;",
"// start",
" v = res(v);",
"// end",
" print(v);",
"}",
"",
"int res(int v) {",
" v = 5;",
" return v;",
"}",
"");
}
public void test_statements_changeIndentation() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" {",
"// start",
" if (true) {",
" print(0);",
" }",
"// end",
" }",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" {",
"// start",
" res();",
"// end",
" }",
"}",
"",
"void res() {",
" if (true) {",
" print(0);",
" }",
"}",
"");
}
public void test_statements_changeIndentation_multilineString() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" {",
"// start",
" print('''",
"first line",
"second line",
" ''');",
"// end",
" }",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" {",
"// start",
" res();",
"// end",
" }",
"}",
"",
"void res() {",
" print('''",
"first line",
"second line",
" ''');",
"}",
"");
}
public void test_statements_definesVariable_notUsedOutside() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a = 1;",
" int b = 1;",
"// start",
" int v = a + b;",
" print(v);",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a = 1;",
" int b = 1;",
"// start",
" res(a, b);",
"// end",
"}",
"",
"void res(int a, int b) {",
" int v = a + b;",
" print(v);",
"}",
"");
}
public void test_statements_definesVariable_oneUsedOutside_assignment() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"myFunctionA() {",
" int a = 1;",
"// start",
" a += 10;",
"// end",
" print(a);",
"}",
"myFunctionB() {",
" int b = 2;",
" b += 10;",
" print(b);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"myFunctionA() {",
" int a = 1;",
"// start",
" a = res(a);",
"// end",
" print(a);",
"}",
"",
"int res(int a) {",
" a += 10;",
" return a;",
"}",
"myFunctionB() {",
" int b = 2;",
" b = res(b);",
" print(b);",
"}",
"");
}
public void test_statements_definesVariable_oneUsedOutside_declaration() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"myFunctionA() {",
" int a = 1;",
" int b = 2;",
"// start",
" int v1 = a + b;",
"// end",
" print(v1);",
"}",
"myFunctionB() {",
" int a = 3;",
" int b = 4;",
" int v2 = a + b;",
" print(v2);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"myFunctionA() {",
" int a = 1;",
" int b = 2;",
"// start",
" int v1 = res(a, b);",
"// end",
" print(v1);",
"}",
"",
"int res(int a, int b) {",
" int v1 = a + b;",
" return v1;",
"}",
"myFunctionB() {",
" int a = 3;",
" int b = 4;",
" int v2 = res(a, b);",
" print(v2);",
"}",
"");
}
public void test_statements_definesVariable_twoUsedOutside() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"myFunctionA() {",
"// start",
" int varA = 1;",
" int varB = 2;",
"// end",
" int v = varA + varB;",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check conditions
assertRefactoringStatus(
refactoringStatus,
RefactoringStatusSeverity.FATAL,
"Ambiguous return value: "
+ "Selected block contains more than one assignment to local variables. "
+ "Affected variables are:\\n\\nvarA\nvarB");
}
public void test_statements_duplicate_absolutelySame() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"myFunctionA() {",
" print(0);",
" print(1);",
"}",
"myFunctionB() {",
"// start",
" print(0);",
" print(1);",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"myFunctionA() {",
" res();",
"}",
"myFunctionB() {",
"// start",
" res();",
"// end",
"}",
"",
"void res() {",
" print(0);",
" print(1);",
"}",
"");
}
/**
* We match code fragments regardless of the used variable names.
*/
public void test_statements_duplicate_declaresDifferentlyNamedVariable() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"myFunctionA() {",
" int varA = 1;",
" print(varA);",
"}",
"myFunctionB() {",
"// start",
" int varB = 1;",
" print(varB);",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"myFunctionA() {",
" res();",
"}",
"myFunctionB() {",
"// start",
" res();",
"// end",
"}",
"",
"void res() {",
" int varB = 1;",
" print(varB);",
"}",
"");
}
public void test_statements_dynamic() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"dynaFunction(p) => 0;",
"main() {",
"// start",
" var a = 1;",
" var v = dynaFunction(a);",
"// end",
" print(v);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"dynaFunction(p) => 0;",
"main() {",
"// start",
" var v = res();",
"// end",
" print(v);",
"}",
"",
"res() {",
" var a = 1;",
" var v = dynaFunction(a);",
" return v;",
"}",
"");
}
/**
* We should always add ";" when invoke method with extracted statements.
*/
public void test_statements_endsWithBlock() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" if (true) {",
" print(0);",
" }",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" res();",
"// end",
"}",
"",
"void res() {",
" if (true) {",
" print(0);",
" }",
"}",
"");
}
public void test_statements_inSwitchMember() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" foo(int p) {",
" switch (p) {",
" case 0:",
"// start",
" print(0);",
"// end",
" break;",
" default:",
" break;",
" }",
" }",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" foo(int p) {",
" switch (p) {",
" case 0:",
"// start",
" res();",
"// end",
" break;",
" default:",
" break;",
" }",
" }",
"",
" void res() {",
" print(0);",
" }",
"}",
"");
}
public void test_statements_method() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" foo() {",
"// start",
" print(0);",
"// end",
" }",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" foo() {",
"// start",
" res();",
"// end",
" }",
"",
" void res() {",
" print(0);",
" }",
"}",
"");
}
public void test_statements_noDuplicates() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a = 1;",
" int b = 1;",
"// start",
" print(a);",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// check number of occurrences
assertEquals(1, refactoring.getNumberOfOccurrences());
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" int a = 1;",
" int b = 1;",
"// start",
" res(a);",
"// end",
"}",
"",
"void res(int a) {",
" print(a);",
"}",
"");
}
public void test_statements_return_last() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" int v = 5;",
" return v + 1;",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" return res();",
"// end",
"}",
"",
"int res() {",
" int v = 5;",
" return v + 1;",
"}",
"");
}
public void test_statements_return_single() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" return 42;",
"// end",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" return res();",
"// end",
"}",
"",
"int res() {",
" return 42;",
"}",
"");
}
/**
* We have 3 identical statements, but select only 2. This should not cause problems.
*/
public void test_statements_twoOfThree() throws Exception {
parseTestUnit(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" print(0);",
" print(0);",
"// end",
" print(0);",
"}",
"");
setSelectionFromStartEndComments();
createRefactoring();
// apply refactoring
assertSuccessfulRefactoring(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
"// start",
" res();",
"// end",
" print(0);",
"}",
"",
"void res() {",
" print(0);",
" print(0);",
"}",
"");
}
/**
* Checks that all conditions are <code>OK</code> and applying {@link Change} to the
* {@link #testUnit} is same source as given lines.
*/
protected final void assertSuccessfulRefactoring(String... lines) throws Exception {
assertRefactoringStatus(refactoringStatus, RefactoringStatusSeverity.OK, null);
Change change = refactoring.createChange(pm);
assertTestChangeResult(change, makeSource(lines));
}
@Override
protected void tearDown() throws Exception {
refactoring = null;
refactoringStatus = null;
super.tearDown();
}
/**
* Creates {@link ExtractMethodRefactoring} in {@link #refactoring}.
*/
private void createRefactoring() throws Exception {
int selectionLength = selectionEnd - selectionStart;
AssistContext context = new AssistContext(
searchEngine,
analysisContext,
null,
testSource,
testUnit,
selectionStart,
selectionLength);
refactoring = new ExtractMethodRefactoringImpl(context);
refactoring.setMethodName(methodName);
refactoring.setReplaceAllOccurrences(replaceAllOccurences);
// just for coverage
assertEquals(replaceAllOccurences, refactoring.getReplaceAllOccurrences());
// prepare status
refactoringStatus = refactoring.checkAllConditions(pm);
// reset some flags
if (!keepGetterFlag) {
refactoring.setExtractGetter(false);
}
}
private void setSelectionFromStartEndComments() throws Exception {
selectionStart = findEnd("// start") + EOL.length();
selectionEnd = findOffset("// end");
}
/**
* Sets selection to the start of the first occurrence of the given string.
*/
private void setSelectionString(String pattern) {
selectionStart = findOffset(pattern);
selectionEnd = findEnd(pattern);
}
}