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

@Deprecated("Tests deprecated functionality")
library sink_base_test;

import 'dart:async';
import 'dart:convert';

import 'package:test/test.dart';

import 'package:async/async.dart';

const int letterA = 0x41;

void main() {
  // We don't explicitly test [EventSinkBase] because it shares all the relevant
  // implementation with [StreamSinkBase].
  group('StreamSinkBase', () {
    test('forwards add() to onAdd()', () {
      var sink = _StreamSink(onAdd: expectAsync1((value) {
        expect(value, equals(123));
      }));
      sink.add(123);
    });

    test('forwards addError() to onError()', () {
      var sink = _StreamSink(onError: expectAsync2((error, [stackTrace]) {
        expect(error, equals('oh no'));
        expect(stackTrace, isA<StackTrace>());
      }));
      sink.addError('oh no', StackTrace.current);
    });

    test('forwards addStream() to onAdd() and onError()', () {
      var sink = _StreamSink(
          onAdd: expectAsync1((value) {
            expect(value, equals(123));
          }, count: 1),
          onError: expectAsync2((error, [stackTrace]) {
            expect(error, equals('oh no'));
            expect(stackTrace, isA<StackTrace>());
          }));

      var controller = StreamController<int>();
      sink.addStream(controller.stream);

      controller.add(123);
      controller.addError('oh no', StackTrace.current);
    });

    test('addStream() returns once the stream closes', () async {
      var sink = _StreamSink();
      var controller = StreamController<int>();
      var addStreamCompleted = false;
      sink.addStream(controller.stream).then((_) => addStreamCompleted = true);

      await pumpEventQueue();
      expect(addStreamCompleted, isFalse);

      controller.addError('oh no', StackTrace.current);
      await pumpEventQueue();
      expect(addStreamCompleted, isFalse);

      controller.close();
      await pumpEventQueue();
      expect(addStreamCompleted, isTrue);
    });

    test('forwards close() to onClose()', () {
      var sink = _StreamSink(onClose: expectAsync0(() {}));
      expect(sink.close(), completes);
    });

    test('onClose() is only invoked once', () {
      var sink = _StreamSink(onClose: expectAsync0(() {}, count: 1));
      expect(sink.close(), completes);
      expect(sink.close(), completes);
      expect(sink.close(), completes);
    });

    test('all invocations of close() return the same future', () async {
      var completer = Completer();
      var sink = _StreamSink(onClose: expectAsync0(() => completer.future));

      var close1Completed = false;
      sink.close().then((_) => close1Completed = true);

      var close2Completed = false;
      sink.close().then((_) => close2Completed = true);

      var doneCompleted = false;
      sink.done.then((_) => doneCompleted = true);

      await pumpEventQueue();
      expect(close1Completed, isFalse);
      expect(close2Completed, isFalse);
      expect(doneCompleted, isFalse);

      completer.complete();
      await pumpEventQueue();
      expect(close1Completed, isTrue);
      expect(close2Completed, isTrue);
      expect(doneCompleted, isTrue);
    });

    test('done returns a future that completes once close() completes',
        () async {
      var completer = Completer();
      var sink = _StreamSink(onClose: expectAsync0(() => completer.future));

      var doneCompleted = false;
      sink.done.then((_) => doneCompleted = true);

      await pumpEventQueue();
      expect(doneCompleted, isFalse);

      expect(sink.close(), completes);
      await pumpEventQueue();
      expect(doneCompleted, isFalse);

      completer.complete();
      await pumpEventQueue();
      expect(doneCompleted, isTrue);
    });

    group('during addStream()', () {
      test('add() throws an error', () {
        var sink = _StreamSink(onAdd: expectAsync1((_) {}, count: 0));
        sink.addStream(StreamController<int>().stream);
        expect(() => sink.add(1), throwsStateError);
      });

      test('addError() throws an error', () {
        var sink = _StreamSink(onError: expectAsync2((_, [__]) {}, count: 0));
        sink.addStream(StreamController<int>().stream);
        expect(() => sink.addError('oh no'), throwsStateError);
      });

      test('addStream() throws an error', () {
        var sink = _StreamSink(onAdd: expectAsync1((_) {}, count: 0));
        sink.addStream(StreamController<int>().stream);
        expect(() => sink.addStream(Stream.value(123)), throwsStateError);
      });

      test('close() throws an error', () {
        var sink = _StreamSink(onClose: expectAsync0(() {}, count: 0));
        sink.addStream(StreamController<int>().stream);
        expect(() => sink.close(), throwsStateError);
      });
    });

    group("once it's closed", () {
      test('add() throws an error', () {
        var sink = _StreamSink(onAdd: expectAsync1((_) {}, count: 0));
        expect(sink.close(), completes);
        expect(() => sink.add(1), throwsStateError);
      });

      test('addError() throws an error', () {
        var sink = _StreamSink(onError: expectAsync2((_, [__]) {}, count: 0));
        expect(sink.close(), completes);
        expect(() => sink.addError('oh no'), throwsStateError);
      });

      test('addStream() throws an error', () {
        var sink = _StreamSink(onAdd: expectAsync1((_) {}, count: 0));
        expect(sink.close(), completes);
        expect(() => sink.addStream(Stream.value(123)), throwsStateError);
      });
    });
  });

  group('IOSinkBase', () {
    group('write()', () {
      test("doesn't call add() for the empty string", () async {
        var sink = _IOSink(onAdd: expectAsync1((_) {}, count: 0));
        sink.write('');
      });

      test('converts the text to data and passes it to add', () async {
        var sink = _IOSink(onAdd: expectAsync1((data) {
          expect(data, equals(utf8.encode('hello')));
        }));
        sink.write('hello');
      });

      test('calls Object.toString()', () async {
        var sink = _IOSink(onAdd: expectAsync1((data) {
          expect(data, equals(utf8.encode('123')));
        }));
        sink.write(123);
      });

      test('respects the encoding', () async {
        var sink = _IOSink(
            onAdd: expectAsync1((data) {
              expect(data, equals(latin1.encode('Æ')));
            }),
            encoding: latin1);
        sink.write('Æ');
      });

      test('throws if the sink is closed', () async {
        var sink = _IOSink(onAdd: expectAsync1((_) {}, count: 0));
        expect(sink.close(), completes);
        expect(() => sink.write('hello'), throwsStateError);
      });
    });

    group('writeAll()', () {
      test('writes nothing for an empty iterable', () async {
        var sink = _IOSink(onAdd: expectAsync1((_) {}, count: 0));
        sink.writeAll([]);
      });

      test('writes each object in the iterable', () async {
        var chunks = <List<int>>[];
        var sink = _IOSink(
            onAdd: expectAsync1((data) {
          chunks.add(data);
        }, count: 3));

        sink.writeAll(['hello', null, 123]);
        expect(chunks, equals(['hello', 'null', '123'].map(utf8.encode)));
      });

      test('writes separators between each object', () async {
        var chunks = <List<int>>[];
        var sink = _IOSink(
            onAdd: expectAsync1((data) {
          chunks.add(data);
        }, count: 5));

        sink.writeAll(['hello', null, 123], '/');
        expect(chunks,
            equals(['hello', '/', 'null', '/', '123'].map(utf8.encode)));
      });

      test('throws if the sink is closed', () async {
        var sink = _IOSink(onAdd: expectAsync1((_) {}, count: 0));
        expect(sink.close(), completes);
        expect(() => sink.writeAll(['hello']), throwsStateError);
      });
    });

    group('writeln()', () {
      test('only writes a newline by default', () async {
        var sink = _IOSink(
            onAdd: expectAsync1((data) {
          expect(data, equals(utf8.encode('\n')));
        }, count: 1));
        sink.writeln();
      });

      test('writes the object followed by a newline', () async {
        var chunks = <List<int>>[];
        var sink = _IOSink(
            onAdd: expectAsync1((data) {
          chunks.add(data);
        }, count: 2));
        sink.writeln(123);

        expect(chunks, equals(['123', '\n'].map(utf8.encode)));
      });

      test('throws if the sink is closed', () async {
        var sink = _IOSink(onAdd: expectAsync1((_) {}, count: 0));
        expect(sink.close(), completes);
        expect(() => sink.writeln(), throwsStateError);
      });
    });

    group('writeCharCode()', () {
      test('writes the character code', () async {
        var sink = _IOSink(onAdd: expectAsync1((data) {
          expect(data, equals(utf8.encode('A')));
        }));
        sink.writeCharCode(letterA);
      });

      test('respects the encoding', () async {
        var sink = _IOSink(
            onAdd: expectAsync1((data) {
              expect(data, equals(latin1.encode('Æ')));
            }),
            encoding: latin1);
        sink.writeCharCode('Æ'.runes.first);
      });

      test('throws if the sink is closed', () async {
        var sink = _IOSink(onAdd: expectAsync1((_) {}, count: 0));
        expect(sink.close(), completes);
        expect(() => sink.writeCharCode(letterA), throwsStateError);
      });
    });

    group('flush()', () {
      test('returns a future that completes when onFlush() is done', () async {
        var completer = Completer();
        var sink = _IOSink(onFlush: expectAsync0(() => completer.future));

        var flushDone = false;
        sink.flush().then((_) => flushDone = true);

        await pumpEventQueue();
        expect(flushDone, isFalse);

        completer.complete();
        await pumpEventQueue();
        expect(flushDone, isTrue);
      });

      test('does nothing after close() is called', () {
        var sink =
            _IOSink(onFlush: expectAsync0(() => Future.value(), count: 0));
        expect(sink.close(), completes);
        expect(sink.flush(), completes);
      });

      test("can't be called during addStream()", () {
        var sink =
            _IOSink(onFlush: expectAsync0(() => Future.value(), count: 0));
        sink.addStream(StreamController<List<int>>().stream);
        expect(() => sink.flush(), throwsStateError);
      });

      test('locks the sink as though a stream was being added', () {
        var sink = _IOSink(onFlush: expectAsync0(() => Completer().future));
        sink.flush();
        expect(() => sink.add([0]), throwsStateError);
        expect(() => sink.addError('oh no'), throwsStateError);
        expect(() => sink.addStream(Stream.empty()), throwsStateError);
        expect(() => sink.flush(), throwsStateError);
        expect(() => sink.close(), throwsStateError);
      });
    });
  });
}

