Add utilities to sharedStdIn. (dart-lang/io#26)
diff --git a/pkgs/io/CHANGELOG.md b/pkgs/io/CHANGELOG.md index a16a183..3dc176d 100644 --- a/pkgs/io/CHANGELOG.md +++ b/pkgs/io/CHANGELOG.md
@@ -1,3 +1,19 @@ +## 0.3.1 + +- Added `SharedStdIn.nextLine` (similar to `readLineSync`) and `lines`: + +```dart +main() async { + // Prints the first line entered on stdin. + print(await sharedStdIn.nextLine()); + + // Prints all remaining lines. + await for (final line in sharedStdIn.lines) { + print(line); + } +} +``` + ## 0.3.0 - **BREAKING CHANGE**: The `arguments` argument to `ProcessManager.spawn` is @@ -5,7 +21,9 @@ built-in `Process.start`, and easier to use as a drop in replacement: ```dart -processManager.spawn('dart', ['--version']); +main() { + processManager.spawn('dart', ['--version']); +} ``` - Fixed a bug where processes created from `ProcessManager.spawn` could not
diff --git a/pkgs/io/lib/src/shared_stdin.dart b/pkgs/io/lib/src/shared_stdin.dart index 79ff97d..23b3d50 100644 --- a/pkgs/io/lib/src/shared_stdin.dart +++ b/pkgs/io/lib/src/shared_stdin.dart
@@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:meta/meta.dart'; @@ -32,6 +33,28 @@ _sub = (stream ??= stdin).listen(_onInput); } + /// Returns a future that completes with the next line. + /// + /// This is similar to the standard [Stdin.readLineSync], but asynchronous. + Future<String> nextLine({Encoding encoding: SYSTEM_ENCODING}) { + return lines(encoding: encoding).first; + } + + /// Returns the stream transformed as UTF8 strings separated by line breaks. + /// + /// This is similar to synchronous code using [Stdin.readLineSync]: + /// ```dart + /// while (true) { + /// var line = stdin.readLineSync(); + /// // ... + /// } + /// ``` + /// + /// ... but asynchronous. + Stream<String> lines({Encoding encoding: SYSTEM_ENCODING}) { + return transform(UTF8.decoder).transform(const LineSplitter()); + } + void _onInput(List<int> event) => _getCurrent().add(event); StreamController<List<int>> _getCurrent() {
diff --git a/pkgs/io/test/shared_stdin_test.dart b/pkgs/io/test/shared_stdin_test.dart index 722ec1f..82e833f 100644 --- a/pkgs/io/test/shared_stdin_test.dart +++ b/pkgs/io/test/shared_stdin_test.dart
@@ -43,4 +43,37 @@ await active.cancel(); expect(() => sharedStdIn.listen((_) {}), returnsNormally); }); + + test('should return a stream of lines', () async { + expect( + sharedStdIn.lines(), + emitsInOrder(<dynamic>[ + '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 new Future<Null>.value(); + + expect(sharedStdIn.nextLine(), completion('Hello World')); + fakeStdIn.add('Hello World\n'); + }); }