blob: 042fdcc3272c9cf6093016637710765c4a5b2144 [file] [log] [blame]
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'abstract_rename.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(RenameLocalTest);
});
}
@reflectiveTest
class RenameLocalTest extends RenameRefactoringTest {
test_checkFinalConditions_hasLocalFunction_after() async {
await indexTestUnit('''
main() {
int test = 0;
newName() => 1;
}
''');
createRenameRefactoringAtString('test = 0');
// check status
refactoring.newName = 'newName';
RefactoringStatus status = await refactoring.checkFinalConditions();
assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
expectedMessage: "Duplicate function 'newName'.",
expectedContextSearch: 'newName() => 1');
}
test_checkFinalConditions_hasLocalFunction_before() async {
await indexTestUnit('''
main() {
newName() => 1;
int test = 0;
}
''');
createRenameRefactoringAtString('test = 0');
// check status
refactoring.newName = 'newName';
RefactoringStatus status = await refactoring.checkFinalConditions();
assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
expectedMessage: "Duplicate function 'newName'.");
}
test_checkFinalConditions_hasLocalVariable_after() async {
await indexTestUnit('''
main() {
int test = 0;
var newName = 1;
print(newName);
}
''');
createRenameRefactoringAtString('test = 0');
// check status
refactoring.newName = 'newName';
RefactoringStatus status = await refactoring.checkFinalConditions();
expect(status.problems, hasLength(1));
assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
expectedMessage: "Duplicate local variable 'newName'.",
expectedContextSearch: 'newName = 1;');
}
test_checkFinalConditions_hasLocalVariable_before() async {
await indexTestUnit('''
main() {
var newName = 1;
int test = 0;
}
''');
createRenameRefactoringAtString('test = 0');
// check status
refactoring.newName = 'newName';
RefactoringStatus status = await refactoring.checkFinalConditions();
assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
expectedMessage: "Duplicate local variable 'newName'.",
expectedContextSearch: 'newName = 1;');
}
test_checkFinalConditions_hasLocalVariable_otherBlock() async {
await indexTestUnit('''
main() {
{
var newName = 1;
}
{
int test = 0;
}
}
''');
createRenameRefactoringAtString('test = 0');
// check status
refactoring.newName = 'newName';
return assertRefactoringConditionsOK();
}
test_checkFinalConditions_hasLocalVariable_otherForEachLoop() async {
await indexTestUnit('''
main() {
for (int newName in []) {}
for (int test in []) {}
}
''');
createRenameRefactoringAtString('test in');
// check status
refactoring.newName = 'newName';
return assertRefactoringConditionsOK();
}
test_checkFinalConditions_hasLocalVariable_otherForLoop() async {
await indexTestUnit('''
main() {
for (int newName = 0; newName < 10; newName++) {}
for (int test = 0; test < 10; test++) {}
}
''');
createRenameRefactoringAtString('test = 0');
// check status
refactoring.newName = 'newName';
return assertRefactoringConditionsOK();
}
test_checkFinalConditions_hasLocalVariable_otherFunction() async {
await indexTestUnit('''
main() {
int test = 0;
}
main2() {
var newName = 1;
}
''');
createRenameRefactoringAtString('test = 0');
// check status
refactoring.newName = 'newName';
return assertRefactoringConditionsOK();
}
test_checkFinalConditions_shadows_classMember() async {
await indexTestUnit('''
class A {
var newName = 1;
main() {
var test = 0;
print(newName);
}
}
''');
createRenameRefactoringAtString('test = 0');
// check status
refactoring.newName = 'newName';
RefactoringStatus status = await refactoring.checkFinalConditions();
assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
expectedMessage: 'Usage of field "A.newName" declared in "test.dart" '
'will be shadowed by renamed local variable.',
expectedContextSearch: 'newName);');
}
test_checkFinalConditions_shadows_classMember_namedParameter() async {
await indexTestUnit('''
class A {
foo({test: 1}) { // in A
}
}
class B extends A {
var newName = 1;
foo({test: 1}) {
print(newName);
}
}
''');
createRenameRefactoringAtString('test: 1}) { // in A');
// check status
refactoring.newName = 'newName';
RefactoringStatus status = await refactoring.checkFinalConditions();
assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
expectedMessage: 'Usage of field "B.newName" declared in "test.dart" '
'will be shadowed by renamed parameter.',
expectedContextSearch: 'newName);');
}
test_checkFinalConditions_shadows_classMemberOK_qualifiedReference() async {
await indexTestUnit('''
class A {
var newName = 1;
main() {
var test = 0;
print(this.newName);
}
}
''');
createRenameRefactoringAtString('test = 0');
// check status
refactoring.newName = 'newName';
return assertRefactoringConditionsOK();
}
test_checkFinalConditions_shadows_OK_namedParameterReference() async {
await indexTestUnit('''
void f({newName}) {}
main() {
var test = 0;
f(newName: test);
}
''');
createRenameRefactoringAtString('test = 0');
// check status
refactoring.newName = 'newName';
return assertRefactoringFinalConditionsOK();
}
test_checkFinalConditions_shadows_topLevelFunction() async {
await indexTestUnit('''
newName() {}
main() {
var test = 0;
newName(); // ref
}
''');
createRenameRefactoringAtString('test = 0');
// check status
refactoring.newName = 'newName';
RefactoringStatus status = await refactoring.checkFinalConditions();
assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
expectedContextSearch: 'newName(); // ref');
}
test_checkNewName_FunctionElement() async {
await indexTestUnit('''
main() {
int test() => 0;
}
''');
createRenameRefactoringAtString('test() => 0;');
// null
refactoring.newName = null;
assertRefactoringStatus(
refactoring.checkNewName(), RefactoringProblemSeverity.FATAL,
expectedMessage: "Function name must not be null.");
// OK
refactoring.newName = 'newName';
assertRefactoringStatusOK(refactoring.checkNewName());
}
test_checkNewName_LocalVariableElement() async {
await indexTestUnit('''
main() {
int test = 0;
}
''');
createRenameRefactoringAtString('test = 0;');
// null
refactoring.newName = null;
assertRefactoringStatus(
refactoring.checkNewName(), RefactoringProblemSeverity.FATAL,
expectedMessage: "Variable name must not be null.");
// empty
refactoring.newName = '';
assertRefactoringStatus(
refactoring.checkNewName(), RefactoringProblemSeverity.FATAL,
expectedMessage: "Variable name must not be empty.");
// OK
refactoring.newName = 'newName';
assertRefactoringStatusOK(refactoring.checkNewName());
}
test_checkNewName_ParameterElement() async {
await indexTestUnit('''
main(test) {
}
''');
createRenameRefactoringAtString('test) {');
// null
refactoring.newName = null;
assertRefactoringStatus(
refactoring.checkNewName(), RefactoringProblemSeverity.FATAL,
expectedMessage: "Parameter name must not be null.");
// OK
refactoring.newName = 'newName';
assertRefactoringStatusOK(refactoring.checkNewName());
}
test_createChange_localFunction() async {
await indexTestUnit('''
main() {
int test() => 0;
print(test);
print(test());
}
''');
// configure refactoring
createRenameRefactoringAtString('test() => 0');
expect(refactoring.refactoringName, 'Rename Local Function');
expect(refactoring.elementKindName, 'function');
refactoring.newName = 'newName';
// validate change
return assertSuccessfulRefactoring('''
main() {
int newName() => 0;
print(newName);
print(newName());
}
''');
}
test_createChange_localFunction_sameNameDifferenceScopes() async {
await indexTestUnit('''
main() {
{
int test() => 0;
print(test);
}
{
int test() => 1;
print(test);
}
{
int test() => 2;
print(test);
}
}
''');
// configure refactoring
createRenameRefactoringAtString('test() => 1');
expect(refactoring.refactoringName, 'Rename Local Function');
refactoring.newName = 'newName';
// validate change
return assertSuccessfulRefactoring('''
main() {
{
int test() => 0;
print(test);
}
{
int newName() => 1;
print(newName);
}
{
int test() => 2;
print(test);
}
}
''');
}
test_createChange_localVariable() async {
await indexTestUnit('''
main() {
int test = 0;
test = 1;
test += 2;
print(test);
}
''');
// configure refactoring
createRenameRefactoringAtString('test = 0');
expect(refactoring.refactoringName, 'Rename Local Variable');
expect(refactoring.elementKindName, 'local variable');
refactoring.newName = 'newName';
// validate change
return assertSuccessfulRefactoring('''
main() {
int newName = 0;
newName = 1;
newName += 2;
print(newName);
}
''');
}
test_createChange_localVariable_sameNameDifferenceScopes() async {
await indexTestUnit('''
main() {
{
int test = 0;
print(test);
}
{
int test = 1;
print(test);
}
{
int test = 2;
print(test);
}
}
''');
// configure refactoring
createRenameRefactoringAtString('test = 1');
expect(refactoring.refactoringName, 'Rename Local Variable');
refactoring.newName = 'newName';
// validate change
return assertSuccessfulRefactoring('''
main() {
{
int test = 0;
print(test);
}
{
int newName = 1;
print(newName);
}
{
int test = 2;
print(test);
}
}
''');
}
test_createChange_parameter_named() async {
await indexTestUnit('''
myFunction({int test}) {
test = 1;
test += 2;
print(test);
}
main() {
myFunction(test: 2);
}
''');
// configure refactoring
createRenameRefactoringAtString('test}) {');
expect(refactoring.refactoringName, 'Rename Parameter');
expect(refactoring.elementKindName, 'parameter');
refactoring.newName = 'newName';
// validate change
return assertSuccessfulRefactoring('''
myFunction({int newName}) {
newName = 1;
newName += 2;
print(newName);
}
main() {
myFunction(newName: 2);
}
''');
}
test_createChange_parameter_named_inOtherFile() async {
var a = convertPath('/home/test/lib/a.dart');
var b = convertPath('/home/test/lib/b.dart');
newFile(a, content: r'''
class A {
A({test});
}
''');
newFile(b, content: r'''
import 'a.dart';
main() {
new A(test: 2);
}
''');
driver.addFile(a);
driver.addFile(b);
var session = driver.currentSession;
testAnalysisResult = await session.getResolvedUnit(a);
testFile = testAnalysisResult.path;
testCode = testAnalysisResult.content;
testUnit = testAnalysisResult.unit;
createRenameRefactoringAtString('test});');
expect(refactoring.refactoringName, 'Rename Parameter');
refactoring.newName = 'newName';
await assertSuccessfulRefactoring('''
class A {
A({newName});
}
''');
assertFileChangeResult(b, '''
import 'a.dart';
main() {
new A(newName: 2);
}
''');
}
test_createChange_parameter_named_updateHierarchy() async {
await indexUnit('/home/test/lib/test2.dart', '''
library test2;
class A {
void foo({int test: 1}) {
print(test);
}
}
class B extends A {
void foo({int test: 2}) {
print(test);
}
}
''');
await indexTestUnit('''
import 'test2.dart';
main() {
new A().foo(test: 10);
new B().foo(test: 20);
new C().foo(test: 30);
}
class C extends A {
void foo({int test: 3}) {
print(test);
}
}
''');
// configure refactoring
createRenameRefactoringAtString('test: 20');
expect(refactoring.refactoringName, 'Rename Parameter');
refactoring.newName = 'newName';
// validate change
await assertSuccessfulRefactoring('''
import 'test2.dart';
main() {
new A().foo(newName: 10);
new B().foo(newName: 20);
new C().foo(newName: 30);
}
class C extends A {
void foo({int newName: 3}) {
print(newName);
}
}
''');
assertFileChangeResult('/home/test/lib/test2.dart', '''
library test2;
class A {
void foo({int newName: 1}) {
print(newName);
}
}
class B extends A {
void foo({int newName: 2}) {
print(newName);
}
}
''');
}
test_createChange_parameter_optionalPositional() async {
await indexTestUnit('''
myFunction([int test]) {
test = 1;
test += 2;
print(test);
}
main() {
myFunction(2);
}
''');
// configure refactoring
createRenameRefactoringAtString('test]) {');
expect(refactoring.refactoringName, 'Rename Parameter');
expect(refactoring.elementKindName, 'parameter');
refactoring.newName = 'newName';
// validate change
return assertSuccessfulRefactoring('''
myFunction([int newName]) {
newName = 1;
newName += 2;
print(newName);
}
main() {
myFunction(2);
}
''');
}
test_oldName() async {
await indexTestUnit('''
main() {
int test = 0;
}
''');
// configure refactoring
createRenameRefactoringAtString('test = 0');
// old name
expect(refactoring.oldName, 'test');
}
}