/// A subclass of [StreamSinkBase] that takes all the overridable methods as
/// callbacks, for ease of testing.
class _StreamSink extends StreamSinkBase<int> {
  final void Function(int value) _onAdd;
  final void Function(Object error, [StackTrace? stackTrace]) _onError;
  final FutureOr<void> Function() _onClose;

  _StreamSink(
      {void Function(int value)? onAdd,
      void Function(Object error, [StackTrace? stackTrace])? onError,
      FutureOr<void> Function()? onClose})
      : _onAdd = onAdd ?? ((_) {}),
        _onError = onError ?? ((_, [__]) {}),
        _onClose = onClose ?? (() {});

  @override
  void onAdd(int value) {
    _onAdd(value);
  }

  @override
  void onError(Object error, [StackTrace? stackTrace]) {
    _onError(error, stackTrace);
  }

  @override
  FutureOr<void> onClose() => _onClose();
}

/// A subclass of [IOSinkBase] that takes all the overridable methods as
/// callbacks, for ease of testing.
class _IOSink extends IOSinkBase {
  final void Function(List<int> value) _onAdd;
  final void Function(Object error, [StackTrace? stackTrace]) _onError;
  final FutureOr<void> Function() _onClose;
  final Future<void> Function() _onFlush;

  _IOSink(
      {void Function(List<int> value)? onAdd,
      void Function(Object error, [StackTrace? stackTrace])? onError,
      FutureOr<void> Function()? onClose,
      Future<void> Function()? onFlush,
      Encoding encoding = utf8})
      : _onAdd = onAdd ?? ((_) {}),
        _onError = onError ?? ((_, [__]) {}),
        _onClose = onClose ?? (() {}),
        _onFlush = onFlush ?? (() => Future.value()),
        super(encoding);

  @override
  void onAdd(List<int> value) {
    _onAdd(value);
  }

  @override
  void onError(Object error, [StackTrace? stackTrace]) {
    _onError(error, stackTrace);
  }

  @override
  FutureOr<void> onClose() => _onClose();

  @override
  Future<void> onFlush() => _onFlush();
}
