// Copyright (c) 2017, 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 'dart:async'; import 'dart:convert'; import 'package:io/io.dart' hide sharedStdIn; import 'package:test/test.dart'; void main() { // ignore: close_sinks late StreamController fakeStdIn; late SharedStdIn sharedStdIn; setUp(() { fakeStdIn = StreamController(sync: true); sharedStdIn = SharedStdIn(fakeStdIn.stream.map((s) => s.codeUnits)); }); test('should allow a single subscriber', () async { final logs = []; final sub = sharedStdIn.transform(utf8.decoder).listen(logs.add); fakeStdIn.add('Hello World'); await sub.cancel(); expect(logs, ['Hello World']); }); test('should allow multiple subscribers', () async { final logs = []; final asUtf8 = sharedStdIn.transform(utf8.decoder); var sub = asUtf8.listen(logs.add); fakeStdIn.add('Hello World'); await sub.cancel(); sub = asUtf8.listen(logs.add); fakeStdIn.add('Goodbye World'); await sub.cancel(); expect(logs, ['Hello World', 'Goodbye World']); }); test('should throw if a subscriber is still active', () async { final active = sharedStdIn.listen((_) {}); expect(() => sharedStdIn.listen((_) {}), throwsStateError); await active.cancel(); expect(() => sharedStdIn.listen((_) {}), returnsNormally); }); test('should return a stream of lines', () async { expect( sharedStdIn.lines(), emitsInOrder([ 'I', 'Think', 'Therefore', 'I', 'Am', ]), ); [ 'I\nThink\n', 'Therefore\n', 'I\n', 'Am\n', ].forEach(fakeStdIn.add); }); test('should return the next line', () { expect(sharedStdIn.nextLine(), completion('Hello World')); fakeStdIn.add('Hello World\n'); }); test('should allow listening for new lines multiple times', () async { expect(sharedStdIn.nextLine(), completion('Hello World')); fakeStdIn.add('Hello World\n'); await Future.value(); expect(sharedStdIn.nextLine(), completion('Hello World')); fakeStdIn.add('Hello World\n'); }); }