CQ. Migrate to assertTestCodeWithStrictCastsDiagnostics().

Change-Id: I10858511860a8c8867ddfe0d60440bb54d4385cd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/506860
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Konstantin Shcheglov
2026-05-28 07:54:46 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 1af709f3f0
commit 062a1fdcc5
18 changed files with 144 additions and 196 deletions
@@ -25,7 +25,7 @@ import 'package:analyzer_testing/experiments/experiments.dart';
import 'package:analyzer_testing/mock_packages/mock_packages.dart';
import 'package:analyzer_testing/package_config_file_builder.dart';
import 'package:analyzer_testing/resource_provider_mixin.dart';
import 'package:analyzer_testing/src/analysis_rule/pub_package_resolution.dart';
import 'package:analyzer_testing/src/expected_diagnostics.dart';
import 'package:analyzer_testing/utilities/utilities.dart';
import 'package:analyzer_utilities/testing/tree_string_sink.dart';
import 'package:linter/src/rules.dart';
@@ -460,14 +460,11 @@ mixin WithoutPrivateNamedParametersMixin on PubPackageResolutionTest {
mixin WithStrictCastsMixin on PubPackageResolutionTest {
/// Asserts that no errors are reported in [code] when implicit casts are
/// allowed, and that [expectedErrors] are reported for the same [code] when
/// implicit casts are not allowed.
Future<void> assertErrorsWithStrictCasts(
String code,
List<ExpectedError> expectedErrors,
) async {
var result = await resolveTestCode(code);
assertErrorsInTestResult(result, const []);
/// allowed, and that the inline diagnostic expectations are reported for the
/// same [code] when implicit casts are not allowed.
Future<void> assertTestCodeWithStrictCastsDiagnostics(String code) async {
var cleanCode = removeDiagnosticExpectations(code);
await resolveTestCodeWithDiagnostics(cleanCode);
await disposeAnalysisContextCollection();
@@ -475,12 +472,6 @@ mixin WithStrictCastsMixin on PubPackageResolutionTest {
analysisOptionsContent(experiments: experiments, strictCasts: true),
);
result = await resolveTestFile();
assertErrorsInTestResult(result, expectedErrors);
await resolveTestCodeWithDiagnostics(code);
}
/// Asserts that no errors are reported in [code], both when implicit casts
/// are allowed and when implicit casts are not allowed.
Future<void> assertNoErrorsWithStrictCasts(String code) async =>
assertErrorsWithStrictCasts(code, []);
}
@@ -196,6 +196,11 @@ class NodeTextExpectationsCollector {
methodName: 'resolveFileWithDiagnostics',
argument: _ArgumentIndex(1),
),
_AssertMethod(
className: 'WithStrictCastsMixin',
methodName: 'assertTestCodeWithStrictCastsDiagnostics',
argument: _ArgumentIndex(0),
),
_AssertMethod(
className: 'ResolutionTest',
methodName: 'resolveFilesWithDiagnostics',
@@ -770,37 +770,34 @@ class ArgumentTypeNotAssignableWithStrictCastsTest
extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_extensionTypePrimaryConstructor() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
extension type E(int i) {}
dynamic a;
var e = E(a);
''',
[error(diag.argumentTypeNotAssignable, 49, 1)],
);
// ^
// [diag.argumentTypeNotAssignable] The argument type 'dynamic' can't be assigned to the parameter type 'int'.
''');
}
test_functionCall() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(int i) {}
void foo(dynamic a) {
f(a);
// ^
// [diag.argumentTypeNotAssignable] The argument type 'dynamic' can't be assigned to the parameter type 'int'.
}
''',
[error(diag.argumentTypeNotAssignable, 43, 1)],
);
''');
}
test_operator() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void foo(int i, dynamic a) {
i + a;
// ^
// [diag.argumentTypeNotAssignable] The argument type 'dynamic' can't be assigned to the parameter type 'num'.
}
''',
[error(diag.argumentTypeNotAssignable, 35, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -57,26 +56,24 @@ class FieldInitializerNotAssignableWithStrictCastsTest
extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_constructorInitializer() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
class A {
int i;
A(dynamic a) : i = a;
// ^
// [diag.fieldInitializerNotAssignable] The initializer type 'dynamic' can't be assigned to the field type 'int'.
}
''',
[error(diag.fieldInitializerNotAssignable, 40, 1)],
);
''');
}
test_constructorInitializer_primaryConstructor() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
class A(dynamic a) {
int i;
this : i = a;
// ^
// [diag.fieldInitializerNotAssignable] The initializer type 'dynamic' can't be assigned to the field type 'int'.
}
''',
[error(diag.fieldInitializerNotAssignable, 43, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -161,15 +160,14 @@ f(Object e) async {
class ForInOfInvalidTypeWithStrictCastsTest extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_forIn() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
f(dynamic e) {
for (var id in e) {
// ^
// [diag.forInOfInvalidType] The type 'dynamic' used in the 'for' loop must implement 'Iterable'.
id;
}
}
''',
[error(diag.forInOfInvalidType, 32, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -1075,32 +1074,29 @@ main() {
class InvalidAssignmentWithStrictCastsTest extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_functionType() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
dynamic a;
void Function(int i) f = a;
''',
[error(diag.invalidAssignment, 36, 1)],
);
// ^
// [diag.invalidAssignment] A value of type 'dynamic' can't be assigned to a variable of type 'void Function(int)'.
''');
}
test_interfaceType() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
dynamic a;
int b = a;
''',
[error(diag.invalidAssignment, 19, 1)],
);
// ^
// [diag.invalidAssignment] A value of type 'dynamic' can't be assigned to a variable of type 'int'.
''');
}
test_recordType() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
dynamic a;
(int i, ) r = a;
''',
[error(diag.invalidAssignment, 25, 1)],
);
// ^
// [diag.invalidAssignment] A value of type 'dynamic' can't be assigned to a variable of type '(int,)'.
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -233,35 +232,32 @@ class ListElementTypeNotAssignableWithStrictCastsTest
extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_ifElement_falseBranch() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(bool c, dynamic a) {
<int>[if (c) 0 else a];
// ^
// [diag.listElementTypeNotAssignable] The element type 'dynamic' can't be assigned to the list type 'int'.
}
''',
[error(diag.listElementTypeNotAssignable, 50, 1)],
);
''');
}
test_ifElement_trueBranch() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(bool c, dynamic a) {
<int>[if (c) a];
// ^
// [diag.listElementTypeNotAssignable] The element type 'dynamic' can't be assigned to the list type 'int'.
}
''',
[error(diag.listElementTypeNotAssignable, 43, 1)],
);
''');
}
test_spread() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(Iterable<dynamic> a) {
<int>[...a];
// ^
// [diag.listElementTypeNotAssignable] The element type 'dynamic' can't be assigned to the list type 'int'.
}
''',
[error(diag.listElementTypeNotAssignable, 41, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -238,35 +237,32 @@ class MapKeyTypeNotAssignableWithStrictCastsTest
extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_ifElement_falseBranch() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(bool c, dynamic a) {
<int, int>{if (c) 0: 0 else a: 0};
// ^
// [diag.mapKeyTypeNotAssignable] The element type 'dynamic' can't be assigned to the map key type 'int'.
}
''',
[error(diag.mapKeyTypeNotAssignable, 58, 1)],
);
''');
}
test_ifElement_trueBranch() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(bool c, dynamic a) {
<int, int>{if (c) a: 0 };
// ^
// [diag.mapKeyTypeNotAssignable] The element type 'dynamic' can't be assigned to the map key type 'int'.
}
''',
[error(diag.mapKeyTypeNotAssignable, 48, 1)],
);
''');
}
test_spread() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(Map<dynamic, int> a) {
<int, int>{...a};
// ^
// [diag.mapKeyTypeNotAssignable] The element type 'dynamic' can't be assigned to the map key type 'int'.
}
''',
[error(diag.mapKeyTypeNotAssignable, 46, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -232,35 +231,32 @@ class MapValueTypeNotAssignableWithStrictCastsTest
extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_ifElement_falseBranch() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(bool c, dynamic a) {
<int, int>{if (c) 0: 0 else 0: a};
// ^
// [diag.mapValueTypeNotAssignable] The element type 'dynamic' can't be assigned to the map value type 'int'.
}
''',
[error(diag.mapValueTypeNotAssignable, 61, 1)],
);
''');
}
test_ifElement_trueBranch() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(bool c, dynamic a) {
<int, int>{if (c) 0: a};
// ^
// [diag.mapValueTypeNotAssignable] The element type 'dynamic' can't be assigned to the map value type 'int'.
}
''',
[error(diag.mapValueTypeNotAssignable, 51, 1)],
);
''');
}
test_spread() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(Map<int, dynamic> a) {
<int, int>{...a};
// ^
// [diag.mapValueTypeNotAssignable] The element type 'dynamic' can't be assigned to the map value type 'int'.
}
''',
[error(diag.mapValueTypeNotAssignable, 46, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -292,24 +291,22 @@ f(Object o) {
class NonBoolConditionWithStrictCastsTest extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_map_ifElement_condition() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(dynamic c) {
<int, int>{if (c) 0: 0};
// ^
// [diag.nonBoolCondition] Conditions must have a static type of 'bool'.
}
''',
[error(diag.nonBoolCondition, 37, 1)],
);
''');
}
test_set_ifElement_condition() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(dynamic c) {
<int>{if (c) 0};
// ^
// [diag.nonBoolCondition] Conditions must have a static type of 'bool'.
}
''',
[error(diag.nonBoolCondition, 32, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -55,13 +54,12 @@ f() {
class NonBoolExpressionWithStrictCastsTest extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_assert() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(dynamic a) {
assert(a);
// ^
// [diag.nonBoolExpression] The expression in an assert must be of type 'bool'.
}
''',
[error(diag.nonBoolExpression, 29, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -64,13 +63,12 @@ class NonBoolNegationExpressionWithStrictCastsTest
extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_negation() async {
await assertErrorsWithStrictCasts(
r'''
await assertTestCodeWithStrictCastsDiagnostics(r'''
void f(dynamic a) {
!a;
// ^
// [diag.nonBoolNegationExpression] A negation operand must have a static type of 'bool'.
}
''',
[error(diag.nonBoolNegationExpression, 23, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -115,13 +114,12 @@ bool f(bool left, double right) {
class NonBoolOperandWithStrictCastsTest extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_and() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(dynamic a) {
if(a && true) {}
// ^
// [diag.nonBoolOperand] The operands of the operator '&&' must be assignable to 'bool'.
}
''',
[error(diag.nonBoolOperand, 25, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -121,24 +120,22 @@ List<int> f() => [...{1: 2, 3: 4}];
class NotIterableSpreadWithStrictCastsTest extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_list() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(dynamic a) {
[...a];
// ^
// [diag.notIterableSpread] Spread elements in list or set literals must implement 'Iterable'.
}
''',
[error(diag.notIterableSpread, 26, 1)],
);
''');
}
test_set() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(dynamic a) {
<int>{...a};
// ^
// [diag.notIterableSpread] Spread elements in list or set literals must implement 'Iterable'.
}
''',
[error(diag.notIterableSpread, 31, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -103,13 +102,12 @@ void f<T extends num>(T a) {
class NotMapSpreadWithStrictCastsTest extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_map() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(dynamic a) {
<int, String>{...a};
// ^
// [diag.notMapSpread] Spread elements in map literals must implement 'Map'.
}
''',
[error(diag.notMapSpread, 39, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -556,22 +555,20 @@ Map<int, int> f() => {...[1, 2, 3, 4]};
class ReturnOfInvalidTypeWithStrictCastsTest extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_return() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
int f(dynamic a) => a;
''',
[error(diag.returnOfInvalidTypeFromFunction, 20, 1)],
);
// ^
// [diag.returnOfInvalidTypeFromFunction] A value of type 'dynamic' can't be returned from the function 'f' because it has a return type of 'int'.
''');
}
test_return_async() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
Future<int> f(dynamic a) async {
return a;
// ^
// [diag.returnOfInvalidTypeFromFunction] A value of type 'dynamic' can't be returned from the function 'f' because it has a return type of 'Future<int>'.
}
''',
[error(diag.returnOfInvalidTypeFromFunction, 42, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -198,35 +197,32 @@ class SetElementTypeNotAssignableWithStrictCastsTest
extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_ifElement_falseBranch() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(bool c, dynamic a) {
<int>{if (c) 0 else a};
// ^
// [diag.setElementTypeNotAssignable] The element type 'dynamic' can't be assigned to the set type 'int'.
}
''',
[error(diag.setElementTypeNotAssignable, 50, 1)],
);
''');
}
test_ifElement_trueBranch() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(bool c, dynamic a) {
<int>{if (c) a};
// ^
// [diag.setElementTypeNotAssignable] The element type 'dynamic' can't be assigned to the set type 'int'.
}
''',
[error(diag.setElementTypeNotAssignable, 43, 1)],
);
''');
}
test_spread() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
void f(Iterable<dynamic> a) {
<int>{...a};
// ^
// [diag.setElementTypeNotAssignable] The element type 'dynamic' can't be assigned to the set type 'int'.
}
''',
[error(diag.setElementTypeNotAssignable, 41, 1)],
);
''');
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -465,24 +464,22 @@ Iterable<String> g() => throw 0;
class YieldOfInvalidTypeWithStrictCastsTest extends PubPackageResolutionTest
with WithStrictCastsMixin {
test_yieldEach_asyncStar() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
f(dynamic a) async* {
yield* a;
// ^
// [diag.yieldEachOfInvalidType] The type 'dynamic' implied by the 'yield*' expression must be assignable to 'Stream<dynamic>'.
}
''',
[error(diag.yieldEachOfInvalidType, 31, 1)],
);
''');
}
test_yieldEach_syncStar() async {
await assertErrorsWithStrictCasts(
'''
await assertTestCodeWithStrictCastsDiagnostics('''
f(dynamic a) sync* {
yield* a;
// ^
// [diag.yieldEachOfInvalidType] The type 'dynamic' implied by the 'yield*' expression must be assignable to 'Iterable<dynamic>'.
}
''',
[error(diag.yieldEachOfInvalidType, 30, 1)],
);
''');
}
}