mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:07:06 +00:00
Migration: make API tests fail if there's an unexpected error.
I've recently wasted a lot of time tracking down strange behaviors that resulted from inadvertenly writing a migration API test containing a static error. Failing the test early if there's an error should avoid that problem in the future. Change-Id: Idc9d84901a517ce9555fa3180f5c669aea449ea5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/204180 Reviewed-by: Samuel Rawlins <srawlins@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
parent
2f9f746d83
commit
62f72311ae
|
@ -507,7 +507,9 @@ abstract class num implements Comparable<num> {
|
|||
int toInt();
|
||||
}
|
||||
|
||||
abstract class Match {}
|
||||
abstract class Match {
|
||||
int get start;
|
||||
}
|
||||
|
||||
class Object {
|
||||
const Object();
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analyzer/dart/analysis/results.dart';
|
||||
import 'package:analyzer/diagnostic/diagnostic.dart';
|
||||
import 'package:analyzer/error/error.dart';
|
||||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||
import 'package:nnbd_migration/nnbd_migration.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
@ -50,7 +52,8 @@ abstract class _ProvisionalApiTestBase extends AbstractContextTest {
|
|||
Map<String, String> input, Map<String, String> expectedOutput,
|
||||
{Map<String, String> migratedInput = const {},
|
||||
bool removeViaComments = false,
|
||||
bool warnOnWeakCode = false}) async {
|
||||
bool warnOnWeakCode = false,
|
||||
bool allowErrors = false}) async {
|
||||
for (var path in migratedInput.keys) {
|
||||
newFile(path, content: migratedInput[path]);
|
||||
}
|
||||
|
@ -66,6 +69,11 @@ abstract class _ProvisionalApiTestBase extends AbstractContextTest {
|
|||
var resolvedLibrary = await session.getResolvedLibrary2(path);
|
||||
if (resolvedLibrary is ResolvedLibraryResult) {
|
||||
for (var unit in resolvedLibrary.units) {
|
||||
var errors =
|
||||
unit.errors.where((e) => e.severity == Severity.error).toList();
|
||||
if (!allowErrors && errors.isNotEmpty) {
|
||||
fail('Unexpected error(s): $errors');
|
||||
}
|
||||
migration.prepareInput(unit);
|
||||
}
|
||||
}
|
||||
|
@ -112,13 +120,15 @@ abstract class _ProvisionalApiTestBase extends AbstractContextTest {
|
|||
Future<void> _checkSingleFileChanges(String content, String expected,
|
||||
{Map<String, String> migratedInput = const {},
|
||||
bool removeViaComments = false,
|
||||
bool warnOnWeakCode = false}) async {
|
||||
bool warnOnWeakCode = false,
|
||||
bool allowErrors = false}) async {
|
||||
var sourcePath = convertPath('$testsPath/lib/test.dart');
|
||||
await _checkMultipleFileChanges(
|
||||
{sourcePath: content}, {sourcePath: expected},
|
||||
migratedInput: migratedInput,
|
||||
removeViaComments: removeViaComments,
|
||||
warnOnWeakCode: warnOnWeakCode);
|
||||
warnOnWeakCode: warnOnWeakCode,
|
||||
allowErrors: allowErrors);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -516,6 +526,7 @@ class B<E> implements List<E/*?*/> {
|
|||
final C c;
|
||||
B(this.c);
|
||||
B<T> cast<T>() => c._castFrom<E, T>(this);
|
||||
noSuchMethod(invocation) => super.noSuchMethod(invocation);
|
||||
}
|
||||
abstract class C {
|
||||
B<T> _castFrom<S, T>(B<S> source);
|
||||
|
@ -526,6 +537,7 @@ class B<E> implements List<E?> {
|
|||
final C c;
|
||||
B(this.c);
|
||||
B<T> cast<T>() => c._castFrom<E, T>(this);
|
||||
noSuchMethod(invocation) => super.noSuchMethod(invocation);
|
||||
}
|
||||
abstract class C {
|
||||
B<T> _castFrom<S, T>(B<S> source);
|
||||
|
@ -609,7 +621,9 @@ main() {
|
|||
f(null, null);
|
||||
}
|
||||
''';
|
||||
await _checkSingleFileChanges(content, expected);
|
||||
// Note: using allowErrors=true because variables introduced by a catch
|
||||
// clause are final
|
||||
await _checkSingleFileChanges(content, expected, allowErrors: true);
|
||||
}
|
||||
|
||||
Future<void> test_catch_with_on() async {
|
||||
|
@ -649,7 +663,9 @@ main() {
|
|||
f(null, null);
|
||||
}
|
||||
''';
|
||||
await _checkSingleFileChanges(content, expected);
|
||||
// Note: using allowErrors=true because variables introduced by a catch
|
||||
// clause are final
|
||||
await _checkSingleFileChanges(content, expected, allowErrors: true);
|
||||
}
|
||||
|
||||
Future<void> test_class_alias_synthetic_constructor_with_parameters() async {
|
||||
|
@ -1947,7 +1963,9 @@ test() {
|
|||
x[0] = 1 as Null;
|
||||
}
|
||||
''';
|
||||
await _checkSingleFileChanges(content, expected);
|
||||
// Note: using allowErrors=true because casting a literal int to a Null is
|
||||
// an error
|
||||
await _checkSingleFileChanges(content, expected, allowErrors: true);
|
||||
}
|
||||
|
||||
Future<void> test_downcast_type_argument_preserve_nullability() async {
|
||||
|
@ -2112,7 +2130,7 @@ List<int> _f(List<int> xs) => [];
|
|||
var content = '''
|
||||
enum E {
|
||||
value
|
||||
};
|
||||
}
|
||||
|
||||
E f() => E.value;
|
||||
int g() => f().index;
|
||||
|
@ -2131,7 +2149,7 @@ void h() {
|
|||
var expected = '''
|
||||
enum E {
|
||||
value
|
||||
};
|
||||
}
|
||||
|
||||
E f() => E.value;
|
||||
int g() => f().index;
|
||||
|
@ -2979,7 +2997,8 @@ class C {
|
|||
}
|
||||
g(String s) {}
|
||||
''';
|
||||
await _checkSingleFileChanges(content, expected);
|
||||
// Note: using allowErrors=true because an uninitialized field is an error
|
||||
await _checkSingleFileChanges(content, expected, allowErrors: true);
|
||||
}
|
||||
|
||||
Future<void> test_field_formal_param_typed() async {
|
||||
|
@ -3159,9 +3178,9 @@ class C {
|
|||
class C {
|
||||
int i;
|
||||
C() : i = 0;
|
||||
factory C.factoryConstructor => C();
|
||||
factory C.factoryRedirect = D;
|
||||
C.redirect : this();
|
||||
factory C.factoryConstructor() => C();
|
||||
factory C.factoryRedirect() = D;
|
||||
C.redirect() : this();
|
||||
}
|
||||
class D extends C {}
|
||||
''';
|
||||
|
@ -3169,9 +3188,9 @@ class D extends C {}
|
|||
class C {
|
||||
int i;
|
||||
C() : i = 0;
|
||||
factory C.factoryConstructor => C();
|
||||
factory C.factoryRedirect = D;
|
||||
C.redirect : this();
|
||||
factory C.factoryConstructor() => C();
|
||||
factory C.factoryRedirect() = D;
|
||||
C.redirect() : this();
|
||||
}
|
||||
class D extends C {}
|
||||
''';
|
||||
|
@ -3666,7 +3685,7 @@ int? test(C c) {
|
|||
void test({String foo}) async {
|
||||
var f = () {
|
||||
return "hello";
|
||||
}
|
||||
};
|
||||
|
||||
foo.length;
|
||||
}
|
||||
|
@ -3675,7 +3694,7 @@ void test({String foo}) async {
|
|||
void test({required String foo}) async {
|
||||
var f = () {
|
||||
return "hello";
|
||||
}
|
||||
};
|
||||
|
||||
foo.length;
|
||||
}
|
||||
|
@ -6969,7 +6988,7 @@ class C<R> {
|
|||
}
|
||||
|
||||
void main() {
|
||||
C<int/*!*/>().m(null!);
|
||||
C<int/*!*/>().m(null/*!*/);
|
||||
}
|
||||
''';
|
||||
var expected = '''
|
||||
|
@ -7312,10 +7331,10 @@ void main() {
|
|||
setUp(() {
|
||||
i = 1;
|
||||
});
|
||||
f(int /*?*/ i) {}
|
||||
test('a', () {
|
||||
f(i);
|
||||
});
|
||||
f(int /*?*/ i) {}
|
||||
}
|
||||
''';
|
||||
var expected = '''
|
||||
|
@ -7325,10 +7344,10 @@ void main() {
|
|||
setUp(() {
|
||||
i = 1;
|
||||
});
|
||||
f(int? i) {}
|
||||
test('a', () {
|
||||
f(i);
|
||||
});
|
||||
f(int? i) {}
|
||||
}
|
||||
''';
|
||||
await _checkSingleFileChanges(content, expected);
|
||||
|
@ -7464,10 +7483,10 @@ int? g() => f();
|
|||
// The inference of C<int?> forces class C to be declared as
|
||||
// C<T extends Object?>.
|
||||
var content = '''
|
||||
class C<T extends Object> {
|
||||
abstract class C<T extends Object> {
|
||||
void m(T t);
|
||||
}
|
||||
class D<T extends Object> {
|
||||
abstract class D<T extends Object> {
|
||||
void m(T t);
|
||||
}
|
||||
f(C<int> c, D<int> d) {
|
||||
|
@ -7475,10 +7494,10 @@ f(C<int> c, D<int> d) {
|
|||
}
|
||||
''';
|
||||
var expected = '''
|
||||
class C<T extends Object?> {
|
||||
abstract class C<T extends Object?> {
|
||||
void m(T t);
|
||||
}
|
||||
class D<T extends Object> {
|
||||
abstract class D<T extends Object> {
|
||||
void m(T t);
|
||||
}
|
||||
f(C<int?> c, D<int> d) {
|
||||
|
|
Loading…
Reference in a new issue