// 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.

// @dart = 2.9

import 'dart:async';

import 'package:async_helper/async_minitest.dart';

import 'utils.dart';

class NotAStream {
  listen(oData, {onError, onDone, cancelOnError}) {
    fail('Not implementing Stream.');
  }
}

StreamTransformer getErrors =
    StreamTransformer.fromHandlers(handleData: (data, sink) {
  fail('Unexpected value');
}, handleError: (e, s, sink) {
  sink.add(e);
}, handleDone: (sink) {
  sink.close();
});

// Obscuring identity function.
id(x) {
  try {
    if (x != null) throw x;
  } catch (e) {
    return e;
  }
  return null;
}

main() {
  test('empty', () {
    f() async* {}
    return f().toList().then((v) {
      expect(v, equals([]));
    });
  });

  test('single', () {
    f() async* {
      yield 42;
    }

    return f().toList().then((v) {
      expect(v, equals([42]));
    });
  });

  test('call delays', () {
    var list = [];
    f() async* {
      list.add(1);
      yield 2;
    }

    var res = f().forEach(list.add);
    list.add(0);
    return res.whenComplete(() {
      expect(list, equals([0, 1, 2]));
    });
  });

  test('throws', () {
    f() async* {
      yield 1;
      throw 2;
    }

    var completer = Completer();
    var list = [];
    f().listen(list.add,
        onError: (v) => list.add('$v'), onDone: completer.complete);
    return completer.future.whenComplete(() {
      expect(list, equals([1, '2']));
    });
  });

  test('multiple', () {
    f() async* {
      for (int i = 0; i < 10; i++) {
        yield i;
      }
    }

    return expectList(f(), List.generate(10, id));
  });

  test('allows await', () {
    f() async* {
      var x = await Future.value(42);
      yield x;
      x = await Future.value(42);
    }

    return expectList(f(), [42]);
  });

  test('allows await in loop', () {
    f() async* {
      for (int i = 0; i < 10; i++) {
        yield await i;
      }
    }

    return expectList(f(), List.generate(10, id));
  });

  test('allows yield*', () {
    f() async* {
      yield* Stream.fromIterable([1, 2, 3]);
    }

    return expectList(f(), [1, 2, 3]);
  });

  test('allows yield* of async*', () {
    f(n) async* {
      yield n;
      if (n == 0) return;
      yield* f(n - 1);
      yield n;
    }

    return expectList(f(3), [3, 2, 1, 0, 1, 2, 3]);
  });

  test('Cannot yield* non-stream', () {
    f(Object s) async* {
      yield* s;
    }

    return f(42).transform(getErrors).single.then((v) {
      // Not implementing Stream.
      expect(v is Error, isTrue);
    });
  });

  test('Cannot yield* non-stream 2', () {
    f(Object s) async* {
      yield* s;
    }

    return f(NotAStream()).transform(getErrors).single.then((v) {
      // Not implementing Stream.
      expect(v is Error, isTrue);
    });
  });
}
