// Copyright (c) 2020, 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 'context_collection_resolution.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(YieldStatementResolutionTest);
  });
}

@reflectiveTest
class YieldStatementResolutionTest extends PubPackageResolutionTest {
  @override
  setUp() {
    super.setUp();

    newFile('$testPackageLibPath/my_stream.dart', content: r'''
import 'dart:async';

export 'dart:async';

class MyStream<T> implements Stream<T> {
  @override
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
''');
  }

  test_downInference_function_asyncStar() async {
    await assertNoErrorsInCode(r'''
import 'my_stream.dart';

Stream f1() async* {
  yield []; // 1
  yield* MyStream(); // 2
}

Stream<List<int>> f2() async* {
  yield []; // 3
  yield* MyStream(); // 4
}
''');
    assertType(
      findNode.listLiteral('[]; // 1'),
      'List<dynamic>',
    );

    assertType(
      findNode.instanceCreation('MyStream(); // 2'),
      'MyStream<dynamic>',
    );

    assertType(
      findNode.listLiteral('[]; // 3'),
      'List<int>',
    );

    assertType(
      findNode.instanceCreation('MyStream(); // 4'),
      'MyStream<List<int>>',
    );
  }

  test_downInference_function_syncStar() async {
    await assertNoErrorsInCode(r'''
Iterable f1() sync* {
  yield []; // 1
  yield* List.empty(); // 2
}

Iterable<List<int>> f2() sync* {
  yield []; // 3
  yield* List.empty(); // 4
}
''');
    assertType(
      findNode.listLiteral('[]; // 1'),
      'List<dynamic>',
    );

    assertType(
      findNode.instanceCreation('List.empty(); // 2'),
      'List<dynamic>',
    );

    assertType(
      findNode.listLiteral('[]; // 3'),
      'List<int>',
    );

    assertType(
      findNode.instanceCreation('List.empty(); // 4'),
      'List<List<int>>',
    );
  }

  test_downInference_functionExpression_asyncStar() async {
    await assertNoErrorsInCode(r'''
import 'my_stream.dart';

main() {
  Stream Function() f1 = () async* {
    yield []; // 1
    yield* MyStream(); // 2
  };
  f1;

  Stream<List<int>> Function() f2 = () async* {
    yield []; // 3
    yield* MyStream(); // 4
  };
  f2;
}
''');
    assertType(
      findNode.listLiteral('[]; // 1'),
      'List<dynamic>',
    );

    assertType(
      findNode.instanceCreation('MyStream(); // 2'),
      'MyStream<dynamic>',
    );

    assertType(
      findNode.listLiteral('[]; // 3'),
      'List<int>',
    );

    assertType(
      findNode.instanceCreation('MyStream(); // 4'),
      'MyStream<List<int>>',
    );
  }

  test_downInference_functionExpression_syncStar() async {
    await assertNoErrorsInCode(r'''
main() {
  Iterable Function() f1 = () sync* {
    yield []; // 1
    yield* List.empty(); // 2
  };
  f1;

  Iterable<List<int>> Function() f2 = () sync* {
    yield []; // 3
    yield* List.empty(); // 4
  };
  f2;
}
''');
    assertType(
      findNode.listLiteral('[]; // 1'),
      'List<dynamic>',
    );

    assertType(
      findNode.instanceCreation('List.empty(); // 2'),
      'List<dynamic>',
    );

    assertType(
      findNode.listLiteral('[]; // 3'),
      'List<int>',
    );

    assertType(
      findNode.instanceCreation('List.empty(); // 4'),
      'List<List<int>>',
    );
  }

  test_downInference_method_asyncStar() async {
    await assertNoErrorsInCode(r'''
import 'my_stream.dart';

class A {
  Stream m1() async* {
    yield []; // 1
    yield* MyStream(); // 2
  }

  Stream<List<int>> m2() async* {
    yield []; // 3
    yield* MyStream(); // 4
  }
}
''');
    assertType(
      findNode.listLiteral('[]; // 1'),
      'List<dynamic>',
    );

    assertType(
      findNode.instanceCreation('MyStream(); // 2'),
      'MyStream<dynamic>',
    );

    assertType(
      findNode.listLiteral('[]; // 3'),
      'List<int>',
    );

    assertType(
      findNode.instanceCreation('MyStream(); // 4'),
      'MyStream<List<int>>',
    );
  }

  test_downInference_method_syncStar() async {
    await assertNoErrorsInCode(r'''
class A {
  Iterable m1() sync* {
    yield []; // 1
    yield* List.empty(); // 2
  }

  Iterable<List<int>> m2() sync* {
    yield []; // 3
    yield* List.empty(); // 4
  }
}
''');
    assertType(
      findNode.listLiteral('[]; // 1'),
      'List<dynamic>',
    );

    assertType(
      findNode.instanceCreation('List.empty(); // 2'),
      'List<dynamic>',
    );

    assertType(
      findNode.listLiteral('[]; // 3'),
      'List<int>',
    );

    assertType(
      findNode.instanceCreation('List.empty(); // 4'),
      'List<List<int>>',
    );
  }
}
