// 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';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(UnnecessaryNullChecksTest);
  });
}

@reflectiveTest
class UnnecessaryNullChecksTest extends LintRuleTest {
  @override
  String get lintRule => LintNames.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.unnecessaryNonNullAssertion, 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.undefinedFunction, 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)],
    );
  }
}
