blob: 81f4673862bf1b3bdb573f944608dcee4b44bde3 [file] [log] [blame]
// Copyright (c) 2021, 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';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(UnnecessaryNullChecksTest);
});
}
@reflectiveTest
class UnnecessaryNullChecksTest extends LintRuleTest {
@override
String get lintRule => 'unnecessary_null_checks';
test_assignment_await_nullableTarget() async {
await assertDiagnostics(r'''
Future<void> f(int? p, int? i, Future<int?> future) async {
i = await future!;
}
''', [
error(StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION, 78, 1),
lint(78, 1),
]);
}
test_assignment_nullable() async {
await assertDiagnostics(r'''
void f(int? v, int? i) {
v = i!;
}
''', [
lint(32, 1),
]);
}
test_assignment_nullable_self() async {
await assertNoDiagnostics(r'''
void f(int? v) {
int? v;
v = v!;
}
''');
}
test_assignment_nullableTarget() async {
await assertDiagnostics(r'''
int? j = i!;
int? i;
''', [
lint(10, 1),
]);
}
test_assignment_nullableTarget_parenthesized() async {
await assertDiagnostics(r'''
int? j2 = (i!);
int? i;
''', [
lint(12, 1),
]);
}
test_binaryOperator_argument() async {
await assertDiagnostics(r'''
class A {
operator +(int? p) => A() + p!;
}
''', [
lint(41, 1),
]);
}
test_completerComplete() async {
await assertNoDiagnostics(r'''
import 'dart:async';
void f(int? i) => Completer<int>().complete(i!);
''');
}
test_compoundAssignment_promotedToNonNullable() async {
await assertNoDiagnostics(r'''
void f(int? v, int? p) {
v ??= 1;
v += p!;
}
''');
}
test_constructorCall_optionalPositionalArgument() async {
await assertDiagnostics(r'''
class A {
A([int? p]);
}
void f(int? i) => A(i!);
''', [
lint(48, 1),
]);
}
test_functionCall_namedArgument() async {
await assertDiagnostics(r'''
void f({int? p, int? i}) => f(p: i!);
''', [
lint(34, 1),
]);
}
test_functionCall_positionalArgument() async {
await assertDiagnostics(r'''
int? i;
void f(int? p) => f(i!);
''', [
lint(29, 1),
]);
}
test_functionCall_positionalArgument_parenthesized() async {
await assertDiagnostics(r'''
int? i;
void f(int? p) => f((i!));
''', [
lint(30, 1),
]);
}
test_futureValue() async {
await assertNoDiagnostics(r'''
void f(int? i) => Future<int>.value(i!);
''');
}
test_listPattern() async {
await assertDiagnostics(r'''
void f(int? a, int? b) {
[b!, ] = [a, ];
}
''', [
lint(29, 1),
]);
}
test_nullableAssignment_nullable() async {
await assertNoDiagnostics(r'''
void f(int? v, int? p) {
v ??= p!;
}
''');
}
test_recordPattern() async {
await assertDiagnostics(r'''
void f(int? a, int? b) {
(b!, ) = (a, );
}
''', [
lint(29, 1),
]);
}
test_return_function_dynamic() async {
// TODO(srawlins): Why does a dynamic-returning function result in a
// diagnostic, but a dynamic-returning method does not?
await assertDiagnostics(r'''
dynamic f(int? p) {
return p!;
}
''', [
lint(30, 1),
]);
}
test_return_list_nonNullable() async {
await assertNoDiagnostics(r'''
List<int> f7ok(int? p) => [p!];
''');
}
test_return_list_nullable() async {
await assertDiagnostics(r'''
List<int?> f7(int? p) => [p!];
''', [
lint(27, 1),
]);
}
test_return_mapKey_nonNullable() async {
await assertNoDiagnostics(r'''
Map<int, String> f(int? p) => {p!: ''};
''');
}
test_return_mapKey_nullable() async {
await assertDiagnostics(r'''
Map<int?, String> f(int? p) => {p!: ''};
''', [
lint(33, 1),
]);
}
test_return_mapValue_forElement_nonNullable() async {
await assertNoDiagnostics(r'''
Map<String, int> f(int? p) => {for (var a in <int>[]) '': p!};
''');
}
test_return_mapValue_forElement_nullable() async {
await assertDiagnostics(r'''
Map<String, int?> f(int? p) => {for (var a in <int>[]) '': p!};
''', [
lint(60, 1),
]);
}
test_return_mapValue_ifElement_nonNullable() async {
await assertNoDiagnostics(r'''
Map<String, int> f(int? p) => {if (1 != 0) '': p!}; // OK
''');
}
test_return_mapValue_ifElement_nullable() async {
await assertDiagnostics(r'''
Map<String, int?> f(int? p) => {if (1 != 0) '': p!};
''', [
lint(49, 1),
]);
}
test_return_mapValue_ifElementNested_nullable() async {
await assertDiagnostics(r'''
Map<String, int?> f(int? p) => {if (1 != 0) if (1 != 0) '': p!};
''', [
lint(61, 1),
]);
}
test_return_mapValue_nonNullable() async {
await assertNoDiagnostics(r'''
Map<String, int> f(int? p) => {'': p!};
''');
}
test_return_mapValue_nullable() async {
await assertDiagnostics(r'''
Map<String, int?> f(int? p) => {'': p!};
''', [
lint(37, 1),
]);
}
test_return_method_dynamic() async {
await assertNoDiagnostics(r'''
class A {
dynamic f(int? p) {
return p!;
}
}
''');
}
test_return_nullable() async {
await assertDiagnostics(r'''
int? f(int? i) { return i!; }
''', [
lint(25, 1),
]);
}
test_return_set_nonNullable() async {
await assertNoDiagnostics(r'''
Set<int> f(int? p) => {p!};
''');
}
test_return_set_nullable() async {
await assertDiagnostics(r'''
Set<int?> f(int? p) => {p!};
''', [
lint(25, 1),
]);
}
test_returnAsync_dynamic() async {
await assertNoDiagnostics(r'''
dynamic f(int? p) async => p!;
''');
}
test_returnAsync_futureOfNonNullable() async {
await assertNoDiagnostics(r'''
Future<int> f15ok(int? p) async => p!;
''');
}
test_returnAsync_futureOfNonNullable_await() async {
await assertNoDiagnostics(r'''
Future<int> f(int? p) async => await p!;
''');
}
test_returnAsync_futureOfNonNullable_typedef() async {
await assertNoDiagnostics(r'''
typedef F = Future<int>;
F f(int? p) async => p!;
''');
}
test_returnAsync_futureOfNullable() async {
await assertDiagnostics(r'''
Future<int?> f(int? p) async => p!;
''', [
lint(33, 1),
]);
}
test_returnAsync_futureOfNullable_await() async {
await assertDiagnostics(r'''
Future<int?> f(int? p) async => await p!;
''', [
lint(39, 1),
]);
}
test_returnAsync_futureOfNullable_typedef() async {
await assertDiagnostics(r'''
typedef F = Future<int?>;
F f(int? p) async => p!;
''', [
lint(48, 1),
]);
}
test_returnExpressionBody_nullable() async {
await assertDiagnostics(r'''
int? f(int? i) => i!;
''', [
lint(19, 1),
]);
}
test_undefinedFunction() async {
await assertDiagnostics(r'''
f6(int? p) {
return B() + p!; // OK
}
''', [
// No lint
error(CompileTimeErrorCode.UNDEFINED_FUNCTION, 22, 1),
]);
}
test_yieldAsyncStar_streamOfNonNullable() async {
await assertNoDiagnostics(r'''
Stream<int> f13ok(int? p) async* {yield p!;}
''');
}
test_yieldAsyncStar_streamOfNullable() async {
await assertDiagnostics(r'''
Stream<int?> f(int? p) async* {yield p!;}
''', [
lint(38, 1),
]);
}
test_yieldSyncStar_iterableOfNonNullable() async {
await assertNoDiagnostics(r'''
Iterable<int> f(int? p) sync* {yield p!;}
''');
}
test_yieldSyncStar_iterableOfNullable() async {
await assertDiagnostics(r'''
Iterable<int?> f(int? p) sync* {yield p!;}
''', [
lint(39, 1),
]);
}
}