blob: 1d5cf23204336bf201125b3a80cbdd72cf57320d [file] [log] [blame]
// Copyright (c) 2020, 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/fix/data_driven/transform_set_manager.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'bulk_fix_processor.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(ExtendsNonClassTest);
defineReflectiveTests(ExtraPositionalArgumentsCouldBeNamedTest);
defineReflectiveTests(ExtraPositionalArgumentsTest);
defineReflectiveTests(ImplementsNonClassTest);
defineReflectiveTests(MixinOfNonClassTest);
defineReflectiveTests(NotEnoughPositionalArgumentsTest);
defineReflectiveTests(OverrideOnNonOverridingMethodTest);
defineReflectiveTests(UndefinedClassTest);
defineReflectiveTests(UndefinedFunctionTest);
defineReflectiveTests(UndefinedGetterTest);
defineReflectiveTests(UndefinedIdentifierTest);
defineReflectiveTests(UndefinedMethodTest);
defineReflectiveTests(UndefinedSetterTest);
});
}
@reflectiveTest
class ExtendsNonClassTest extends _DataDrivenTest {
Future<void> test_rename() async {
setPackageContent('''
class New {}
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Rename to New'
date: 2020-09-01
element:
uris: ['$importUri']
class: 'Old'
changes:
- kind: 'rename'
newName: 'New'
''');
await resolveTestUnit('''
import '$importUri';
class A extends Old {}
class B extends Old {}
''');
await assertHasFix('''
import '$importUri';
class A extends New {}
class B extends New {}
''');
}
}
@reflectiveTest
class ExtraPositionalArgumentsCouldBeNamedTest extends _DataDrivenTest {
@failingTest
Future<void> test_replaceParameter() async {
// This fails because we grab the argument from the outer invocation before
// we modify it, but then we add the edits to modify it, which causes the
// wrong code to be put in the wrong places.
setPackageContent('''
int f(int x, {int y = 0}) => x;
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Replace parameter'
date: 2020-09-01
element:
uris: ['$importUri']
function: 'f'
changes:
- kind: 'addParameter'
index: 1
name: 'y'
style: required_named
argumentValue:
expression: '{% old %}'
variables:
old:
kind: 'argument'
index: 1
- kind: 'removeParameter'
index: 1
''');
await resolveTestUnit('''
import '$importUri';
void g() {
f(0, f(1, 2));
}
''');
await assertHasFix('''
import '$importUri';
void g() {
f(0, y: f(1, y: 2));
}
''');
}
}
@reflectiveTest
class ExtraPositionalArgumentsTest extends _DataDrivenTest {
@failingTest
Future<void> test_removeParameter() async {
// This fails because we delete the extra argument from the inner invocation
// (`, 2`) before deleting the argument from the outer invocation, which
// results in three characters too many being deleted.
setPackageContent('''
int f(int x) => x;
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Remove parameter'
date: 2020-09-01
element:
uris: ['$importUri']
function: 'f'
changes:
- kind: 'removeParameter'
index: 1
''');
await resolveTestUnit('''
import '$importUri';
void g() {
f(0, f(1, 2));
}
''');
await assertHasFix('''
import '$importUri';
void g() {
f(0);
}
''');
}
}
@reflectiveTest
class ImplementsNonClassTest extends _DataDrivenTest {
Future<void> test_rename() async {
setPackageContent('''
class New {}
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Rename to New'
date: 2020-09-01
element:
uris: ['$importUri']
class: 'Old'
changes:
- kind: 'rename'
newName: 'New'
''');
await resolveTestUnit('''
import '$importUri';
class A implements Old {}
class B implements Old {}
''');
await assertHasFix('''
import '$importUri';
class A implements New {}
class B implements New {}
''');
}
}
@reflectiveTest
class MixinOfNonClassTest extends _DataDrivenTest {
Future<void> test_rename() async {
setPackageContent('''
class New {}
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Rename to New'
date: 2020-09-01
element:
uris: ['$importUri']
class: 'Old'
changes:
- kind: 'rename'
newName: 'New'
''');
await resolveTestUnit('''
import '$importUri';
class A with Old {}
class B with Old {}
''');
await assertHasFix('''
import '$importUri';
class A with New {}
class B with New {}
''');
}
}
@reflectiveTest
class NotEnoughPositionalArgumentsTest extends _DataDrivenTest {
Future<void> test_removeParameter() async {
setPackageContent('''
int f(int x, int y) => x + y;
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Add parameter'
date: 2020-09-01
element:
uris: ['$importUri']
function: 'f'
changes:
- kind: 'addParameter'
index: 1
name: 'y'
style: required_positional
argumentValue:
expression: '0'
''');
await resolveTestUnit('''
import '$importUri';
void g() {
f(f(0));
}
''');
await assertHasFix('''
import '$importUri';
void g() {
f(f(0, 0), 0);
}
''');
}
}
@reflectiveTest
class OverrideOnNonOverridingMethodTest extends _DataDrivenTest {
Future<void> test_rename() async {
setPackageContent('''
class C {
int new(int x) => x + 1;
}
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Rename to new'
date: 2020-09-01
element:
uris: ['$importUri']
method: 'old'
inClass: 'C'
changes:
- kind: 'rename'
newName: 'new'
''');
await resolveTestUnit('''
import '$importUri';
class D extends C {
@override
int old(int x) => x + 2;
}
class E extends C {
@override
int old(int x) => x + 3;
}
''');
await assertHasFix('''
import '$importUri';
class D extends C {
@override
int new(int x) => x + 2;
}
class E extends C {
@override
int new(int x) => x + 3;
}
''');
}
}
@reflectiveTest
class UndefinedClassTest extends _DataDrivenTest {
Future<void> test_rename() async {
setPackageContent('''
class New {}
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Rename to New'
date: 2020-09-01
element:
uris: ['$importUri']
class: 'Old'
changes:
- kind: 'rename'
newName: 'New'
''');
await resolveTestUnit('''
import '$importUri';
void f(Old a, Old b) {}
''');
await assertHasFix('''
import '$importUri';
void f(New a, New b) {}
''');
}
}
@reflectiveTest
class UndefinedFunctionTest extends _DataDrivenTest {
Future<void> test_rename() async {
setPackageContent('''
int new(int x) => x + 1;
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Rename to new'
date: 2020-09-01
element:
uris: ['$importUri']
function: 'old'
changes:
- kind: 'rename'
newName: 'new'
''');
await resolveTestUnit('''
import '$importUri';
void f() {
old(old(0));
}
''');
await assertHasFix('''
import '$importUri';
void f() {
new(new(0));
}
''');
}
}
@reflectiveTest
class UndefinedGetterTest extends _DataDrivenTest {
Future<void> test_rename() async {
setPackageContent('''
class C {
int get new => 0;
}
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Rename to new'
date: 2020-09-01
element:
uris: ['$importUri']
getter: 'old'
inClass: 'C'
changes:
- kind: 'rename'
newName: 'new'
''');
await resolveTestUnit('''
import '$importUri';
void f(C a, C b) {
a.old + b.old;
}
''');
await assertHasFix('''
import '$importUri';
void f(C a, C b) {
a.new + b.new;
}
''');
}
}
@reflectiveTest
class UndefinedIdentifierTest extends _DataDrivenTest {
Future<void> test_rename_topLevelVariable() async {
setPackageContent('''
int new = 0;
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Rename to new'
date: 2020-09-01
element:
uris: ['$importUri']
function: 'old'
changes:
- kind: 'rename'
newName: 'new'
''');
await resolveTestUnit('''
import '$importUri';
void f() {
old + old;
}
''');
await assertHasFix('''
import '$importUri';
void f() {
new + new;
}
''');
}
}
@reflectiveTest
class UndefinedMethodTest extends _DataDrivenTest {
Future<void> test_rename() async {
setPackageContent('''
class C {
int new(int x) => x + 1;
}
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Rename to new'
date: 2020-09-01
element:
uris: ['$importUri']
method: 'old'
inClass: 'C'
changes:
- kind: 'rename'
newName: 'new'
''');
await resolveTestUnit('''
import '$importUri';
void f(C a, C b) {
a.old(b.old(0));
}
''');
await assertHasFix('''
import '$importUri';
void f(C a, C b) {
a.new(b.new(0));
}
''');
}
}
@reflectiveTest
class UndefinedSetterTest extends _DataDrivenTest {
Future<void> test_rename() async {
setPackageContent('''
class C {
set new(int x) {}
}
''');
addPackageDataFile('''
version: 1
transforms:
- title: 'Rename to new'
date: 2020-09-01
element:
uris: ['$importUri']
setter: 'old'
inClass: 'C'
changes:
- kind: 'rename'
newName: 'new'
''');
await resolveTestUnit('''
import '$importUri';
void f(C a, C b) {
a.old = b.old = 1;
}
''');
await assertHasFix('''
import '$importUri';
void f(C a, C b) {
a.new = b.new = 1;
}
''');
}
}
class _DataDrivenTest extends BulkFixProcessorTest {
/// Return the URI used to import the library created by [setPackageContent].
String get importUri => 'package:p/lib.dart';
/// Add the file containing the data used by the data-driven fix with the
/// given [content].
void addPackageDataFile(String content) {
addPackageFile('p', TransformSetManager.dataFileName, content);
}
/// Set the content of the library that defines the element referenced by the
/// data on which this test is based.
void setPackageContent(String content) {
addPackageFile('p', 'lib.dart', content);
}
}