blob: 675631fc03f5a23a453dd8f4e2c9a03904255774 [file] [log] [blame]
// Copyright (c) 2025, 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:test_reflective_loader/test_reflective_loader.dart';
import '../rule_test_support.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(UnnecessaryAsyncTest);
});
}
@reflectiveTest
class UnnecessaryAsyncTest extends LintRuleTest {
@override
String get lintRule => LintNames.unnecessary_async;
test_closure_imposedReturnTypeFuture_noAwait() async {
await assertNoDiagnostics(r'''
void f() {
useFunction(() async {});
}
void useFunction(Future<void> Function() x) {}
''');
}
test_closure_imposedReturnTypeVoid_hasAwait() async {
await assertNoDiagnostics(r'''
void f() {
useFunction(() async {
await 0;
});
}
void useFunction(void Function() x) {}
''');
}
test_closure_imposedReturnTypeVoid_noAwait() async {
await assertDiagnostics(
r'''
void f() {
useFunction(() async {});
}
void useFunction(void Function() x) {}
''',
[lint(28, 5)],
);
}
test_closure_noImposedReturnType_hasAwait() async {
await assertNoDiagnostics(r'''
void f() {
var v = () async {
await 0;
};
}
''');
}
test_closure_noImposedReturnType_noAwait() async {
await assertDiagnostics(
r'''
void f() {
var v = () async {};
}
''',
[lint(24, 5)],
);
}
test_localFunction_void_hasAwait() async {
await assertNoDiagnostics(r'''
void foo() {
void f() async {
await 0;
}
}
''');
}
test_localFunction_void_noAwait() async {
await assertDiagnostics(
r'''
void foo() {
void f() async {}
}
''',
[lint(24, 5)],
);
}
test_localFunction_void_noAwait_outerHasAwait() async {
await assertDiagnostics(
r'''
Future<void> foo() async {
void f() async {}
await 0;
}
''',
[lint(38, 5)],
);
}
test_method_future_returnFuture() async {
await assertDiagnostics(
r'''
class A {
Future<int> f() async {
return Future.value(0);
}
}
''',
[lint(28, 5)],
);
}
test_method_future_returnValue() async {
await assertNoDiagnostics(r'''
class A {
Future<int> f() async {
return 0;
}
}
''');
}
test_method_futureOr_returnFuture() async {
await assertDiagnostics(
r'''
import 'dart:async';
class A {
FutureOr<int> f() async {
return Future.value(0);
}
}
''',
[lint(52, 5)],
);
}
test_method_futureOr_returnValue() async {
await assertDiagnostics(
r'''
import 'dart:async';
class A {
FutureOr<int> f() async {
return 0;
}
}
''',
[lint(52, 5)],
);
}
test_method_void_hasAwaitExpression() async {
await assertNoDiagnostics(r'''
class A {
void f() async {
await 0;
}
}
''');
}
test_method_void_noAwait() async {
await assertDiagnostics(
r'''
class A {
void f() async {}
}
''',
[lint(21, 5)],
);
}
test_topLevelFunction_block_future_intNullable_returnNullable() async {
await assertNoDiagnostics(r'''
Future<int?> f(int? x) async {
return x == null ? null : Future.value(x);
}
''');
}
test_topLevelFunction_blockBody_dynamic() async {
await assertNoDiagnostics(r'''
dynamic f() async {
return 0;
}
''');
}
test_topLevelFunction_blockBody_future_int_hasReturn_futureCustom() async {
await assertDiagnostics(
r'''
Future<int> f() async {
return MyFuture.value(0);
}
class MyFuture<T> implements Future<T> {
MyFuture.value(T _);
@override
noSuchMethod(invocation) => super.noSuchMethod(invocation);
}
''',
[lint(16, 5)],
);
}
test_topLevelFunction_blockBody_future_int_returnFuture() async {
await assertDiagnostics(
r'''
Future<int> f() async {
return Future.value(0);
}
''',
[lint(16, 5)],
);
}
test_topLevelFunction_blockBody_future_int_returnValue() async {
await assertNoDiagnostics(r'''
Future<int> f() async {
return 0;
}
''');
}
test_topLevelFunction_blockBody_future_intNullable_hasReturn_null() async {
await assertNoDiagnostics(r'''
Future<int?> f() async {
return null;
}
''');
}
test_topLevelFunction_blockBody_future_void_hasReturn_future() async {
await assertDiagnostics(
r'''
Future<void> f() async {
return foo();
}
Future<void> foo() {
return Future.value();
}
''',
[lint(17, 5)],
);
}
test_topLevelFunction_blockBody_future_void_hasReturn_nothing() async {
await assertNoDiagnostics(r'''
Future<void> f() async {
return;
}
''');
}
test_topLevelFunction_blockBody_future_void_noReturn_atAll() async {
await assertNoDiagnostics(r'''
Future<void> f() async {}
''');
}
test_topLevelFunction_blockBody_future_void_noReturn_atEnd_hasReturnFuture() async {
await assertNoDiagnostics(r'''
Future<void> f() async {
if (0 == 0) {
return Future.value();
}
}
''');
}
test_topLevelFunction_blockBody_future_void_noReturn_atEnd_hasReturnNothing() async {
await assertNoDiagnostics(r'''
Future<void> f() async {
if (0 == 0) {
return;
}
}
''');
}
test_topLevelFunction_blockBody_futureNullable_int_hasReturn_future() async {
await assertDiagnostics(
r'''
Future<int>? f() async {
return Future.value(0);
}
''',
[lint(17, 5)],
);
}
test_topLevelFunction_blockBody_futureNullable_int_hasReturn_value() async {
await assertNoDiagnostics(r'''
Future<int>? f() async {
return 0;
}
''');
}
test_topLevelFunction_blockBody_futureNullable_intNullable_hasReturn_null() async {
await assertNoDiagnostics(r'''
Future<int?>? f() async {
return null;
}
''');
}
test_topLevelFunction_blockBody_futureNullable_intNullable_noReturn() async {
await assertDiagnostics(
r'''
Future<int?>? f() async {}
''',
[error(WarningCode.bodyMightCompleteNormallyNullable, 14, 1)],
);
}
test_topLevelFunction_blockBody_futureNullable_void_hasReturn_nothing() async {
await assertNoDiagnostics(r'''
Future<void>? f() async {
return;
}
''');
}
test_topLevelFunction_blockBody_futureNullable_void_noReturn_atAll() async {
await assertNoDiagnostics(r'''
Future<void>? f() async {}
''');
}
test_topLevelFunction_blockBody_futureNullable_void_noReturn_atEnd_hasReturnFuture() async {
await assertNoDiagnostics(r'''
Future<void>? f() async {
if (0 == 0) {
return Future.value();
}
}
''');
}
test_topLevelFunction_blockBody_futureNullable_void_noReturn_atEnd_hasReturnNull() async {
await assertNoDiagnostics(r'''
Future<void>? f() async {
if (0 == 0) {
return null;
}
}
''');
}
test_topLevelFunction_blockBody_futureOr_returnFuture() async {
await assertDiagnostics(
r'''
import 'dart:async';
FutureOr<int> f() async {
return Future.value(0);
}
''',
[lint(40, 5)],
);
}
test_topLevelFunction_blockBody_futureOr_returnValue() async {
await assertDiagnostics(
r'''
import 'dart:async';
FutureOr<int> f() async {
return 0;
}
''',
[lint(40, 5)],
);
}
test_topLevelFunction_blockBody_object() async {
await assertNoDiagnostics(r'''
Object f() async {
return 0;
}
''');
}
test_topLevelFunction_blockBody_void_hasAwait_expression() async {
await assertNoDiagnostics(r'''
void f() async {
await 0;
}
''');
}
test_topLevelFunction_blockBody_void_hasAwait_forElement() async {
await assertNoDiagnostics(r'''
void f(Stream<int> values) async {
[
await for (var value in values) value,
];
}
''');
}
test_topLevelFunction_blockBody_void_hasAwait_forStatement() async {
await assertNoDiagnostics(r'''
void f(Stream<int> values) async {
await for (var value in values) {}
}
''');
}
test_topLevelFunction_blockBody_void_hasAwait_nestedFunctionExpression() async {
await assertDiagnostics(
r'''
void f() async {
() async {
await 0;
}();
}
''',
[lint(9, 5)],
);
}
test_topLevelFunction_blockBody_void_noAwait() async {
await assertDiagnostics(
r'''
void f() async {}
''',
[lint(9, 5)],
);
}
test_topLevelFunction_exprBody_future_int_returnFuture() async {
await assertDiagnostics(
r'''
Future<int> f() async => Future.value(0);
''',
[lint(16, 5)],
);
}
test_topLevelFunction_exprBody_future_int_returnValue() async {
await assertNoDiagnostics(r'''
Future<int> f() async => 0;
''');
}
test_topLevelFunction_exprBody_future_intNullable_returnNullable() async {
await assertNoDiagnostics(r'''
Future<int?> f(int? x) async => x == null ? null : Future.value(x);
''');
}
test_topLevelFunction_exprBody_futureNullable_intNullable_returnNull() async {
await assertNoDiagnostics(r'''
Future<int?>? f() async => null;
''');
}
}