From d56a057cd1a4039ad70949238f4f500d069709f8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 19 Jan 2016 16:41:33 -0800 Subject: [PATCH 001/138] Initial commit. --- pkgs/stream_channel/.gitignore | 9 ++++++++ pkgs/stream_channel/.test_config | 3 +++ pkgs/stream_channel/AUTHORS | 6 ++++++ pkgs/stream_channel/CHANGELOG.md | 3 +++ pkgs/stream_channel/CONTRIBUTING.md | 33 +++++++++++++++++++++++++++++ pkgs/stream_channel/LICENSE | 26 +++++++++++++++++++++++ pkgs/stream_channel/README.md | 16 ++++++++++++++ pkgs/stream_channel/pubspec.yaml | 9 ++++++++ 8 files changed, 105 insertions(+) create mode 100644 pkgs/stream_channel/.gitignore create mode 100644 pkgs/stream_channel/.test_config create mode 100644 pkgs/stream_channel/AUTHORS create mode 100644 pkgs/stream_channel/CHANGELOG.md create mode 100644 pkgs/stream_channel/CONTRIBUTING.md create mode 100644 pkgs/stream_channel/LICENSE create mode 100644 pkgs/stream_channel/README.md create mode 100644 pkgs/stream_channel/pubspec.yaml diff --git a/pkgs/stream_channel/.gitignore b/pkgs/stream_channel/.gitignore new file mode 100644 index 000000000..25a1df332 --- /dev/null +++ b/pkgs/stream_channel/.gitignore @@ -0,0 +1,9 @@ +.buildlog +.DS_Store +.idea +.pub/ +.settings/ +build/ +packages +.packages +pubspec.lock diff --git a/pkgs/stream_channel/.test_config b/pkgs/stream_channel/.test_config new file mode 100644 index 000000000..352d2feee --- /dev/null +++ b/pkgs/stream_channel/.test_config @@ -0,0 +1,3 @@ +{ + "test_package": true +} diff --git a/pkgs/stream_channel/AUTHORS b/pkgs/stream_channel/AUTHORS new file mode 100644 index 000000000..e8063a8cd --- /dev/null +++ b/pkgs/stream_channel/AUTHORS @@ -0,0 +1,6 @@ +# Below is a list of people and organizations that have contributed +# to the project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md new file mode 100644 index 000000000..847d60daa --- /dev/null +++ b/pkgs/stream_channel/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* Initial version diff --git a/pkgs/stream_channel/CONTRIBUTING.md b/pkgs/stream_channel/CONTRIBUTING.md new file mode 100644 index 000000000..6f5e0ea67 --- /dev/null +++ b/pkgs/stream_channel/CONTRIBUTING.md @@ -0,0 +1,33 @@ +Want to contribute? Great! First, read this page (including the small print at +the end). + +### Before you contribute +Before we can use your code, you must sign the +[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual) +(CLA), which you can do online. The CLA is necessary mainly because you own the +copyright to your changes, even after your contribution becomes part of our +codebase, so we need your permission to use and distribute your code. We also +need to be sure of various other things—for instance that you'll tell us if you +know that your code infringes on other people's patents. You don't have to sign +the CLA until after you've submitted your code for review and a member has +approved it, but you must do it before we can put your code into our codebase. + +Before you start working on a larger contribution, you should get in touch with +us first through the issue tracker with your idea so that we can help out and +possibly guide you. Coordinating up front makes it much easier to avoid +frustration later on. + +### Code reviews +All submissions, including submissions by project members, require review. + +### File headers +All files in the project must start with the following header. + + // Copyright (c) 2015, 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. + +### The small print +Contributions made by corporations are covered by a different agreement than the +one above, the +[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate). diff --git a/pkgs/stream_channel/LICENSE b/pkgs/stream_channel/LICENSE new file mode 100644 index 000000000..de31e1a0a --- /dev/null +++ b/pkgs/stream_channel/LICENSE @@ -0,0 +1,26 @@ +Copyright 2015, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkgs/stream_channel/README.md b/pkgs/stream_channel/README.md new file mode 100644 index 000000000..5d6a2b4e0 --- /dev/null +++ b/pkgs/stream_channel/README.md @@ -0,0 +1,16 @@ +This package exposes the `StreamChannel` interface, which represents a two-way +communication channel. Each `StreamChannel` exposes a `Stream` for receiving +data and a `StreamSink` for sending it. + +`StreamChannel` helps abstract communication logic away from the underlying +protocol. For example, the [`test`][test] package re-uses its test suite +communication protocol for both WebSocket connections to browser suites and +Isolate connections to VM tests. + +[test]: https://pub.dartlang.org/packages/test + +This package also contains utilities for dealing with `StreamChannel`s and with +two-way communications in general. For documentation of these utilities, see +[the API docs][api]. + +[api]: https://www.dartdocs.org/documentation/stream_channel/latest diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml new file mode 100644 index 000000000..76f22b7da --- /dev/null +++ b/pkgs/stream_channel/pubspec.yaml @@ -0,0 +1,9 @@ +name: stream_channel +version: 1.0.0-dev +description: An abstraction for two-way communication channels. +author: Dart Team +homepage: https://github.com/dart-lang/stream_channel +environment: + sdk: '>=1.0.0 <2.0.0' +dev_dependencies: + test: '^0.12.0' From d0b0d2d1150f7de04e3d4bfac27a238358197611 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 19 Jan 2016 16:50:25 -0800 Subject: [PATCH 002/138] Add codereview.settings. --- pkgs/stream_channel/codereview.settings | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 pkgs/stream_channel/codereview.settings diff --git a/pkgs/stream_channel/codereview.settings b/pkgs/stream_channel/codereview.settings new file mode 100644 index 000000000..7b0a9edc6 --- /dev/null +++ b/pkgs/stream_channel/codereview.settings @@ -0,0 +1,3 @@ +CODE_REVIEW_SERVER: https://codereview.chromium.org/ +VIEW_VC: https://github.com/dart-lang/stream_channel/commit/ +CC_LIST: reviews@dartlang.org \ No newline at end of file From 3ee20be6a7e5baa85fd75c270faa2c3af528734d Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 20 Jan 2016 17:02:20 -0800 Subject: [PATCH 003/138] Add StreamChannel and MultiChannel. These are exact copies of the classes and tests from the test package. R=rnystrom@google.com, kevmoo@google.com Review URL: https://codereview.chromium.org//1610443002 . --- .../stream_channel/lib/src/multi_channel.dart | 244 ++++++++++++++ pkgs/stream_channel/lib/stream_channel.dart | 50 +++ .../test/multi_channel_test.dart | 310 ++++++++++++++++++ pkgs/stream_channel/test/utils.dart | 20 ++ 4 files changed, 624 insertions(+) create mode 100644 pkgs/stream_channel/lib/src/multi_channel.dart create mode 100644 pkgs/stream_channel/lib/stream_channel.dart create mode 100644 pkgs/stream_channel/test/multi_channel_test.dart create mode 100644 pkgs/stream_channel/test/utils.dart diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart new file mode 100644 index 000000000..e87deb33b --- /dev/null +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -0,0 +1,244 @@ +// Copyright (c) 2016, 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 '../stream_channel.dart'; + +/// A class that multiplexes multiple virtual channels across a single +/// underlying transport layer. +/// +/// This should be connected to another [MultiChannel] on the other end of the +/// underlying channel. It starts with a single default virtual channel, +/// accessible via [stream] and [sink]. Additional virtual channels can be +/// created with [virtualChannel]. +/// +/// When a virtual channel is created by one endpoint, the other must connect to +/// it before messages may be sent through it. The first endpoint passes its +/// [VirtualChannel.id] to the second, which then creates a channel from that id +/// also using [virtualChannel]. For example: +/// +/// ```dart +/// // First endpoint +/// var virtual = multiChannel.virtualChannel(); +/// multiChannel.sink.add({ +/// "channel": virtual.id +/// }); +/// +/// // Second endpoint +/// multiChannel.stream.listen((message) { +/// var virtual = multiChannel.virtualChannel(message["channel"]); +/// // ... +/// }); +/// ``` +/// +/// Sending errors across a [MultiChannel] is not supported. Any errors from the +/// underlying stream will be reported only via the default +/// [MultiChannel.stream]. +/// +/// Each virtual channel may be closed individually. When all of them are +/// closed, the underlying [StreamSink] is closed automatically. +abstract class MultiChannel implements StreamChannel { + /// The default input stream. + /// + /// This connects to the remote [sink]. + Stream get stream; + + /// The default output stream. + /// + /// This connects to the remote [stream]. If this is closed, the remote + /// [stream] will close, but other virtual channels will remain open and new + /// virtual channels may be opened. + StreamSink get sink; + + /// Creates a new [MultiChannel] that sends messages over [innerStream] and + /// [innerSink]. + /// + /// The inner streams must take JSON-like objects. + factory MultiChannel(Stream innerStream, StreamSink innerSink) => + new _MultiChannel(innerStream, innerSink); + + /// Creates a new virtual channel. + /// + /// If [id] is not passed, this creates a virtual channel from scratch. Before + /// it's used, its [VirtualChannel.id] must be sent to the remote endpoint + /// where [virtualChannel] should be called with that id. + /// + /// If [id] is passed, this creates a virtual channel corresponding to the + /// channel with that id on the remote channel. + /// + /// Throws an [ArgumentError] if a virtual channel already exists for [id]. + /// Throws a [StateError] if the underlying channel is closed. + VirtualChannel virtualChannel([id]); +} + +/// The implementation of [MultiChannel]. +/// +/// This is private so that [VirtualChannel] can inherit from [MultiChannel] +/// without having to implement all the private members. +class _MultiChannel extends StreamChannelMixin implements MultiChannel { + /// The inner stream over which all communication is received. + /// + /// This will be `null` if the underlying communication channel is closed. + Stream _innerStream; + + /// The inner sink over which all communication is sent. + /// + /// This will be `null` if the underlying communication channel is closed. + StreamSink _innerSink; + + /// The subscription to [_innerStream]. + StreamSubscription _innerStreamSubscription; + + Stream get stream => _streamController.stream; + final _streamController = new StreamController(sync: true); + + StreamSink get sink => _sinkController.sink; + final _sinkController = new StreamController(sync: true); + + /// A map from virtual channel ids to [StreamController]s that should be used + /// to write messages received from those channels. + final _streamControllers = new Map(); + + /// A map from virtual channel ids to [StreamControllers]s that are used + /// to receive messages to write to those channels. + /// + /// Note that this uses the same keys as [_streamControllers]. + final _sinkControllers = new Map(); + + /// The next id to use for a local virtual channel. + /// + /// Ids are used to identify virtual channels. Each message is tagged with an + /// id; the receiving [MultiChannel] uses this id to look up which + /// [VirtualChannel] the message should be dispatched to. + /// + /// The id scheme for virtual channels is somewhat complicated. This is + /// necessary to ensure that there are no conflicts even when both endpoints + /// have virtual channels with the same id; since both endpoints can send and + /// receive messages across each virtual channel, a naïve scheme would make it + /// impossible to tell whether a message was from a channel that originated in + /// the remote endpoint or a reply on a channel that originated in the local + /// endpoint. + /// + /// The trick is that each endpoint only uses odd ids for its own channels. + /// When sending a message over a channel that was created by the remote + /// endpoint, the channel's id plus one is used. This way each [MultiChannel] + /// knows that if an incoming message has an odd id, it's using the local id + /// scheme, but if it has an even id, it's using the remote id scheme. + var _nextId = 1; + + _MultiChannel(this._innerStream, this._innerSink) { + // The default connection is a special case which has id 0 on both ends. + // This allows it to begin connected without having to send over an id. + _streamControllers[0] = _streamController; + _sinkControllers[0] = _sinkController; + _sinkController.stream.listen( + (message) => _innerSink.add([0, message]), + onDone: () => _closeChannel(0, 0)); + + _innerStreamSubscription = _innerStream.listen((message) { + var id = message[0]; + var sink = _streamControllers[id]; + + // A sink might not exist if the channel was closed before an incoming + // message was processed. + if (sink == null) return; + if (message.length > 1) { + sink.add(message[1]); + return; + } + + // A message without data indicates that the channel has been closed. + _sinkControllers[id].close(); + }, onDone: _closeInnerChannel, + onError: _streamController.addError); + } + + VirtualChannel virtualChannel([id]) { + if (_innerStream == null) { + throw new StateError("The underlying channel is closed."); + } + + var inputId; + var outputId; + if (id != null) { + // Since the user is passing in an id, we're connected to a remote + // VirtualChannel. This means messages they send over this channel will + // have the original odd id, but our replies will have an even id. + inputId = id; + outputId = (id as int) + 1; + } else { + // Since we're generating an id, we originated this VirtualChannel. This + // means messages we send over this channel will have the original odd id, + // but the remote channel's replies will have an even id. + inputId = _nextId + 1; + outputId = _nextId; + _nextId += 2; + } + + if (_streamControllers.containsKey(inputId)) { + throw new ArgumentError("A virtual channel with id $id already exists."); + } + + var streamController = new StreamController(sync: true); + var sinkController = new StreamController(sync: true); + _streamControllers[inputId] = streamController; + _sinkControllers[inputId] = sinkController; + sinkController.stream.listen( + (message) => _innerSink.add([outputId, message]), + onDone: () => _closeChannel(inputId, outputId)); + + return new VirtualChannel._( + this, outputId, streamController.stream, sinkController.sink); + } + + /// Closes the virtual channel for which incoming messages have [inputId] and + /// outgoing messages have [outputId]. + void _closeChannel(int inputId, int outputId) { + _streamControllers.remove(inputId).close(); + _sinkControllers.remove(inputId).close(); + + if (_innerSink == null) return; + + // A message without data indicates that the virtual channel has been + // closed. + _innerSink.add([outputId]); + if (_streamControllers.isEmpty) _closeInnerChannel(); + } + + /// Closes the underlying communication channel. + void _closeInnerChannel() { + _innerSink.close(); + _innerStreamSubscription.cancel(); + _innerStream = null; + _innerSink = null; + for (var controller in _sinkControllers.values.toList()) { + controller.close(); + } + } +} + +/// A virtual channel created by [MultiChannel]. +/// +/// This implements [MultiChannel] for convenience. +/// [VirtualChannel.virtualChannel] is semantically identical to the parent's +/// [MultiChannel.virtualChannel]. +class VirtualChannel extends StreamChannelMixin implements MultiChannel { + /// The [MultiChannel] that created this. + final MultiChannel _parent; + + /// The identifier for this channel. + /// + /// This can be sent across the [MultiChannel] to provide the remote endpoint + /// a means to connect to this channel. Nothing about this is guaranteed + /// except that it will be JSON-serializable. + final id; + + final Stream stream; + final StreamSink sink; + + VirtualChannel._(this._parent, this.id, this.stream, this.sink); + + VirtualChannel virtualChannel([id]) => _parent.virtualChannel(id); +} diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart new file mode 100644 index 000000000..c4e28a0e3 --- /dev/null +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 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'; + +export 'src/multi_channel.dart'; + +/// An abstract class representing a two-way communication channel. +/// +/// Subclasses are strongly encouraged to mix in or extend [StreamChannelMixin] +/// to get default implementations of the various instance methods. Adding new +/// methods to this interface will not be considered a breaking change if +/// implementations are also added to [StreamChannelMixin]. +abstract class StreamChannel { + /// The stream that emits values from the other endpoint. + Stream get stream; + + /// The sink for sending values to the other endpoint. + StreamSink get sink; + + /// Creates a new [StreamChannel] that communicates over [stream] and [sink]. + factory StreamChannel(Stream stream, StreamSink sink) => + new _StreamChannel(stream, sink); + + /// Connects [this] to [other], so that any values emitted by either are sent + /// directly to the other. + void pipe(StreamChannel other); +} + +/// An implementation of [StreamChannel] that simply takes a stream and a sink +/// as parameters. +/// +/// This is distinct from [StreamChannel] so that it can use +/// [StreamChannelMixin]. +class _StreamChannel extends StreamChannelMixin { + final Stream stream; + final StreamSink sink; + + _StreamChannel(this.stream, this.sink); +} + +/// A mixin that implements the instance methods of [StreamChannel] in terms of +/// [stream] and [sink]. +abstract class StreamChannelMixin implements StreamChannel { + void pipe(StreamChannel other) { + stream.pipe(other.sink); + other.stream.pipe(sink); + } +} diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart new file mode 100644 index 000000000..e4594128a --- /dev/null +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -0,0 +1,310 @@ +// Copyright (c) 2016, 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 'package:stream_channel/stream_channel.dart'; +import 'package:test/test.dart'; + +import 'utils.dart'; + +void main() { + var oneToTwo; + var twoToOne; + var channel1; + var channel2; + setUp(() { + oneToTwo = new StreamController(); + twoToOne = new StreamController(); + channel1 = new MultiChannel(twoToOne.stream, oneToTwo.sink); + channel2 = new MultiChannel(oneToTwo.stream, twoToOne.sink); + }); + + group("the default virtual channel", () { + test("begins connected", () { + var first = true; + channel2.stream.listen(expectAsync((message) { + if (first) { + expect(message, equals("hello")); + first = false; + } else { + expect(message, equals("world")); + } + }, count: 2)); + + channel1.sink.add("hello"); + channel1.sink.add("world"); + }); + + test("closes the remote virtual channel when it closes", () { + expect(channel2.stream.toList(), completion(isEmpty)); + expect(channel2.sink.done, completes); + + channel1.sink.close(); + }); + + test("closes the local virtual channel when it closes", () { + expect(channel1.stream.toList(), completion(isEmpty)); + expect(channel1.sink.done, completes); + + channel1.sink.close(); + }); + + test("doesn't closes the local virtual channel when the stream " + "subscription is canceled", () { + channel1.sink.done.then(expectAsync((_) {}, count: 0)); + + channel1.stream.listen((_) {}).cancel(); + + // Ensure that there's enough time for the channel to close if it's going + // to. + return pumpEventQueue(); + }); + + test("closes the underlying channel when it closes without any other " + "virtual channels", () { + expect(oneToTwo.done, completes); + expect(twoToOne.done, completes); + + channel1.sink.close(); + }); + + test("doesn't close the underlying channel when it closes with other " + "virtual channels", () { + oneToTwo.done.then(expectAsync((_) {}, count: 0)); + twoToOne.done.then(expectAsync((_) {}, count: 0)); + + // Establish another virtual connection which should keep the underlying + // connection open. + channel2.virtualChannel(channel1.virtualChannel().id); + channel1.sink.close(); + + // Ensure that there's enough time for the underlying channel to complete + // if it's going to. + return pumpEventQueue(); + }); + }); + + group("a locally-created virtual channel", () { + var virtual1; + var virtual2; + setUp(() { + virtual1 = channel1.virtualChannel(); + virtual2 = channel2.virtualChannel(virtual1.id); + }); + + test("sends messages only to the other virtual channel", () { + var first = true; + virtual2.stream.listen(expectAsync((message) { + if (first) { + expect(message, equals("hello")); + first = false; + } else { + expect(message, equals("world")); + } + }, count: 2)); + + // No other virtual channels should receive the message. + for (var i = 0; i < 10; i++) { + var virtual = channel2.virtualChannel(channel1.virtualChannel().id); + virtual.stream.listen(expectAsync((_) {}, count: 0)); + } + channel2.stream.listen(expectAsync((_) {}, count: 0)); + + virtual1.sink.add("hello"); + virtual1.sink.add("world"); + }); + + test("closes the remote virtual channel when it closes", () { + expect(virtual2.stream.toList(), completion(isEmpty)); + expect(virtual2.sink.done, completes); + + virtual1.sink.close(); + }); + + test("closes the local virtual channel when it closes", () { + expect(virtual1.stream.toList(), completion(isEmpty)); + expect(virtual1.sink.done, completes); + + virtual1.sink.close(); + }); + + test("doesn't closes the local virtual channel when the stream " + "subscription is canceled", () { + virtual1.sink.done.then(expectAsync((_) {}, count: 0)); + virtual1.stream.listen((_) {}).cancel(); + + // Ensure that there's enough time for the channel to close if it's going + // to. + return pumpEventQueue(); + }); + + test("closes the underlying channel when it closes without any other " + "virtual channels", () async { + // First close the default channel so we can test the new channel as the + // last living virtual channel. + channel1.sink.close(); + + await channel2.stream.toList(); + expect(oneToTwo.done, completes); + expect(twoToOne.done, completes); + + virtual1.sink.close(); + }); + + test("doesn't close the underlying channel when it closes with other " + "virtual channels", () { + oneToTwo.done.then(expectAsync((_) {}, count: 0)); + twoToOne.done.then(expectAsync((_) {}, count: 0)); + + virtual1.sink.close(); + + // Ensure that there's enough time for the underlying channel to complete + // if it's going to. + return pumpEventQueue(); + }); + + test("doesn't conflict with a remote virtual channel", () { + var virtual3 = channel2.virtualChannel(); + var virtual4 = channel1.virtualChannel(virtual3.id); + + // This is an implementation detail, but we assert it here to make sure + // we're properly testing two channels with the same id. + expect(virtual1.id, equals(virtual3.id)); + + virtual2.stream.listen( + expectAsync((message) => expect(message, equals("hello")))); + virtual4.stream.listen( + expectAsync((message) => expect(message, equals("goodbye")))); + + virtual1.sink.add("hello"); + virtual3.sink.add("goodbye"); + }); + }); + + group("a remotely-created virtual channel", () { + var virtual1; + var virtual2; + setUp(() { + virtual1 = channel1.virtualChannel(); + virtual2 = channel2.virtualChannel(virtual1.id); + }); + + test("sends messages only to the other virtual channel", () { + var first = true; + virtual1.stream.listen(expectAsync((message) { + if (first) { + expect(message, equals("hello")); + first = false; + } else { + expect(message, equals("world")); + } + }, count: 2)); + + // No other virtual channels should receive the message. + for (var i = 0; i < 10; i++) { + var virtual = channel2.virtualChannel(channel1.virtualChannel().id); + virtual.stream.listen(expectAsync((_) {}, count: 0)); + } + channel1.stream.listen(expectAsync((_) {}, count: 0)); + + virtual2.sink.add("hello"); + virtual2.sink.add("world"); + }); + + test("closes the remote virtual channel when it closes", () { + expect(virtual1.stream.toList(), completion(isEmpty)); + expect(virtual1.sink.done, completes); + + virtual2.sink.close(); + }); + + test("closes the local virtual channel when it closes", () { + expect(virtual2.stream.toList(), completion(isEmpty)); + expect(virtual2.sink.done, completes); + + virtual2.sink.close(); + }); + + test("doesn't closes the local virtual channel when the stream " + "subscription is canceled", () { + virtual2.sink.done.then(expectAsync((_) {}, count: 0)); + virtual2.stream.listen((_) {}).cancel(); + + // Ensure that there's enough time for the channel to close if it's going + // to. + return pumpEventQueue(); + }); + + test("closes the underlying channel when it closes without any other " + "virtual channels", () async { + // First close the default channel so we can test the new channel as the + // last living virtual channel. + channel2.sink.close(); + + await channel1.stream.toList(); + expect(oneToTwo.done, completes); + expect(twoToOne.done, completes); + + virtual2.sink.close(); + }); + + test("doesn't close the underlying channel when it closes with other " + "virtual channels", () { + oneToTwo.done.then(expectAsync((_) {}, count: 0)); + twoToOne.done.then(expectAsync((_) {}, count: 0)); + + virtual2.sink.close(); + + // Ensure that there's enough time for the underlying channel to complete + // if it's going to. + return pumpEventQueue(); + }); + + test("doesn't allow another virtual channel with the same id", () { + expect(() => channel2.virtualChannel(virtual1.id), + throwsArgumentError); + }); + }); + + group("when the underlying stream", () { + var virtual1; + var virtual2; + setUp(() { + virtual1 = channel1.virtualChannel(); + virtual2 = channel2.virtualChannel(virtual1.id); + }); + + test("closes, all virtual channels close", () { + expect(channel1.stream.toList(), completion(isEmpty)); + expect(channel1.sink.done, completes); + expect(channel2.stream.toList(), completion(isEmpty)); + expect(channel2.sink.done, completes); + expect(virtual1.stream.toList(), completion(isEmpty)); + expect(virtual1.sink.done, completes); + expect(virtual2.stream.toList(), completion(isEmpty)); + expect(virtual2.sink.done, completes); + + oneToTwo.close(); + }); + + test("closes, no more virtual channels may be created", () { + expect(channel1.sink.done.then((_) => channel1.virtualChannel()), + throwsStateError); + expect(channel2.sink.done.then((_) => channel2.virtualChannel()), + throwsStateError); + + oneToTwo.close(); + }); + + test("emits an error, the error is sent only to the default channel", () { + channel1.stream.listen(expectAsync((_) {}, count: 0), + onError: expectAsync((error) => expect(error, equals("oh no")))); + virtual1.stream.listen(expectAsync((_) {}, count: 0), + onError: expectAsync((_) {}, count: 0)); + + twoToOne.addError("oh no"); + }); + }); +} diff --git a/pkgs/stream_channel/test/utils.dart b/pkgs/stream_channel/test/utils.dart new file mode 100644 index 000000000..130a3e12b --- /dev/null +++ b/pkgs/stream_channel/test/utils.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2016, 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'; + +/// Returns a [Future] that completes after pumping the event queue [times] +/// times. +/// +/// By default, this should pump the event queue enough times to allow any code +/// to run, as long as it's not waiting on some external event. +Future pumpEventQueue([int times=20]) { + if (times == 0) return new Future.value(); + // Use [new Future] future to allow microtask events to finish. The [new + // Future.value] constructor uses scheduleMicrotask itself and would therefore + // not wait for microtask callbacks that are scheduled after invoking this + // method. + return new Future(() => pumpEventQueue(times - 1)); +} + From 31deacaede3144d32b836a16f8a778f93f461356 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 21 Jan 2016 15:19:27 -0800 Subject: [PATCH 004/138] Add a DelegatingStreamChannel class. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1617483003 . --- .../lib/src/delegating_stream_channel.dart | 17 +++++++++++++++++ pkgs/stream_channel/lib/stream_channel.dart | 1 + 2 files changed, 18 insertions(+) create mode 100644 pkgs/stream_channel/lib/src/delegating_stream_channel.dart diff --git a/pkgs/stream_channel/lib/src/delegating_stream_channel.dart b/pkgs/stream_channel/lib/src/delegating_stream_channel.dart new file mode 100644 index 000000000..9d6ad90fd --- /dev/null +++ b/pkgs/stream_channel/lib/src/delegating_stream_channel.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2016, 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. + +/// A simple delegating wrapper around [StreamChannel]. +/// +/// Subclasses can override individual methods, or use this to expose only +/// [StreamChannel] methods. +class StreamChannelView extends StreamChannelMixin { + /// The inner channel to which methods are forwarded. + final StreamChannel _inner; + + Stream get stream => _inner.stream; + StreamSink get sink => _inner.sink; + + StreamChannelView(this._inner); +} diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index c4e28a0e3..a8c9a0903 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -4,6 +4,7 @@ import 'dart:async'; +export 'src/delegating_stream_channel.dart'; export 'src/multi_channel.dart'; /// An abstract class representing a two-way communication channel. From 9eea7761575466adb45a7c1300a3d8d9be558cbc Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 21 Jan 2016 15:29:15 -0800 Subject: [PATCH 005/138] Add clearer rules for implementations. This helps implementations know how to handle corner cases, and helps users know what behavior they can rely on. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1604903006 . --- pkgs/stream_channel/lib/stream_channel.dart | 47 ++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index a8c9a0903..fd7b09327 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -9,18 +9,55 @@ export 'src/multi_channel.dart'; /// An abstract class representing a two-way communication channel. /// -/// Subclasses are strongly encouraged to mix in or extend [StreamChannelMixin] -/// to get default implementations of the various instance methods. Adding new -/// methods to this interface will not be considered a breaking change if -/// implementations are also added to [StreamChannelMixin]. +/// Users should consider the [stream] emitting a "done" event to be the +/// canonical indicator that the channel has closed. If they wish to close the +/// channel, they should close the [sink]—canceling the stream subscription is +/// not sufficient. Protocol errors may be emitted through the stream or through +/// [Sink.done], depending on their underlying cause. Note that the sink may +/// silently drop events if the channel closes before [Sink.close] is called. +/// +/// Implementations are strongly encouraged to mix in or extend +/// [StreamChannelMixin] to get default implementations of the various instance +/// methods. Adding new methods to this interface will not be considered a +/// breaking change if implementations are also added to [StreamChannelMixin]. +/// +/// Implementations must provide the following guarantees: +/// +/// * The stream is single-subscription, and must follow all the guarantees of +/// single-subscription streams. +/// +/// * Closing the sink causes the stream to close before it emits any more +/// events. +/// +/// * After the stream closes, the sink is automatically closed. If this +/// happens, sink methods should silently drop their arguments until +/// [Sink.close] is called. +/// +/// * If the stream closes before it has a listener, the sink should silently +/// drop events if possible. +/// +/// * Canceling the stream's subscription has no effect on the sink. The channel +/// must still be able to respond to the other endpoint closing the channel +/// even after the subscription has been canceled. +/// +/// * The sink *either* forwards errors to the other endpoint *or* closes as +/// soon as an error is added and forwards that error to the [Sink.done] +/// future. +/// +/// These guarantees allow users to interact uniformly with all implementations, +/// and ensure that either endpoint closing the stream produces consistent +/// behavior. abstract class StreamChannel { - /// The stream that emits values from the other endpoint. + /// The single-subscription stream that emits values from the other endpoint. Stream get stream; /// The sink for sending values to the other endpoint. StreamSink get sink; /// Creates a new [StreamChannel] that communicates over [stream] and [sink]. + /// + /// Note that this stream/sink pair must provide the guarantees listed in the + /// [StreamChannel] documentation. factory StreamChannel(Stream stream, StreamSink sink) => new _StreamChannel(stream, sink); From 58ce9f4560f9141a401b4b4f77fe97cb6d63f0b6 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 25 Jan 2016 15:09:57 -0800 Subject: [PATCH 006/138] Fix DelegatingStreamChannel. I apparently forgot to add imports and named it the wrong thing. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1615043004 . --- .../stream_channel/lib/src/delegating_stream_channel.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/lib/src/delegating_stream_channel.dart b/pkgs/stream_channel/lib/src/delegating_stream_channel.dart index 9d6ad90fd..4434cf62a 100644 --- a/pkgs/stream_channel/lib/src/delegating_stream_channel.dart +++ b/pkgs/stream_channel/lib/src/delegating_stream_channel.dart @@ -2,16 +2,20 @@ // 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 '../stream_channel.dart'; + /// A simple delegating wrapper around [StreamChannel]. /// /// Subclasses can override individual methods, or use this to expose only /// [StreamChannel] methods. -class StreamChannelView extends StreamChannelMixin { +class DelegatingStreamChannel extends StreamChannelMixin { /// The inner channel to which methods are forwarded. final StreamChannel _inner; Stream get stream => _inner.stream; StreamSink get sink => _inner.sink; - StreamChannelView(this._inner); + DelegatingStreamChannel(this._inner); } From 8c8923d24a14f1cb4103b07d96271cca957874f9 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 26 Jan 2016 15:25:07 -0800 Subject: [PATCH 007/138] Add a StreamChannelCompleter class. This is by analogy with StreamCompleter and StreamSinkCompleter in the async package, and is in fact implemented using them. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1631103002 . --- .../lib/src/stream_channel_completer.dart | 77 +++++++++++ pkgs/stream_channel/lib/stream_channel.dart | 1 + pkgs/stream_channel/pubspec.yaml | 2 + .../test/stream_channel_completer_test.dart | 124 ++++++++++++++++++ 4 files changed, 204 insertions(+) create mode 100644 pkgs/stream_channel/lib/src/stream_channel_completer.dart create mode 100644 pkgs/stream_channel/test/stream_channel_completer_test.dart diff --git a/pkgs/stream_channel/lib/src/stream_channel_completer.dart b/pkgs/stream_channel/lib/src/stream_channel_completer.dart new file mode 100644 index 000000000..d15adcf94 --- /dev/null +++ b/pkgs/stream_channel/lib/src/stream_channel_completer.dart @@ -0,0 +1,77 @@ +// Copyright (c) 2016, 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 'package:async/async.dart'; + +import '../stream_channel.dart'; + +/// A [channel] where the source and destination are provided later. +/// +/// The [channel] is a normal channel that can be listened to and that events +/// can be added to immediately, but until [setChannel] is called it won't emit +/// any events and all events added to it will be buffered. +class StreamChannelCompleter { + /// The completer for this channel's stream. + final _streamCompleter = new StreamCompleter(); + + /// The completer for this channel's sink. + final _sinkCompleter = new StreamSinkCompleter(); + + /// The channel for this completer. + StreamChannel get channel => _channel; + StreamChannel _channel; + + /// Whether [setChannel] has been called. + bool _set = false; + + /// Convert a `Future` to a `StreamChannel`. + /// + /// This creates a channel using a channel completer, and sets the source + /// channel to the result of the future when the future completes. + /// + /// If the future completes with an error, the returned channel's stream will + /// instead contain just that error. The sink will silently discard all + /// events. + static StreamChannel fromFuture(Future channelFuture) { + var completer = new StreamChannelCompleter(); + channelFuture.then(completer.setChannel, onError: completer.setError); + return completer.channel; + } + + StreamChannelCompleter() { + _channel = new StreamChannel( + _streamCompleter.stream, _sinkCompleter.sink); + } + + /// Set a channel as the source and destination for [channel]. + /// + /// A channel may be set at most once. + /// + /// Either [setChannel] or [setError] may be called at most once. Trying to + /// call either of them again will fail. + void setChannel(StreamChannel channel) { + if (_set) throw new StateError("The channel has already been set."); + _set = true; + + _streamCompleter.setSourceStream(channel.stream); + _sinkCompleter.setDestinationSink(channel.sink); + } + + /// Indicates that there was an error connecting the channel. + /// + /// This makes the stream emit [error] and close. It makes the sink discard + /// all its events. + /// + /// Either [setChannel] or [setError] may be called at most once. Trying to + /// call either of them again will fail. + void setError(error, [StackTrace stackTrace]) { + if (_set) throw new StateError("The channel has already been set."); + _set = true; + + _streamCompleter.setError(error, stackTrace); + _sinkCompleter.setDestinationSink(new NullStreamSink()); + } +} diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index fd7b09327..4b3c659ae 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -6,6 +6,7 @@ import 'dart:async'; export 'src/delegating_stream_channel.dart'; export 'src/multi_channel.dart'; +export 'src/stream_channel_completer.dart'; /// An abstract class representing a two-way communication channel. /// diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 76f22b7da..a0d8d2200 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -5,5 +5,7 @@ author: Dart Team homepage: https://github.com/dart-lang/stream_channel environment: sdk: '>=1.0.0 <2.0.0' +dependencies: + async: '^1.8.0' dev_dependencies: test: '^0.12.0' diff --git a/pkgs/stream_channel/test/stream_channel_completer_test.dart b/pkgs/stream_channel/test/stream_channel_completer_test.dart new file mode 100644 index 000000000..1ee40a5ca --- /dev/null +++ b/pkgs/stream_channel/test/stream_channel_completer_test.dart @@ -0,0 +1,124 @@ +// Copyright (c) 2016, 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 'package:stream_channel/stream_channel.dart'; +import 'package:test/test.dart'; + +import 'utils.dart'; + +void main() { + var completer; + var streamController; + var sinkController; + var innerChannel; + setUp(() { + completer = new StreamChannelCompleter(); + streamController = new StreamController(); + sinkController = new StreamController(); + innerChannel = new StreamChannel( + streamController.stream, sinkController.sink); + }); + + group("when a channel is set before accessing", () { + test("forwards events through the stream", () { + completer.setChannel(innerChannel); + expect(completer.channel.stream.toList(), completion(equals([1, 2, 3]))); + + streamController.add(1); + streamController.add(2); + streamController.add(3); + streamController.close(); + }); + + test("forwards events through the sink", () { + completer.setChannel(innerChannel); + expect(sinkController.stream.toList(), completion(equals([1, 2, 3]))); + + completer.channel.sink.add(1); + completer.channel.sink.add(2); + completer.channel.sink.add(3); + completer.channel.sink.close(); + }); + + test("forwards an error through the stream", () { + completer.setError("oh no"); + expect(completer.channel.stream.first, throwsA("oh no")); + }); + + test("drops sink events", () { + completer.setError("oh no"); + expect(completer.channel.sink.done, completes); + completer.channel.sink.add(1); + completer.channel.sink.addError("oh no"); + }); + }); + + group("when a channel is set after accessing", () { + test("forwards events through the stream", () async { + expect(completer.channel.stream.toList(), completion(equals([1, 2, 3]))); + await pumpEventQueue(); + + completer.setChannel(innerChannel); + streamController.add(1); + streamController.add(2); + streamController.add(3); + streamController.close(); + }); + + test("forwards events through the sink", () async { + completer.channel.sink.add(1); + completer.channel.sink.add(2); + completer.channel.sink.add(3); + completer.channel.sink.close(); + await pumpEventQueue(); + + completer.setChannel(innerChannel); + expect(sinkController.stream.toList(), completion(equals([1, 2, 3]))); + }); + + test("forwards an error through the stream", () async { + expect(completer.channel.stream.first, throwsA("oh no")); + await pumpEventQueue(); + + completer.setError("oh no"); + }); + + test("drops sink events", () async { + expect(completer.channel.sink.done, completes); + completer.channel.sink.add(1); + completer.channel.sink.addError("oh no"); + await pumpEventQueue(); + + completer.setError("oh no"); + }); + }); + + group("forFuture", () { + test("forwards a StreamChannel", () { + var channel = StreamChannelCompleter.fromFuture( + new Future.value(innerChannel)); + channel.sink.add(1); + channel.sink.close(); + streamController.sink.add(2); + streamController.sink.close(); + + expect(sinkController.stream.toList(), completion(equals([1]))); + expect(channel.stream.toList(), completion(equals([2]))); + }); + + test("forwards an error", () { + var channel = StreamChannelCompleter.fromFuture( + new Future.error("oh no")); + expect(channel.stream.toList(), throwsA("oh no")); + }); + }); + + test("doesn't allow the channel to be set multiple times", () { + completer.setChannel(innerChannel); + expect(() => completer.setChannel(innerChannel), throwsStateError); + expect(() => completer.setChannel(innerChannel), throwsStateError); + }); +} From 6c2fd24f90e5556c78207390ef5bb1f5289d36c8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 26 Jan 2016 15:26:25 -0800 Subject: [PATCH 008/138] Add an IsolateChannel class. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1635873002 . --- .../lib/src/isolate_channel.dart | 146 ++++++++++++++++++ pkgs/stream_channel/lib/stream_channel.dart | 1 + pkgs/stream_channel/pubspec.yaml | 2 +- .../test/isolate_channel_test.dart | 126 +++++++++++++++ 4 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 pkgs/stream_channel/lib/src/isolate_channel.dart create mode 100644 pkgs/stream_channel/test/isolate_channel_test.dart diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart new file mode 100644 index 000000000..c6645438d --- /dev/null +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -0,0 +1,146 @@ +// Copyright (c) 2016, 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:isolate'; + +import '../stream_channel.dart'; + +/// A [StreamChannel] that communicates over a [ReceivePort]/[SendPort] pair, +/// presumably with another isolate. +/// +/// The remote endpoint doesn't necessarily need to be running an +/// [IsolateChannel]. This can be used with any two ports, although the +/// [StreamChannel] semantics mean that this class will treat them as being +/// paired (for example, closing the [sink] will cause the [stream] to stop +/// emitting events). +/// +/// The underlying isolate ports have no notion of closing connections. This +/// means that [stream] won't close unless [sink] is closed, and that closing +/// [sink] won't cause the remote endpoint to close. Users should take care to +/// ensure that they always close the [sink] of every [IsolateChannel] they use +/// to avoid leaving dangling [ReceivePort]s. +class IsolateChannel extends StreamChannelMixin { + /// The port that produces incoming messages. + /// + /// This is wrapped in a [StreamView] to produce [stream]. + final ReceivePort _receivePort; + + /// The port that sends outgoing messages. + final SendPort _sendPort; + + Stream get stream => _stream; + final Stream _stream; + + StreamSink get sink => _sink; + _SendPortSink _sink; + + /// Creates a stream channel that receives messages from [receivePort] and + /// sends them over [sendPort]. + IsolateChannel(ReceivePort receivePort, this._sendPort) + : _receivePort = receivePort, + _stream = new StreamView(receivePort) { + _sink = new _SendPortSink(this); + } +} + +/// The sink for [IsolateChannel]. +/// +/// [SendPort] doesn't natively implement any sink API, so this adds that API as +/// a wrapper. Closing this just closes the [ReceivePort]. +class _SendPortSink implements StreamSink { + /// The channel that this sink is for. + final IsolateChannel _channel; + + Future get done => _doneCompleter.future; + final _doneCompleter = new Completer(); + + /// Whether [done] has been completed. + /// + /// This is distinct from [_closed] because [done] can complete with an error + /// without the user explicitly calling [close]. + bool get _isDone => _doneCompleter.isCompleted; + + /// Whether the user has called [close]. + bool _closed = false; + + /// Whether we're currently adding a stream with [addStream]. + bool _inAddStream = false; + + _SendPortSink(this._channel); + + void add(T data) { + if (_closed) throw new StateError("Cannot add event after closing."); + if (_inAddStream) { + throw new StateError("Cannot add event while adding stream."); + } + if (_isDone) return; + + _add(data); + } + + /// A helper for [add] that doesn't check for [StateError]s. + /// + /// This is called from [addStream], so it shouldn't check [_inAddStream]. + void _add(T data) { + _channel._sendPort.send(data); + } + + void addError(error, [StackTrace stackTrace]) { + if (_closed) throw new StateError("Cannot add event after closing."); + if (_inAddStream) { + throw new StateError("Cannot add event while adding stream."); + } + + _close(error, stackTrace); + } + + Future close() { + if (_inAddStream) { + throw new StateError("Cannot close sink while adding stream."); + } + + _closed = true; + return _close(); + } + + /// A helper for [close] that doesn't check for [StateError]s. + /// + /// This is called from [addStream], so it shouldn't check [_inAddStream]. It + /// also forwards [error] and [stackTrace] to [done] if they're passed. + Future _close([error, StackTrace stackTrace]) { + if (_isDone) return done; + + _channel._receivePort.close(); + + if (error != null) { + _doneCompleter.completeError(error, stackTrace); + } else { + _doneCompleter.complete(); + } + + return done; + } + + Future addStream(Stream stream) { + if (_closed) throw new StateError("Cannot add stream after closing."); + if (_inAddStream) { + throw new StateError("Cannot add stream while adding stream."); + } + if (_isDone) return; + + _inAddStream = true; + var completer = new Completer.sync(); + stream.listen(_add, + onError: (error, stackTrace) { + _close(error, stackTrace); + completer.complete(); + }, + onDone: completer.complete, + cancelOnError: true); + return completer.future.then((_) { + _inAddStream = false; + }); + } +} diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index 4b3c659ae..ff36ec78b 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -5,6 +5,7 @@ import 'dart:async'; export 'src/delegating_stream_channel.dart'; +export 'src/isolate_channel.dart'; export 'src/multi_channel.dart'; export 'src/stream_channel_completer.dart'; diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index a0d8d2200..97057abe0 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -4,7 +4,7 @@ description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel environment: - sdk: '>=1.0.0 <2.0.0' + sdk: '>=1.8.0 <2.0.0' dependencies: async: '^1.8.0' dev_dependencies: diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart new file mode 100644 index 000000000..9e4fddc95 --- /dev/null +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -0,0 +1,126 @@ +// Copyright (c) 2016, 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:isolate'; + +import 'package:stream_channel/stream_channel.dart'; +import 'package:test/test.dart'; + +import 'utils.dart'; + +void main() { + var receivePort; + var sendPort; + var channel; + setUp(() { + receivePort = new ReceivePort(); + var receivePortForSend = new ReceivePort(); + sendPort = receivePortForSend.sendPort; + channel = new IsolateChannel(receivePortForSend, receivePort.sendPort); + }); + + tearDown(() { + receivePort.close(); + channel.sink.close(); + }); + + test("the channel can send messages", () { + channel.sink.add(1); + channel.sink.add(2); + channel.sink.add(3); + + expect(receivePort.take(3).toList(), completion(equals([1, 2, 3]))); + }); + + test("the channel can receive messages", () { + sendPort.send(1); + sendPort.send(2); + sendPort.send(3); + + expect(channel.stream.take(3).toList(), completion(equals([1, 2, 3]))); + }); + + test("events can't be added to an explicitly-closed sink", () { + expect(channel.sink.close(), completes); + expect(() => channel.sink.add(1), throwsStateError); + expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addStream(new Stream.fromIterable([])), + throwsStateError); + }); + + test("events can't be added while a stream is being added", () { + var controller = new StreamController(); + channel.sink.addStream(controller.stream); + + expect(() => channel.sink.add(1), throwsStateError); + expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addStream(new Stream.fromIterable([])), + throwsStateError); + expect(() => channel.sink.close(), throwsStateError); + + controller.close(); + }); + + group("stream channel rules", () { + test("closing the sink causes the stream to close before it emits any more " + "events", () { + sendPort.send(1); + sendPort.send(2); + sendPort.send(3); + sendPort.send(4); + sendPort.send(5); + + channel.stream.listen(expectAsync((message) { + expect(message, equals(1)); + channel.sink.close(); + }, count: 1)); + }); + + test("cancelling the stream's subscription has no effect on the sink", + () async { + channel.stream.listen(null).cancel(); + await pumpEventQueue(); + + channel.sink.add(1); + channel.sink.add(2); + channel.sink.add(3); + expect(receivePort.take(3).toList(), completion(equals([1, 2, 3]))); + }); + + test("the sink closes as soon as an error is added", () async { + channel.sink.addError("oh no"); + channel.sink.add(1); + expect(channel.sink.done, throwsA("oh no")); + + // Since the sink is closed, the stream should also be closed. + expect(channel.stream.isEmpty, completion(isTrue)); + + // The other end shouldn't receive the next event, since the sink was + // closed. Pump the event queue to give it a chance to. + receivePort.listen(expectAsync((_) {}, count: 0)); + await pumpEventQueue(); + }); + + test("the sink closes as soon as an error is added via addStream", + () async { + var canceled = false; + var controller = new StreamController(onCancel: () { + canceled = true; + }); + + // This future shouldn't get the error, because it's sent to [Sink.done]. + expect(channel.sink.addStream(controller.stream), completes); + + controller.addError("oh no"); + expect(channel.sink.done, throwsA("oh no")); + await pumpEventQueue(); + expect(canceled, isTrue); + + // Even though the sink is closed, this shouldn't throw an error because + // the user didn't explicitly close it. + channel.sink.add(1); + }); + }); +} From 1a2eb425eba28db3bd20e191c6eb7a1769550bd8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 26 Jan 2016 15:28:31 -0800 Subject: [PATCH 009/138] Add StreamChannel.transform(). R=rnystrom@google.com Review URL: https://codereview.chromium.org//1639643002 . --- pkgs/stream_channel/lib/stream_channel.dart | 18 ++++++ .../test/stream_channel_test.dart | 58 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 pkgs/stream_channel/test/stream_channel_test.dart diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index ff36ec78b..2885e2d23 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -3,6 +3,9 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; + +import 'package:async/async.dart'; export 'src/delegating_stream_channel.dart'; export 'src/isolate_channel.dart'; @@ -66,6 +69,13 @@ abstract class StreamChannel { /// Connects [this] to [other], so that any values emitted by either are sent /// directly to the other. void pipe(StreamChannel other); + + /// Transforms [this] using [codec]. + /// + /// This returns a stream channel that encodes all input using [Codec.encoder] + /// before passing it to this channel's [sink], and decodes all output from + /// this channel's [stream] using [Codec.decoder]. + StreamChannel transform(Codec codec); } /// An implementation of [StreamChannel] that simply takes a stream and a sink @@ -87,4 +97,12 @@ abstract class StreamChannelMixin implements StreamChannel { stream.pipe(other.sink); other.stream.pipe(sink); } + + StreamChannel transform(Codec codec) { + var sinkTransformer = + new StreamSinkTransformer.fromStreamTransformer(codec.encoder); + return new _StreamChannel( + stream.transform(codec.decoder), + sinkTransformer.bind(sink)); + } } diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart new file mode 100644 index 000000000..30a7db4fa --- /dev/null +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -0,0 +1,58 @@ +// Copyright (c) 2016, 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 'dart:isolate'; + +import 'package:stream_channel/stream_channel.dart'; +import 'package:test/test.dart'; + +import 'utils.dart'; + +void main() { + var streamController; + var sinkController; + var channel; + setUp(() { + streamController = new StreamController(); + sinkController = new StreamController(); + channel = new StreamChannel( + streamController.stream, sinkController.sink); + }); + + test("pipe() pipes data from each channel's stream into the other's sink", + () { + var otherStreamController = new StreamController(); + var otherSinkController = new StreamController(); + var otherChannel = new StreamChannel( + otherStreamController.stream, otherSinkController.sink); + channel.pipe(otherChannel); + + streamController.add(1); + streamController.add(2); + streamController.add(3); + streamController.close(); + expect(otherSinkController.stream.toList(), completion(equals([1, 2, 3]))); + + otherStreamController.add(4); + otherStreamController.add(5); + otherStreamController.add(6); + otherStreamController.close(); + expect(sinkController.stream.toList(), completion(equals([4, 5, 6]))); + }); + + test("transform() transforms the channel", () { + var transformed = channel.transform(UTF8); + + streamController.add([102, 111, 111, 98, 97, 114]); + streamController.close(); + expect(transformed.stream.toList(), completion(equals(["foobar"]))); + + transformed.sink.add("fblthp"); + transformed.sink.close(); + expect(sinkController.stream.toList(), + completion(equals([[102, 98, 108, 116, 104, 112]]))); + }); +} From 8a594ea113d24950f2d6723b8f8034cb3bd81779 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 27 Jan 2016 15:24:46 -0800 Subject: [PATCH 010/138] Add StreamChannelTransformer. This makes StreamChannel.transform() take a StreamChannelTransformer rather than a codec. This is better, since a codec is explicitly intended to convert chunked data, while transformers are more general. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1632903004 . --- .../lib/src/isolate_channel.dart | 2 +- .../lib/src/stream_channel_transformer.dart | 52 +++++++++++++++++++ pkgs/stream_channel/lib/stream_channel.dart | 21 +++----- .../test/stream_channel_test.dart | 3 +- 4 files changed, 62 insertions(+), 16 deletions(-) create mode 100644 pkgs/stream_channel/lib/src/stream_channel_transformer.dart diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index c6645438d..46375c986 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -128,7 +128,7 @@ class _SendPortSink implements StreamSink { if (_inAddStream) { throw new StateError("Cannot add stream while adding stream."); } - if (_isDone) return; + if (_isDone) return new Future.value(); _inAddStream = true; var completer = new Completer.sync(); diff --git a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart new file mode 100644 index 000000000..be032c60d --- /dev/null +++ b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 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:async/async.dart'; + +import '../stream_channel.dart'; + +/// A [StreamChannelTransformer] transforms the events being passed to and +/// emitted by a [StreamChannel]. +/// +/// This works on the same principle as [StreamTransformer] and +/// [StreamSinkTransformer]. Each transformer defines a [bind] method that takes +/// in the original [StreamChannel] and returns the transformed version. +/// +/// Transformers must be able to have `bind` called multiple times. +class StreamChannelTransformer { + /// The transformer to use on the channel's stream. + final StreamTransformer _streamTransformer; + + /// The transformer to use on the channel's sink. + final StreamSinkTransformer _sinkTransformer; + + /// Creates a [StreamChannelTransformer] from existing stream and sink + /// transformers. + const StreamChannelTransformer( + this._streamTransformer, this._sinkTransformer); + + /// Creates a [StreamChannelTransformer] from a codec's encoder and decoder. + /// + /// All input to the inner channel's sink is encoded using [Codec.encoder], + /// and all output from its stream is decoded using [Codec.decoder]. + StreamChannelTransformer.fromCodec(Codec codec) + : this( + codec.decoder, + new StreamSinkTransformer.fromStreamTransformer(codec.encoder)); + + /// Transforms the events sent to and emitted by [channel]. + /// + /// Creates a new channel. When events are passed to the returned channel's + /// sink, the transformer will transform them and pass the transformed + /// versions to `channel.sink`. When events are emitted from the + /// `channel.straem`, the transformer will transform them and pass the + /// transformed versions to the returned channel's stream. + StreamChannel bind(StreamChannel channel) => + new StreamChannel( + channel.stream.transform(_streamTransformer), + _sinkTransformer.bind(channel.sink)); +} diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index 2885e2d23..e7fb055aa 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -3,14 +3,14 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; -import 'dart:convert'; -import 'package:async/async.dart'; +import 'src/stream_channel_transformer.dart'; export 'src/delegating_stream_channel.dart'; export 'src/isolate_channel.dart'; export 'src/multi_channel.dart'; export 'src/stream_channel_completer.dart'; +export 'src/stream_channel_transformer.dart'; /// An abstract class representing a two-way communication channel. /// @@ -70,12 +70,10 @@ abstract class StreamChannel { /// directly to the other. void pipe(StreamChannel other); - /// Transforms [this] using [codec]. + /// Transforms [this] using [transformer]. /// - /// This returns a stream channel that encodes all input using [Codec.encoder] - /// before passing it to this channel's [sink], and decodes all output from - /// this channel's [stream] using [Codec.decoder]. - StreamChannel transform(Codec codec); + /// This is identical to calling `transformer.bind(channel)`. + StreamChannel transform(StreamChannelTransformer transformer); } /// An implementation of [StreamChannel] that simply takes a stream and a sink @@ -98,11 +96,6 @@ abstract class StreamChannelMixin implements StreamChannel { other.stream.pipe(sink); } - StreamChannel transform(Codec codec) { - var sinkTransformer = - new StreamSinkTransformer.fromStreamTransformer(codec.encoder); - return new _StreamChannel( - stream.transform(codec.decoder), - sinkTransformer.bind(sink)); - } + StreamChannel transform(StreamChannelTransformer transformer) => + transformer.bind(this); } diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index 30a7db4fa..5f006c39c 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -44,7 +44,8 @@ void main() { }); test("transform() transforms the channel", () { - var transformed = channel.transform(UTF8); + var transformed = channel.transform( + new StreamChannelTransformer.fromCodec(UTF8)); streamController.add([102, 111, 111, 98, 97, 114]); streamController.close(); From 83b986e85c009e5dfd42c11e64381ba062cf0bd4 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 27 Jan 2016 15:28:46 -0800 Subject: [PATCH 011/138] Add IsolateChannel.connect* constructors. These constructors use a lightweight protocol to establish a two-way connection over a previously-one-way connection. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1638183002 . --- .../lib/src/isolate_channel.dart | 172 +++++++----------- .../src/isolate_channel/send_port_sink.dart | 111 +++++++++++ pkgs/stream_channel/pubspec.yaml | 1 + .../test/isolate_channel_test.dart | 35 ++++ 4 files changed, 208 insertions(+), 111 deletions(-) create mode 100644 pkgs/stream_channel/lib/src/isolate_channel/send_port_sink.dart diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index 46375c986..a466d87f3 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -5,7 +5,11 @@ import 'dart:async'; import 'dart:isolate'; +import 'package:async/async.dart'; +import 'package:stack_trace/stack_trace.dart'; + import '../stream_channel.dart'; +import 'isolate_channel/send_port_sink.dart'; /// A [StreamChannel] that communicates over a [ReceivePort]/[SendPort] pair, /// presumably with another isolate. @@ -22,125 +26,71 @@ import '../stream_channel.dart'; /// ensure that they always close the [sink] of every [IsolateChannel] they use /// to avoid leaving dangling [ReceivePort]s. class IsolateChannel extends StreamChannelMixin { - /// The port that produces incoming messages. - /// - /// This is wrapped in a [StreamView] to produce [stream]. - final ReceivePort _receivePort; - - /// The port that sends outgoing messages. - final SendPort _sendPort; - - Stream get stream => _stream; - final Stream _stream; - - StreamSink get sink => _sink; - _SendPortSink _sink; + final Stream stream; + final StreamSink sink; - /// Creates a stream channel that receives messages from [receivePort] and - /// sends them over [sendPort]. - IsolateChannel(ReceivePort receivePort, this._sendPort) - : _receivePort = receivePort, - _stream = new StreamView(receivePort) { - _sink = new _SendPortSink(this); - } -} - -/// The sink for [IsolateChannel]. -/// -/// [SendPort] doesn't natively implement any sink API, so this adds that API as -/// a wrapper. Closing this just closes the [ReceivePort]. -class _SendPortSink implements StreamSink { - /// The channel that this sink is for. - final IsolateChannel _channel; - - Future get done => _doneCompleter.future; - final _doneCompleter = new Completer(); - - /// Whether [done] has been completed. + /// Connects to a remote channel that was created with + /// [IsolateChannel.connectSend]. /// - /// This is distinct from [_closed] because [done] can complete with an error - /// without the user explicitly calling [close]. - bool get _isDone => _doneCompleter.isCompleted; - - /// Whether the user has called [close]. - bool _closed = false; - - /// Whether we're currently adding a stream with [addStream]. - bool _inAddStream = false; - - _SendPortSink(this._channel); - - void add(T data) { - if (_closed) throw new StateError("Cannot add event after closing."); - if (_inAddStream) { - throw new StateError("Cannot add event while adding stream."); - } - if (_isDone) return; - - _add(data); - } - - /// A helper for [add] that doesn't check for [StateError]s. + /// These constructors establish a connection using only a single + /// [SendPort]/[ReceivePort] pair, as long as each side uses one of the + /// connect constructors. /// - /// This is called from [addStream], so it shouldn't check [_inAddStream]. - void _add(T data) { - _channel._sendPort.send(data); - } - - void addError(error, [StackTrace stackTrace]) { - if (_closed) throw new StateError("Cannot add event after closing."); - if (_inAddStream) { - throw new StateError("Cannot add event while adding stream."); - } - - _close(error, stackTrace); - } - - Future close() { - if (_inAddStream) { - throw new StateError("Cannot close sink while adding stream."); - } + /// The connection protocol is guaranteed to remain compatible across versions + /// at least until the next major version release. If the protocol is + /// violated, the resulting channel will emit a single value on its stream and + /// then close. + factory IsolateChannel.connectReceive(ReceivePort receivePort) { + // We can't use a [StreamChannelCompleter] here because we need the return + // value to be an [IsolateChannel]. + var streamCompleter = new StreamCompleter(); + var sinkCompleter = new StreamSinkCompleter(); + var channel = new IsolateChannel._( + streamCompleter.stream, sinkCompleter.sink); + + // The first message across the ReceivePort should be a SendPort pointing to + // the remote end. If it's not, we'll make the stream emit an error + // complaining. + var subscription; + subscription = receivePort.listen((message) { + if (message is SendPort) { + streamCompleter.setSourceStream( + new SubscriptionStream(subscription)); + sinkCompleter.setDestinationSink( + new SendPortSink(receivePort, message)); + return; + } + + streamCompleter.setError( + new StateError('Unexpected Isolate response "$message".'), + new Trace.current()); + sinkCompleter.setDestinationSink(new NullStreamSink()); + subscription.cancel(); + }); - _closed = true; - return _close(); + return channel; } - /// A helper for [close] that doesn't check for [StateError]s. + /// Connects to a remote channel that was created with + /// [IsolateChannel.connectReceive]. /// - /// This is called from [addStream], so it shouldn't check [_inAddStream]. It - /// also forwards [error] and [stackTrace] to [done] if they're passed. - Future _close([error, StackTrace stackTrace]) { - if (_isDone) return done; - - _channel._receivePort.close(); - - if (error != null) { - _doneCompleter.completeError(error, stackTrace); - } else { - _doneCompleter.complete(); - } - - return done; + /// These constructors establish a connection using only a single + /// [SendPort]/[ReceivePort] pair, as long as each side uses one of the + /// connect constructors. + /// + /// The connection protocol is guaranteed to remain compatible across versions + /// at least until the next major version release. + factory IsolateChannel.connectSend(SendPort sendPort) { + var receivePort = new ReceivePort(); + sendPort.send(receivePort.sendPort); + return new IsolateChannel(receivePort, sendPort); } - Future addStream(Stream stream) { - if (_closed) throw new StateError("Cannot add stream after closing."); - if (_inAddStream) { - throw new StateError("Cannot add stream while adding stream."); - } - if (_isDone) return new Future.value(); + /// Creates a stream channel that receives messages from [receivePort] and + /// sends them over [sendPort]. + IsolateChannel(ReceivePort receivePort, SendPort sendPort) + : stream = new StreamView(receivePort), + sink = new SendPortSink(receivePort, sendPort); - _inAddStream = true; - var completer = new Completer.sync(); - stream.listen(_add, - onError: (error, stackTrace) { - _close(error, stackTrace); - completer.complete(); - }, - onDone: completer.complete, - cancelOnError: true); - return completer.future.then((_) { - _inAddStream = false; - }); - } + IsolateChannel._(this.stream, this.sink); } diff --git a/pkgs/stream_channel/lib/src/isolate_channel/send_port_sink.dart b/pkgs/stream_channel/lib/src/isolate_channel/send_port_sink.dart new file mode 100644 index 000000000..d98f1da65 --- /dev/null +++ b/pkgs/stream_channel/lib/src/isolate_channel/send_port_sink.dart @@ -0,0 +1,111 @@ +// Copyright (c) 2016, 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:isolate'; + +/// The sink for [IsolateChannel]. +/// +/// [SendPort] doesn't natively implement any sink API, so this adds that API as +/// a wrapper. Closing this just closes the [ReceivePort]. +class SendPortSink implements StreamSink { + /// The port that produces incoming messages. + /// + /// This is wrapped in a [StreamView] to produce [stream]. + final ReceivePort _receivePort; + + /// The port that sends outgoing messages. + final SendPort _sendPort; + + Future get done => _doneCompleter.future; + final _doneCompleter = new Completer(); + + /// Whether [done] has been completed. + /// + /// This is distinct from [_closed] because [done] can complete with an error + /// without the user explicitly calling [close]. + bool get _isDone => _doneCompleter.isCompleted; + + /// Whether the user has called [close]. + bool _closed = false; + + /// Whether we're currently adding a stream with [addStream]. + bool _inAddStream = false; + + SendPortSink(this._receivePort, this._sendPort); + + void add(T data) { + if (_closed) throw new StateError("Cannot add event after closing."); + if (_inAddStream) { + throw new StateError("Cannot add event while adding stream."); + } + if (_isDone) return; + + _add(data); + } + + /// A helper for [add] that doesn't check for [StateError]s. + /// + /// This is called from [addStream], so it shouldn't check [_inAddStream]. + void _add(T data) { + _sendPort.send(data); + } + + void addError(error, [StackTrace stackTrace]) { + if (_closed) throw new StateError("Cannot add event after closing."); + if (_inAddStream) { + throw new StateError("Cannot add event while adding stream."); + } + + _close(error, stackTrace); + } + + Future close() { + if (_inAddStream) { + throw new StateError("Cannot close sink while adding stream."); + } + + _closed = true; + return _close(); + } + + /// A helper for [close] that doesn't check for [StateError]s. + /// + /// This is called from [addStream], so it shouldn't check [_inAddStream]. It + /// also forwards [error] and [stackTrace] to [done] if they're passed. + Future _close([error, StackTrace stackTrace]) { + if (_isDone) return done; + + _receivePort.close(); + + if (error != null) { + _doneCompleter.completeError(error, stackTrace); + } else { + _doneCompleter.complete(); + } + + return done; + } + + Future addStream(Stream stream) { + if (_closed) throw new StateError("Cannot add stream after closing."); + if (_inAddStream) { + throw new StateError("Cannot add stream while adding stream."); + } + if (_isDone) return new Future.value(); + + _inAddStream = true; + var completer = new Completer.sync(); + stream.listen(_add, + onError: (error, stackTrace) { + _close(error, stackTrace); + completer.complete(); + }, + onDone: completer.complete, + cancelOnError: true); + return completer.future.then((_) { + _inAddStream = false; + }); + } +} diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 97057abe0..a8e26cd17 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -7,5 +7,6 @@ environment: sdk: '>=1.8.0 <2.0.0' dependencies: async: '^1.8.0' + stack_trace: '^1.0.0' dev_dependencies: test: '^0.12.0' diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index 9e4fddc95..fa4d8d532 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -123,4 +123,39 @@ void main() { channel.sink.add(1); }); }); + + group("connect constructors", () { + var connectPort; + setUp(() { + connectPort = new ReceivePort(); + }); + + tearDown(() { + connectPort.close(); + }); + + test("create a connected pair of channels", () { + var channel1 = new IsolateChannel.connectReceive(connectPort); + var channel2 = new IsolateChannel.connectSend(connectPort.sendPort); + + channel1.sink.add(1); + channel1.sink.add(2); + channel1.sink.add(3); + expect(channel2.stream.take(3).toList(), completion(equals([1, 2, 3]))); + + channel2.sink.add(4); + channel2.sink.add(5); + channel2.sink.add(6); + expect(channel1.stream.take(3).toList(), completion(equals([4, 5, 6]))); + }); + + test("the receiving channel produces an error if it gets the wrong message", + () { + var connectedChannel = new IsolateChannel.connectReceive(connectPort); + connectPort.sendPort.send("wrong value"); + + expect(connectedChannel.stream.toList(), throwsStateError); + expect(connectedChannel.sink.done, completes); + }); + }); } From 58a473046d65f1ca07349c933a071de2df8c11a6 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 28 Jan 2016 12:00:25 -0800 Subject: [PATCH 012/138] Add a document-by-document JSON transformer. This makes it easy to send JSON over WebSocket connections, for example. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1643843002 . --- .../lib/src/json_document_transformer.dart | 41 +++++++++++++++ pkgs/stream_channel/lib/stream_channel.dart | 1 + .../test/json_document_transformer_test.dart | 50 +++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 pkgs/stream_channel/lib/src/json_document_transformer.dart create mode 100644 pkgs/stream_channel/test/json_document_transformer_test.dart diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart new file mode 100644 index 000000000..8d8dcce23 --- /dev/null +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 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:convert'; + +import 'package:async/async.dart'; + +import '../stream_channel.dart'; +import 'stream_channel_transformer.dart'; + +/// The canonical instance of [JsonDocumentTransformer]. +final jsonDocument = new JsonDocumentTransformer(); + +/// A [StreamChannelTransformer] that transforms JSON documents—strings that +/// contain individual objects encoded as JSON—into decoded Dart objects. +/// +/// This decodes JSON that's emitted by the transformed channel's stream, and +/// encodes objects so that JSON is passed to the transformed channel's sink. +class JsonDocumentTransformer + implements StreamChannelTransformer { + /// The underlying codec that implements the encoding and decoding logic. + final JsonCodec _codec; + + /// Creates a new transformer. + /// + /// The [reviver] and [toEncodable] arguments work the same way as the + /// corresponding arguments to [new JsonCodec]. + JsonDocumentTransformer({reviver(key, value), toEncodable(object)}) + : _codec = new JsonCodec(reviver: reviver, toEncodable: toEncodable); + + JsonDocumentTransformer._(this._codec); + + StreamChannel bind(StreamChannel channel) { + var stream = channel.stream.map(_codec.decode); + var sink = new StreamSinkTransformer.fromHandlers(handleData: (data, sink) { + sink.add(_codec.encode(data)); + }).bind(channel.sink); + return new StreamChannel(stream, sink); + } +} diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index e7fb055aa..f914188e6 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -8,6 +8,7 @@ import 'src/stream_channel_transformer.dart'; export 'src/delegating_stream_channel.dart'; export 'src/isolate_channel.dart'; +export 'src/json_document_transformer.dart'; export 'src/multi_channel.dart'; export 'src/stream_channel_completer.dart'; export 'src/stream_channel_transformer.dart'; diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart new file mode 100644 index 000000000..fec3d2ac1 --- /dev/null +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 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:stream_channel/stream_channel.dart'; +import 'package:test/test.dart'; + +import 'utils.dart'; + +void main() { + var streamController; + var sinkController; + var channel; + setUp(() { + streamController = new StreamController(); + sinkController = new StreamController(); + channel = new StreamChannel( + streamController.stream, sinkController.sink); + }); + + test("decodes JSON emitted by the channel", () { + var transformed = channel.transform(jsonDocument); + streamController.add('{"foo": "bar"}'); + expect(transformed.stream.first, completion(equals({"foo": "bar"}))); + }); + + test("encodes objects added to the channel", () { + var transformed = channel.transform(jsonDocument); + transformed.sink.add({"foo": "bar"}); + expect(sinkController.stream.first, + completion(equals(JSON.encode({"foo": "bar"})))); + }); + + test("supports the reviver function", () { + var transformed = channel.transform( + new JsonDocumentTransformer(reviver: (key, value) => "decoded")); + streamController.add('{"foo": "bar"}'); + expect(transformed.stream.first, completion(equals("decoded"))); + }); + + test("supports the toEncodable function", () { + var transformed = channel.transform( + new JsonDocumentTransformer(toEncodable: (object) => "encoded")); + transformed.sink.add(new Object()); + expect(sinkController.stream.first, completion(equals('"encoded"'))); + }); +} From 27f7f49ac0aa49d6934ce0d67aac7674b65909e9 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 28 Jan 2016 13:04:12 -0800 Subject: [PATCH 013/138] Release version 1.0.0. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1647983003 . --- pkgs/stream_channel/CHANGELOG.md | 2 +- pkgs/stream_channel/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 847d60daa..31490590d 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,3 @@ -## 0.0.1 +## 1.0.0 * Initial version diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index a8e26cd17..5f1a73963 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.0.0-dev +version: 1.0.0 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From b2d21787d4dca41b75b03fd0c4ea68f8273b1cc9 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 28 Jan 2016 14:10:11 -0800 Subject: [PATCH 014/138] Fix the MultiChannel constructor. R=kevmoo@google.com, rnystrom@google.com Review URL: https://codereview.chromium.org//1644943004 . --- pkgs/stream_channel/CHANGELOG.md | 6 +++ .../stream_channel/lib/src/multi_channel.dart | 39 ++++++++----------- pkgs/stream_channel/pubspec.yaml | 2 +- .../test/multi_channel_test.dart | 6 ++- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 31490590d..c85bbe3c4 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.0.1 + +* Fix `MultiChannel`'s constructor to take a `StreamChannel`. This is + technically a breaking change, but since 1.0.0 was only released an hour ago, + we're treating it as a bug fix. + ## 1.0.0 * Initial version diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index e87deb33b..cba592ab5 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -52,12 +52,11 @@ abstract class MultiChannel implements StreamChannel { /// virtual channels may be opened. StreamSink get sink; - /// Creates a new [MultiChannel] that sends messages over [innerStream] and - /// [innerSink]. + /// Creates a new [MultiChannel] that sends and receives messages over + /// [inner]. /// - /// The inner streams must take JSON-like objects. - factory MultiChannel(Stream innerStream, StreamSink innerSink) => - new _MultiChannel(innerStream, innerSink); + /// The inner channel must take JSON-like objects. + factory MultiChannel(StreamChannel inner) => new _MultiChannel(inner); /// Creates a new virtual channel. /// @@ -78,17 +77,12 @@ abstract class MultiChannel implements StreamChannel { /// This is private so that [VirtualChannel] can inherit from [MultiChannel] /// without having to implement all the private members. class _MultiChannel extends StreamChannelMixin implements MultiChannel { - /// The inner stream over which all communication is received. + /// The inner channel over which all communication is conducted. /// /// This will be `null` if the underlying communication channel is closed. - Stream _innerStream; + StreamChannel _inner; - /// The inner sink over which all communication is sent. - /// - /// This will be `null` if the underlying communication channel is closed. - StreamSink _innerSink; - - /// The subscription to [_innerStream]. + /// The subscription to [_inner.stream]. StreamSubscription _innerStreamSubscription; Stream get stream => _streamController.stream; @@ -128,16 +122,16 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { /// scheme, but if it has an even id, it's using the remote id scheme. var _nextId = 1; - _MultiChannel(this._innerStream, this._innerSink) { + _MultiChannel(this._inner) { // The default connection is a special case which has id 0 on both ends. // This allows it to begin connected without having to send over an id. _streamControllers[0] = _streamController; _sinkControllers[0] = _sinkController; _sinkController.stream.listen( - (message) => _innerSink.add([0, message]), + (message) => _inner.sink.add([0, message]), onDone: () => _closeChannel(0, 0)); - _innerStreamSubscription = _innerStream.listen((message) { + _innerStreamSubscription = _inner.stream.listen((message) { var id = message[0]; var sink = _streamControllers[id]; @@ -156,7 +150,7 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { } VirtualChannel virtualChannel([id]) { - if (_innerStream == null) { + if (_inner == null) { throw new StateError("The underlying channel is closed."); } @@ -186,7 +180,7 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { _streamControllers[inputId] = streamController; _sinkControllers[inputId] = sinkController; sinkController.stream.listen( - (message) => _innerSink.add([outputId, message]), + (message) => _inner.sink.add([outputId, message]), onDone: () => _closeChannel(inputId, outputId)); return new VirtualChannel._( @@ -199,20 +193,19 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { _streamControllers.remove(inputId).close(); _sinkControllers.remove(inputId).close(); - if (_innerSink == null) return; + if (_inner == null) return; // A message without data indicates that the virtual channel has been // closed. - _innerSink.add([outputId]); + _inner.sink.add([outputId]); if (_streamControllers.isEmpty) _closeInnerChannel(); } /// Closes the underlying communication channel. void _closeInnerChannel() { - _innerSink.close(); + _inner.sink.close(); _innerStreamSubscription.cancel(); - _innerStream = null; - _innerSink = null; + _inner = null; for (var controller in _sinkControllers.values.toList()) { controller.close(); } diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 5f1a73963..09df4a797 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.0.0 +version: 1.0.1 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index e4594128a..cc9ed1d26 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -17,8 +17,10 @@ void main() { setUp(() { oneToTwo = new StreamController(); twoToOne = new StreamController(); - channel1 = new MultiChannel(twoToOne.stream, oneToTwo.sink); - channel2 = new MultiChannel(oneToTwo.stream, twoToOne.sink); + channel1 = new MultiChannel( + new StreamChannel(twoToOne.stream, oneToTwo.sink)); + channel2 = new MultiChannel( + new StreamChannel(oneToTwo.stream, twoToOne.sink)); }); group("the default virtual channel", () { From 7c16f9368ea38930bc96099fa956cdd6d835d550 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 1 Feb 2016 15:55:12 -0800 Subject: [PATCH 015/138] Be more explicit about JSON error handling. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1658833002 . --- pkgs/stream_channel/CHANGELOG.md | 4 ++++ .../lib/src/json_document_transformer.dart | 4 ++++ pkgs/stream_channel/pubspec.yaml | 2 +- .../test/json_document_transformer_test.dart | 12 ++++++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index c85bbe3c4..d101ea0d2 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.2 + +* Be more explicit about `JsonDocumentTransformer`'s error-handling behavior. + ## 1.0.1 * Fix `MultiChannel`'s constructor to take a `StreamChannel`. This is diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index 8d8dcce23..19b2e08f7 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -17,6 +17,10 @@ final jsonDocument = new JsonDocumentTransformer(); /// /// This decodes JSON that's emitted by the transformed channel's stream, and /// encodes objects so that JSON is passed to the transformed channel's sink. +/// +/// If the transformed channel emits invalid JSON, this emits a +/// [FormatException]. If an unencodable object is added to the sink, it +/// synchronously throws a [JsonUnsupportedObjectError]. class JsonDocumentTransformer implements StreamChannelTransformer { /// The underlying codec that implements the encoding and decoding logic. diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 09df4a797..54e919873 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.0.1 +version: 1.0.2 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index fec3d2ac1..65a349724 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -47,4 +47,16 @@ void main() { transformed.sink.add(new Object()); expect(sinkController.stream.first, completion(equals('"encoded"'))); }); + + test("emits a stream error when incoming JSON is malformed", () { + var transformed = channel.transform(jsonDocument); + streamController.add("{invalid"); + expect(transformed.stream.first, throwsFormatException); + }); + + test("synchronously throws if an unencodable object is added", () { + var transformed = channel.transform(jsonDocument); + expect(() => transformed.sink.add(new Object()), + throwsA(new isInstanceOf())); + }); } From ad406409f2380deb69e76cca692eeac9d3140470 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 1 Feb 2016 15:56:24 -0800 Subject: [PATCH 016/138] Add support for stream- and sink-specific changes. These are especially useful when doing stream-specific transformations like error handling. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1657943002 . --- pkgs/stream_channel/CHANGELOG.md | 6 +- pkgs/stream_channel/lib/stream_channel.dart | 28 +++++++++ pkgs/stream_channel/pubspec.yaml | 2 +- .../test/stream_channel_test.dart | 59 +++++++++++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index d101ea0d2..ab0807249 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,4 +1,8 @@ -## 1.0.2 +## 1.1.0 + +* Add `StreamChannel.transformStream()`, `StreamChannel.transformSink()`, + `StreamChannel.changeStream()`, and `StreamChannel.changeSink()` to support + changing only the stream or only the sink of a channel. * Be more explicit about `JsonDocumentTransformer`'s error-handling behavior. diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index f914188e6..ff3104212 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -4,6 +4,8 @@ import 'dart:async'; +import 'package:async/async.dart'; + import 'src/stream_channel_transformer.dart'; export 'src/delegating_stream_channel.dart'; @@ -75,6 +77,20 @@ abstract class StreamChannel { /// /// This is identical to calling `transformer.bind(channel)`. StreamChannel transform(StreamChannelTransformer transformer); + + /// Transforms only the [stream] component of [this] using [transformer]. + StreamChannel transformStream(StreamTransformer transformer); + + /// Transforms only the [sink] component of [this] using [transformer]. + StreamChannel transformSink(StreamSinkTransformer transformer); + + /// Returns a copy of [this] with [stream] replaced by [change]'s return + /// value. + StreamChannel changeStream(Stream change(Stream stream)); + + /// Returns a copy of [this] with [sink] replaced by [change]'s return + /// value. + StreamChannel changeSink(StreamSink change(StreamSink sink)); } /// An implementation of [StreamChannel] that simply takes a stream and a sink @@ -99,4 +115,16 @@ abstract class StreamChannelMixin implements StreamChannel { StreamChannel transform(StreamChannelTransformer transformer) => transformer.bind(this); + + StreamChannel transformStream(StreamTransformer transformer) => + changeStream(transformer.bind); + + StreamChannel transformSink(StreamSinkTransformer transformer) => + changeSink(transformer.bind); + + StreamChannel changeStream(Stream change(Stream stream)) => + new StreamChannel(change(stream), sink); + + StreamChannel changeSink(StreamSink change(StreamSink sink)) => + new StreamChannel(stream, change(sink)); } diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 54e919873..7ef11010f 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.0.2 +version: 1.1.0 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index 5f006c39c..f5251778d 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:isolate'; +import 'package:async/async.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; @@ -56,4 +57,62 @@ void main() { expect(sinkController.stream.toList(), completion(equals([[102, 98, 108, 116, 104, 112]]))); }); + + test("transformStream() transforms only the stream", () { + var transformed = channel.transformStream(UTF8.decoder); + + streamController.add([102, 111, 111, 98, 97, 114]); + streamController.close(); + expect(transformed.stream.toList(), completion(equals(["foobar"]))); + + transformed.sink.add("fblthp"); + transformed.sink.close(); + expect(sinkController.stream.toList(), + completion(equals(["fblthp"]))); + }); + + test("transformSink() transforms only the sink", () { + var transformed = channel.transformSink( + new StreamSinkTransformer.fromStreamTransformer(UTF8.encoder)); + + streamController.add([102, 111, 111, 98, 97, 114]); + streamController.close(); + expect(transformed.stream.toList(), + completion(equals([[102, 111, 111, 98, 97, 114]]))); + + transformed.sink.add("fblthp"); + transformed.sink.close(); + expect(sinkController.stream.toList(), + completion(equals([[102, 98, 108, 116, 104, 112]]))); + }); + + test("changeStream() changes the stream", () { + var newController = new StreamController(); + var changed = channel.changeStream((stream) { + expect(stream, equals(channel.stream)); + return newController.stream; + }); + + newController.add(10); + newController.close(); + + streamController.add(20); + streamController.close(); + + expect(changed.stream.toList(), completion(equals([10]))); + }); + + test("changeSink() changes the sink", () { + var newController = new StreamController(); + var changed = channel.changeSink((sink) { + expect(sink, equals(channel.sink)); + return newController.sink; + }); + + expect(newController.stream.toList(), completion(equals([10]))); + streamController.stream.listen(expectAsync((_) {}, count: 0)); + + changed.sink.add(10); + changed.sink.close(); + }); } From a251a33379742b54d2752003d37a079b457f06bd Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 1 Feb 2016 17:29:51 -0800 Subject: [PATCH 017/138] Fix inverted generic parameters. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1658893002 . --- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/lib/stream_channel.dart | 4 ++-- pkgs/stream_channel/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index ab0807249..813870874 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.1 + +* Fix the type annotation for `StreamChannel.transform()`'s parameter. + ## 1.1.0 * Add `StreamChannel.transformStream()`, `StreamChannel.transformSink()`, diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index ff3104212..7fff6744c 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -76,7 +76,7 @@ abstract class StreamChannel { /// Transforms [this] using [transformer]. /// /// This is identical to calling `transformer.bind(channel)`. - StreamChannel transform(StreamChannelTransformer transformer); + StreamChannel transform(StreamChannelTransformer transformer); /// Transforms only the [stream] component of [this] using [transformer]. StreamChannel transformStream(StreamTransformer transformer); @@ -113,7 +113,7 @@ abstract class StreamChannelMixin implements StreamChannel { other.stream.pipe(sink); } - StreamChannel transform(StreamChannelTransformer transformer) => + StreamChannel transform(StreamChannelTransformer transformer) => transformer.bind(this); StreamChannel transformStream(StreamTransformer transformer) => diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 7ef11010f..7d1c6a3e4 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.1.0 +version: 1.1.1 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From d0af7ea9dedf277718f7fb9272f712babcd3f73f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 3 Feb 2016 17:33:46 -0800 Subject: [PATCH 018/138] Add StreamChannel.withGuarantees and StreamChannelController. These APIs make it easier for users to create their own stream channels that follow the StreamChannel guarantees. R=tjblasi@google.com Review URL: https://codereview.chromium.org//1662773003 . --- pkgs/stream_channel/CHANGELOG.md | 8 + .../lib/src/guarantee_channel.dart | 163 ++++++++++++++++++ .../lib/src/stream_channel_controller.dart | 58 +++++++ pkgs/stream_channel/lib/stream_channel.dart | 14 +- pkgs/stream_channel/pubspec.yaml | 2 +- .../test/stream_channel_controller_test.dart | 86 +++++++++ .../test/with_guarantees_test.dart | 110 ++++++++++++ 7 files changed, 439 insertions(+), 2 deletions(-) create mode 100644 pkgs/stream_channel/lib/src/guarantee_channel.dart create mode 100644 pkgs/stream_channel/lib/src/stream_channel_controller.dart create mode 100644 pkgs/stream_channel/test/stream_channel_controller_test.dart create mode 100644 pkgs/stream_channel/test/with_guarantees_test.dart diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 813870874..0b61d81f8 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.2.0 + +* Add `new StreamChannel.withGuarantees()`, which creates a channel with extra + wrapping to ensure that it obeys the stream channel guarantees. + +* Add `StreamChannelController`, which can be used to create custom + `StreamChannel` objects. + ## 1.1.1 * Fix the type annotation for `StreamChannel.transform()`'s parameter. diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart new file mode 100644 index 000000000..849cc2ffe --- /dev/null +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -0,0 +1,163 @@ +// Copyright (c) 2016, 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 'package:async/async.dart'; + +import '../stream_channel.dart'; + +/// A [StreamChannel] that enforces the stream channel guarantees. +/// +/// This is exposed via [new StreamChannel.withGuarantees]. +class GuaranteeChannel extends StreamChannelMixin { + Stream get stream => _streamController.stream; + + StreamSink get sink => _sink; + _GuaranteeSink _sink; + + /// The controller for [stream]. + /// + /// This intermediate controller allows us to continue listening for a done + /// event even after the user has canceled their subscription, and to send our + /// own done event when the sink is closed. + StreamController _streamController; + + /// The subscription to the inner stream. + StreamSubscription _subscription; + + /// Whether the sink has closed, causing the underlying channel to disconnect. + bool _disconnected = false; + + GuaranteeChannel(Stream innerStream, StreamSink innerSink) { + _sink = new _GuaranteeSink(innerSink, this); + + // Enforce the single-subscription guarantee by changing a broadcast stream + // to single-subscription. + if (innerStream.isBroadcast) { + innerStream = innerStream.transform( + const SingleSubscriptionTransformer()); + } + + _streamController = new StreamController(onListen: () { + // If the sink has disconnected, we've already called + // [_streamController.close]. + if (_disconnected) return; + + _subscription = innerStream.listen(_streamController.add, + onError: _streamController.addError, + onDone: () { + _sink._onStreamDisconnected(); + _streamController.close(); + }); + }, sync: true); + } + + /// Called by [_GuaranteeSink] when the user closes it. + /// + /// The sink closing indicates that the connection is closed, so the stream + /// should stop emitting events. + void _onSinkDisconnected() { + _disconnected = true; + if (_subscription != null) _subscription.cancel(); + _streamController.close(); + } +} + +/// The sink for [GuaranteeChannel]. +/// +/// This wraps the inner sink to ignore events and cancel any in-progress +/// [addStream] calls when the underlying channel closes. +class _GuaranteeSink implements StreamSink { + /// The inner sink being wrapped. + final StreamSink _inner; + + /// The [GuaranteeChannel] this belongs to. + final GuaranteeChannel _channel; + + Future get done => _inner.done; + + /// Whether the stream has emitted a done event, causing the underlying + /// channel to disconnect. + bool _disconnected = false; + + /// Whether the user has called [close]. + bool _closed = false; + + /// The subscription to the stream passed to [addStream], if a stream is + /// currently being added. + StreamSubscription _addStreamSubscription; + + /// The completer for the future returned by [addStream], if a stream is + /// currently being added. + Completer _addStreamCompleter; + + /// Whether we're currently adding a stream with [addStream]. + bool get _inAddStream => _addStreamSubscription != null; + + _GuaranteeSink(this._inner, this._channel); + + void add(T data) { + if (_closed) throw new StateError("Cannot add event after closing."); + if (_inAddStream) { + throw new StateError("Cannot add event while adding stream."); + } + if (_disconnected) return; + + _inner.add(data); + } + + void addError(error, [StackTrace stackTrace]) { + if (_closed) throw new StateError("Cannot add event after closing."); + if (_inAddStream) { + throw new StateError("Cannot add event while adding stream."); + } + if (_disconnected) return; + + _inner.addError(error, stackTrace); + } + + Future addStream(Stream stream) { + if (_closed) throw new StateError("Cannot add stream after closing."); + if (_inAddStream) { + throw new StateError("Cannot add stream while adding stream."); + } + if (_disconnected) return new Future.value(); + + _addStreamCompleter = new Completer.sync(); + _addStreamSubscription = stream.listen( + _inner.add, + onError: _inner.addError, + onDone: _addStreamCompleter.complete); + return _addStreamCompleter.future.then((_) { + _addStreamCompleter = null; + _addStreamSubscription = null; + }); + } + + Future close() { + if (_inAddStream) { + throw new StateError("Cannot close sink while adding stream."); + } + + _closed = true; + if (_disconnected) return new Future.value(); + + _channel._onSinkDisconnected(); + return _inner.close(); + } + + /// Called by [GuaranteeChannel] when the stream emits a done event. + /// + /// The stream being done indicates that the connection is closed, so the + /// sink should stop forwarding events. + void _onStreamDisconnected() { + _disconnected = true; + if (!_inAddStream) return; + + _addStreamCompleter.complete(_addStreamSubscription.cancel()); + _addStreamCompleter = null; + _addStreamSubscription = null; + } +} diff --git a/pkgs/stream_channel/lib/src/stream_channel_controller.dart b/pkgs/stream_channel/lib/src/stream_channel_controller.dart new file mode 100644 index 000000000..1812a0e3a --- /dev/null +++ b/pkgs/stream_channel/lib/src/stream_channel_controller.dart @@ -0,0 +1,58 @@ +// Copyright (c) 2016, 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 '../stream_channel.dart'; + +/// A controller for exposing a new [StreamChannel]. +/// +/// This exposes two connected [StreamChannel]s, [local] and [foreign]. The +/// user's code should use [local] to emit and receive events. Then [foreign] +/// can be returned for others to use. For example, here's a simplified version +/// of the implementation of [new IsolateChannel]: +/// +/// ```dart +/// StreamChannel isolateChannel(ReceivePort receivePort, SendPort sendPort) { +/// var controller = new StreamChannelController(); +/// +/// // Pipe all events from the receive port into the local sink... +/// receivePort.pipe(controller.local.sink); +/// +/// // ...and all events from the local stream into the send port. +/// controller.local.listen(sendPort.add, onDone: receivePort.close); +/// +/// // Then return the foreign controller for your users to use. +/// return controller.foreign; +/// } +/// ``` +class StreamChannelController { + /// The local channel. + /// + /// This channel should be used directly by the creator of this + /// [StreamChannelController] to send and receive events. + StreamChannel get local => _local; + StreamChannel _local; + + /// The foreign channel. + /// + /// This channel should be returned to external users so they can communicate + /// with [local]. + StreamChannel get foreign => _foreign; + StreamChannel _foreign; + + /// Creates a [StreamChannelController]. + /// + /// If [sync] is true, events added to either channel's sink are synchronously + /// dispatched to the other channel's stream. This should only be done if the + /// source of those events is already asynchronous. + StreamChannelController({bool sync: false}) { + var localToForeignController = new StreamController(sync: sync); + var foreignToLocalController = new StreamController(sync: sync); + _local = new StreamChannel.withGuarantees( + foreignToLocalController.stream, localToForeignController.sink); + _foreign = new StreamChannel.withGuarantees( + localToForeignController.stream, foreignToLocalController.sink); + } +} diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index 7fff6744c..8c4fad520 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'package:async/async.dart'; +import 'src/guarantee_channel.dart'; import 'src/stream_channel_transformer.dart'; export 'src/delegating_stream_channel.dart'; @@ -13,6 +14,7 @@ export 'src/isolate_channel.dart'; export 'src/json_document_transformer.dart'; export 'src/multi_channel.dart'; export 'src/stream_channel_completer.dart'; +export 'src/stream_channel_controller.dart'; export 'src/stream_channel_transformer.dart'; /// An abstract class representing a two-way communication channel. @@ -65,10 +67,20 @@ abstract class StreamChannel { /// Creates a new [StreamChannel] that communicates over [stream] and [sink]. /// /// Note that this stream/sink pair must provide the guarantees listed in the - /// [StreamChannel] documentation. + /// [StreamChannel] documentation. If they don't do so natively, [new + /// StreamChannel.withGuarantees] should be used instead. factory StreamChannel(Stream stream, StreamSink sink) => new _StreamChannel(stream, sink); + /// Creates a new [StreamChannel] that communicates over [stream] and [sink]. + /// + /// Unlike [new StreamChannel], this enforces the guarantees listed in the + /// [StreamChannel] documentation. This makes it somewhat less efficient than + /// just wrapping a stream and a sink directly, so [new StreamChannel] should + /// be used when the guarantees are provided natively. + factory StreamChannel.withGuarantees(Stream stream, StreamSink sink) => + new GuaranteeChannel(stream, sink); + /// Connects [this] to [other], so that any values emitted by either are sent /// directly to the other. void pipe(StreamChannel other); diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 7d1c6a3e4..f0b830ca1 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.1.1 +version: 1.2.0-dev description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/stream_channel_controller_test.dart b/pkgs/stream_channel/test/stream_channel_controller_test.dart new file mode 100644 index 000000000..e45f09062 --- /dev/null +++ b/pkgs/stream_channel/test/stream_channel_controller_test.dart @@ -0,0 +1,86 @@ +// Copyright (c) 2016, 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 'package:stream_channel/stream_channel.dart'; +import 'package:test/test.dart'; + +import 'utils.dart'; + +void main() { + group("asynchronously", () { + var controller; + setUp(() { + controller = new StreamChannelController(); + }); + + test("forwards events from the local sink to the foreign stream", () { + controller.local.sink..add(1)..add(2)..add(3)..close(); + expect(controller.foreign.stream.toList(), completion(equals([1, 2, 3]))); + }); + + test("forwards events from the foreign sink to the local stream", () { + controller.foreign.sink..add(1)..add(2)..add(3)..close(); + expect(controller.local.stream.toList(), completion(equals([1, 2, 3]))); + }); + }); + + group("synchronously", () { + var controller; + setUp(() { + controller = new StreamChannelController(sync: true); + }); + + test("synchronously forwards events from the local sink to the foreign " + "stream", () { + var receivedEvent = false; + var receivedError = false; + var receivedDone = false; + controller.foreign.stream.listen(expectAsync((event) { + expect(event, equals(1)); + receivedEvent = true; + }), onError: expectAsync((error) { + expect(error, equals("oh no")); + receivedError = true; + }), onDone: expectAsync(() { + receivedDone = true; + })); + + controller.local.sink.add(1); + expect(receivedEvent, isTrue); + + controller.local.sink.addError("oh no"); + expect(receivedError, isTrue); + + controller.local.sink.close(); + expect(receivedDone, isTrue); + }); + + test("synchronously forwards events from the foreign sink to the local " + "stream", () { + var receivedEvent = false; + var receivedError = false; + var receivedDone = false; + controller.local.stream.listen(expectAsync((event) { + expect(event, equals(1)); + receivedEvent = true; + }), onError: expectAsync((error) { + expect(error, equals("oh no")); + receivedError = true; + }), onDone: expectAsync(() { + receivedDone = true; + })); + + controller.foreign.sink.add(1); + expect(receivedEvent, isTrue); + + controller.foreign.sink.addError("oh no"); + expect(receivedError, isTrue); + + controller.foreign.sink.close(); + expect(receivedDone, isTrue); + }); + }); +} diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart new file mode 100644 index 000000000..0e95f9d88 --- /dev/null +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -0,0 +1,110 @@ +// Copyright (c) 2016, 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 'package:stream_channel/stream_channel.dart'; +import 'package:test/test.dart'; + +import 'utils.dart'; + +void main() { + var streamController; + var sinkController; + var channel; + setUp(() { + streamController = new StreamController(); + sinkController = new StreamController(); + channel = new StreamChannel.withGuarantees( + streamController.stream, sinkController.sink); + }); + + group("with a broadcast stream", () { + setUp(() { + streamController = new StreamController.broadcast(); + channel = new StreamChannel.withGuarantees( + streamController.stream, sinkController.sink); + }); + + test("buffers events", () async { + streamController.add(1); + streamController.add(2); + streamController.add(3); + await pumpEventQueue(); + + expect(channel.stream.toList(), completion(equals([1, 2, 3]))); + streamController.close(); + }); + + test("only allows a single subscription", () { + channel.stream.listen(null); + expect(() => channel.stream.listen(null), throwsStateError); + }); + }); + + test("closing the event sink causes the stream to close before it emits any " + "more events", () { + streamController.add(1); + streamController.add(2); + streamController.add(3); + + expect(channel.stream.listen(expectAsync((event) { + if (event == 2) channel.sink.close(); + }, count: 2)).asFuture(), completes); + }); + + test("after the stream closes, the sink ignores events", () async { + streamController.close(); + + // Wait for the done event to be delivered. + await channel.stream.toList(); + channel.sink.add(1); + channel.sink.add(2); + channel.sink.add(3); + channel.sink.close(); + + // None of our channel.sink additions should make it to the other endpoint. + sinkController.stream.listen( + expectAsync((_) {}, count: 0), + onDone: expectAsync(() {}, count: 0)); + await pumpEventQueue(); + }); + + test("canceling the stream's subscription has no effect on the sink", + () async { + channel.stream.listen(null).cancel(); + await pumpEventQueue(); + + channel.sink.add(1); + channel.sink.add(2); + channel.sink.add(3); + channel.sink.close(); + expect(sinkController.stream.toList(), completion(equals([1, 2, 3]))); + }); + + test("canceling the stream's subscription doesn't stop a done event", + () async { + channel.stream.listen(null).cancel(); + await pumpEventQueue(); + + streamController.close(); + await pumpEventQueue(); + + channel.sink.add(1); + channel.sink.add(2); + channel.sink.add(3); + channel.sink.close(); + + // The sink should be ignoring events because the stream closed. + sinkController.stream.listen( + expectAsync((_) {}, count: 0), + onDone: expectAsync(() {}, count: 0)); + await pumpEventQueue(); + }); + + test("forwards errors to the other endpoint", () { + channel.sink.addError("error"); + expect(sinkController.stream.first, throwsA("error")); + }); +} From 8bd8af51f53b27dd99eeac67a8b8bfa2d0548bd4 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 4 Feb 2016 16:10:16 -0800 Subject: [PATCH 019/138] Provide more error-handling customization. This makes it easier to wrap underlying channels that don't support errors at all. R=tjblasi@google.com Review URL: https://codereview.chromium.org//1669953002 . --- .../lib/src/guarantee_channel.dart | 52 +++++++++++++++---- .../lib/src/stream_channel_controller.dart | 10 +++- pkgs/stream_channel/lib/stream_channel.dart | 9 +++- pkgs/stream_channel/pubspec.yaml | 2 +- .../test/stream_channel_controller_test.dart | 11 ++++ .../test/with_guarantees_test.dart | 40 ++++++++++++++ 6 files changed, 108 insertions(+), 16 deletions(-) diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart index 849cc2ffe..1047e14ff 100644 --- a/pkgs/stream_channel/lib/src/guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -30,8 +30,10 @@ class GuaranteeChannel extends StreamChannelMixin { /// Whether the sink has closed, causing the underlying channel to disconnect. bool _disconnected = false; - GuaranteeChannel(Stream innerStream, StreamSink innerSink) { - _sink = new _GuaranteeSink(innerSink, this); + GuaranteeChannel(Stream innerStream, StreamSink innerSink, + {bool allowSinkErrors: true}) { + _sink = new _GuaranteeSink(innerSink, this, + allowErrors: allowSinkErrors); // Enforce the single-subscription guarantee by changing a broadcast stream // to single-subscription. @@ -76,10 +78,13 @@ class _GuaranteeSink implements StreamSink { /// The [GuaranteeChannel] this belongs to. final GuaranteeChannel _channel; - Future get done => _inner.done; + Future get done => _doneCompleter.future; + final _doneCompleter = new Completer(); - /// Whether the stream has emitted a done event, causing the underlying - /// channel to disconnect. + /// Whether connection is disconnected. + /// + /// This can happen because the stream has emitted a done event, or because + /// the user added an error when [_allowErrors] is `false`. bool _disconnected = false; /// Whether the user has called [close]. @@ -96,7 +101,14 @@ class _GuaranteeSink implements StreamSink { /// Whether we're currently adding a stream with [addStream]. bool get _inAddStream => _addStreamSubscription != null; - _GuaranteeSink(this._inner, this._channel); + /// Whether errors are passed on to the underlying sink. + /// + /// If this is `false`, any error passed to the sink is piped to [done] and + /// the underlying sink is closed. + final bool _allowErrors; + + _GuaranteeSink(this._inner, this._channel, {bool allowErrors: true}) + : _allowErrors = allowErrors; void add(T data) { if (_closed) throw new StateError("Cannot add event after closing."); @@ -115,7 +127,20 @@ class _GuaranteeSink implements StreamSink { } if (_disconnected) return; - _inner.addError(error, stackTrace); + if (_allowErrors) { + _inner.addError(error, stackTrace); + return; + } + + _doneCompleter.completeError(error, stackTrace); + + // Treat an error like both the stream and sink disconnecting. + _onStreamDisconnected(); + _channel._onSinkDisconnected(); + + // Ignore errors from the inner sink. We're already surfacing one error, and + // if the user handles it we don't want them to have another top-level. + _inner.close().catchError((_) {}); } Future addStream(Stream stream) { @@ -141,11 +166,15 @@ class _GuaranteeSink implements StreamSink { throw new StateError("Cannot close sink while adding stream."); } + if (_closed) return done; _closed = true; - if (_disconnected) return new Future.value(); - _channel._onSinkDisconnected(); - return _inner.close(); + if (!_disconnected) { + _channel._onSinkDisconnected(); + _doneCompleter.complete(_inner.close()); + } + + return done; } /// Called by [GuaranteeChannel] when the stream emits a done event. @@ -154,8 +183,9 @@ class _GuaranteeSink implements StreamSink { /// sink should stop forwarding events. void _onStreamDisconnected() { _disconnected = true; - if (!_inAddStream) return; + if (!_doneCompleter.isCompleted) _doneCompleter.complete(); + if (!_inAddStream) return; _addStreamCompleter.complete(_addStreamSubscription.cancel()); _addStreamCompleter = null; _addStreamSubscription = null; diff --git a/pkgs/stream_channel/lib/src/stream_channel_controller.dart b/pkgs/stream_channel/lib/src/stream_channel_controller.dart index 1812a0e3a..ad78323ef 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_controller.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_controller.dart @@ -47,12 +47,18 @@ class StreamChannelController { /// If [sync] is true, events added to either channel's sink are synchronously /// dispatched to the other channel's stream. This should only be done if the /// source of those events is already asynchronous. - StreamChannelController({bool sync: false}) { + /// + /// If [allowForeignErrors] is `false`, errors are not allowed to be passed to + /// the foreign channel's sink. If any are, the connection will close and the + /// error will be forwarded to the foreign channel's [Sink.done] future. This + /// guarantees that the local stream will never emit errors. + StreamChannelController({bool allowForeignErrors: true, bool sync: false}) { var localToForeignController = new StreamController(sync: sync); var foreignToLocalController = new StreamController(sync: sync); _local = new StreamChannel.withGuarantees( foreignToLocalController.stream, localToForeignController.sink); _foreign = new StreamChannel.withGuarantees( - localToForeignController.stream, foreignToLocalController.sink); + localToForeignController.stream, foreignToLocalController.sink, + allowSinkErrors: allowForeignErrors); } } diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index 8c4fad520..992f7026a 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -78,8 +78,13 @@ abstract class StreamChannel { /// [StreamChannel] documentation. This makes it somewhat less efficient than /// just wrapping a stream and a sink directly, so [new StreamChannel] should /// be used when the guarantees are provided natively. - factory StreamChannel.withGuarantees(Stream stream, StreamSink sink) => - new GuaranteeChannel(stream, sink); + /// + /// If [allowSinkErrors] is `false`, errors are not allowed to be passed to + /// [sink]. If any are, the connection will close and the error will be + /// forwarded to [Sink.done]. + factory StreamChannel.withGuarantees(Stream stream, StreamSink sink, + {bool allowSinkErrors: true}) => + new GuaranteeChannel(stream, sink, allowSinkErrors: allowSinkErrors); /// Connects [this] to [other], so that any values emitted by either are sent /// directly to the other. diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index f0b830ca1..52ee52171 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.2.0-dev +version: 1.2.0 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/stream_channel_controller_test.dart b/pkgs/stream_channel/test/stream_channel_controller_test.dart index e45f09062..cf8a31b36 100644 --- a/pkgs/stream_channel/test/stream_channel_controller_test.dart +++ b/pkgs/stream_channel/test/stream_channel_controller_test.dart @@ -25,6 +25,17 @@ void main() { controller.foreign.sink..add(1)..add(2)..add(3)..close(); expect(controller.local.stream.toList(), completion(equals([1, 2, 3]))); }); + + test("with allowForeignErrors: false, shuts down the connection if an " + "error is added to the foreign channel", () { + controller = new StreamChannelController(allowForeignErrors: false); + + controller.foreign.sink.addError("oh no"); + expect(controller.foreign.sink.done, throwsA("oh no")); + expect(controller.foreign.stream.toList(), completion(isEmpty)); + expect(controller.local.sink.done, completes); + expect(controller.local.stream.toList(), completion(isEmpty)); + }); }); group("synchronously", () { diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index 0e95f9d88..38afefac0 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -107,4 +107,44 @@ void main() { channel.sink.addError("error"); expect(sinkController.stream.first, throwsA("error")); }); + + test("Sink.done completes once the stream is done", () { + channel.stream.listen(null); + expect(channel.sink.done, completes); + streamController.close(); + }); + + group("with allowSinkErrors: false", () { + setUp(() { + streamController = new StreamController(); + sinkController = new StreamController(); + channel = new StreamChannel.withGuarantees( + streamController.stream, sinkController.sink, allowSinkErrors: false); + }); + + test("forwards errors to Sink.done but not the stream", () { + channel.sink.addError("oh no"); + expect(channel.sink.done, throwsA("oh no")); + sinkController.stream.listen(null, + onError: expectAsync((_) {}, count: 0)); + }); + + test("adding an error causes the stream to emit a done event", () { + expect(channel.sink.done, throwsA("oh no")); + + streamController.add(1); + streamController.add(2); + streamController.add(3); + + expect(channel.stream.listen(expectAsync((event) { + if (event == 2) channel.sink.addError("oh no"); + }, count: 2)).asFuture(), completes); + }); + + test("adding an error closes the inner sink", () { + channel.sink.addError("oh no"); + expect(channel.sink.done, throwsA("oh no")); + expect(sinkController.stream.toList(), completion(isEmpty)); + }); + }); } From f5810280eba19d7de62256fc35170c3e345d9dcc Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 8 Feb 2016 16:11:18 -0800 Subject: [PATCH 020/138] Make IsolateChannel use StreamChannelCompleter. This exposed some lingering bugs in GuaranteeChannel as well. R=tjblasi@google.com Review URL: https://codereview.chromium.org//1671763002 . --- .../lib/src/guarantee_channel.dart | 10 +- .../lib/src/isolate_channel.dart | 22 ++-- .../src/isolate_channel/send_port_sink.dart | 111 ------------------ .../lib/src/stream_channel_controller.dart | 4 +- .../test/with_guarantees_test.dart | 43 +++++++ 5 files changed, 68 insertions(+), 122 deletions(-) delete mode 100644 pkgs/stream_channel/lib/src/isolate_channel/send_port_sink.dart diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart index 1047e14ff..a874799c1 100644 --- a/pkgs/stream_channel/lib/src/guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -127,6 +127,14 @@ class _GuaranteeSink implements StreamSink { } if (_disconnected) return; + _addError(error, stackTrace); + } + + /// Like [addError], but doesn't check to ensure that an error can be added. + /// + /// This is called from [addStream], so it shouldn't fail if a stream is being + /// added. + void _addError(error, [StackTrace stackTrace]) { if (_allowErrors) { _inner.addError(error, stackTrace); return; @@ -153,7 +161,7 @@ class _GuaranteeSink implements StreamSink { _addStreamCompleter = new Completer.sync(); _addStreamSubscription = stream.listen( _inner.add, - onError: _inner.addError, + onError: _addError, onDone: _addStreamCompleter.complete); return _addStreamCompleter.future.then((_) { _addStreamCompleter = null; diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index a466d87f3..3466d19dd 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -9,7 +9,6 @@ import 'package:async/async.dart'; import 'package:stack_trace/stack_trace.dart'; import '../stream_channel.dart'; -import 'isolate_channel/send_port_sink.dart'; /// A [StreamChannel] that communicates over a [ReceivePort]/[SendPort] pair, /// presumably with another isolate. @@ -54,10 +53,13 @@ class IsolateChannel extends StreamChannelMixin { var subscription; subscription = receivePort.listen((message) { if (message is SendPort) { - streamCompleter.setSourceStream( - new SubscriptionStream(subscription)); - sinkCompleter.setDestinationSink( - new SendPortSink(receivePort, message)); + var controller = new StreamChannelController(allowForeignErrors: false); + new SubscriptionStream(subscription).pipe(controller.local.sink); + controller.local.stream.listen(message.send, + onDone: receivePort.close); + + streamCompleter.setSourceStream(controller.foreign.stream); + sinkCompleter.setDestinationSink(controller.foreign.sink); return; } @@ -88,9 +90,13 @@ class IsolateChannel extends StreamChannelMixin { /// Creates a stream channel that receives messages from [receivePort] and /// sends them over [sendPort]. - IsolateChannel(ReceivePort receivePort, SendPort sendPort) - : stream = new StreamView(receivePort), - sink = new SendPortSink(receivePort, sendPort); + factory IsolateChannel(ReceivePort receivePort, SendPort sendPort) { + var controller = new StreamChannelController(allowForeignErrors: false); + receivePort.pipe(controller.local.sink); + controller.local.stream.listen(sendPort.send, onDone: receivePort.close); + return new IsolateChannel._( + controller.foreign.stream, controller.foreign.sink); + } IsolateChannel._(this.stream, this.sink); } diff --git a/pkgs/stream_channel/lib/src/isolate_channel/send_port_sink.dart b/pkgs/stream_channel/lib/src/isolate_channel/send_port_sink.dart deleted file mode 100644 index d98f1da65..000000000 --- a/pkgs/stream_channel/lib/src/isolate_channel/send_port_sink.dart +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2016, 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:isolate'; - -/// The sink for [IsolateChannel]. -/// -/// [SendPort] doesn't natively implement any sink API, so this adds that API as -/// a wrapper. Closing this just closes the [ReceivePort]. -class SendPortSink implements StreamSink { - /// The port that produces incoming messages. - /// - /// This is wrapped in a [StreamView] to produce [stream]. - final ReceivePort _receivePort; - - /// The port that sends outgoing messages. - final SendPort _sendPort; - - Future get done => _doneCompleter.future; - final _doneCompleter = new Completer(); - - /// Whether [done] has been completed. - /// - /// This is distinct from [_closed] because [done] can complete with an error - /// without the user explicitly calling [close]. - bool get _isDone => _doneCompleter.isCompleted; - - /// Whether the user has called [close]. - bool _closed = false; - - /// Whether we're currently adding a stream with [addStream]. - bool _inAddStream = false; - - SendPortSink(this._receivePort, this._sendPort); - - void add(T data) { - if (_closed) throw new StateError("Cannot add event after closing."); - if (_inAddStream) { - throw new StateError("Cannot add event while adding stream."); - } - if (_isDone) return; - - _add(data); - } - - /// A helper for [add] that doesn't check for [StateError]s. - /// - /// This is called from [addStream], so it shouldn't check [_inAddStream]. - void _add(T data) { - _sendPort.send(data); - } - - void addError(error, [StackTrace stackTrace]) { - if (_closed) throw new StateError("Cannot add event after closing."); - if (_inAddStream) { - throw new StateError("Cannot add event while adding stream."); - } - - _close(error, stackTrace); - } - - Future close() { - if (_inAddStream) { - throw new StateError("Cannot close sink while adding stream."); - } - - _closed = true; - return _close(); - } - - /// A helper for [close] that doesn't check for [StateError]s. - /// - /// This is called from [addStream], so it shouldn't check [_inAddStream]. It - /// also forwards [error] and [stackTrace] to [done] if they're passed. - Future _close([error, StackTrace stackTrace]) { - if (_isDone) return done; - - _receivePort.close(); - - if (error != null) { - _doneCompleter.completeError(error, stackTrace); - } else { - _doneCompleter.complete(); - } - - return done; - } - - Future addStream(Stream stream) { - if (_closed) throw new StateError("Cannot add stream after closing."); - if (_inAddStream) { - throw new StateError("Cannot add stream while adding stream."); - } - if (_isDone) return new Future.value(); - - _inAddStream = true; - var completer = new Completer.sync(); - stream.listen(_add, - onError: (error, stackTrace) { - _close(error, stackTrace); - completer.complete(); - }, - onDone: completer.complete, - cancelOnError: true); - return completer.future.then((_) { - _inAddStream = false; - }); - } -} diff --git a/pkgs/stream_channel/lib/src/stream_channel_controller.dart b/pkgs/stream_channel/lib/src/stream_channel_controller.dart index ad78323ef..45b2865ed 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_controller.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_controller.dart @@ -15,13 +15,13 @@ import '../stream_channel.dart'; /// /// ```dart /// StreamChannel isolateChannel(ReceivePort receivePort, SendPort sendPort) { -/// var controller = new StreamChannelController(); +/// var controller = new StreamChannelController(allowForeignErrors: false); /// /// // Pipe all events from the receive port into the local sink... /// receivePort.pipe(controller.local.sink); /// /// // ...and all events from the local stream into the send port. -/// controller.local.listen(sendPort.add, onDone: receivePort.close); +/// controller.local.stream.listen(sendPort.send, onDone: receivePort.close); /// /// // Then return the foreign controller for your users to use. /// return controller.foreign; diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index 38afefac0..409b28fdd 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -114,6 +114,29 @@ void main() { streamController.close(); }); + test("events can't be added to an explicitly-closed sink", () { + sinkController.stream.listen(null); // Work around sdk#19095. + + expect(channel.sink.close(), completes); + expect(() => channel.sink.add(1), throwsStateError); + expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addStream(new Stream.fromIterable([])), + throwsStateError); + }); + + test("events can't be added while a stream is being added", () { + var controller = new StreamController(); + channel.sink.addStream(controller.stream); + + expect(() => channel.sink.add(1), throwsStateError); + expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addStream(new Stream.fromIterable([])), + throwsStateError); + expect(() => channel.sink.close(), throwsStateError); + + controller.close(); + }); + group("with allowSinkErrors: false", () { setUp(() { streamController = new StreamController(); @@ -146,5 +169,25 @@ void main() { expect(channel.sink.done, throwsA("oh no")); expect(sinkController.stream.toList(), completion(isEmpty)); }); + + test("adding an error via via addStream causes the stream to emit a done " + "event", () async { + var canceled = false; + var controller = new StreamController(onCancel: () { + canceled = true; + }); + + // This future shouldn't get the error, because it's sent to [Sink.done]. + expect(channel.sink.addStream(controller.stream), completes); + + controller.addError("oh no"); + expect(channel.sink.done, throwsA("oh no")); + await pumpEventQueue(); + expect(canceled, isTrue); + + // Even though the sink is closed, this shouldn't throw an error because + // the user didn't explicitly close it. + channel.sink.add(1); + }); }); } From ed797d0f08bcf0c9368b2d21771adbeb8548079d Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 9 Feb 2016 11:11:06 -0800 Subject: [PATCH 021/138] Add a Disconnector class. R=tjblasi@google.com Review URL: https://codereview.chromium.org//1679193002 . --- pkgs/stream_channel/CHANGELOG.md | 5 + pkgs/stream_channel/lib/src/disconnector.dart | 139 ++++++++++++++++++ pkgs/stream_channel/lib/stream_channel.dart | 1 + pkgs/stream_channel/pubspec.yaml | 2 +- .../test/disconnector_test.dart | 113 ++++++++++++++ 5 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 pkgs/stream_channel/lib/src/disconnector.dart create mode 100644 pkgs/stream_channel/test/disconnector_test.dart diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 0b61d81f8..dd749369e 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.3.0 + +* Add `Disconnector`, a transformer that allows the caller to disconnect the + transformed channel. + ## 1.2.0 * Add `new StreamChannel.withGuarantees()`, which creates a channel with extra diff --git a/pkgs/stream_channel/lib/src/disconnector.dart b/pkgs/stream_channel/lib/src/disconnector.dart new file mode 100644 index 000000000..35ecd1cc4 --- /dev/null +++ b/pkgs/stream_channel/lib/src/disconnector.dart @@ -0,0 +1,139 @@ +// Copyright (c) 2016, 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 '../stream_channel.dart'; + +/// Allows the caller to force a channel to disconnect. +/// +/// When [disconnect] is called, the channel (or channels) transformed by this +/// transformer will act as though the remote end had disconnected—the stream +/// will emit a done event, and the sink will ignore future inputs. The inner +/// sink will also be closed to notify the remote end of the disconnection. +/// +/// If a channel is transformed after the [disconnect] has been called, it will +/// be disconnected immediately. +class Disconnector implements StreamChannelTransformer { + /// Whether [disconnect] has been called. + bool get isDisconnected => _isDisconnected; + var _isDisconnected = false; + + /// The sinks for transformed channels. + /// + /// Note that we assume that transformed channels provide the stream channel + /// guarantees. This allows us to only track sinks, because we know closing + /// the underlying sink will cause the stream to emit a done event. + final _sinks = <_DisconnectorSink>[]; + + /// Disconnects all channels that have been transformed. + void disconnect() { + _isDisconnected = true; + for (var sink in _sinks) { + sink._disconnect(); + } + _sinks.clear(); + } + + StreamChannel bind(StreamChannel channel) { + return channel.changeSink((innerSink) { + var sink = new _DisconnectorSink(innerSink); + + if (_isDisconnected) { + sink._disconnect(); + } else { + _sinks.add(sink); + } + + return sink; + }); + } +} + +/// A sink wrapper that can force a disconnection. +class _DisconnectorSink implements StreamSink { + /// The inner sink. + final StreamSink _inner; + + Future get done => _inner.done; + + /// Whether [Disconnector.disconnect] has been called. + var _isDisconnected = false; + + /// Whether the user has called [close]. + var _closed = false; + + /// The subscription to the stream passed to [addStream], if a stream is + /// currently being added. + StreamSubscription _addStreamSubscription; + + /// The completer for the future returned by [addStream], if a stream is + /// currently being added. + Completer _addStreamCompleter; + + /// Whether we're currently adding a stream with [addStream]. + bool get _inAddStream => _addStreamSubscription != null; + + _DisconnectorSink(this._inner); + + void add(T data) { + if (_closed) throw new StateError("Cannot add event after closing."); + if (_inAddStream) { + throw new StateError("Cannot add event while adding stream."); + } + if (_isDisconnected) return; + + _inner.add(data); + } + + void addError(error, [StackTrace stackTrace]) { + if (_closed) throw new StateError("Cannot add event after closing."); + if (_inAddStream) { + throw new StateError("Cannot add event while adding stream."); + } + if (_isDisconnected) return; + + _inner.addError(error, stackTrace); + } + + Future addStream(Stream stream) { + if (_closed) throw new StateError("Cannot add stream after closing."); + if (_inAddStream) { + throw new StateError("Cannot add stream while adding stream."); + } + if (_isDisconnected) return new Future.value(); + + _addStreamCompleter = new Completer.sync(); + _addStreamSubscription = stream.listen( + _inner.add, + onError: _inner.addError, + onDone: _addStreamCompleter.complete); + return _addStreamCompleter.future.then((_) { + _addStreamCompleter = null; + _addStreamSubscription = null; + }); + } + + Future close() { + if (_inAddStream) { + throw new StateError("Cannot close sink while adding stream."); + } + + _closed = true; + return _inner.close(); + } + + /// Disconnects this sink. + /// + /// This closes the underlying sink and stops forwarding events. + void _disconnect() { + _isDisconnected = true; + _inner.close(); + + if (!_inAddStream) return; + _addStreamCompleter.complete(_addStreamSubscription.cancel()); + _addStreamCompleter = null; + _addStreamSubscription = null; + } +} diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index 992f7026a..b89845d05 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -10,6 +10,7 @@ import 'src/guarantee_channel.dart'; import 'src/stream_channel_transformer.dart'; export 'src/delegating_stream_channel.dart'; +export 'src/disconnector.dart'; export 'src/isolate_channel.dart'; export 'src/json_document_transformer.dart'; export 'src/multi_channel.dart'; diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 52ee52171..c787b95ea 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.2.0 +version: 1.3.0 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart new file mode 100644 index 000000000..09cdddc57 --- /dev/null +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -0,0 +1,113 @@ +// Copyright (c) 2016, 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 'dart:isolate'; + +import 'package:async/async.dart'; +import 'package:stream_channel/stream_channel.dart'; +import 'package:test/test.dart'; + +import 'utils.dart'; + +void main() { + var streamController; + var sinkController; + var disconnector; + var channel; + setUp(() { + streamController = new StreamController(); + sinkController = new StreamController(); + disconnector = new Disconnector(); + channel = new StreamChannel.withGuarantees( + streamController.stream, sinkController.sink) + .transform(disconnector); + }); + + group("before disconnection", () { + test("forwards events from the sink as normal", () { + channel.sink.add(1); + channel.sink.add(2); + channel.sink.add(3); + channel.sink.close(); + + expect(sinkController.stream.toList(), completion(equals([1, 2, 3]))); + }); + + test("forwards events to the stream as normal", () { + streamController.add(1); + streamController.add(2); + streamController.add(3); + streamController.close(); + + expect(channel.stream.toList(), completion(equals([1, 2, 3]))); + }); + + test("events can't be added when the sink is explicitly closed", () { + sinkController.stream.listen(null); // Work around sdk#19095. + + expect(channel.sink.close(), completes); + expect(() => channel.sink.add(1), throwsStateError); + expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addStream(new Stream.fromIterable([])), + throwsStateError); + }); + + test("events can't be added while a stream is being added", () { + var controller = new StreamController(); + channel.sink.addStream(controller.stream); + + expect(() => channel.sink.add(1), throwsStateError); + expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addStream(new Stream.fromIterable([])), + throwsStateError); + expect(() => channel.sink.close(), throwsStateError); + + controller.close(); + }); + }); + + test("cancels addStream when disconnected", () async { + var canceled = false; + var controller = new StreamController(onCancel: () { + canceled = true; + }); + expect(channel.sink.addStream(controller.stream), completes); + disconnector.disconnect(); + + await pumpEventQueue(); + expect(canceled, isTrue); + }); + + group("after disconnection", () { + setUp(() => disconnector.disconnect()); + + test("closes the inner sink and ignores events to the outer sink", () { + channel.sink.add(1); + channel.sink.add(2); + channel.sink.add(3); + channel.sink.close(); + + expect(sinkController.stream.toList(), completion(isEmpty)); + }); + + test("closes the stream", () { + expect(channel.stream.toList(), completion(isEmpty)); + }); + + test("completes done", () { + sinkController.stream.listen(null); // Work around sdk#19095. + expect(channel.sink.done, completes); + }); + + test("still emits state errors after explicit close", () { + sinkController.stream.listen(null); // Work around sdk#19095. + expect(channel.sink.close(), completes); + + expect(() => channel.sink.add(1), throwsStateError); + expect(() => channel.sink.addError("oh no"), throwsStateError); + }); + }); +} \ No newline at end of file From 0f4b74769c54889b9eaa430c4cb48d2ecacb6e5a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 10 Feb 2016 13:08:55 -0800 Subject: [PATCH 022/138] Make IsolateChannel's controllers synchronous. This is slightly more efficient, and also make it easier for other packages to work around dart-lang/sdkdart-lang/stream_channel#25745. R=tjblasi@google.com Review URL: https://codereview.chromium.org//1690473002 . --- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/lib/src/isolate_channel.dart | 6 ++++-- pkgs/stream_channel/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index dd749369e..05a83e074 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.1 + +* Make `IsolateChannel` slightly more efficient. + ## 1.3.0 * Add `Disconnector`, a transformer that allows the caller to disconnect the diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index 3466d19dd..dcb52cbf3 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -53,7 +53,8 @@ class IsolateChannel extends StreamChannelMixin { var subscription; subscription = receivePort.listen((message) { if (message is SendPort) { - var controller = new StreamChannelController(allowForeignErrors: false); + var controller = new StreamChannelController( + allowForeignErrors: false, sync: true); new SubscriptionStream(subscription).pipe(controller.local.sink); controller.local.stream.listen(message.send, onDone: receivePort.close); @@ -91,7 +92,8 @@ class IsolateChannel extends StreamChannelMixin { /// Creates a stream channel that receives messages from [receivePort] and /// sends them over [sendPort]. factory IsolateChannel(ReceivePort receivePort, SendPort sendPort) { - var controller = new StreamChannelController(allowForeignErrors: false); + var controller = new StreamChannelController( + allowForeignErrors: false, sync: true); receivePort.pipe(controller.local.sink); controller.local.stream.listen(sendPort.send, onDone: receivePort.close); return new IsolateChannel._( diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index c787b95ea..930f74431 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.3.0 +version: 1.3.1-dev description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From 2ff097b8b67a2ba5dfceeb1ed5e6ec92a4e09de8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 10 Feb 2016 14:26:24 -0800 Subject: [PATCH 023/138] Make MultiChannel follow the stream channel rules. It was written before the rules were fully fleshed-out, and I forgot to update it to comply. R=tjblasi@google.com Review URL: https://codereview.chromium.org//1686263002 . --- pkgs/stream_channel/CHANGELOG.md | 2 + .../stream_channel/lib/src/multi_channel.dart | 86 ++++---- pkgs/stream_channel/pubspec.yaml | 2 +- .../test/multi_channel_test.dart | 187 +++++++++++++++--- 4 files changed, 207 insertions(+), 70 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 05a83e074..b1b735072 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -2,6 +2,8 @@ * Make `IsolateChannel` slightly more efficient. +* Make `MultiChannel` follow the stream channel rules. + ## 1.3.0 * Add `Disconnector`, a transformer that allows the caller to disconnect the diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index cba592ab5..112997e57 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -4,6 +4,8 @@ import 'dart:async'; +import 'package:async/async.dart'; + import '../stream_channel.dart'; /// A class that multiplexes multiple virtual channels across a single @@ -85,21 +87,15 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { /// The subscription to [_inner.stream]. StreamSubscription _innerStreamSubscription; - Stream get stream => _streamController.stream; - final _streamController = new StreamController(sync: true); - - StreamSink get sink => _sinkController.sink; - final _sinkController = new StreamController(sync: true); + Stream get stream => _mainController.foreign.stream; + StreamSink get sink => _mainController.foreign.sink; - /// A map from virtual channel ids to [StreamController]s that should be used - /// to write messages received from those channels. - final _streamControllers = new Map(); + /// The controller for this channel. + final _mainController = new StreamChannelController(sync: true); - /// A map from virtual channel ids to [StreamControllers]s that are used - /// to receive messages to write to those channels. - /// - /// Note that this uses the same keys as [_streamControllers]. - final _sinkControllers = new Map(); + /// A map from virtual channel ids to [StreamChannelController]s that should + /// be used to communicate over those channels. + final _controllers = {}; /// The next id to use for a local virtual channel. /// @@ -125,35 +121,34 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { _MultiChannel(this._inner) { // The default connection is a special case which has id 0 on both ends. // This allows it to begin connected without having to send over an id. - _streamControllers[0] = _streamController; - _sinkControllers[0] = _sinkController; - _sinkController.stream.listen( + _controllers[0] = _mainController; + _mainController.local.stream.listen( (message) => _inner.sink.add([0, message]), onDone: () => _closeChannel(0, 0)); _innerStreamSubscription = _inner.stream.listen((message) { var id = message[0]; - var sink = _streamControllers[id]; + var controller = _controllers[id]; - // A sink might not exist if the channel was closed before an incoming - // message was processed. - if (sink == null) return; + // A controller might not exist if the channel was closed before an + // incoming message was processed. + if (controller == null) return; if (message.length > 1) { - sink.add(message[1]); + controller.local.sink.add(message[1]); return; } - // A message without data indicates that the channel has been closed. - _sinkControllers[id].close(); - }, onDone: _closeInnerChannel, - onError: _streamController.addError); + // A message without data indicates that the channel has been closed. We + // can only close the sink here without doing any more cleanup, because + // the sink closing will cause the stream to emit a done event which will + // trigger more cleanup. + controller.local.sink.close(); + }, + onDone: _closeInnerChannel, + onError: _mainController.local.sink.addError); } VirtualChannel virtualChannel([id]) { - if (_inner == null) { - throw new StateError("The underlying channel is closed."); - } - var inputId; var outputId; if (id != null) { @@ -171,34 +166,39 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { _nextId += 2; } - if (_streamControllers.containsKey(inputId)) { + // If the inner channel has already closed, create new virtual channels in a + // closed state. + if (_inner == null) { + return new VirtualChannel._( + this, inputId, new Stream.empty(), new NullStreamSink()); + } + + if (_controllers.containsKey(inputId)) { throw new ArgumentError("A virtual channel with id $id already exists."); } - var streamController = new StreamController(sync: true); - var sinkController = new StreamController(sync: true); - _streamControllers[inputId] = streamController; - _sinkControllers[inputId] = sinkController; - sinkController.stream.listen( + var controller = new StreamChannelController(sync: true); + _controllers[inputId] = controller; + controller.local.stream.listen( (message) => _inner.sink.add([outputId, message]), onDone: () => _closeChannel(inputId, outputId)); return new VirtualChannel._( - this, outputId, streamController.stream, sinkController.sink); + this, outputId, controller.foreign.stream, controller.foreign.sink); } /// Closes the virtual channel for which incoming messages have [inputId] and /// outgoing messages have [outputId]. void _closeChannel(int inputId, int outputId) { - _streamControllers.remove(inputId).close(); - _sinkControllers.remove(inputId).close(); + var controller = _controllers.remove(inputId); + controller.local.sink.close(); if (_inner == null) return; // A message without data indicates that the virtual channel has been // closed. _inner.sink.add([outputId]); - if (_streamControllers.isEmpty) _closeInnerChannel(); + if (_controllers.isEmpty) _closeInnerChannel(); } /// Closes the underlying communication channel. @@ -206,9 +206,13 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { _inner.sink.close(); _innerStreamSubscription.cancel(); _inner = null; - for (var controller in _sinkControllers.values.toList()) { - controller.close(); + + // Convert this to a list because the close is dispatched synchronously, and + // that could conceivably remove a controller from [_controllers]. + for (var controller in new List.from(_controllers.values)) { + controller.local.sink.close(); } + _controllers.clear(); } } diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 930f74431..c38c167f3 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.3.1-dev +version: 1.3.1 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index cc9ed1d26..5be250535 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -10,17 +10,13 @@ import 'package:test/test.dart'; import 'utils.dart'; void main() { - var oneToTwo; - var twoToOne; + var controller; var channel1; var channel2; setUp(() { - oneToTwo = new StreamController(); - twoToOne = new StreamController(); - channel1 = new MultiChannel( - new StreamChannel(twoToOne.stream, oneToTwo.sink)); - channel2 = new MultiChannel( - new StreamChannel(oneToTwo.stream, twoToOne.sink)); + controller = new StreamChannelController(); + channel1 = new MultiChannel(controller.local); + channel2 = new MultiChannel(controller.foreign); }); group("the default virtual channel", () { @@ -66,16 +62,16 @@ void main() { test("closes the underlying channel when it closes without any other " "virtual channels", () { - expect(oneToTwo.done, completes); - expect(twoToOne.done, completes); + expect(controller.local.sink.done, completes); + expect(controller.foreign.sink.done, completes); channel1.sink.close(); }); test("doesn't close the underlying channel when it closes with other " "virtual channels", () { - oneToTwo.done.then(expectAsync((_) {}, count: 0)); - twoToOne.done.then(expectAsync((_) {}, count: 0)); + controller.local.sink.done.then(expectAsync((_) {}, count: 0)); + controller.foreign.sink.done.then(expectAsync((_) {}, count: 0)); // Establish another virtual connection which should keep the underlying // connection open. @@ -149,16 +145,16 @@ void main() { channel1.sink.close(); await channel2.stream.toList(); - expect(oneToTwo.done, completes); - expect(twoToOne.done, completes); + expect(controller.local.sink.done, completes); + expect(controller.foreign.sink.done, completes); virtual1.sink.close(); }); test("doesn't close the underlying channel when it closes with other " "virtual channels", () { - oneToTwo.done.then(expectAsync((_) {}, count: 0)); - twoToOne.done.then(expectAsync((_) {}, count: 0)); + controller.local.sink.done.then(expectAsync((_) {}, count: 0)); + controller.foreign.sink.done.then(expectAsync((_) {}, count: 0)); virtual1.sink.close(); @@ -246,16 +242,16 @@ void main() { channel2.sink.close(); await channel1.stream.toList(); - expect(oneToTwo.done, completes); - expect(twoToOne.done, completes); + expect(controller.local.sink.done, completes); + expect(controller.foreign.sink.done, completes); virtual2.sink.close(); }); test("doesn't close the underlying channel when it closes with other " "virtual channels", () { - oneToTwo.done.then(expectAsync((_) {}, count: 0)); - twoToOne.done.then(expectAsync((_) {}, count: 0)); + controller.local.sink.done.then(expectAsync((_) {}, count: 0)); + controller.foreign.sink.done.then(expectAsync((_) {}, count: 0)); virtual2.sink.close(); @@ -288,16 +284,24 @@ void main() { expect(virtual2.stream.toList(), completion(isEmpty)); expect(virtual2.sink.done, completes); - oneToTwo.close(); + controller.local.sink.close(); }); - test("closes, no more virtual channels may be created", () { - expect(channel1.sink.done.then((_) => channel1.virtualChannel()), - throwsStateError); - expect(channel2.sink.done.then((_) => channel2.virtualChannel()), - throwsStateError); + test("closes, more virtual channels are created closed", () async { + channel2.sink.close(); + virtual2.sink.close(); + + // Wait for the existing channels to emit done events. + await channel1.stream.toList(); + await virtual1.stream.toList(); + + var virtual = channel1.virtualChannel(); + expect(virtual.stream.toList(), completion(isEmpty)); + expect(virtual.sink.done, completes); - oneToTwo.close(); + virtual = channel1.virtualChannel(); + expect(virtual.stream.toList(), completion(isEmpty)); + expect(virtual.sink.done, completes); }); test("emits an error, the error is sent only to the default channel", () { @@ -306,7 +310,134 @@ void main() { virtual1.stream.listen(expectAsync((_) {}, count: 0), onError: expectAsync((_) {}, count: 0)); - twoToOne.addError("oh no"); + controller.foreign.sink.addError("oh no"); + }); + }); + + group("stream channel rules", () { + group("for the main stream:", () { + test("closing the sink causes the stream to close before it emits any more " + "events", () { + channel1.sink.add(1); + channel1.sink.add(2); + channel1.sink.add(3); + + channel2.stream.listen(expectAsync((message) { + expect(message, equals(1)); + channel2.sink.close(); + }, count: 1)); + }); + + test("after the stream closes, the sink ignores events", () async { + channel1.sink.close(); + + // Wait for the done event to be delivered. + await channel2.stream.toList(); + channel2.sink.add(1); + channel2.sink.add(2); + channel2.sink.add(3); + channel2.sink.close(); + + // None of our channel.sink additions should make it to the other endpoint. + channel1.stream.listen(expectAsync((_) {}, count: 0)); + await pumpEventQueue(); + }); + + test("canceling the stream's subscription has no effect on the sink", + () async { + channel1.stream.listen(null).cancel(); + await pumpEventQueue(); + + channel1.sink.add(1); + channel1.sink.add(2); + channel1.sink.add(3); + channel1.sink.close(); + expect(channel2.stream.toList(), completion(equals([1, 2, 3]))); + }); + + test("canceling the stream's subscription doesn't stop a done event", + () async { + channel1.stream.listen(null).cancel(); + await pumpEventQueue(); + + channel2.sink.close(); + await pumpEventQueue(); + + channel1.sink.add(1); + channel1.sink.add(2); + channel1.sink.add(3); + channel1.sink.close(); + + // The sink should be ignoring events because the channel closed. + channel2.stream.listen(expectAsync((_) {}, count: 0)); + await pumpEventQueue(); + }); + }); + + group("for a virtual channel:", () { + var virtual1; + var virtual2; + setUp(() { + virtual1 = channel1.virtualChannel(); + virtual2 = channel2.virtualChannel(virtual1.id); + }); + + test("closing the sink causes the stream to close before it emits any more " + "events", () { + virtual1.sink.add(1); + virtual1.sink.add(2); + virtual1.sink.add(3); + + virtual2.stream.listen(expectAsync((message) { + expect(message, equals(1)); + virtual2.sink.close(); + }, count: 1)); + }); + + test("after the stream closes, the sink ignores events", () async { + virtual1.sink.close(); + + // Wait for the done event to be delivered. + await virtual2.stream.toList(); + virtual2.sink.add(1); + virtual2.sink.add(2); + virtual2.sink.add(3); + virtual2.sink.close(); + + // None of our virtual.sink additions should make it to the other endpoint. + virtual1.stream.listen(expectAsync((_) {}, count: 0)); + await pumpEventQueue(); + }); + + test("canceling the stream's subscription has no effect on the sink", + () async { + virtual1.stream.listen(null).cancel(); + await pumpEventQueue(); + + virtual1.sink.add(1); + virtual1.sink.add(2); + virtual1.sink.add(3); + virtual1.sink.close(); + expect(virtual2.stream.toList(), completion(equals([1, 2, 3]))); + }); + + test("canceling the stream's subscription doesn't stop a done event", + () async { + virtual1.stream.listen(null).cancel(); + await pumpEventQueue(); + + virtual2.sink.close(); + await pumpEventQueue(); + + virtual1.sink.add(1); + virtual1.sink.add(2); + virtual1.sink.add(3); + virtual1.sink.close(); + + // The sink should be ignoring events because the stream closed. + virtual2.stream.listen(expectAsync((_) {}, count: 0)); + await pumpEventQueue(); + }); }); }); } From 05da8f92b2e7ec573bbcc55974d1c6c58f863a79 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Tue, 8 Mar 2016 17:09:46 -0800 Subject: [PATCH 024/138] Fix unused imports --- pkgs/stream_channel/test/disconnector_test.dart | 5 +---- pkgs/stream_channel/test/json_document_transformer_test.dart | 2 -- pkgs/stream_channel/test/multi_channel_test.dart | 2 -- pkgs/stream_channel/test/stream_channel_controller_test.dart | 4 ---- pkgs/stream_channel/test/stream_channel_test.dart | 3 --- 5 files changed, 1 insertion(+), 15 deletions(-) diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index 09cdddc57..d7fa885cd 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -3,10 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; -import 'dart:convert'; -import 'dart:isolate'; -import 'package:async/async.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; @@ -110,4 +107,4 @@ void main() { expect(() => channel.sink.addError("oh no"), throwsStateError); }); }); -} \ No newline at end of file +} diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index 65a349724..4dd5ea7fb 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -8,8 +8,6 @@ import 'dart:convert'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; -import 'utils.dart'; - void main() { var streamController; var sinkController; diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index 5be250535..0e58d382e 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -2,8 +2,6 @@ // 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 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; diff --git a/pkgs/stream_channel/test/stream_channel_controller_test.dart b/pkgs/stream_channel/test/stream_channel_controller_test.dart index cf8a31b36..7503387d5 100644 --- a/pkgs/stream_channel/test/stream_channel_controller_test.dart +++ b/pkgs/stream_channel/test/stream_channel_controller_test.dart @@ -2,13 +2,9 @@ // 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 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; -import 'utils.dart'; - void main() { group("asynchronously", () { var controller; diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index f5251778d..2a6566ac7 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -4,14 +4,11 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:isolate'; import 'package:async/async.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; -import 'utils.dart'; - void main() { var streamController; var sinkController; From d58d636733c810835851ace1aee70c23dd4f6ef5 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 10 May 2016 14:54:50 -0700 Subject: [PATCH 025/138] Fix all strong-mode errors and warnings. R=sigmund@google.com Review URL: https://codereview.chromium.org//1966893002 . --- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/lib/src/disconnector.dart | 2 +- pkgs/stream_channel/lib/src/isolate_channel.dart | 15 +++++++++------ .../lib/src/json_document_transformer.dart | 2 +- .../lib/src/stream_channel_transformer.dart | 9 +++++---- pkgs/stream_channel/pubspec.yaml | 2 +- 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index b1b735072..a5a7e466b 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.2 + +* Fix all strong-mode errors and warnings. + ## 1.3.1 * Make `IsolateChannel` slightly more efficient. diff --git a/pkgs/stream_channel/lib/src/disconnector.dart b/pkgs/stream_channel/lib/src/disconnector.dart index 35ecd1cc4..beff71dd0 100644 --- a/pkgs/stream_channel/lib/src/disconnector.dart +++ b/pkgs/stream_channel/lib/src/disconnector.dart @@ -38,7 +38,7 @@ class Disconnector implements StreamChannelTransformer { StreamChannel bind(StreamChannel channel) { return channel.changeSink((innerSink) { - var sink = new _DisconnectorSink(innerSink); + var sink = new _DisconnectorSink(innerSink); if (_isDisconnected) { sink._disconnect(); diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index dcb52cbf3..c725fef8e 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -44,7 +44,7 @@ class IsolateChannel extends StreamChannelMixin { // value to be an [IsolateChannel]. var streamCompleter = new StreamCompleter(); var sinkCompleter = new StreamSinkCompleter(); - var channel = new IsolateChannel._( + var channel = new IsolateChannel._( streamCompleter.stream, sinkCompleter.sink); // The first message across the ReceivePort should be a SendPort pointing to @@ -53,10 +53,11 @@ class IsolateChannel extends StreamChannelMixin { var subscription; subscription = receivePort.listen((message) { if (message is SendPort) { - var controller = new StreamChannelController( + var controller = new StreamChannelController( allowForeignErrors: false, sync: true); - new SubscriptionStream(subscription).pipe(controller.local.sink); - controller.local.stream.listen(message.send, + new SubscriptionStream(subscription).pipe(controller.local.sink); + controller.local.stream.listen( + (data) => message.send(data), onDone: receivePort.close); streamCompleter.setSourceStream(controller.foreign.stream); @@ -92,10 +93,12 @@ class IsolateChannel extends StreamChannelMixin { /// Creates a stream channel that receives messages from [receivePort] and /// sends them over [sendPort]. factory IsolateChannel(ReceivePort receivePort, SendPort sendPort) { - var controller = new StreamChannelController( + var controller = new StreamChannelController( allowForeignErrors: false, sync: true); receivePort.pipe(controller.local.sink); - controller.local.stream.listen(sendPort.send, onDone: receivePort.close); + controller.local.stream.listen( + (data) => sendPort.send(data), + onDone: receivePort.close); return new IsolateChannel._( controller.foreign.stream, controller.foreign.sink); } diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index 19b2e08f7..c62c597cb 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -22,7 +22,7 @@ final jsonDocument = new JsonDocumentTransformer(); /// [FormatException]. If an unencodable object is added to the sink, it /// synchronously throws a [JsonUnsupportedObjectError]. class JsonDocumentTransformer - implements StreamChannelTransformer { + implements StreamChannelTransformer { /// The underlying codec that implements the encoding and decoding logic. final JsonCodec _codec; diff --git a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart index be032c60d..ac980859d 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart @@ -19,10 +19,10 @@ import '../stream_channel.dart'; /// Transformers must be able to have `bind` called multiple times. class StreamChannelTransformer { /// The transformer to use on the channel's stream. - final StreamTransformer _streamTransformer; + final StreamTransformer _streamTransformer; /// The transformer to use on the channel's sink. - final StreamSinkTransformer _sinkTransformer; + final StreamSinkTransformer _sinkTransformer; /// Creates a [StreamChannelTransformer] from existing stream and sink /// transformers. @@ -35,8 +35,9 @@ class StreamChannelTransformer { /// and all output from its stream is decoded using [Codec.decoder]. StreamChannelTransformer.fromCodec(Codec codec) : this( - codec.decoder, - new StreamSinkTransformer.fromStreamTransformer(codec.encoder)); + typedStreamTransformer(codec.decoder), + StreamSinkTransformer.typed( + new StreamSinkTransformer.fromStreamTransformer(codec.encoder))); /// Transforms the events sent to and emitted by [channel]. /// diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index c38c167f3..8410e05c3 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -6,7 +6,7 @@ homepage: https://github.com/dart-lang/stream_channel environment: sdk: '>=1.8.0 <2.0.0' dependencies: - async: '^1.8.0' + async: '^1.11.0' stack_trace: '^1.0.0' dev_dependencies: test: '^0.12.0' From cafec58f341bd7b7cae073e9c6b7c20d3acd0ed5 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 10 May 2016 14:59:00 -0700 Subject: [PATCH 026/138] Bump the version to 1.3.2. This was supposed to happen in the last CL, but didn't instead. R=sigmund@google.com Review URL: https://codereview.chromium.org//1971573002 . --- pkgs/stream_channel/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 8410e05c3..3e87e2bba 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.3.1 +version: 1.3.2 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From 0029c282a14810946eb2e686e0792912b0127322 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 10 May 2016 15:42:17 -0700 Subject: [PATCH 027/138] Add type-coercion functions. These match (and are based on) the coercion functions in dart-lang/async. R=sigmund@google.com Review URL: https://codereview.chromium.org//1966853003 . --- pkgs/stream_channel/.analysis_options | 2 ++ pkgs/stream_channel/CHANGELOG.md | 8 ++++++++ .../lib/src/stream_channel_transformer.dart | 16 ++++++++++++++++ .../lib/src/transformer/typed.dart | 17 +++++++++++++++++ pkgs/stream_channel/lib/stream_channel.dart | 10 ++++++++++ pkgs/stream_channel/pubspec.yaml | 2 +- 6 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 pkgs/stream_channel/.analysis_options create mode 100644 pkgs/stream_channel/lib/src/transformer/typed.dart diff --git a/pkgs/stream_channel/.analysis_options b/pkgs/stream_channel/.analysis_options new file mode 100644 index 000000000..a10d4c5a0 --- /dev/null +++ b/pkgs/stream_channel/.analysis_options @@ -0,0 +1,2 @@ +analyzer: + strong-mode: true diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index a5a7e466b..6d86e4886 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.4.0 + +* Add `StreamChannel.cast()`, which soundly coerces the generic type of a + channel. + +* Add `StreamChannelTransformer.typed()`, which soundly coerces the generic type + of a transformer. + ## 1.3.2 * Fix all strong-mode errors and warnings. diff --git a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart index ac980859d..ca09ea16b 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart @@ -8,6 +8,7 @@ import 'dart:convert'; import 'package:async/async.dart'; import '../stream_channel.dart'; +import 'transformer/typed.dart'; /// A [StreamChannelTransformer] transforms the events being passed to and /// emitted by a [StreamChannel]. @@ -24,6 +25,21 @@ class StreamChannelTransformer { /// The transformer to use on the channel's sink. final StreamSinkTransformer _sinkTransformer; + /// Creates a wrapper that coerces the type of [transformer]. + /// + /// This soundly converts a [StreamChannelTransformer] to a + /// `StreamChannelTransformer`, regardless of its original generic type, + /// by asserting that the events emitted by the transformed channel's stream + /// are instances of `T` whenever they're provided. If they're not, the stream + /// throws a [CastError]. This also means that calls to [StreamSink.add] on + /// the transformed channel's sink may throw a [CastError] if the argument + /// type doesn't match the reified type of the sink. + static StreamChannelTransformer/**/ typed/**/( + StreamChannelTransformer transformer) => + transformer is StreamChannelTransformer/**/ + ? transformer + : new TypeSafeStreamChannelTransformer(transformer); + /// Creates a [StreamChannelTransformer] from existing stream and sink /// transformers. const StreamChannelTransformer( diff --git a/pkgs/stream_channel/lib/src/transformer/typed.dart b/pkgs/stream_channel/lib/src/transformer/typed.dart new file mode 100644 index 000000000..f35e01c98 --- /dev/null +++ b/pkgs/stream_channel/lib/src/transformer/typed.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2016, 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 '../../stream_channel.dart'; + +/// A wrapper that coerces the generic type of the channel returned by an inner +/// transformer to `S`. +class TypeSafeStreamChannelTransformer + implements StreamChannelTransformer { + final StreamChannelTransformer _inner; + + TypeSafeStreamChannelTransformer(this._inner); + + StreamChannel bind(StreamChannel channel) => + _inner.bind(channel).cast(); +} diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index b89845d05..3615d2129 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -109,6 +109,13 @@ abstract class StreamChannel { /// Returns a copy of [this] with [sink] replaced by [change]'s return /// value. StreamChannel changeSink(StreamSink change(StreamSink sink)); + + /// Returns a copy of [this] with the generic type coerced to [S]. + /// + /// If any events emitted by [stream] aren't of type [S], they're converted + /// into [CastError] events. Similarly, if any events are added to [sync] that + /// aren't of type [S], a [CastError] is thrown. + StreamChannel/**/ cast/**/(); } /// An implementation of [StreamChannel] that simply takes a stream and a sink @@ -145,4 +152,7 @@ abstract class StreamChannelMixin implements StreamChannel { StreamChannel changeSink(StreamSink change(StreamSink sink)) => new StreamChannel(stream, change(sink)); + + StreamChannel/**/ cast/**/() => new StreamChannel( + DelegatingStream.typed(stream), DelegatingStreamSink.typed(sink)); } diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 3e87e2bba..1c1df3136 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.3.2 +version: 1.4.0 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From 29a1b0242ec1a713d2f2957049574cf26a7c0196 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 6 Jun 2016 16:25:39 -0700 Subject: [PATCH 028/138] Add StreamChannel.withCloseGuarantee. This also properly enforces the close guarantee for transformers provided by this package. R=rnystrom@google.com Review URL: https://codereview.chromium.org//2041983003 . --- pkgs/stream_channel/CHANGELOG.md | 11 +++ .../lib/src/close_guarantee_channel.dart | 86 +++++++++++++++++++ .../lib/src/json_document_transformer.dart | 2 +- .../lib/src/stream_channel_transformer.dart | 11 ++- pkgs/stream_channel/lib/stream_channel.dart | 18 +++- .../test/with_close_guarantee_test.dart | 66 ++++++++++++++ 6 files changed, 189 insertions(+), 5 deletions(-) create mode 100644 pkgs/stream_channel/lib/src/close_guarantee_channel.dart create mode 100644 pkgs/stream_channel/test/with_close_guarantee_test.dart diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 6d86e4886..6e3a6ac94 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,14 @@ +## 1.5.0 + +* Add `new StreamChannel.withCloseGuarantee()` to provide the specific guarantee + that closing the sink causes the stream to close before it emits any more + events. This is the only guarantee that isn't automatically preserved when + transforming a channel. + +* `StreamChannelTransformer`s provided by the `stream_channel` package now + properly provide the guarantee that closing the sink causes the stream to + close before it emits any more events + ## 1.4.0 * Add `StreamChannel.cast()`, which soundly coerces the generic type of a diff --git a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart new file mode 100644 index 000000000..a2c69bcb8 --- /dev/null +++ b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart @@ -0,0 +1,86 @@ +// Copyright (c) 2016, 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 'package:async/async.dart'; + +import '../stream_channel.dart'; + +/// A [StreamChannel] that specifically enforces the stream channel guarantee +/// that closing the sink causes the stream to close before it emits any more +/// events +/// +/// This is exposed via [new StreamChannel.withCloseGuarantee]. +class CloseGuaranteeChannel extends StreamChannelMixin { + Stream get stream => _stream; + _CloseGuaranteeStream _stream; + + StreamSink get sink => _sink; + _CloseGuaranteeSink _sink; + + /// The subscription to the inner stream. + StreamSubscription _subscription; + + /// Whether the sink has closed, causing the underlying channel to disconnect. + bool _disconnected = false; + + CloseGuaranteeChannel(Stream innerStream, StreamSink innerSink) { + _sink = new _CloseGuaranteeSink(innerSink, this); + _stream = new _CloseGuaranteeStream(innerStream, this); + } +} + +/// The stream for [CloseGuaranteeChannel]. +/// +/// This wraps the inner stream to save the subscription on the channel when +/// [listen] is called. +class _CloseGuaranteeStream extends Stream { + /// The inner stream this is delegating to. + final Stream _inner; + + /// The [CloseGuaranteeChannel] this belongs to. + final CloseGuaranteeChannel _channel; + + _CloseGuaranteeStream(this._inner, this._channel); + + StreamSubscription listen(void onData(T event), + {Function onError, void onDone(), bool cancelOnError}) { + // If the channel is already disconnected, we shouldn't dispatch anything + // but a done event. + if (_channel._disconnected) { + onData = null; + onError = null; + } + + var subscription = _inner.listen(onData, + onError: onError, onDone: onDone, cancelOnError: cancelOnError); + if (!_channel._disconnected) { + _channel._subscription = subscription; + } + return subscription; + } +} + +/// The sink for [CloseGuaranteeChannel]. +/// +/// This wraps the inner sink to cancel the stream subscription when the sink is +/// canceled. +class _CloseGuaranteeSink extends DelegatingStreamSink { + /// The [CloseGuaranteeChannel] this belongs to. + final CloseGuaranteeChannel _channel; + + _CloseGuaranteeSink(StreamSink inner, this._channel) : super(inner); + + Future close() { + var done = super.close(); + _channel._disconnected = true; + if (_channel._subscription != null) { + // Don't dispatch anything but a done event. + _channel._subscription.onData(null); + _channel._subscription.onError(null); + } + return done; + } +} diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index c62c597cb..86b9ae71c 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -40,6 +40,6 @@ class JsonDocumentTransformer var sink = new StreamSinkTransformer.fromHandlers(handleData: (data, sink) { sink.add(_codec.encode(data)); }).bind(channel.sink); - return new StreamChannel(stream, sink); + return new StreamChannel.withCloseGuarantee(stream, sink); } } diff --git a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart index ca09ea16b..46232d74c 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart @@ -17,7 +17,14 @@ import 'transformer/typed.dart'; /// [StreamSinkTransformer]. Each transformer defines a [bind] method that takes /// in the original [StreamChannel] and returns the transformed version. /// -/// Transformers must be able to have `bind` called multiple times. +/// Transformers must be able to have [bind] called multiple times. If a +/// subclass implements [bind] explicitly, it should be sure that the returned +/// stream follows the second stream channel guarantee: closing the sink causes +/// the stream to close before it emits any more events. This guarantee is +/// invalidated when an asynchronous gap is added between the original stream's +/// event dispatch and the returned stream's, for example by transforming it +/// with a [StreamTransformer]. The guarantee can be easily preserved using [new +/// StreamChannel.withCloseGuarantee]. class StreamChannelTransformer { /// The transformer to use on the channel's stream. final StreamTransformer _streamTransformer; @@ -63,7 +70,7 @@ class StreamChannelTransformer { /// `channel.straem`, the transformer will transform them and pass the /// transformed versions to the returned channel's stream. StreamChannel bind(StreamChannel channel) => - new StreamChannel( + new StreamChannel.withCloseGuarantee( channel.stream.transform(_streamTransformer), _sinkTransformer.bind(channel.sink)); } diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index 3615d2129..16323b169 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'package:async/async.dart'; import 'src/guarantee_channel.dart'; +import 'src/close_guarantee_channel.dart'; import 'src/stream_channel_transformer.dart'; export 'src/delegating_stream_channel.dart'; @@ -87,6 +88,19 @@ abstract class StreamChannel { {bool allowSinkErrors: true}) => new GuaranteeChannel(stream, sink, allowSinkErrors: allowSinkErrors); + /// Creates a new [StreamChannel] that communicates over [stream] and [sink]. + /// + /// This specifically enforces the second guarantee: closing the sink causes + /// the stream to close before it emits any more events. This guarantee is + /// invalidated when an asynchronous gap is added between the original + /// stream's event dispatch and the returned stream's, for example by + /// transforming it with a [StreamTransformer]. This is a lighter-weight way + /// of preserving that guarantee in particular than + /// [StreamChannel.withGuarantees]. + factory StreamChannel.withCloseGuarantee(Stream stream, + StreamSink sink) => + new CloseGuaranteeChannel(stream, sink); + /// Connects [this] to [other], so that any values emitted by either are sent /// directly to the other. void pipe(StreamChannel other); @@ -148,10 +162,10 @@ abstract class StreamChannelMixin implements StreamChannel { changeSink(transformer.bind); StreamChannel changeStream(Stream change(Stream stream)) => - new StreamChannel(change(stream), sink); + new StreamChannel.withCloseGuarantee(change(stream), sink); StreamChannel changeSink(StreamSink change(StreamSink sink)) => - new StreamChannel(stream, change(sink)); + new StreamChannel.withCloseGuarantee(stream, change(sink)); StreamChannel/**/ cast/**/() => new StreamChannel( DelegatingStream.typed(stream), DelegatingStreamSink.typed(sink)); diff --git a/pkgs/stream_channel/test/with_close_guarantee_test.dart b/pkgs/stream_channel/test/with_close_guarantee_test.dart new file mode 100644 index 000000000..caf48cf1c --- /dev/null +++ b/pkgs/stream_channel/test/with_close_guarantee_test.dart @@ -0,0 +1,66 @@ +// Copyright (c) 2016, 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 'package:async/async.dart'; +import 'package:stream_channel/stream_channel.dart'; +import 'package:test/test.dart'; + +import 'utils.dart'; + +final _delayTransformer = new StreamTransformer.fromHandlers( + handleData: (data, sink) => new Future.microtask(() => sink.add(data)), + handleDone: (sink) => new Future.microtask(() => sink.close())); + +final _delaySinkTransformer = + new StreamSinkTransformer.fromStreamTransformer(_delayTransformer); + +void main() { + var controller; + var channel; + setUp(() { + controller = new StreamChannelController(); + + // Add a bunch of layers of asynchronous dispatch between the channel and + // the underlying controllers. + var stream = controller.foreign.stream; + var sink = controller.foreign.sink; + for (var i = 0; i < 10; i++) { + stream = stream.transform(_delayTransformer); + sink = _delaySinkTransformer.bind(sink); + } + + channel = new StreamChannel.withCloseGuarantee(stream, sink); + }); + + test("closing the event sink causes the stream to close before it emits any " + "more events", () async { + controller.local.sink.add(1); + controller.local.sink.add(2); + controller.local.sink.add(3); + + expect(channel.stream.listen(expectAsync((event) { + if (event == 2) channel.sink.close(); + }, count: 2)).asFuture(), completes); + + await pumpEventQueue(); + }); + + test("closing the event sink before events are emitted causes the stream to " + "close immediately", () async { + channel.sink.close(); + channel.stream.listen( + expectAsync((_) {}, count: 0), + onError: expectAsync((_, __) {}, count: 0), + onDone: expectAsync(() {})); + + controller.local.sink.add(1); + controller.local.sink.add(2); + controller.local.sink.add(3); + controller.local.sink.close(); + + await pumpEventQueue(); + }); +} From e39e092305561edffc588391472e4bdc94df9d76 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 6 Jun 2016 16:35:00 -0700 Subject: [PATCH 029/138] Bump the pubspec version to 1.5.0. R=cbracken@google.com Review URL: https://codereview.chromium.org//2041813003 . --- pkgs/stream_channel/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 1c1df3136..3428dac28 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.4.0 +version: 1.5.0 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From a35416e22a7b83ab32268f1122bc51dc148b79fa Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 6 Jun 2016 16:54:35 -0700 Subject: [PATCH 030/138] Fix transformer tests. These tests should never have passed, since they were closing a sink before its controller emitted events. R=cbracken@google.com Review URL: https://codereview.chromium.org//2048473002 . --- pkgs/stream_channel/pubspec.yaml | 2 +- pkgs/stream_channel/test/stream_channel_test.dart | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 3428dac28..bcdfe8e78 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.5.0 +version: 1.5.1-dev description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index 2a6566ac7..41f4c32ec 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -41,13 +41,13 @@ void main() { expect(sinkController.stream.toList(), completion(equals([4, 5, 6]))); }); - test("transform() transforms the channel", () { + test("transform() transforms the channel", () async { var transformed = channel.transform( new StreamChannelTransformer.fromCodec(UTF8)); streamController.add([102, 111, 111, 98, 97, 114]); streamController.close(); - expect(transformed.stream.toList(), completion(equals(["foobar"]))); + expect(await transformed.stream.toList(), equals(["foobar"])); transformed.sink.add("fblthp"); transformed.sink.close(); @@ -55,12 +55,12 @@ void main() { completion(equals([[102, 98, 108, 116, 104, 112]]))); }); - test("transformStream() transforms only the stream", () { + test("transformStream() transforms only the stream", () async { var transformed = channel.transformStream(UTF8.decoder); streamController.add([102, 111, 111, 98, 97, 114]); streamController.close(); - expect(transformed.stream.toList(), completion(equals(["foobar"]))); + expect(await transformed.stream.toList(), equals(["foobar"])); transformed.sink.add("fblthp"); transformed.sink.close(); @@ -68,14 +68,14 @@ void main() { completion(equals(["fblthp"]))); }); - test("transformSink() transforms only the sink", () { + test("transformSink() transforms only the sink", () async { var transformed = channel.transformSink( new StreamSinkTransformer.fromStreamTransformer(UTF8.encoder)); streamController.add([102, 111, 111, 98, 97, 114]); streamController.close(); - expect(transformed.stream.toList(), - completion(equals([[102, 111, 111, 98, 97, 114]]))); + expect(await transformed.stream.toList(), + equals([[102, 111, 111, 98, 97, 114]])); transformed.sink.add("fblthp"); transformed.sink.close(); From 6a99277c40fa77a3bc7dbcc6e003d5386b0b8143 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 19 Jan 2017 13:43:02 -0800 Subject: [PATCH 031/138] Return a future from Disconnector.disconnect(). (dart-lang/stream_channel#4) --- pkgs/stream_channel/CHANGELOG.md | 5 +++ pkgs/stream_channel/lib/src/disconnector.dart | 44 ++++++++++++------- pkgs/stream_channel/pubspec.yaml | 2 +- .../test/disconnector_test.dart | 44 ++++++++++++++++++- 4 files changed, 76 insertions(+), 19 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 6e3a6ac94..a018418ef 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.6.0 + +* `Disconnector.disconnect()` now returns a future that completes when all the + inner `StreamSink.close()` futures have completed. + ## 1.5.0 * Add `new StreamChannel.withCloseGuarantee()` to provide the specific guarantee diff --git a/pkgs/stream_channel/lib/src/disconnector.dart b/pkgs/stream_channel/lib/src/disconnector.dart index beff71dd0..b23813e96 100644 --- a/pkgs/stream_channel/lib/src/disconnector.dart +++ b/pkgs/stream_channel/lib/src/disconnector.dart @@ -4,6 +4,8 @@ import 'dart:async'; +import 'package:async/async.dart'; + import '../stream_channel.dart'; /// Allows the caller to force a channel to disconnect. @@ -17,8 +19,7 @@ import '../stream_channel.dart'; /// be disconnected immediately. class Disconnector implements StreamChannelTransformer { /// Whether [disconnect] has been called. - bool get isDisconnected => _isDisconnected; - var _isDisconnected = false; + bool get isDisconnected => _disconnectMemo.hasRun; /// The sinks for transformed channels. /// @@ -28,20 +29,25 @@ class Disconnector implements StreamChannelTransformer { final _sinks = <_DisconnectorSink>[]; /// Disconnects all channels that have been transformed. - void disconnect() { - _isDisconnected = true; - for (var sink in _sinks) { - sink._disconnect(); - } + /// + /// Returns a future that completes when all inner sinks' [StreamSink.close] + /// futures have completed. Note that a [StreamController]'s sink won't close + /// until the corresponding stream has a listener. + Future disconnect() => _disconnectMemo.runOnce(() { + var futures = _sinks.map((sink) => sink._disconnect()).toList(); _sinks.clear(); - } + return Future.wait(futures, eagerError: true); + }); + final _disconnectMemo = new AsyncMemoizer(); StreamChannel bind(StreamChannel channel) { return channel.changeSink((innerSink) { var sink = new _DisconnectorSink(innerSink); - if (_isDisconnected) { - sink._disconnect(); + if (isDisconnected) { + // Ignore errors here, because otherwise there would be no way for the + // user to handle them gracefully. + sink._disconnect().catchError((_) {}); } else { _sinks.add(sink); } @@ -126,14 +132,18 @@ class _DisconnectorSink implements StreamSink { /// Disconnects this sink. /// - /// This closes the underlying sink and stops forwarding events. - void _disconnect() { + /// This closes the underlying sink and stops forwarding events. It returns + /// the [StreamSink.close] future for the underlying sink. + Future _disconnect() { _isDisconnected = true; - _inner.close(); + var future = _inner.close(); + + if (_inAddStream) { + _addStreamCompleter.complete(_addStreamSubscription.cancel()); + _addStreamCompleter = null; + _addStreamSubscription = null; + } - if (!_inAddStream) return; - _addStreamCompleter.complete(_addStreamSubscription.cancel()); - _addStreamCompleter = null; - _addStreamSubscription = null; + return future; } } diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index bcdfe8e78..46d77617c 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.5.1-dev +version: 1.6.0 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index d7fa885cd..311a41c9a 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:async/async.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; @@ -78,8 +79,35 @@ void main() { expect(canceled, isTrue); }); + test("disconnect() returns the close future from the inner sink", () async { + var streamController = new StreamController(); + var sinkController = new StreamController(); + var disconnector = new Disconnector(); + var sink = new _CloseCompleterSink(sinkController.sink); + var channel = new StreamChannel.withGuarantees( + streamController.stream, sink) + .transform(disconnector); + + var disconnectFutureFired = false; + expect(disconnector.disconnect().then((_) { + disconnectFutureFired = true; + }), completes); + + // Give the future time to fire early if it's going to. + await pumpEventQueue(); + expect(disconnectFutureFired, isFalse); + + // When the inner sink's close future completes, so should the + // disconnector's. + sink.completer.complete(); + await pumpEventQueue(); + expect(disconnectFutureFired, isTrue); + }); + group("after disconnection", () { - setUp(() => disconnector.disconnect()); + setUp(() { + disconnector.disconnect(); + }); test("closes the inner sink and ignores events to the outer sink", () { channel.sink.add(1); @@ -108,3 +136,17 @@ void main() { }); }); } + +/// A [StreamSink] wrapper that adds the ability to manually complete the Future +/// returned by [close] using [completer]. +class _CloseCompleterSink extends DelegatingStreamSink { + /// The completer for the future returned by [close]. + final completer = new Completer(); + + _CloseCompleterSink(StreamSink inner) : super(inner); + + Future close() { + super.close(); + return completer.future; + } +} From 963bab00ef228ba381f4fbfba1d62be09a00ff8f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 25 Jan 2017 15:01:46 -0800 Subject: [PATCH 032/138] Fix the type args for StreamChannel.transform(). (dart-lang/stream_channel#7) Closes dart-lang/stream_channel#6 --- pkgs/stream_channel/CHANGELOG.md | 6 ++++++ pkgs/stream_channel/lib/stream_channel.dart | 6 ++++-- pkgs/stream_channel/pubspec.yaml | 2 +- .../stream_channel/test/json_document_transformer_test.dart | 4 ++-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index a018418ef..8d44b214a 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.6.1 + +* Fix the type of `StreamChannel.transform()`. This previously inverted the + generic parameters, so it only really worked with transformers where both + generic types were identical. + ## 1.6.0 * `Disconnector.disconnect()` now returns a future that completes when all the diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index 16323b169..34be085ea 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -108,7 +108,8 @@ abstract class StreamChannel { /// Transforms [this] using [transformer]. /// /// This is identical to calling `transformer.bind(channel)`. - StreamChannel transform(StreamChannelTransformer transformer); + StreamChannel/**/ transform/**/( + StreamChannelTransformer transformer); /// Transforms only the [stream] component of [this] using [transformer]. StreamChannel transformStream(StreamTransformer transformer); @@ -152,7 +153,8 @@ abstract class StreamChannelMixin implements StreamChannel { other.stream.pipe(sink); } - StreamChannel transform(StreamChannelTransformer transformer) => + StreamChannel/**/ transform/**/( + StreamChannelTransformer transformer) => transformer.bind(this); StreamChannel transformStream(StreamTransformer transformer) => diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 46d77617c..7d395a3ea 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.6.0 +version: 1.6.1 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index 4dd5ea7fb..6f18e361f 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -11,11 +11,11 @@ import 'package:test/test.dart'; void main() { var streamController; var sinkController; - var channel; + StreamChannel channel; setUp(() { streamController = new StreamController(); sinkController = new StreamController(); - channel = new StreamChannel( + channel = new StreamChannel( streamController.stream, sinkController.sink); }); From 48080d014f179add2150a1e82f78e85708cf29f5 Mon Sep 17 00:00:00 2001 From: Keerti Parthasarathy Date: Wed, 26 Jul 2017 14:54:07 -0700 Subject: [PATCH 033/138] Update comment style generic syntax BUG= R=kevmoo@google.com Review-Url: https://codereview.chromium.org//2987963002 . --- .../lib/src/stream_channel_transformer.dart | 4 ++-- pkgs/stream_channel/lib/stream_channel.dart | 12 ++++++------ pkgs/stream_channel/pubspec.yaml | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart index 46232d74c..d6d10ff5e 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart @@ -41,9 +41,9 @@ class StreamChannelTransformer { /// throws a [CastError]. This also means that calls to [StreamSink.add] on /// the transformed channel's sink may throw a [CastError] if the argument /// type doesn't match the reified type of the sink. - static StreamChannelTransformer/**/ typed/**/( + static StreamChannelTransformer typed( StreamChannelTransformer transformer) => - transformer is StreamChannelTransformer/**/ + transformer is StreamChannelTransformer ? transformer : new TypeSafeStreamChannelTransformer(transformer); diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index 34be085ea..dcbc9a07e 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -108,8 +108,8 @@ abstract class StreamChannel { /// Transforms [this] using [transformer]. /// /// This is identical to calling `transformer.bind(channel)`. - StreamChannel/**/ transform/**/( - StreamChannelTransformer transformer); + StreamChannel transform( + StreamChannelTransformer transformer); /// Transforms only the [stream] component of [this] using [transformer]. StreamChannel transformStream(StreamTransformer transformer); @@ -130,7 +130,7 @@ abstract class StreamChannel { /// If any events emitted by [stream] aren't of type [S], they're converted /// into [CastError] events. Similarly, if any events are added to [sync] that /// aren't of type [S], a [CastError] is thrown. - StreamChannel/**/ cast/**/(); + StreamChannel cast(); } /// An implementation of [StreamChannel] that simply takes a stream and a sink @@ -153,8 +153,8 @@ abstract class StreamChannelMixin implements StreamChannel { other.stream.pipe(sink); } - StreamChannel/**/ transform/**/( - StreamChannelTransformer transformer) => + StreamChannel transform( + StreamChannelTransformer transformer) => transformer.bind(this); StreamChannel transformStream(StreamTransformer transformer) => @@ -169,6 +169,6 @@ abstract class StreamChannelMixin implements StreamChannel { StreamChannel changeSink(StreamSink change(StreamSink sink)) => new StreamChannel.withCloseGuarantee(stream, change(sink)); - StreamChannel/**/ cast/**/() => new StreamChannel( + StreamChannel cast() => new StreamChannel( DelegatingStream.typed(stream), DelegatingStreamSink.typed(sink)); } diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 7d395a3ea..19a3bd07c 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,10 +1,10 @@ name: stream_channel -version: 1.6.1 +version: 1.6.2-dev description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel environment: - sdk: '>=1.8.0 <2.0.0' + sdk: '>=1.21.0 <2.0.0-dev.infinity' dependencies: async: '^1.11.0' stack_trace: '^1.0.0' From 6f2269b5438c1460e5b4e71b787f2ceebf795491 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 26 Jul 2017 14:35:03 -0700 Subject: [PATCH 034/138] Rename analysis options --- pkgs/stream_channel/{.analysis_options => analysis_options.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pkgs/stream_channel/{.analysis_options => analysis_options.yaml} (100%) diff --git a/pkgs/stream_channel/.analysis_options b/pkgs/stream_channel/analysis_options.yaml similarity index 100% rename from pkgs/stream_channel/.analysis_options rename to pkgs/stream_channel/analysis_options.yaml From 398407eeaeba3fc852123300b6f65c3215a9b3bf Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 26 Jul 2017 14:37:58 -0700 Subject: [PATCH 035/138] dartfmt --- pkgs/stream_channel/lib/src/disconnector.dart | 14 +++--- .../lib/src/guarantee_channel.dart | 31 +++++++------ .../lib/src/isolate_channel.dart | 18 ++++---- .../lib/src/stream_channel_completer.dart | 4 +- .../lib/src/stream_channel_transformer.dart | 7 +-- .../lib/src/transformer/typed.dart | 2 +- pkgs/stream_channel/lib/stream_channel.dart | 10 ++--- .../test/disconnector_test.dart | 18 ++++---- .../test/isolate_channel_test.dart | 3 +- .../test/json_document_transformer_test.dart | 4 +- .../test/multi_channel_test.dart | 44 ++++++++++++------- .../test/stream_channel_completer_test.dart | 12 ++--- .../test/stream_channel_controller_test.dart | 21 ++++++--- .../test/stream_channel_test.dart | 31 ++++++++----- pkgs/stream_channel/test/utils.dart | 3 +- .../test/with_close_guarantee_test.dart | 22 ++++++---- .../test/with_guarantees_test.dart | 39 +++++++++------- 17 files changed, 160 insertions(+), 123 deletions(-) diff --git a/pkgs/stream_channel/lib/src/disconnector.dart b/pkgs/stream_channel/lib/src/disconnector.dart index b23813e96..37a376c31 100644 --- a/pkgs/stream_channel/lib/src/disconnector.dart +++ b/pkgs/stream_channel/lib/src/disconnector.dart @@ -34,10 +34,10 @@ class Disconnector implements StreamChannelTransformer { /// futures have completed. Note that a [StreamController]'s sink won't close /// until the corresponding stream has a listener. Future disconnect() => _disconnectMemo.runOnce(() { - var futures = _sinks.map((sink) => sink._disconnect()).toList(); - _sinks.clear(); - return Future.wait(futures, eagerError: true); - }); + var futures = _sinks.map((sink) => sink._disconnect()).toList(); + _sinks.clear(); + return Future.wait(futures, eagerError: true); + }); final _disconnectMemo = new AsyncMemoizer(); StreamChannel bind(StreamChannel channel) { @@ -111,10 +111,8 @@ class _DisconnectorSink implements StreamSink { if (_isDisconnected) return new Future.value(); _addStreamCompleter = new Completer.sync(); - _addStreamSubscription = stream.listen( - _inner.add, - onError: _inner.addError, - onDone: _addStreamCompleter.complete); + _addStreamSubscription = stream.listen(_inner.add, + onError: _inner.addError, onDone: _addStreamCompleter.complete); return _addStreamCompleter.future.then((_) { _addStreamCompleter = null; _addStreamSubscription = null; diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart index a874799c1..f18cbb973 100644 --- a/pkgs/stream_channel/lib/src/guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -32,28 +32,29 @@ class GuaranteeChannel extends StreamChannelMixin { GuaranteeChannel(Stream innerStream, StreamSink innerSink, {bool allowSinkErrors: true}) { - _sink = new _GuaranteeSink(innerSink, this, - allowErrors: allowSinkErrors); + _sink = + new _GuaranteeSink(innerSink, this, allowErrors: allowSinkErrors); // Enforce the single-subscription guarantee by changing a broadcast stream // to single-subscription. if (innerStream.isBroadcast) { - innerStream = innerStream.transform( - const SingleSubscriptionTransformer()); + innerStream = + innerStream.transform(const SingleSubscriptionTransformer()); } - _streamController = new StreamController(onListen: () { - // If the sink has disconnected, we've already called - // [_streamController.close]. - if (_disconnected) return; + _streamController = new StreamController( + onListen: () { + // If the sink has disconnected, we've already called + // [_streamController.close]. + if (_disconnected) return; - _subscription = innerStream.listen(_streamController.add, - onError: _streamController.addError, - onDone: () { + _subscription = innerStream.listen(_streamController.add, + onError: _streamController.addError, onDone: () { _sink._onStreamDisconnected(); _streamController.close(); }); - }, sync: true); + }, + sync: true); } /// Called by [_GuaranteeSink] when the user closes it. @@ -159,10 +160,8 @@ class _GuaranteeSink implements StreamSink { if (_disconnected) return new Future.value(); _addStreamCompleter = new Completer.sync(); - _addStreamSubscription = stream.listen( - _inner.add, - onError: _addError, - onDone: _addStreamCompleter.complete); + _addStreamSubscription = stream.listen(_inner.add, + onError: _addError, onDone: _addStreamCompleter.complete); return _addStreamCompleter.future.then((_) { _addStreamCompleter = null; _addStreamSubscription = null; diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index c725fef8e..f1328c03d 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -44,8 +44,8 @@ class IsolateChannel extends StreamChannelMixin { // value to be an [IsolateChannel]. var streamCompleter = new StreamCompleter(); var sinkCompleter = new StreamSinkCompleter(); - var channel = new IsolateChannel._( - streamCompleter.stream, sinkCompleter.sink); + var channel = + new IsolateChannel._(streamCompleter.stream, sinkCompleter.sink); // The first message across the ReceivePort should be a SendPort pointing to // the remote end. If it's not, we'll make the stream emit an error @@ -56,9 +56,8 @@ class IsolateChannel extends StreamChannelMixin { var controller = new StreamChannelController( allowForeignErrors: false, sync: true); new SubscriptionStream(subscription).pipe(controller.local.sink); - controller.local.stream.listen( - (data) => message.send(data), - onDone: receivePort.close); + controller.local.stream + .listen((data) => message.send(data), onDone: receivePort.close); streamCompleter.setSourceStream(controller.foreign.stream); sinkCompleter.setDestinationSink(controller.foreign.sink); @@ -93,12 +92,11 @@ class IsolateChannel extends StreamChannelMixin { /// Creates a stream channel that receives messages from [receivePort] and /// sends them over [sendPort]. factory IsolateChannel(ReceivePort receivePort, SendPort sendPort) { - var controller = new StreamChannelController( - allowForeignErrors: false, sync: true); + var controller = + new StreamChannelController(allowForeignErrors: false, sync: true); receivePort.pipe(controller.local.sink); - controller.local.stream.listen( - (data) => sendPort.send(data), - onDone: receivePort.close); + controller.local.stream + .listen((data) => sendPort.send(data), onDone: receivePort.close); return new IsolateChannel._( controller.foreign.stream, controller.foreign.sink); } diff --git a/pkgs/stream_channel/lib/src/stream_channel_completer.dart b/pkgs/stream_channel/lib/src/stream_channel_completer.dart index d15adcf94..b9881b913 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_completer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_completer.dart @@ -42,8 +42,8 @@ class StreamChannelCompleter { } StreamChannelCompleter() { - _channel = new StreamChannel( - _streamCompleter.stream, _sinkCompleter.sink); + _channel = + new StreamChannel(_streamCompleter.stream, _sinkCompleter.sink); } /// Set a channel as the source and destination for [channel]. diff --git a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart index d6d10ff5e..1a4afcae2 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart @@ -58,9 +58,10 @@ class StreamChannelTransformer { /// and all output from its stream is decoded using [Codec.decoder]. StreamChannelTransformer.fromCodec(Codec codec) : this( - typedStreamTransformer(codec.decoder), - StreamSinkTransformer.typed( - new StreamSinkTransformer.fromStreamTransformer(codec.encoder))); + typedStreamTransformer(codec.decoder), + StreamSinkTransformer.typed( + new StreamSinkTransformer.fromStreamTransformer( + codec.encoder))); /// Transforms the events sent to and emitted by [channel]. /// diff --git a/pkgs/stream_channel/lib/src/transformer/typed.dart b/pkgs/stream_channel/lib/src/transformer/typed.dart index f35e01c98..9c2d72b41 100644 --- a/pkgs/stream_channel/lib/src/transformer/typed.dart +++ b/pkgs/stream_channel/lib/src/transformer/typed.dart @@ -8,7 +8,7 @@ import '../../stream_channel.dart'; /// transformer to `S`. class TypeSafeStreamChannelTransformer implements StreamChannelTransformer { - final StreamChannelTransformer _inner; + final StreamChannelTransformer _inner; TypeSafeStreamChannelTransformer(this._inner); diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index dcbc9a07e..8d0e60421 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -97,8 +97,8 @@ abstract class StreamChannel { /// transforming it with a [StreamTransformer]. This is a lighter-weight way /// of preserving that guarantee in particular than /// [StreamChannel.withGuarantees]. - factory StreamChannel.withCloseGuarantee(Stream stream, - StreamSink sink) => + factory StreamChannel.withCloseGuarantee( + Stream stream, StreamSink sink) => new CloseGuaranteeChannel(stream, sink); /// Connects [this] to [other], so that any values emitted by either are sent @@ -108,8 +108,7 @@ abstract class StreamChannel { /// Transforms [this] using [transformer]. /// /// This is identical to calling `transformer.bind(channel)`. - StreamChannel transform( - StreamChannelTransformer transformer); + StreamChannel transform(StreamChannelTransformer transformer); /// Transforms only the [stream] component of [this] using [transformer]. StreamChannel transformStream(StreamTransformer transformer); @@ -153,8 +152,7 @@ abstract class StreamChannelMixin implements StreamChannel { other.stream.pipe(sink); } - StreamChannel transform( - StreamChannelTransformer transformer) => + StreamChannel transform(StreamChannelTransformer transformer) => transformer.bind(this); StreamChannel transformStream(StreamTransformer transformer) => diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index 311a41c9a..e194ee3cf 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -84,14 +84,16 @@ void main() { var sinkController = new StreamController(); var disconnector = new Disconnector(); var sink = new _CloseCompleterSink(sinkController.sink); - var channel = new StreamChannel.withGuarantees( - streamController.stream, sink) - .transform(disconnector); + var channel = + new StreamChannel.withGuarantees(streamController.stream, sink) + .transform(disconnector); var disconnectFutureFired = false; - expect(disconnector.disconnect().then((_) { - disconnectFutureFired = true; - }), completes); + expect( + disconnector.disconnect().then((_) { + disconnectFutureFired = true; + }), + completes); // Give the future time to fire early if it's going to. await pumpEventQueue(); @@ -114,7 +116,7 @@ void main() { channel.sink.add(2); channel.sink.add(3); channel.sink.close(); - + expect(sinkController.stream.toList(), completion(isEmpty)); }); @@ -126,7 +128,7 @@ void main() { sinkController.stream.listen(null); // Work around sdk#19095. expect(channel.sink.done, completes); }); - + test("still emits state errors after explicit close", () { sinkController.stream.listen(null); // Work around sdk#19095. expect(channel.sink.close(), completes); diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index fa4d8d532..7316c6a42 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -64,7 +64,8 @@ void main() { }); group("stream channel rules", () { - test("closing the sink causes the stream to close before it emits any more " + test( + "closing the sink causes the stream to close before it emits any more " "events", () { sendPort.send(1); sendPort.send(2); diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index 6f18e361f..22bb83009 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -15,8 +15,8 @@ void main() { setUp(() { streamController = new StreamController(); sinkController = new StreamController(); - channel = new StreamChannel( - streamController.stream, sinkController.sink); + channel = + new StreamChannel(streamController.stream, sinkController.sink); }); test("decodes JSON emitted by the channel", () { diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index 0e58d382e..69059b682 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -47,7 +47,8 @@ void main() { channel1.sink.close(); }); - test("doesn't closes the local virtual channel when the stream " + test( + "doesn't closes the local virtual channel when the stream " "subscription is canceled", () { channel1.sink.done.then(expectAsync((_) {}, count: 0)); @@ -58,7 +59,8 @@ void main() { return pumpEventQueue(); }); - test("closes the underlying channel when it closes without any other " + test( + "closes the underlying channel when it closes without any other " "virtual channels", () { expect(controller.local.sink.done, completes); expect(controller.foreign.sink.done, completes); @@ -66,7 +68,8 @@ void main() { channel1.sink.close(); }); - test("doesn't close the underlying channel when it closes with other " + test( + "doesn't close the underlying channel when it closes with other " "virtual channels", () { controller.local.sink.done.then(expectAsync((_) {}, count: 0)); controller.foreign.sink.done.then(expectAsync((_) {}, count: 0)); @@ -126,7 +129,8 @@ void main() { virtual1.sink.close(); }); - test("doesn't closes the local virtual channel when the stream " + test( + "doesn't closes the local virtual channel when the stream " "subscription is canceled", () { virtual1.sink.done.then(expectAsync((_) {}, count: 0)); virtual1.stream.listen((_) {}).cancel(); @@ -136,7 +140,8 @@ void main() { return pumpEventQueue(); }); - test("closes the underlying channel when it closes without any other " + test( + "closes the underlying channel when it closes without any other " "virtual channels", () async { // First close the default channel so we can test the new channel as the // last living virtual channel. @@ -149,7 +154,8 @@ void main() { virtual1.sink.close(); }); - test("doesn't close the underlying channel when it closes with other " + test( + "doesn't close the underlying channel when it closes with other " "virtual channels", () { controller.local.sink.done.then(expectAsync((_) {}, count: 0)); controller.foreign.sink.done.then(expectAsync((_) {}, count: 0)); @@ -169,10 +175,10 @@ void main() { // we're properly testing two channels with the same id. expect(virtual1.id, equals(virtual3.id)); - virtual2.stream.listen( - expectAsync((message) => expect(message, equals("hello")))); - virtual4.stream.listen( - expectAsync((message) => expect(message, equals("goodbye")))); + virtual2.stream + .listen(expectAsync((message) => expect(message, equals("hello")))); + virtual4.stream + .listen(expectAsync((message) => expect(message, equals("goodbye")))); virtual1.sink.add("hello"); virtual3.sink.add("goodbye"); @@ -223,7 +229,8 @@ void main() { virtual2.sink.close(); }); - test("doesn't closes the local virtual channel when the stream " + test( + "doesn't closes the local virtual channel when the stream " "subscription is canceled", () { virtual2.sink.done.then(expectAsync((_) {}, count: 0)); virtual2.stream.listen((_) {}).cancel(); @@ -233,7 +240,8 @@ void main() { return pumpEventQueue(); }); - test("closes the underlying channel when it closes without any other " + test( + "closes the underlying channel when it closes without any other " "virtual channels", () async { // First close the default channel so we can test the new channel as the // last living virtual channel. @@ -246,7 +254,8 @@ void main() { virtual2.sink.close(); }); - test("doesn't close the underlying channel when it closes with other " + test( + "doesn't close the underlying channel when it closes with other " "virtual channels", () { controller.local.sink.done.then(expectAsync((_) {}, count: 0)); controller.foreign.sink.done.then(expectAsync((_) {}, count: 0)); @@ -259,8 +268,7 @@ void main() { }); test("doesn't allow another virtual channel with the same id", () { - expect(() => channel2.virtualChannel(virtual1.id), - throwsArgumentError); + expect(() => channel2.virtualChannel(virtual1.id), throwsArgumentError); }); }); @@ -314,7 +322,8 @@ void main() { group("stream channel rules", () { group("for the main stream:", () { - test("closing the sink causes the stream to close before it emits any more " + test( + "closing the sink causes the stream to close before it emits any more " "events", () { channel1.sink.add(1); channel1.sink.add(2); @@ -380,7 +389,8 @@ void main() { virtual2 = channel2.virtualChannel(virtual1.id); }); - test("closing the sink causes the stream to close before it emits any more " + test( + "closing the sink causes the stream to close before it emits any more " "events", () { virtual1.sink.add(1); virtual1.sink.add(2); diff --git a/pkgs/stream_channel/test/stream_channel_completer_test.dart b/pkgs/stream_channel/test/stream_channel_completer_test.dart index 1ee40a5ca..e08dd8a7a 100644 --- a/pkgs/stream_channel/test/stream_channel_completer_test.dart +++ b/pkgs/stream_channel/test/stream_channel_completer_test.dart @@ -18,8 +18,8 @@ void main() { completer = new StreamChannelCompleter(); streamController = new StreamController(); sinkController = new StreamController(); - innerChannel = new StreamChannel( - streamController.stream, sinkController.sink); + innerChannel = + new StreamChannel(streamController.stream, sinkController.sink); }); group("when a channel is set before accessing", () { @@ -98,8 +98,8 @@ void main() { group("forFuture", () { test("forwards a StreamChannel", () { - var channel = StreamChannelCompleter.fromFuture( - new Future.value(innerChannel)); + var channel = + StreamChannelCompleter.fromFuture(new Future.value(innerChannel)); channel.sink.add(1); channel.sink.close(); streamController.sink.add(2); @@ -110,8 +110,8 @@ void main() { }); test("forwards an error", () { - var channel = StreamChannelCompleter.fromFuture( - new Future.error("oh no")); + var channel = + StreamChannelCompleter.fromFuture(new Future.error("oh no")); expect(channel.stream.toList(), throwsA("oh no")); }); }); diff --git a/pkgs/stream_channel/test/stream_channel_controller_test.dart b/pkgs/stream_channel/test/stream_channel_controller_test.dart index 7503387d5..8162a1746 100644 --- a/pkgs/stream_channel/test/stream_channel_controller_test.dart +++ b/pkgs/stream_channel/test/stream_channel_controller_test.dart @@ -13,16 +13,25 @@ void main() { }); test("forwards events from the local sink to the foreign stream", () { - controller.local.sink..add(1)..add(2)..add(3)..close(); + controller.local.sink + ..add(1) + ..add(2) + ..add(3) + ..close(); expect(controller.foreign.stream.toList(), completion(equals([1, 2, 3]))); }); test("forwards events from the foreign sink to the local stream", () { - controller.foreign.sink..add(1)..add(2)..add(3)..close(); + controller.foreign.sink + ..add(1) + ..add(2) + ..add(3) + ..close(); expect(controller.local.stream.toList(), completion(equals([1, 2, 3]))); }); - test("with allowForeignErrors: false, shuts down the connection if an " + test( + "with allowForeignErrors: false, shuts down the connection if an " "error is added to the foreign channel", () { controller = new StreamChannelController(allowForeignErrors: false); @@ -40,7 +49,8 @@ void main() { controller = new StreamChannelController(sync: true); }); - test("synchronously forwards events from the local sink to the foreign " + test( + "synchronously forwards events from the local sink to the foreign " "stream", () { var receivedEvent = false; var receivedError = false; @@ -65,7 +75,8 @@ void main() { expect(receivedDone, isTrue); }); - test("synchronously forwards events from the foreign sink to the local " + test( + "synchronously forwards events from the foreign sink to the local " "stream", () { var receivedEvent = false; var receivedError = false; diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index 41f4c32ec..f0a838385 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -16,8 +16,7 @@ void main() { setUp(() { streamController = new StreamController(); sinkController = new StreamController(); - channel = new StreamChannel( - streamController.stream, sinkController.sink); + channel = new StreamChannel(streamController.stream, sinkController.sink); }); test("pipe() pipes data from each channel's stream into the other's sink", @@ -42,8 +41,8 @@ void main() { }); test("transform() transforms the channel", () async { - var transformed = channel.transform( - new StreamChannelTransformer.fromCodec(UTF8)); + var transformed = + channel.transform(new StreamChannelTransformer.fromCodec(UTF8)); streamController.add([102, 111, 111, 98, 97, 114]); streamController.close(); @@ -51,8 +50,11 @@ void main() { transformed.sink.add("fblthp"); transformed.sink.close(); - expect(sinkController.stream.toList(), - completion(equals([[102, 98, 108, 116, 104, 112]]))); + expect( + sinkController.stream.toList(), + completion(equals([ + [102, 98, 108, 116, 104, 112] + ]))); }); test("transformStream() transforms only the stream", () async { @@ -64,8 +66,7 @@ void main() { transformed.sink.add("fblthp"); transformed.sink.close(); - expect(sinkController.stream.toList(), - completion(equals(["fblthp"]))); + expect(sinkController.stream.toList(), completion(equals(["fblthp"]))); }); test("transformSink() transforms only the sink", () async { @@ -74,13 +75,19 @@ void main() { streamController.add([102, 111, 111, 98, 97, 114]); streamController.close(); - expect(await transformed.stream.toList(), - equals([[102, 111, 111, 98, 97, 114]])); + expect( + await transformed.stream.toList(), + equals([ + [102, 111, 111, 98, 97, 114] + ])); transformed.sink.add("fblthp"); transformed.sink.close(); - expect(sinkController.stream.toList(), - completion(equals([[102, 98, 108, 116, 104, 112]]))); + expect( + sinkController.stream.toList(), + completion(equals([ + [102, 98, 108, 116, 104, 112] + ]))); }); test("changeStream() changes the stream", () { diff --git a/pkgs/stream_channel/test/utils.dart b/pkgs/stream_channel/test/utils.dart index 130a3e12b..e53389540 100644 --- a/pkgs/stream_channel/test/utils.dart +++ b/pkgs/stream_channel/test/utils.dart @@ -9,7 +9,7 @@ import 'dart:async'; /// /// By default, this should pump the event queue enough times to allow any code /// to run, as long as it's not waiting on some external event. -Future pumpEventQueue([int times=20]) { +Future pumpEventQueue([int times = 20]) { if (times == 0) return new Future.value(); // Use [new Future] future to allow microtask events to finish. The [new // Future.value] constructor uses scheduleMicrotask itself and would therefore @@ -17,4 +17,3 @@ Future pumpEventQueue([int times=20]) { // method. return new Future(() => pumpEventQueue(times - 1)); } - diff --git a/pkgs/stream_channel/test/with_close_guarantee_test.dart b/pkgs/stream_channel/test/with_close_guarantee_test.dart index caf48cf1c..dafbfeffb 100644 --- a/pkgs/stream_channel/test/with_close_guarantee_test.dart +++ b/pkgs/stream_channel/test/with_close_guarantee_test.dart @@ -35,26 +35,30 @@ void main() { channel = new StreamChannel.withCloseGuarantee(stream, sink); }); - test("closing the event sink causes the stream to close before it emits any " + test( + "closing the event sink causes the stream to close before it emits any " "more events", () async { controller.local.sink.add(1); controller.local.sink.add(2); controller.local.sink.add(3); - expect(channel.stream.listen(expectAsync((event) { - if (event == 2) channel.sink.close(); - }, count: 2)).asFuture(), completes); + expect( + channel.stream + .listen(expectAsync((event) { + if (event == 2) channel.sink.close(); + }, count: 2)) + .asFuture(), + completes); await pumpEventQueue(); }); - test("closing the event sink before events are emitted causes the stream to " + test( + "closing the event sink before events are emitted causes the stream to " "close immediately", () async { channel.sink.close(); - channel.stream.listen( - expectAsync((_) {}, count: 0), - onError: expectAsync((_, __) {}, count: 0), - onDone: expectAsync(() {})); + channel.stream.listen(expectAsync((_) {}, count: 0), + onError: expectAsync((_, __) {}, count: 0), onDone: expectAsync(() {})); controller.local.sink.add(1); controller.local.sink.add(2); diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index 409b28fdd..b8156f20a 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -43,15 +43,20 @@ void main() { }); }); - test("closing the event sink causes the stream to close before it emits any " + test( + "closing the event sink causes the stream to close before it emits any " "more events", () { streamController.add(1); streamController.add(2); streamController.add(3); - expect(channel.stream.listen(expectAsync((event) { - if (event == 2) channel.sink.close(); - }, count: 2)).asFuture(), completes); + expect( + channel.stream + .listen(expectAsync((event) { + if (event == 2) channel.sink.close(); + }, count: 2)) + .asFuture(), + completes); }); test("after the stream closes, the sink ignores events", () async { @@ -65,8 +70,7 @@ void main() { channel.sink.close(); // None of our channel.sink additions should make it to the other endpoint. - sinkController.stream.listen( - expectAsync((_) {}, count: 0), + sinkController.stream.listen(expectAsync((_) {}, count: 0), onDone: expectAsync(() {}, count: 0)); await pumpEventQueue(); }); @@ -97,8 +101,7 @@ void main() { channel.sink.close(); // The sink should be ignoring events because the stream closed. - sinkController.stream.listen( - expectAsync((_) {}, count: 0), + sinkController.stream.listen(expectAsync((_) {}, count: 0), onDone: expectAsync(() {}, count: 0)); await pumpEventQueue(); }); @@ -142,14 +145,15 @@ void main() { streamController = new StreamController(); sinkController = new StreamController(); channel = new StreamChannel.withGuarantees( - streamController.stream, sinkController.sink, allowSinkErrors: false); + streamController.stream, sinkController.sink, + allowSinkErrors: false); }); test("forwards errors to Sink.done but not the stream", () { channel.sink.addError("oh no"); expect(channel.sink.done, throwsA("oh no")); - sinkController.stream.listen(null, - onError: expectAsync((_) {}, count: 0)); + sinkController.stream + .listen(null, onError: expectAsync((_) {}, count: 0)); }); test("adding an error causes the stream to emit a done event", () { @@ -159,9 +163,13 @@ void main() { streamController.add(2); streamController.add(3); - expect(channel.stream.listen(expectAsync((event) { - if (event == 2) channel.sink.addError("oh no"); - }, count: 2)).asFuture(), completes); + expect( + channel.stream + .listen(expectAsync((event) { + if (event == 2) channel.sink.addError("oh no"); + }, count: 2)) + .asFuture(), + completes); }); test("adding an error closes the inner sink", () { @@ -170,7 +178,8 @@ void main() { expect(sinkController.stream.toList(), completion(isEmpty)); }); - test("adding an error via via addStream causes the stream to emit a done " + test( + "adding an error via via addStream causes the stream to emit a done " "event", () async { var canceled = false; var controller = new StreamController(onCancel: () { From 045a8c6f5e1b02ab696c5d80e03e2013d9a06257 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 26 Jul 2017 14:40:50 -0700 Subject: [PATCH 036/138] Stop using deprecated pkg/test expect methods --- pkgs/stream_channel/pubspec.yaml | 2 +- .../test/isolate_channel_test.dart | 4 +- .../test/multi_channel_test.dart | 58 +++++++++---------- .../test/stream_channel_controller_test.dart | 12 ++-- .../test/stream_channel_test.dart | 2 +- .../test/with_close_guarantee_test.dart | 7 ++- .../test/with_guarantees_test.dart | 14 ++--- 7 files changed, 50 insertions(+), 49 deletions(-) diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 19a3bd07c..5813c4a0e 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -9,4 +9,4 @@ dependencies: async: '^1.11.0' stack_trace: '^1.0.0' dev_dependencies: - test: '^0.12.0' + test: '^0.12.18' diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index 7316c6a42..b3b252e6e 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -73,7 +73,7 @@ void main() { sendPort.send(4); sendPort.send(5); - channel.stream.listen(expectAsync((message) { + channel.stream.listen(expectAsync1((message) { expect(message, equals(1)); channel.sink.close(); }, count: 1)); @@ -100,7 +100,7 @@ void main() { // The other end shouldn't receive the next event, since the sink was // closed. Pump the event queue to give it a chance to. - receivePort.listen(expectAsync((_) {}, count: 0)); + receivePort.listen(expectAsync1((_) {}, count: 0)); await pumpEventQueue(); }); diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index 69059b682..b1156738a 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -20,7 +20,7 @@ void main() { group("the default virtual channel", () { test("begins connected", () { var first = true; - channel2.stream.listen(expectAsync((message) { + channel2.stream.listen(expectAsync1((message) { if (first) { expect(message, equals("hello")); first = false; @@ -50,7 +50,7 @@ void main() { test( "doesn't closes the local virtual channel when the stream " "subscription is canceled", () { - channel1.sink.done.then(expectAsync((_) {}, count: 0)); + channel1.sink.done.then(expectAsync1((_) {}, count: 0)); channel1.stream.listen((_) {}).cancel(); @@ -71,8 +71,8 @@ void main() { test( "doesn't close the underlying channel when it closes with other " "virtual channels", () { - controller.local.sink.done.then(expectAsync((_) {}, count: 0)); - controller.foreign.sink.done.then(expectAsync((_) {}, count: 0)); + controller.local.sink.done.then(expectAsync1((_) {}, count: 0)); + controller.foreign.sink.done.then(expectAsync1((_) {}, count: 0)); // Establish another virtual connection which should keep the underlying // connection open. @@ -95,7 +95,7 @@ void main() { test("sends messages only to the other virtual channel", () { var first = true; - virtual2.stream.listen(expectAsync((message) { + virtual2.stream.listen(expectAsync1((message) { if (first) { expect(message, equals("hello")); first = false; @@ -107,9 +107,9 @@ void main() { // No other virtual channels should receive the message. for (var i = 0; i < 10; i++) { var virtual = channel2.virtualChannel(channel1.virtualChannel().id); - virtual.stream.listen(expectAsync((_) {}, count: 0)); + virtual.stream.listen(expectAsync1((_) {}, count: 0)); } - channel2.stream.listen(expectAsync((_) {}, count: 0)); + channel2.stream.listen(expectAsync1((_) {}, count: 0)); virtual1.sink.add("hello"); virtual1.sink.add("world"); @@ -132,7 +132,7 @@ void main() { test( "doesn't closes the local virtual channel when the stream " "subscription is canceled", () { - virtual1.sink.done.then(expectAsync((_) {}, count: 0)); + virtual1.sink.done.then(expectAsync1((_) {}, count: 0)); virtual1.stream.listen((_) {}).cancel(); // Ensure that there's enough time for the channel to close if it's going @@ -157,8 +157,8 @@ void main() { test( "doesn't close the underlying channel when it closes with other " "virtual channels", () { - controller.local.sink.done.then(expectAsync((_) {}, count: 0)); - controller.foreign.sink.done.then(expectAsync((_) {}, count: 0)); + controller.local.sink.done.then(expectAsync1((_) {}, count: 0)); + controller.foreign.sink.done.then(expectAsync1((_) {}, count: 0)); virtual1.sink.close(); @@ -176,9 +176,9 @@ void main() { expect(virtual1.id, equals(virtual3.id)); virtual2.stream - .listen(expectAsync((message) => expect(message, equals("hello")))); - virtual4.stream - .listen(expectAsync((message) => expect(message, equals("goodbye")))); + .listen(expectAsync1((message) => expect(message, equals("hello")))); + virtual4.stream.listen( + expectAsync1((message) => expect(message, equals("goodbye")))); virtual1.sink.add("hello"); virtual3.sink.add("goodbye"); @@ -195,7 +195,7 @@ void main() { test("sends messages only to the other virtual channel", () { var first = true; - virtual1.stream.listen(expectAsync((message) { + virtual1.stream.listen(expectAsync1((message) { if (first) { expect(message, equals("hello")); first = false; @@ -207,9 +207,9 @@ void main() { // No other virtual channels should receive the message. for (var i = 0; i < 10; i++) { var virtual = channel2.virtualChannel(channel1.virtualChannel().id); - virtual.stream.listen(expectAsync((_) {}, count: 0)); + virtual.stream.listen(expectAsync1((_) {}, count: 0)); } - channel1.stream.listen(expectAsync((_) {}, count: 0)); + channel1.stream.listen(expectAsync1((_) {}, count: 0)); virtual2.sink.add("hello"); virtual2.sink.add("world"); @@ -232,7 +232,7 @@ void main() { test( "doesn't closes the local virtual channel when the stream " "subscription is canceled", () { - virtual2.sink.done.then(expectAsync((_) {}, count: 0)); + virtual2.sink.done.then(expectAsync1((_) {}, count: 0)); virtual2.stream.listen((_) {}).cancel(); // Ensure that there's enough time for the channel to close if it's going @@ -257,8 +257,8 @@ void main() { test( "doesn't close the underlying channel when it closes with other " "virtual channels", () { - controller.local.sink.done.then(expectAsync((_) {}, count: 0)); - controller.foreign.sink.done.then(expectAsync((_) {}, count: 0)); + controller.local.sink.done.then(expectAsync1((_) {}, count: 0)); + controller.foreign.sink.done.then(expectAsync1((_) {}, count: 0)); virtual2.sink.close(); @@ -311,10 +311,10 @@ void main() { }); test("emits an error, the error is sent only to the default channel", () { - channel1.stream.listen(expectAsync((_) {}, count: 0), - onError: expectAsync((error) => expect(error, equals("oh no")))); - virtual1.stream.listen(expectAsync((_) {}, count: 0), - onError: expectAsync((_) {}, count: 0)); + channel1.stream.listen(expectAsync1((_) {}, count: 0), + onError: expectAsync1((error) => expect(error, equals("oh no")))); + virtual1.stream.listen(expectAsync1((_) {}, count: 0), + onError: expectAsync1((_) {}, count: 0)); controller.foreign.sink.addError("oh no"); }); @@ -329,7 +329,7 @@ void main() { channel1.sink.add(2); channel1.sink.add(3); - channel2.stream.listen(expectAsync((message) { + channel2.stream.listen(expectAsync1((message) { expect(message, equals(1)); channel2.sink.close(); }, count: 1)); @@ -346,7 +346,7 @@ void main() { channel2.sink.close(); // None of our channel.sink additions should make it to the other endpoint. - channel1.stream.listen(expectAsync((_) {}, count: 0)); + channel1.stream.listen(expectAsync1((_) {}, count: 0)); await pumpEventQueue(); }); @@ -376,7 +376,7 @@ void main() { channel1.sink.close(); // The sink should be ignoring events because the channel closed. - channel2.stream.listen(expectAsync((_) {}, count: 0)); + channel2.stream.listen(expectAsync1((_) {}, count: 0)); await pumpEventQueue(); }); }); @@ -396,7 +396,7 @@ void main() { virtual1.sink.add(2); virtual1.sink.add(3); - virtual2.stream.listen(expectAsync((message) { + virtual2.stream.listen(expectAsync1((message) { expect(message, equals(1)); virtual2.sink.close(); }, count: 1)); @@ -413,7 +413,7 @@ void main() { virtual2.sink.close(); // None of our virtual.sink additions should make it to the other endpoint. - virtual1.stream.listen(expectAsync((_) {}, count: 0)); + virtual1.stream.listen(expectAsync1((_) {}, count: 0)); await pumpEventQueue(); }); @@ -443,7 +443,7 @@ void main() { virtual1.sink.close(); // The sink should be ignoring events because the stream closed. - virtual2.stream.listen(expectAsync((_) {}, count: 0)); + virtual2.stream.listen(expectAsync1((_) {}, count: 0)); await pumpEventQueue(); }); }); diff --git a/pkgs/stream_channel/test/stream_channel_controller_test.dart b/pkgs/stream_channel/test/stream_channel_controller_test.dart index 8162a1746..c092570f5 100644 --- a/pkgs/stream_channel/test/stream_channel_controller_test.dart +++ b/pkgs/stream_channel/test/stream_channel_controller_test.dart @@ -55,13 +55,13 @@ void main() { var receivedEvent = false; var receivedError = false; var receivedDone = false; - controller.foreign.stream.listen(expectAsync((event) { + controller.foreign.stream.listen(expectAsync1((event) { expect(event, equals(1)); receivedEvent = true; - }), onError: expectAsync((error) { + }), onError: expectAsync1((error) { expect(error, equals("oh no")); receivedError = true; - }), onDone: expectAsync(() { + }), onDone: expectAsync0(() { receivedDone = true; })); @@ -81,13 +81,13 @@ void main() { var receivedEvent = false; var receivedError = false; var receivedDone = false; - controller.local.stream.listen(expectAsync((event) { + controller.local.stream.listen(expectAsync1((event) { expect(event, equals(1)); receivedEvent = true; - }), onError: expectAsync((error) { + }), onError: expectAsync1((error) { expect(error, equals("oh no")); receivedError = true; - }), onDone: expectAsync(() { + }), onDone: expectAsync0(() { receivedDone = true; })); diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index f0a838385..b8ebcbd85 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -114,7 +114,7 @@ void main() { }); expect(newController.stream.toList(), completion(equals([10]))); - streamController.stream.listen(expectAsync((_) {}, count: 0)); + streamController.stream.listen(expectAsync1((_) {}, count: 0)); changed.sink.add(10); changed.sink.close(); diff --git a/pkgs/stream_channel/test/with_close_guarantee_test.dart b/pkgs/stream_channel/test/with_close_guarantee_test.dart index dafbfeffb..bed6f0db6 100644 --- a/pkgs/stream_channel/test/with_close_guarantee_test.dart +++ b/pkgs/stream_channel/test/with_close_guarantee_test.dart @@ -44,7 +44,7 @@ void main() { expect( channel.stream - .listen(expectAsync((event) { + .listen(expectAsync1((event) { if (event == 2) channel.sink.close(); }, count: 2)) .asFuture(), @@ -57,8 +57,9 @@ void main() { "closing the event sink before events are emitted causes the stream to " "close immediately", () async { channel.sink.close(); - channel.stream.listen(expectAsync((_) {}, count: 0), - onError: expectAsync((_, __) {}, count: 0), onDone: expectAsync(() {})); + channel.stream.listen(expectAsync1((_) {}, count: 0), + onError: expectAsync2((_, __) {}, count: 0), + onDone: expectAsync0(() {})); controller.local.sink.add(1); controller.local.sink.add(2); diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index b8156f20a..07dd8e52f 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -52,7 +52,7 @@ void main() { expect( channel.stream - .listen(expectAsync((event) { + .listen(expectAsync1((event) { if (event == 2) channel.sink.close(); }, count: 2)) .asFuture(), @@ -70,8 +70,8 @@ void main() { channel.sink.close(); // None of our channel.sink additions should make it to the other endpoint. - sinkController.stream.listen(expectAsync((_) {}, count: 0), - onDone: expectAsync(() {}, count: 0)); + sinkController.stream.listen(expectAsync1((_) {}, count: 0), + onDone: expectAsync0(() {}, count: 0)); await pumpEventQueue(); }); @@ -101,8 +101,8 @@ void main() { channel.sink.close(); // The sink should be ignoring events because the stream closed. - sinkController.stream.listen(expectAsync((_) {}, count: 0), - onDone: expectAsync(() {}, count: 0)); + sinkController.stream.listen(expectAsync1((_) {}, count: 0), + onDone: expectAsync0(() {}, count: 0)); await pumpEventQueue(); }); @@ -153,7 +153,7 @@ void main() { channel.sink.addError("oh no"); expect(channel.sink.done, throwsA("oh no")); sinkController.stream - .listen(null, onError: expectAsync((_) {}, count: 0)); + .listen(null, onError: expectAsync1((_) {}, count: 0)); }); test("adding an error causes the stream to emit a done event", () { @@ -165,7 +165,7 @@ void main() { expect( channel.stream - .listen(expectAsync((event) { + .listen(expectAsync1((event) { if (event == 2) channel.sink.addError("oh no"); }, count: 2)) .asFuture(), From d63ae51d3157c7cb1fe7480d04cdc54cde2a813e Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 26 Jul 2017 14:41:31 -0700 Subject: [PATCH 037/138] Remove unused var --- pkgs/stream_channel/test/disconnector_test.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index e194ee3cf..cd1300c66 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -84,9 +84,8 @@ void main() { var sinkController = new StreamController(); var disconnector = new Disconnector(); var sink = new _CloseCompleterSink(sinkController.sink); - var channel = - new StreamChannel.withGuarantees(streamController.stream, sink) - .transform(disconnector); + new StreamChannel.withGuarantees(streamController.stream, sink) + .transform(disconnector); var disconnectFutureFired = false; expect( From 97446793a44967a0257a1a5356ab33e8e7c2672e Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 26 Jul 2017 14:43:24 -0700 Subject: [PATCH 038/138] enable travis-ci --- pkgs/stream_channel/.travis.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 pkgs/stream_channel/.travis.yml diff --git a/pkgs/stream_channel/.travis.yml b/pkgs/stream_channel/.travis.yml new file mode 100644 index 000000000..d5c64e9dd --- /dev/null +++ b/pkgs/stream_channel/.travis.yml @@ -0,0 +1,20 @@ +language: dart +sudo: false +dart: + - dev + - stable +dart_task: + - test: --platform vm + - test: --platform firefox -j 1 + - test: --platform dartium + install_dartium: true + - dartfmt + - dartanalyzer + +# Only building master means that we don't run two builds for each pull request. +branches: + only: [master] + +cache: + directories: + - $HOME/.pub-cache From 2a9b499e0759a514025163f7819db32e58b35773 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 18 Sep 2017 18:12:56 -0700 Subject: [PATCH 039/138] Remove -dev.infinity in SDK upper constraint --- pkgs/stream_channel/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 5813c4a0e..2d863620b 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -4,7 +4,7 @@ description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel environment: - sdk: '>=1.21.0 <2.0.0-dev.infinity' + sdk: '>=1.21.0 <2.0.0' dependencies: async: '^1.11.0' stack_trace: '^1.0.0' From 6cac0360526f12590c1320f762448bdfa6c1bc99 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 22 Sep 2017 13:44:15 -0700 Subject: [PATCH 040/138] Declare support for async 2.0.0 (dart-lang/stream_channel#10) --- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 8d44b214a..a1cf9edec 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.2 + +* Declare support for `async` 2.0.0. + ## 1.6.1 * Fix the type of `StreamChannel.transform()`. This previously inverted the diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 2d863620b..fee64337e 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,12 +1,12 @@ name: stream_channel -version: 1.6.2-dev +version: 1.6.2 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel environment: sdk: '>=1.21.0 <2.0.0' dependencies: - async: '^1.11.0' + async: '>=1.11.0 <3.0.0' stack_trace: '^1.0.0' dev_dependencies: test: '^0.12.18' From dc0bf362a58ad38e78d04d1b3e4032abb3d3c941 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 20 Nov 2017 13:49:39 -0800 Subject: [PATCH 041/138] Use pumpEventQueue() from test (dart-lang/stream_channel#12) --- pkgs/stream_channel/pubspec.yaml | 4 ++-- .../test/disconnector_test.dart | 2 -- .../test/isolate_channel_test.dart | 2 -- .../test/multi_channel_test.dart | 2 -- .../test/stream_channel_completer_test.dart | 2 -- pkgs/stream_channel/test/utils.dart | 19 ------------------- .../test/with_close_guarantee_test.dart | 2 -- .../test/with_guarantees_test.dart | 2 -- 8 files changed, 2 insertions(+), 33 deletions(-) delete mode 100644 pkgs/stream_channel/test/utils.dart diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index fee64337e..6faac8570 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.6.2 +version: 1.6.3-dev description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel @@ -9,4 +9,4 @@ dependencies: async: '>=1.11.0 <3.0.0' stack_trace: '^1.0.0' dev_dependencies: - test: '^0.12.18' + test: '^0.12.28' diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index cd1300c66..5b725740c 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -8,8 +8,6 @@ import 'package:async/async.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; -import 'utils.dart'; - void main() { var streamController; var sinkController; diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index b3b252e6e..66834cace 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -8,8 +8,6 @@ import 'dart:isolate'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; -import 'utils.dart'; - void main() { var receivePort; var sendPort; diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index b1156738a..2a87cafa3 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -5,8 +5,6 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; -import 'utils.dart'; - void main() { var controller; var channel1; diff --git a/pkgs/stream_channel/test/stream_channel_completer_test.dart b/pkgs/stream_channel/test/stream_channel_completer_test.dart index e08dd8a7a..8d830058a 100644 --- a/pkgs/stream_channel/test/stream_channel_completer_test.dart +++ b/pkgs/stream_channel/test/stream_channel_completer_test.dart @@ -7,8 +7,6 @@ import 'dart:async'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; -import 'utils.dart'; - void main() { var completer; var streamController; diff --git a/pkgs/stream_channel/test/utils.dart b/pkgs/stream_channel/test/utils.dart deleted file mode 100644 index e53389540..000000000 --- a/pkgs/stream_channel/test/utils.dart +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2016, 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'; - -/// Returns a [Future] that completes after pumping the event queue [times] -/// times. -/// -/// By default, this should pump the event queue enough times to allow any code -/// to run, as long as it's not waiting on some external event. -Future pumpEventQueue([int times = 20]) { - if (times == 0) return new Future.value(); - // Use [new Future] future to allow microtask events to finish. The [new - // Future.value] constructor uses scheduleMicrotask itself and would therefore - // not wait for microtask callbacks that are scheduled after invoking this - // method. - return new Future(() => pumpEventQueue(times - 1)); -} diff --git a/pkgs/stream_channel/test/with_close_guarantee_test.dart b/pkgs/stream_channel/test/with_close_guarantee_test.dart index bed6f0db6..a6527a716 100644 --- a/pkgs/stream_channel/test/with_close_guarantee_test.dart +++ b/pkgs/stream_channel/test/with_close_guarantee_test.dart @@ -8,8 +8,6 @@ import 'package:async/async.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; -import 'utils.dart'; - final _delayTransformer = new StreamTransformer.fromHandlers( handleData: (data, sink) => new Future.microtask(() => sink.add(data)), handleDone: (sink) => new Future.microtask(() => sink.close())); diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index 07dd8e52f..e1302f64c 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -7,8 +7,6 @@ import 'dart:async'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; -import 'utils.dart'; - void main() { var streamController; var sinkController; From 677ee9a08c296eb78feed772c195e3d266aa2efc Mon Sep 17 00:00:00 2001 From: Gary Roumanis Date: Tue, 19 Dec 2017 13:07:03 -0800 Subject: [PATCH 042/138] prep for release --- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index a1cf9edec..ece9e1d5a 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.3 + +* Use `pumpEventQueue()` from test. + ## 1.6.2 * Declare support for `async` 2.0.0. diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 6faac8570..9a123b128 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.6.3-dev +version: 1.6.3 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From 4c5a9c982d18be77a2b244d4f4cfdef64dbafb6f Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 20 Feb 2018 13:12:32 -0800 Subject: [PATCH 043/138] Stop testing on Dartium (dart-lang/stream_channel#15) Fixes https://github.com/dart-lang/stream_channel/issues/14 --- pkgs/stream_channel/.travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkgs/stream_channel/.travis.yml b/pkgs/stream_channel/.travis.yml index d5c64e9dd..a9510326d 100644 --- a/pkgs/stream_channel/.travis.yml +++ b/pkgs/stream_channel/.travis.yml @@ -1,13 +1,12 @@ language: dart -sudo: false + dart: - dev - stable + dart_task: - test: --platform vm - test: --platform firefox -j 1 - - test: --platform dartium - install_dartium: true - dartfmt - dartanalyzer From 7a53d88bd342312efa6cb4dce0f2c57d62f4e1cf Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 27 Feb 2018 14:59:26 -0800 Subject: [PATCH 044/138] Fix a race condition (dart-lang/stream_channel#16) MultiChannel wasn't buffering incoming remote events if their virtual channels hadn't been created locally yet. --- pkgs/stream_channel/CHANGELOG.md | 6 ++ .../stream_channel/lib/src/multi_channel.dart | 61 +++++++++++++------ pkgs/stream_channel/pubspec.yaml | 2 +- .../test/multi_channel_test.dart | 26 ++++++++ 4 files changed, 75 insertions(+), 20 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index ece9e1d5a..093a2421d 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.6.4 + +* Fix a race condition in `MultiChannel` where messages from a remote virtual + channel could get dropped if the corresponding local channel wasn't registered + quickly enough. + ## 1.6.3 * Use `pumpEventQueue()` from test. diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index 112997e57..e54154304 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -93,10 +93,18 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { /// The controller for this channel. final _mainController = new StreamChannelController(sync: true); - /// A map from virtual channel ids to [StreamChannelController]s that should - /// be used to communicate over those channels. + /// A map from input IDs to [StreamChannelController]s that should be used to + /// communicate over those channels. final _controllers = {}; + /// Input IDs of controllers in [_controllers] that we've received messages + /// for but that have not yet had a local [virtualChannel] created. + final _pendingIds = new Set(); + + /// Input IDs of virtual channels that used to exist but have since been + /// closed. + final _closedIds = new Set(); + /// The next id to use for a local virtual channel. /// /// Ids are used to identify virtual channels. Each message is tagged with an @@ -114,8 +122,9 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { /// The trick is that each endpoint only uses odd ids for its own channels. /// When sending a message over a channel that was created by the remote /// endpoint, the channel's id plus one is used. This way each [MultiChannel] - /// knows that if an incoming message has an odd id, it's using the local id - /// scheme, but if it has an even id, it's using the remote id scheme. + /// knows that if an incoming message has an odd id, it's coming from a + /// channel that was originally created remotely, but if it has an even id, + /// it's coming from a channel that was originally created locally. var _nextId = 1; _MultiChannel(this._inner) { @@ -128,21 +137,28 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { _innerStreamSubscription = _inner.stream.listen((message) { var id = message[0]; - var controller = _controllers[id]; - // A controller might not exist if the channel was closed before an - // incoming message was processed. - if (controller == null) return; + // If the channel was closed before an incoming message was processed, + // ignore that message. + if (_closedIds.contains(id)) return; + + var controller = _controllers.putIfAbsent(id, () { + // If we receive a message for a controller that doesn't have a local + // counterpart yet, create a controller for it to buffer incoming + // messages for when a local connection is created. + _pendingIds.add(id); + return new StreamChannelController(sync: true); + }); + if (message.length > 1) { controller.local.sink.add(message[1]); - return; + } else { + // A message without data indicates that the channel has been closed. We + // can just close the sink here without doing any more cleanup, because + // the sink closing will cause the stream to emit a done event which + // will trigger more cleanup. + controller.local.sink.close(); } - - // A message without data indicates that the channel has been closed. We - // can only close the sink here without doing any more cleanup, because - // the sink closing will cause the stream to emit a done event which will - // trigger more cleanup. - controller.local.sink.close(); }, onDone: _closeInnerChannel, onError: _mainController.local.sink.addError); @@ -173,16 +189,22 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { this, inputId, new Stream.empty(), new NullStreamSink()); } - if (_controllers.containsKey(inputId)) { + StreamChannelController controller; + if (_pendingIds.remove(inputId)) { + // If we've already received messages for this channel, use the controller + // where those messages are buffered. + controller = _controllers[inputId]; + } else if (_controllers.containsKey(inputId) || + _closedIds.contains(inputId)) { throw new ArgumentError("A virtual channel with id $id already exists."); + } else { + controller = new StreamChannelController(sync: true); + _controllers[inputId] = controller; } - var controller = new StreamChannelController(sync: true); - _controllers[inputId] = controller; controller.local.stream.listen( (message) => _inner.sink.add([outputId, message]), onDone: () => _closeChannel(inputId, outputId)); - return new VirtualChannel._( this, outputId, controller.foreign.stream, controller.foreign.sink); } @@ -190,6 +212,7 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { /// Closes the virtual channel for which incoming messages have [inputId] and /// outgoing messages have [outputId]. void _closeChannel(int inputId, int outputId) { + _closedIds.add(inputId); var controller = _controllers.remove(inputId); controller.local.sink.close(); diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 9a123b128..393e60f3b 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.6.3 +version: 1.6.4 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index 2a87cafa3..0c9316abb 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -268,6 +268,32 @@ void main() { test("doesn't allow another virtual channel with the same id", () { expect(() => channel2.virtualChannel(virtual1.id), throwsArgumentError); }); + + test("dispatches events received before the virtual channel is created", + () async { + virtual1 = channel1.virtualChannel(); + + virtual1.sink.add("hello"); + await pumpEventQueue(); + + virtual1.sink.add("world"); + await pumpEventQueue(); + + expect(channel2.virtualChannel(virtual1.id).stream, + emitsInOrder(["hello", "world"])); + }); + + test( + "dispatches close events received before the virtual channel is " + "created", () async { + virtual1 = channel1.virtualChannel(); + + virtual1.sink.close(); + await pumpEventQueue(); + + expect(channel2.virtualChannel(virtual1.id).stream.toList(), + completion(isEmpty)); + }); }); group("when the underlying stream", () { From 7b0392bef85ec2f8d61ee1221e0b6c774e47cf0f Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Mon, 16 Apr 2018 11:57:37 -0700 Subject: [PATCH 045/138] make sure the inner sink is properly typed in JsonDocumentTransformer.bind --- pkgs/stream_channel/lib/src/json_document_transformer.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index 86b9ae71c..40e5155a9 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -2,6 +2,7 @@ // 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:async/async.dart'; @@ -35,9 +36,10 @@ class JsonDocumentTransformer JsonDocumentTransformer._(this._codec); - StreamChannel bind(StreamChannel channel) { + StreamChannel bind(StreamChannel channel) { var stream = channel.stream.map(_codec.decode); - var sink = new StreamSinkTransformer.fromHandlers(handleData: (data, sink) { + var sink = new StreamSinkTransformer.fromHandlers( + handleData: (Object data, EventSink sink) { sink.add(_codec.encode(data)); }).bind(channel.sink); return new StreamChannel.withCloseGuarantee(stream, sink); From 4e385426b1e7c144406f515903f093ec2120f83e Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Mon, 16 Apr 2018 11:59:09 -0700 Subject: [PATCH 046/138] update pubspec/changelog --- pkgs/stream_channel/CHANGELOG.md | 5 +++++ pkgs/stream_channel/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 093a2421d..d15b0c032 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.6.4+1 + +* Fix an issue with `JsonDocumentTransformer.bind` where it created an internal + stream channel which didn't get a properly inferred type for its `sink`. + ## 1.6.4 * Fix a race condition in `MultiChannel` where messages from a remote virtual diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 393e60f3b..5abd523ee 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.6.4 +version: 1.6.4+5 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From 3b092fb932e61a7cbcd70f25dfe75b7b1d1fa80a Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Mon, 16 Apr 2018 12:11:25 -0700 Subject: [PATCH 047/138] fix pubspec version to match changelog --- pkgs/stream_channel/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 5abd523ee..09179771c 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.6.4+5 +version: 1.6.4+1 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From c4dcc8d1a0a39fec7d05346f87531b96c50b4573 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Mon, 16 Apr 2018 13:48:36 -0700 Subject: [PATCH 048/138] code review updates --- pkgs/stream_channel/CHANGELOG.md | 2 +- pkgs/stream_channel/lib/src/json_document_transformer.dart | 4 ++-- pkgs/stream_channel/pubspec.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index d15b0c032..4813e9a1f 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.6.4+1 +## 1.6.5 * Fix an issue with `JsonDocumentTransformer.bind` where it created an internal stream channel which didn't get a properly inferred type for its `sink`. diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index 40e5155a9..533d23823 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -38,8 +38,8 @@ class JsonDocumentTransformer StreamChannel bind(StreamChannel channel) { var stream = channel.stream.map(_codec.decode); - var sink = new StreamSinkTransformer.fromHandlers( - handleData: (Object data, EventSink sink) { + var sink = new StreamSinkTransformer.fromHandlers( + handleData: (data, sink) { sink.add(_codec.encode(data)); }).bind(channel.sink); return new StreamChannel.withCloseGuarantee(stream, sink); diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 09179771c..9221866dc 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.6.4+1 +version: 1.6.5 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From 278de144374bce9c49f16384f6f428d01b02e342 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 17 Apr 2018 14:13:30 -0700 Subject: [PATCH 049/138] Upgrade some hints to errors (dart-lang/stream_channel#19) These prevent building internally. Fix an unused import. --- pkgs/stream_channel/analysis_options.yaml | 6 ++++++ pkgs/stream_channel/lib/src/json_document_transformer.dart | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index a10d4c5a0..743cc902d 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -1,2 +1,8 @@ analyzer: strong-mode: true + # These are errors when building in Google + errors: + unused_import: error + unused_element: error + unused_local_variable: error + dead_code: error diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index 533d23823..6377eeda7 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -2,7 +2,6 @@ // 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:async/async.dart'; From 51947287a3bf2323d86933187c51c203d48ec0d6 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 1 May 2018 08:02:29 -0700 Subject: [PATCH 050/138] fix tests for dart 2 --- pkgs/stream_channel/lib/src/guarantee_channel.dart | 2 +- pkgs/stream_channel/test/json_document_transformer_test.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart index f18cbb973..ba79ed9bc 100644 --- a/pkgs/stream_channel/lib/src/guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -39,7 +39,7 @@ class GuaranteeChannel extends StreamChannelMixin { // to single-subscription. if (innerStream.isBroadcast) { innerStream = - innerStream.transform(const SingleSubscriptionTransformer()); + innerStream.transform(new SingleSubscriptionTransformer()); } _streamController = new StreamController( diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index 22bb83009..b55a11887 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -13,8 +13,8 @@ void main() { var sinkController; StreamChannel channel; setUp(() { - streamController = new StreamController(); - sinkController = new StreamController(); + streamController = new StreamController(); + sinkController = new StreamController(); channel = new StreamChannel(streamController.stream, sinkController.sink); }); From b32ad837ec902416a1846bde58a307e57d3e8fa8 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 1 May 2018 08:06:51 -0700 Subject: [PATCH 051/138] update changelog/pubspec --- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 4813e9a1f..a2404d27e 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.6 + +* Fix a Dart2 issue with inner stream transformation in `GuaranteeChannel`. + ## 1.6.5 * Fix an issue with `JsonDocumentTransformer.bind` where it created an internal diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 9221866dc..c121f5f13 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.6.5 +version: 1.6.6 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From 99325e82bfb017f4edd275bdb7a159ef94a638e2 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 1 May 2018 09:58:15 -0700 Subject: [PATCH 052/138] fix some stream channel tests --- pkgs/stream_channel/.gitignore | 1 + .../test/stream_channel_test.dart | 43 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pkgs/stream_channel/.gitignore b/pkgs/stream_channel/.gitignore index 25a1df332..1447012ea 100644 --- a/pkgs/stream_channel/.gitignore +++ b/pkgs/stream_channel/.gitignore @@ -1,4 +1,5 @@ .buildlog +.dart_tool/ .DS_Store .idea .pub/ diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index b8ebcbd85..c29002fdf 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -10,9 +10,9 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - var streamController; - var sinkController; - var channel; + StreamController streamController; + StreamController sinkController; + StreamChannel channel; setUp(() { streamController = new StreamController(); sinkController = new StreamController(); @@ -58,36 +58,35 @@ void main() { }); test("transformStream() transforms only the stream", () async { - var transformed = channel.transformStream(UTF8.decoder); + var transformed = + channel.cast().transformStream(const LineSplitter()); - streamController.add([102, 111, 111, 98, 97, 114]); + streamController.add("hello world"); + streamController.add(" what\nis"); + streamController.add("\nup"); streamController.close(); - expect(await transformed.stream.toList(), equals(["foobar"])); + expect(await transformed.stream.toList(), + equals(["hello world what", "is", "up"])); - transformed.sink.add("fblthp"); + transformed.sink.add("fbl\nthp"); transformed.sink.close(); - expect(sinkController.stream.toList(), completion(equals(["fblthp"]))); + expect(sinkController.stream.toList(), completion(equals(["fbl\nthp"]))); }); test("transformSink() transforms only the sink", () async { - var transformed = channel.transformSink( - new StreamSinkTransformer.fromStreamTransformer(UTF8.encoder)); + var transformed = channel.cast().transformSink( + new StreamSinkTransformer.fromStreamTransformer(const LineSplitter())); - streamController.add([102, 111, 111, 98, 97, 114]); + streamController.add("fbl\nthp"); streamController.close(); - expect( - await transformed.stream.toList(), - equals([ - [102, 111, 111, 98, 97, 114] - ])); + expect(await transformed.stream.toList(), equals(["fbl\nthp"])); - transformed.sink.add("fblthp"); + transformed.sink.add("hello world"); + transformed.sink.add(" what\nis"); + transformed.sink.add("\nup"); transformed.sink.close(); - expect( - sinkController.stream.toList(), - completion(equals([ - [102, 98, 108, 116, 104, 112] - ]))); + expect(sinkController.stream.toList(), + completion(equals(["hello world what", "is", "up"]))); }); test("changeStream() changes the stream", () { From 509e7364b58c6db8b8ecd1e7dd358383d63561f7 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 2 May 2018 12:51:37 -0700 Subject: [PATCH 053/138] Fix a remaining Dart 2 issue (dart-lang/stream_channel#23) We had some unnecessary typed wrappers that were interfering with runtime type arguments. Closes dart-lang/stream_channel#22 --- pkgs/stream_channel/CHANGELOG.md | 4 +++- .../stream_channel/lib/src/stream_channel_transformer.dart | 7 ++----- pkgs/stream_channel/test/stream_channel_test.dart | 5 +++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index a2404d27e..014b2fcc3 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,6 +1,8 @@ ## 1.6.6 -* Fix a Dart2 issue with inner stream transformation in `GuaranteeChannel`. +* Fix a Dart 2 issue with inner stream transformation in `GuaranteeChannel`. + +* Fix a Dart 2 issue with `StreamChannelTransformer.fromCodec()`. ## 1.6.5 diff --git a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart index 1a4afcae2..4fcd3cd69 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart @@ -57,11 +57,8 @@ class StreamChannelTransformer { /// All input to the inner channel's sink is encoded using [Codec.encoder], /// and all output from its stream is decoded using [Codec.decoder]. StreamChannelTransformer.fromCodec(Codec codec) - : this( - typedStreamTransformer(codec.decoder), - StreamSinkTransformer.typed( - new StreamSinkTransformer.fromStreamTransformer( - codec.encoder))); + : this(codec.decoder, + new StreamSinkTransformer.fromStreamTransformer(codec.encoder)); /// Transforms the events sent to and emitted by [channel]. /// diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index c29002fdf..4ec84bc26 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -41,8 +41,9 @@ void main() { }); test("transform() transforms the channel", () async { - var transformed = - channel.transform(new StreamChannelTransformer.fromCodec(UTF8)); + var transformed = channel + .cast>() + .transform(new StreamChannelTransformer.fromCodec(UTF8)); streamController.add([102, 111, 111, 98, 97, 114]); streamController.close(); From 9a1991971381e2a2ecd7d7285bb5f74f55e52dfe Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 20 May 2018 13:28:26 +0100 Subject: [PATCH 054/138] Stop testing IsolateChannel on browsers (dart-lang/stream_channel#24) --- pkgs/stream_channel/test/isolate_channel_test.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index 66834cace..8f3318469 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -2,6 +2,8 @@ // 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. +@TestOn('vm') + import 'dart:async'; import 'dart:isolate'; From dbe4ec143efd91a28d76a89f845669adc8ec7095 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Fri, 1 Jun 2018 14:57:12 +0200 Subject: [PATCH 055/138] Remove upper case constants (dart-lang/stream_channel#17) * Remove usage of upper-case constants. * update SDK version * remove stable from Travis config --- pkgs/stream_channel/.travis.yml | 2 -- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/pubspec.yaml | 4 ++-- pkgs/stream_channel/test/json_document_transformer_test.dart | 2 +- pkgs/stream_channel/test/stream_channel_test.dart | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pkgs/stream_channel/.travis.yml b/pkgs/stream_channel/.travis.yml index a9510326d..45359fb40 100644 --- a/pkgs/stream_channel/.travis.yml +++ b/pkgs/stream_channel/.travis.yml @@ -2,8 +2,6 @@ language: dart dart: - dev - - stable - dart_task: - test: --platform vm - test: --platform firefox -j 1 diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 014b2fcc3..eafdb8122 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.7 + +* Update SDK version to 2.0.0-dev.17.0. + ## 1.6.6 * Fix a Dart 2 issue with inner stream transformation in `GuaranteeChannel`. diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index c121f5f13..47e24c2f7 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,10 +1,10 @@ name: stream_channel -version: 1.6.6 +version: 1.6.7-dev description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel environment: - sdk: '>=1.21.0 <2.0.0' + sdk: '>=2.0.0-dev.17.0 <2.0.0' dependencies: async: '>=1.11.0 <3.0.0' stack_trace: '^1.0.0' diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index b55a11887..d6fd72b96 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -29,7 +29,7 @@ void main() { var transformed = channel.transform(jsonDocument); transformed.sink.add({"foo": "bar"}); expect(sinkController.stream.first, - completion(equals(JSON.encode({"foo": "bar"})))); + completion(equals(jsonEncode({"foo": "bar"})))); }); test("supports the reviver function", () { diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index 4ec84bc26..dbe421195 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -43,7 +43,7 @@ void main() { test("transform() transforms the channel", () async { var transformed = channel .cast>() - .transform(new StreamChannelTransformer.fromCodec(UTF8)); + .transform(new StreamChannelTransformer.fromCodec(utf8)); streamController.add([102, 111, 111, 98, 97, 114]); streamController.close(); From 533026d8efb58d8c68bcbc977ee69b4aff091ecd Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Fri, 8 Jun 2018 14:59:31 -0700 Subject: [PATCH 056/138] Allow a type on MultiChannel (dart-lang/stream_channel#26) - Add generic type arguments to the classes and relevant fields. - Explicitly indicate which arguments take a `StreamChannel`. - Update the test for MultiChannel to use a consistent type. --- pkgs/stream_channel/CHANGELOG.md | 1 + .../stream_channel/lib/src/multi_channel.dart | 41 +++++++++-------- pkgs/stream_channel/pubspec.yaml | 2 +- .../test/multi_channel_test.dart | 45 +++++++++---------- 4 files changed, 46 insertions(+), 43 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index eafdb8122..b284e5ed8 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,6 +1,7 @@ ## 1.6.7 * Update SDK version to 2.0.0-dev.17.0. +* Add a type argument to `MultiChannel`. ## 1.6.6 diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index e54154304..e7e2584aa 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -41,24 +41,25 @@ import '../stream_channel.dart'; /// /// Each virtual channel may be closed individually. When all of them are /// closed, the underlying [StreamSink] is closed automatically. -abstract class MultiChannel implements StreamChannel { +abstract class MultiChannel implements StreamChannel { /// The default input stream. /// /// This connects to the remote [sink]. - Stream get stream; + Stream get stream; /// The default output stream. /// /// This connects to the remote [stream]. If this is closed, the remote /// [stream] will close, but other virtual channels will remain open and new /// virtual channels may be opened. - StreamSink get sink; + StreamSink get sink; /// Creates a new [MultiChannel] that sends and receives messages over /// [inner]. /// /// The inner channel must take JSON-like objects. - factory MultiChannel(StreamChannel inner) => new _MultiChannel(inner); + factory MultiChannel(StreamChannel inner) => + new _MultiChannel(inner); /// Creates a new virtual channel. /// @@ -71,31 +72,32 @@ abstract class MultiChannel implements StreamChannel { /// /// Throws an [ArgumentError] if a virtual channel already exists for [id]. /// Throws a [StateError] if the underlying channel is closed. - VirtualChannel virtualChannel([id]); + VirtualChannel virtualChannel([id]); } /// The implementation of [MultiChannel]. /// /// This is private so that [VirtualChannel] can inherit from [MultiChannel] /// without having to implement all the private members. -class _MultiChannel extends StreamChannelMixin implements MultiChannel { +class _MultiChannel extends StreamChannelMixin + implements MultiChannel { /// The inner channel over which all communication is conducted. /// /// This will be `null` if the underlying communication channel is closed. - StreamChannel _inner; + StreamChannel _inner; /// The subscription to [_inner.stream]. - StreamSubscription _innerStreamSubscription; + StreamSubscription _innerStreamSubscription; - Stream get stream => _mainController.foreign.stream; - StreamSink get sink => _mainController.foreign.sink; + Stream get stream => _mainController.foreign.stream; + StreamSink get sink => _mainController.foreign.sink; /// The controller for this channel. - final _mainController = new StreamChannelController(sync: true); + final _mainController = new StreamChannelController(sync: true); /// A map from input IDs to [StreamChannelController]s that should be used to /// communicate over those channels. - final _controllers = {}; + final _controllers = >{}; /// Input IDs of controllers in [_controllers] that we've received messages /// for but that have not yet had a local [virtualChannel] created. @@ -164,7 +166,7 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { onError: _mainController.local.sink.addError); } - VirtualChannel virtualChannel([id]) { + VirtualChannel virtualChannel([id]) { var inputId; var outputId; if (id != null) { @@ -189,7 +191,7 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { this, inputId, new Stream.empty(), new NullStreamSink()); } - StreamChannelController controller; + StreamChannelController controller; if (_pendingIds.remove(inputId)) { // If we've already received messages for this channel, use the controller // where those messages are buffered. @@ -244,9 +246,10 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel { /// This implements [MultiChannel] for convenience. /// [VirtualChannel.virtualChannel] is semantically identical to the parent's /// [MultiChannel.virtualChannel]. -class VirtualChannel extends StreamChannelMixin implements MultiChannel { +class VirtualChannel extends StreamChannelMixin + implements MultiChannel { /// The [MultiChannel] that created this. - final MultiChannel _parent; + final MultiChannel _parent; /// The identifier for this channel. /// @@ -255,10 +258,10 @@ class VirtualChannel extends StreamChannelMixin implements MultiChannel { /// except that it will be JSON-serializable. final id; - final Stream stream; - final StreamSink sink; + final Stream stream; + final StreamSink sink; VirtualChannel._(this._parent, this.id, this.stream, this.sink); - VirtualChannel virtualChannel([id]) => _parent.virtualChannel(id); + VirtualChannel virtualChannel([id]) => _parent.virtualChannel(id); } diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 47e24c2f7..bbb29d8b7 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.6.7-dev +version: 1.6.7 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index 0c9316abb..99a53c328 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -11,8 +11,8 @@ void main() { var channel2; setUp(() { controller = new StreamChannelController(); - channel1 = new MultiChannel(controller.local); - channel2 = new MultiChannel(controller.foreign); + channel1 = new MultiChannel(controller.local); + channel2 = new MultiChannel(controller.foreign); }); group("the default virtual channel", () { @@ -20,15 +20,15 @@ void main() { var first = true; channel2.stream.listen(expectAsync1((message) { if (first) { - expect(message, equals("hello")); + expect(message, equals(1)); first = false; } else { - expect(message, equals("world")); + expect(message, equals(2)); } }, count: 2)); - channel1.sink.add("hello"); - channel1.sink.add("world"); + channel1.sink.add(1); + channel1.sink.add(2); }); test("closes the remote virtual channel when it closes", () { @@ -95,10 +95,10 @@ void main() { var first = true; virtual2.stream.listen(expectAsync1((message) { if (first) { - expect(message, equals("hello")); + expect(message, equals(1)); first = false; } else { - expect(message, equals("world")); + expect(message, equals(2)); } }, count: 2)); @@ -109,8 +109,8 @@ void main() { } channel2.stream.listen(expectAsync1((_) {}, count: 0)); - virtual1.sink.add("hello"); - virtual1.sink.add("world"); + virtual1.sink.add(1); + virtual1.sink.add(2); }); test("closes the remote virtual channel when it closes", () { @@ -174,12 +174,12 @@ void main() { expect(virtual1.id, equals(virtual3.id)); virtual2.stream - .listen(expectAsync1((message) => expect(message, equals("hello")))); - virtual4.stream.listen( - expectAsync1((message) => expect(message, equals("goodbye")))); + .listen(expectAsync1((message) => expect(message, equals(1)))); + virtual4.stream + .listen(expectAsync1((message) => expect(message, equals(2)))); - virtual1.sink.add("hello"); - virtual3.sink.add("goodbye"); + virtual1.sink.add(1); + virtual3.sink.add(2); }); }); @@ -195,10 +195,10 @@ void main() { var first = true; virtual1.stream.listen(expectAsync1((message) { if (first) { - expect(message, equals("hello")); + expect(message, equals(1)); first = false; } else { - expect(message, equals("world")); + expect(message, equals(2)); } }, count: 2)); @@ -209,8 +209,8 @@ void main() { } channel1.stream.listen(expectAsync1((_) {}, count: 0)); - virtual2.sink.add("hello"); - virtual2.sink.add("world"); + virtual2.sink.add(1); + virtual2.sink.add(2); }); test("closes the remote virtual channel when it closes", () { @@ -273,14 +273,13 @@ void main() { () async { virtual1 = channel1.virtualChannel(); - virtual1.sink.add("hello"); + virtual1.sink.add(1); await pumpEventQueue(); - virtual1.sink.add("world"); + virtual1.sink.add(2); await pumpEventQueue(); - expect(channel2.virtualChannel(virtual1.id).stream, - emitsInOrder(["hello", "world"])); + expect(channel2.virtualChannel(virtual1.id).stream, emitsInOrder([1, 2])); }); test( From 58810c95b4898e49b0ee681f8aff4d9fbce4a52b Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Fri, 8 Jun 2018 14:59:51 -0700 Subject: [PATCH 057/138] Drop dependency on StackTrace (dart-lang/stream_channel#27) The extra wrapping of `StackTrace.current` can always be done by the receiver. --- pkgs/stream_channel/lib/src/isolate_channel.dart | 3 +-- pkgs/stream_channel/pubspec.yaml | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index f1328c03d..290c2ff2c 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'dart:isolate'; import 'package:async/async.dart'; -import 'package:stack_trace/stack_trace.dart'; import '../stream_channel.dart'; @@ -66,7 +65,7 @@ class IsolateChannel extends StreamChannelMixin { streamCompleter.setError( new StateError('Unexpected Isolate response "$message".'), - new Trace.current()); + StackTrace.current); sinkCompleter.setDestinationSink(new NullStreamSink()); subscription.cancel(); }); diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index bbb29d8b7..ff2209c94 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -7,6 +7,5 @@ environment: sdk: '>=2.0.0-dev.17.0 <2.0.0' dependencies: async: '>=1.11.0 <3.0.0' - stack_trace: '^1.0.0' dev_dependencies: test: '^0.12.28' From ff1febd21c1b5e137bd70997a0b54581319fad1e Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Fri, 8 Jun 2018 15:40:42 -0700 Subject: [PATCH 058/138] Fix doc comment references (dart-lang/stream_channel#28) --- pkgs/stream_channel/analysis_options.yaml | 4 +++ .../stream_channel/lib/src/multi_channel.dart | 2 +- .../lib/src/stream_channel_controller.dart | 4 +-- .../lib/src/stream_channel_transformer.dart | 4 +-- pkgs/stream_channel/lib/stream_channel.dart | 30 +++++++++---------- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index 743cc902d..107424e55 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -6,3 +6,7 @@ analyzer: unused_element: error unused_local_variable: error dead_code: error + +linter: + rules: + - comment_references diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index e7e2584aa..a1ee0574f 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -86,7 +86,7 @@ class _MultiChannel extends StreamChannelMixin /// This will be `null` if the underlying communication channel is closed. StreamChannel _inner; - /// The subscription to [_inner.stream]. + /// The subscription to [_inner].stream. StreamSubscription _innerStreamSubscription; Stream get stream => _mainController.foreign.stream; diff --git a/pkgs/stream_channel/lib/src/stream_channel_controller.dart b/pkgs/stream_channel/lib/src/stream_channel_controller.dart index 45b2865ed..146e99667 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_controller.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_controller.dart @@ -50,8 +50,8 @@ class StreamChannelController { /// /// If [allowForeignErrors] is `false`, errors are not allowed to be passed to /// the foreign channel's sink. If any are, the connection will close and the - /// error will be forwarded to the foreign channel's [Sink.done] future. This - /// guarantees that the local stream will never emit errors. + /// error will be forwarded to the foreign channel's [StreamSink.done] future. + /// This guarantees that the local stream will never emit errors. StreamChannelController({bool allowForeignErrors: true, bool sync: false}) { var localToForeignController = new StreamController(sync: sync); var foreignToLocalController = new StreamController(sync: sync); diff --git a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart index 4fcd3cd69..cc9bad881 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart @@ -23,8 +23,8 @@ import 'transformer/typed.dart'; /// the stream to close before it emits any more events. This guarantee is /// invalidated when an asynchronous gap is added between the original stream's /// event dispatch and the returned stream's, for example by transforming it -/// with a [StreamTransformer]. The guarantee can be easily preserved using [new -/// StreamChannel.withCloseGuarantee]. +/// with a [StreamTransformer]. The guarantee can be easily preserved using +/// [StreamChannel.withCloseGuarantee]. class StreamChannelTransformer { /// The transformer to use on the channel's stream. final StreamTransformer _streamTransformer; diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index 8d0e60421..ce3cf04a7 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -25,8 +25,8 @@ export 'src/stream_channel_transformer.dart'; /// canonical indicator that the channel has closed. If they wish to close the /// channel, they should close the [sink]—canceling the stream subscription is /// not sufficient. Protocol errors may be emitted through the stream or through -/// [Sink.done], depending on their underlying cause. Note that the sink may -/// silently drop events if the channel closes before [Sink.close] is called. +/// [sink].done, depending on their underlying cause. Note that the sink may +/// silently drop events if the channel closes before [sink].close is called. /// /// Implementations are strongly encouraged to mix in or extend /// [StreamChannelMixin] to get default implementations of the various instance @@ -43,7 +43,7 @@ export 'src/stream_channel_transformer.dart'; /// /// * After the stream closes, the sink is automatically closed. If this /// happens, sink methods should silently drop their arguments until -/// [Sink.close] is called. +/// [sink].close is called. /// /// * If the stream closes before it has a listener, the sink should silently /// drop events if possible. @@ -53,7 +53,7 @@ export 'src/stream_channel_transformer.dart'; /// even after the subscription has been canceled. /// /// * The sink *either* forwards errors to the other endpoint *or* closes as -/// soon as an error is added and forwards that error to the [Sink.done] +/// soon as an error is added and forwards that error to the [sink].done /// future. /// /// These guarantees allow users to interact uniformly with all implementations, @@ -69,8 +69,8 @@ abstract class StreamChannel { /// Creates a new [StreamChannel] that communicates over [stream] and [sink]. /// /// Note that this stream/sink pair must provide the guarantees listed in the - /// [StreamChannel] documentation. If they don't do so natively, [new - /// StreamChannel.withGuarantees] should be used instead. + /// [StreamChannel] documentation. If they don't do so natively, + /// [StreamChannel.withGuarantees] should be used instead. factory StreamChannel(Stream stream, StreamSink sink) => new _StreamChannel(stream, sink); @@ -83,7 +83,7 @@ abstract class StreamChannel { /// /// If [allowSinkErrors] is `false`, errors are not allowed to be passed to /// [sink]. If any are, the connection will close and the error will be - /// forwarded to [Sink.done]. + /// forwarded to [sink].done. factory StreamChannel.withGuarantees(Stream stream, StreamSink sink, {bool allowSinkErrors: true}) => new GuaranteeChannel(stream, sink, allowSinkErrors: allowSinkErrors); @@ -101,33 +101,33 @@ abstract class StreamChannel { Stream stream, StreamSink sink) => new CloseGuaranteeChannel(stream, sink); - /// Connects [this] to [other], so that any values emitted by either are sent + /// Connects this to [other], so that any values emitted by either are sent /// directly to the other. void pipe(StreamChannel other); - /// Transforms [this] using [transformer]. + /// Transforms this using [transformer]. /// /// This is identical to calling `transformer.bind(channel)`. StreamChannel transform(StreamChannelTransformer transformer); - /// Transforms only the [stream] component of [this] using [transformer]. + /// Transforms only the [stream] component of this using [transformer]. StreamChannel transformStream(StreamTransformer transformer); - /// Transforms only the [sink] component of [this] using [transformer]. + /// Transforms only the [sink] component of this using [transformer]. StreamChannel transformSink(StreamSinkTransformer transformer); - /// Returns a copy of [this] with [stream] replaced by [change]'s return + /// Returns a copy of this with [stream] replaced by [change]'s return /// value. StreamChannel changeStream(Stream change(Stream stream)); - /// Returns a copy of [this] with [sink] replaced by [change]'s return + /// Returns a copy of this with [sink] replaced by [change]'s return /// value. StreamChannel changeSink(StreamSink change(StreamSink sink)); - /// Returns a copy of [this] with the generic type coerced to [S]. + /// Returns a copy of this with the generic type coerced to [S]. /// /// If any events emitted by [stream] aren't of type [S], they're converted - /// into [CastError] events. Similarly, if any events are added to [sync] that + /// into [CastError] events. Similarly, if any events are added to [sink] that /// aren't of type [S], a [CastError] is thrown. StreamChannel cast(); } From b0dc30207fa6f5c617f0618ed3edc22b75f1da74 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 12 Jun 2018 09:27:35 -0700 Subject: [PATCH 059/138] Enable prefer_typing_unitialized_varables lint (dart-lang/stream_channel#30) Work towards dart-lang/stream_channel#29 Using the lint catches a bug were an uninitialized variable was causing an instantiation to pick up a reified type of `dynamic` instead of a useful type. --- pkgs/stream_channel/analysis_options.yaml | 1 + .../lib/src/isolate_channel.dart | 2 +- .../stream_channel/lib/src/multi_channel.dart | 12 +++++----- .../test/disconnector_test.dart | 8 +++---- .../test/isolate_channel_test.dart | 8 +++---- .../test/json_document_transformer_test.dart | 4 ++-- .../test/multi_channel_test.dart | 22 +++++++++---------- .../test/stream_channel_completer_test.dart | 8 +++---- .../test/stream_channel_controller_test.dart | 4 ++-- .../test/with_close_guarantee_test.dart | 4 ++-- .../test/with_guarantees_test.dart | 6 ++--- 11 files changed, 40 insertions(+), 39 deletions(-) diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index 107424e55..bf7c331dd 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -10,3 +10,4 @@ analyzer: linter: rules: - comment_references + - prefer_typing_uninitialized_variables diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index 290c2ff2c..4a1717df1 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -49,7 +49,7 @@ class IsolateChannel extends StreamChannelMixin { // The first message across the ReceivePort should be a SendPort pointing to // the remote end. If it's not, we'll make the stream emit an error // complaining. - var subscription; + StreamSubscription subscription; subscription = receivePort.listen((message) { if (message is SendPort) { var controller = new StreamChannelController( diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index a1ee0574f..a6d684a13 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -72,7 +72,7 @@ abstract class MultiChannel implements StreamChannel { /// /// Throws an [ArgumentError] if a virtual channel already exists for [id]. /// Throws a [StateError] if the underlying channel is closed. - VirtualChannel virtualChannel([id]); + VirtualChannel virtualChannel([int id]); } /// The implementation of [MultiChannel]. @@ -166,15 +166,15 @@ class _MultiChannel extends StreamChannelMixin onError: _mainController.local.sink.addError); } - VirtualChannel virtualChannel([id]) { - var inputId; - var outputId; + VirtualChannel virtualChannel([int id]) { + int inputId; + int outputId; if (id != null) { // Since the user is passing in an id, we're connected to a remote // VirtualChannel. This means messages they send over this channel will // have the original odd id, but our replies will have an even id. inputId = id; - outputId = (id as int) + 1; + outputId = id + 1; } else { // Since we're generating an id, we originated this VirtualChannel. This // means messages we send over this channel will have the original odd id, @@ -256,7 +256,7 @@ class VirtualChannel extends StreamChannelMixin /// This can be sent across the [MultiChannel] to provide the remote endpoint /// a means to connect to this channel. Nothing about this is guaranteed /// except that it will be JSON-serializable. - final id; + final int id; final Stream stream; final StreamSink sink; diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index 5b725740c..62ef78b54 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -9,10 +9,10 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - var streamController; - var sinkController; - var disconnector; - var channel; + StreamController streamController; + StreamController sinkController; + Disconnector disconnector; + StreamChannel channel; setUp(() { streamController = new StreamController(); sinkController = new StreamController(); diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index 8f3318469..00f45844c 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -11,9 +11,9 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - var receivePort; - var sendPort; - var channel; + ReceivePort receivePort; + SendPort sendPort; + StreamChannel channel; setUp(() { receivePort = new ReceivePort(); var receivePortForSend = new ReceivePort(); @@ -126,7 +126,7 @@ void main() { }); group("connect constructors", () { - var connectPort; + ReceivePort connectPort; setUp(() { connectPort = new ReceivePort(); }); diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index d6fd72b96..3c6d11c91 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -9,8 +9,8 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - var streamController; - var sinkController; + StreamController streamController; + StreamController sinkController; StreamChannel channel; setUp(() { streamController = new StreamController(); diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index 99a53c328..ddc4150bb 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -6,9 +6,9 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - var controller; - var channel1; - var channel2; + StreamChannelController controller; + MultiChannel channel1; + MultiChannel channel2; setUp(() { controller = new StreamChannelController(); channel1 = new MultiChannel(controller.local); @@ -84,8 +84,8 @@ void main() { }); group("a locally-created virtual channel", () { - var virtual1; - var virtual2; + VirtualChannel virtual1; + VirtualChannel virtual2; setUp(() { virtual1 = channel1.virtualChannel(); virtual2 = channel2.virtualChannel(virtual1.id); @@ -184,8 +184,8 @@ void main() { }); group("a remotely-created virtual channel", () { - var virtual1; - var virtual2; + VirtualChannel virtual1; + VirtualChannel virtual2; setUp(() { virtual1 = channel1.virtualChannel(); virtual2 = channel2.virtualChannel(virtual1.id); @@ -296,8 +296,8 @@ void main() { }); group("when the underlying stream", () { - var virtual1; - var virtual2; + VirtualChannel virtual1; + VirtualChannel virtual2; setUp(() { virtual1 = channel1.virtualChannel(); virtual2 = channel2.virtualChannel(virtual1.id); @@ -405,8 +405,8 @@ void main() { }); group("for a virtual channel:", () { - var virtual1; - var virtual2; + VirtualChannel virtual1; + VirtualChannel virtual2; setUp(() { virtual1 = channel1.virtualChannel(); virtual2 = channel2.virtualChannel(virtual1.id); diff --git a/pkgs/stream_channel/test/stream_channel_completer_test.dart b/pkgs/stream_channel/test/stream_channel_completer_test.dart index 8d830058a..666efe9ed 100644 --- a/pkgs/stream_channel/test/stream_channel_completer_test.dart +++ b/pkgs/stream_channel/test/stream_channel_completer_test.dart @@ -8,10 +8,10 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - var completer; - var streamController; - var sinkController; - var innerChannel; + StreamChannelCompleter completer; + StreamController streamController; + StreamController sinkController; + StreamChannel innerChannel; setUp(() { completer = new StreamChannelCompleter(); streamController = new StreamController(); diff --git a/pkgs/stream_channel/test/stream_channel_controller_test.dart b/pkgs/stream_channel/test/stream_channel_controller_test.dart index c092570f5..483b7f6f1 100644 --- a/pkgs/stream_channel/test/stream_channel_controller_test.dart +++ b/pkgs/stream_channel/test/stream_channel_controller_test.dart @@ -7,7 +7,7 @@ import 'package:test/test.dart'; void main() { group("asynchronously", () { - var controller; + StreamChannelController controller; setUp(() { controller = new StreamChannelController(); }); @@ -44,7 +44,7 @@ void main() { }); group("synchronously", () { - var controller; + StreamChannelController controller; setUp(() { controller = new StreamChannelController(sync: true); }); diff --git a/pkgs/stream_channel/test/with_close_guarantee_test.dart b/pkgs/stream_channel/test/with_close_guarantee_test.dart index a6527a716..8e1b63119 100644 --- a/pkgs/stream_channel/test/with_close_guarantee_test.dart +++ b/pkgs/stream_channel/test/with_close_guarantee_test.dart @@ -16,8 +16,8 @@ final _delaySinkTransformer = new StreamSinkTransformer.fromStreamTransformer(_delayTransformer); void main() { - var controller; - var channel; + StreamChannelController controller; + StreamChannel channel; setUp(() { controller = new StreamChannelController(); diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index e1302f64c..dcdffe089 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -8,9 +8,9 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - var streamController; - var sinkController; - var channel; + StreamController streamController; + StreamController sinkController; + StreamChannel channel; setUp(() { streamController = new StreamController(); sinkController = new StreamController(); From 338ee53371ac67e88a094bb4fcb6af73075edfa4 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 12 Jun 2018 10:53:40 -0700 Subject: [PATCH 060/138] Cast streams to correct types in IsolateChannel (dart-lang/stream_channel#31) Fixes dart-lang/stream_channel#29 - Add a type on the IsolateChannel in one of the tests so that it exhibits the problem when run in Dart 2 mode. - Cast the streams coming from the ReceivePort instances to the appropriate types since ReceivePort is always `Stream`. - Remove the type on the subscription variable since it's a subscription on a dynamic stream and otherwise would never have the correct type. --- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/lib/src/isolate_channel.dart | 8 +++++--- pkgs/stream_channel/pubspec.yaml | 2 +- pkgs/stream_channel/test/isolate_channel_test.dart | 4 ++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index b284e5ed8..3dfbbc6f9 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.7+1 + +* Fix Dart 2 runtime types in `IsolateChannel`. + ## 1.6.7 * Update SDK version to 2.0.0-dev.17.0. diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index 4a1717df1..d785ae118 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -49,12 +49,14 @@ class IsolateChannel extends StreamChannelMixin { // The first message across the ReceivePort should be a SendPort pointing to // the remote end. If it's not, we'll make the stream emit an error // complaining. - StreamSubscription subscription; + StreamSubscription subscription; subscription = receivePort.listen((message) { if (message is SendPort) { var controller = new StreamChannelController( allowForeignErrors: false, sync: true); - new SubscriptionStream(subscription).pipe(controller.local.sink); + new SubscriptionStream(subscription) + .cast() + .pipe(controller.local.sink); controller.local.stream .listen((data) => message.send(data), onDone: receivePort.close); @@ -93,7 +95,7 @@ class IsolateChannel extends StreamChannelMixin { factory IsolateChannel(ReceivePort receivePort, SendPort sendPort) { var controller = new StreamChannelController(allowForeignErrors: false, sync: true); - receivePort.pipe(controller.local.sink); + receivePort.cast().pipe(controller.local.sink); controller.local.stream .listen((data) => sendPort.send(data), onDone: receivePort.close); return new IsolateChannel._( diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index ff2209c94..54bd97217 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.6.7 +version: 1.6.7+1 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index 00f45844c..4c73ab090 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -136,8 +136,8 @@ void main() { }); test("create a connected pair of channels", () { - var channel1 = new IsolateChannel.connectReceive(connectPort); - var channel2 = new IsolateChannel.connectSend(connectPort.sendPort); + var channel1 = new IsolateChannel.connectReceive(connectPort); + var channel2 = new IsolateChannel.connectSend(connectPort.sendPort); channel1.sink.add(1); channel1.sink.add(2); From 19ba981cfb19b60437170202d27c18cc2ce98527 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 18 Jul 2018 19:28:11 -0400 Subject: [PATCH 061/138] Allow SDK versions <3.0.0 (dart-lang/stream_channel#32) And update some dependencies. --- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/analysis_options.yaml | 1 - pkgs/stream_channel/pubspec.yaml | 10 +++++++--- .../test/json_document_transformer_test.dart | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 3dfbbc6f9..ce98fe038 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.8 + +* Set max SDK version to `<3.0.0`, and adjust other dependencies. + ## 1.6.7+1 * Fix Dart 2 runtime types in `IsolateChannel`. diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index bf7c331dd..d19ee843f 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -1,5 +1,4 @@ analyzer: - strong-mode: true # These are errors when building in Google errors: unused_import: error diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 54bd97217..6b1ace36f 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,11 +1,15 @@ name: stream_channel -version: 1.6.7+1 +version: 1.6.8 + description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel + environment: - sdk: '>=2.0.0-dev.17.0 <2.0.0' + sdk: '>=2.0.0-dev.17.0 <3.0.0' + dependencies: async: '>=1.11.0 <3.0.0' + dev_dependencies: - test: '^0.12.28' + test: ^1.2.0 diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index 3c6d11c91..6cb97f945 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -55,6 +55,6 @@ void main() { test("synchronously throws if an unencodable object is added", () { var transformed = channel.transform(jsonDocument); expect(() => transformed.sink.add(new Object()), - throwsA(new isInstanceOf())); + throwsA(new TypeMatcher())); }); } From 3191148f2fa5311d55bf717678e2e8d9dc3bece4 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 26 Mar 2019 14:00:09 -0700 Subject: [PATCH 062/138] Remove optional new/const (dart-lang/stream_channel#37) - Run `dartfmt --fix`. - Update version to start working towards next breaking change. - Update minimum SDK to 2.0.0 stable. --- pkgs/stream_channel/CHANGELOG.md | 5 +++ .../lib/src/close_guarantee_channel.dart | 4 +-- pkgs/stream_channel/lib/src/disconnector.dart | 22 ++++++------- .../lib/src/guarantee_channel.dart | 31 +++++++++---------- .../lib/src/isolate_channel.dart | 27 +++++++--------- .../lib/src/json_document_transformer.dart | 8 ++--- .../stream_channel/lib/src/multi_channel.dart | 22 ++++++------- .../lib/src/stream_channel_completer.dart | 15 +++++---- .../lib/src/stream_channel_controller.dart | 10 +++--- .../lib/src/stream_channel_transformer.dart | 6 ++-- pkgs/stream_channel/lib/stream_channel.dart | 14 ++++----- pkgs/stream_channel/pubspec.yaml | 4 +-- .../test/disconnector_test.dart | 28 ++++++++--------- .../test/isolate_channel_test.dart | 22 ++++++------- .../test/json_document_transformer_test.dart | 20 ++++++------ .../test/multi_channel_test.dart | 6 ++-- .../test/stream_channel_completer_test.dart | 14 ++++----- .../test/stream_channel_controller_test.dart | 6 ++-- .../test/stream_channel_test.dart | 22 ++++++------- .../test/with_close_guarantee_test.dart | 12 +++---- .../test/with_guarantees_test.dart | 24 +++++++------- 21 files changed, 159 insertions(+), 163 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index ce98fe038..87ba42fe7 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.6.9 + +* Require `2.0.0` or newer SDK. +* Drop unnecessary `new` and `const`. + ## 1.6.8 * Set max SDK version to `<3.0.0`, and adjust other dependencies. diff --git a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart index a2c69bcb8..b8a3f0289 100644 --- a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart @@ -27,8 +27,8 @@ class CloseGuaranteeChannel extends StreamChannelMixin { bool _disconnected = false; CloseGuaranteeChannel(Stream innerStream, StreamSink innerSink) { - _sink = new _CloseGuaranteeSink(innerSink, this); - _stream = new _CloseGuaranteeStream(innerStream, this); + _sink = _CloseGuaranteeSink(innerSink, this); + _stream = _CloseGuaranteeStream(innerStream, this); } } diff --git a/pkgs/stream_channel/lib/src/disconnector.dart b/pkgs/stream_channel/lib/src/disconnector.dart index 37a376c31..9d35cfc63 100644 --- a/pkgs/stream_channel/lib/src/disconnector.dart +++ b/pkgs/stream_channel/lib/src/disconnector.dart @@ -38,11 +38,11 @@ class Disconnector implements StreamChannelTransformer { _sinks.clear(); return Future.wait(futures, eagerError: true); }); - final _disconnectMemo = new AsyncMemoizer(); + final _disconnectMemo = AsyncMemoizer(); StreamChannel bind(StreamChannel channel) { return channel.changeSink((innerSink) { - var sink = new _DisconnectorSink(innerSink); + var sink = _DisconnectorSink(innerSink); if (isDisconnected) { // Ignore errors here, because otherwise there would be no way for the @@ -84,9 +84,9 @@ class _DisconnectorSink implements StreamSink { _DisconnectorSink(this._inner); void add(T data) { - if (_closed) throw new StateError("Cannot add event after closing."); + if (_closed) throw StateError("Cannot add event after closing."); if (_inAddStream) { - throw new StateError("Cannot add event while adding stream."); + throw StateError("Cannot add event while adding stream."); } if (_isDisconnected) return; @@ -94,9 +94,9 @@ class _DisconnectorSink implements StreamSink { } void addError(error, [StackTrace stackTrace]) { - if (_closed) throw new StateError("Cannot add event after closing."); + if (_closed) throw StateError("Cannot add event after closing."); if (_inAddStream) { - throw new StateError("Cannot add event while adding stream."); + throw StateError("Cannot add event while adding stream."); } if (_isDisconnected) return; @@ -104,13 +104,13 @@ class _DisconnectorSink implements StreamSink { } Future addStream(Stream stream) { - if (_closed) throw new StateError("Cannot add stream after closing."); + if (_closed) throw StateError("Cannot add stream after closing."); if (_inAddStream) { - throw new StateError("Cannot add stream while adding stream."); + throw StateError("Cannot add stream while adding stream."); } - if (_isDisconnected) return new Future.value(); + if (_isDisconnected) return Future.value(); - _addStreamCompleter = new Completer.sync(); + _addStreamCompleter = Completer.sync(); _addStreamSubscription = stream.listen(_inner.add, onError: _inner.addError, onDone: _addStreamCompleter.complete); return _addStreamCompleter.future.then((_) { @@ -121,7 +121,7 @@ class _DisconnectorSink implements StreamSink { Future close() { if (_inAddStream) { - throw new StateError("Cannot close sink while adding stream."); + throw StateError("Cannot close sink while adding stream."); } _closed = true; diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart index ba79ed9bc..e96f5c3c8 100644 --- a/pkgs/stream_channel/lib/src/guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -31,18 +31,17 @@ class GuaranteeChannel extends StreamChannelMixin { bool _disconnected = false; GuaranteeChannel(Stream innerStream, StreamSink innerSink, - {bool allowSinkErrors: true}) { - _sink = - new _GuaranteeSink(innerSink, this, allowErrors: allowSinkErrors); + {bool allowSinkErrors = true}) { + _sink = _GuaranteeSink(innerSink, this, allowErrors: allowSinkErrors); // Enforce the single-subscription guarantee by changing a broadcast stream // to single-subscription. if (innerStream.isBroadcast) { innerStream = - innerStream.transform(new SingleSubscriptionTransformer()); + innerStream.transform(SingleSubscriptionTransformer()); } - _streamController = new StreamController( + _streamController = StreamController( onListen: () { // If the sink has disconnected, we've already called // [_streamController.close]. @@ -80,7 +79,7 @@ class _GuaranteeSink implements StreamSink { final GuaranteeChannel _channel; Future get done => _doneCompleter.future; - final _doneCompleter = new Completer(); + final _doneCompleter = Completer(); /// Whether connection is disconnected. /// @@ -108,13 +107,13 @@ class _GuaranteeSink implements StreamSink { /// the underlying sink is closed. final bool _allowErrors; - _GuaranteeSink(this._inner, this._channel, {bool allowErrors: true}) + _GuaranteeSink(this._inner, this._channel, {bool allowErrors = true}) : _allowErrors = allowErrors; void add(T data) { - if (_closed) throw new StateError("Cannot add event after closing."); + if (_closed) throw StateError("Cannot add event after closing."); if (_inAddStream) { - throw new StateError("Cannot add event while adding stream."); + throw StateError("Cannot add event while adding stream."); } if (_disconnected) return; @@ -122,9 +121,9 @@ class _GuaranteeSink implements StreamSink { } void addError(error, [StackTrace stackTrace]) { - if (_closed) throw new StateError("Cannot add event after closing."); + if (_closed) throw StateError("Cannot add event after closing."); if (_inAddStream) { - throw new StateError("Cannot add event while adding stream."); + throw StateError("Cannot add event while adding stream."); } if (_disconnected) return; @@ -153,13 +152,13 @@ class _GuaranteeSink implements StreamSink { } Future addStream(Stream stream) { - if (_closed) throw new StateError("Cannot add stream after closing."); + if (_closed) throw StateError("Cannot add stream after closing."); if (_inAddStream) { - throw new StateError("Cannot add stream while adding stream."); + throw StateError("Cannot add stream while adding stream."); } - if (_disconnected) return new Future.value(); + if (_disconnected) return Future.value(); - _addStreamCompleter = new Completer.sync(); + _addStreamCompleter = Completer.sync(); _addStreamSubscription = stream.listen(_inner.add, onError: _addError, onDone: _addStreamCompleter.complete); return _addStreamCompleter.future.then((_) { @@ -170,7 +169,7 @@ class _GuaranteeSink implements StreamSink { Future close() { if (_inAddStream) { - throw new StateError("Cannot close sink while adding stream."); + throw StateError("Cannot close sink while adding stream."); } if (_closed) return done; diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index d785ae118..c7f573fd2 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -41,10 +41,10 @@ class IsolateChannel extends StreamChannelMixin { factory IsolateChannel.connectReceive(ReceivePort receivePort) { // We can't use a [StreamChannelCompleter] here because we need the return // value to be an [IsolateChannel]. - var streamCompleter = new StreamCompleter(); - var sinkCompleter = new StreamSinkCompleter(); + var streamCompleter = StreamCompleter(); + var sinkCompleter = StreamSinkCompleter(); var channel = - new IsolateChannel._(streamCompleter.stream, sinkCompleter.sink); + IsolateChannel._(streamCompleter.stream, sinkCompleter.sink); // The first message across the ReceivePort should be a SendPort pointing to // the remote end. If it's not, we'll make the stream emit an error @@ -52,11 +52,9 @@ class IsolateChannel extends StreamChannelMixin { StreamSubscription subscription; subscription = receivePort.listen((message) { if (message is SendPort) { - var controller = new StreamChannelController( - allowForeignErrors: false, sync: true); - new SubscriptionStream(subscription) - .cast() - .pipe(controller.local.sink); + var controller = + StreamChannelController(allowForeignErrors: false, sync: true); + SubscriptionStream(subscription).cast().pipe(controller.local.sink); controller.local.stream .listen((data) => message.send(data), onDone: receivePort.close); @@ -66,9 +64,9 @@ class IsolateChannel extends StreamChannelMixin { } streamCompleter.setError( - new StateError('Unexpected Isolate response "$message".'), + StateError('Unexpected Isolate response "$message".'), StackTrace.current); - sinkCompleter.setDestinationSink(new NullStreamSink()); + sinkCompleter.setDestinationSink(NullStreamSink()); subscription.cancel(); }); @@ -85,21 +83,20 @@ class IsolateChannel extends StreamChannelMixin { /// The connection protocol is guaranteed to remain compatible across versions /// at least until the next major version release. factory IsolateChannel.connectSend(SendPort sendPort) { - var receivePort = new ReceivePort(); + var receivePort = ReceivePort(); sendPort.send(receivePort.sendPort); - return new IsolateChannel(receivePort, sendPort); + return IsolateChannel(receivePort, sendPort); } /// Creates a stream channel that receives messages from [receivePort] and /// sends them over [sendPort]. factory IsolateChannel(ReceivePort receivePort, SendPort sendPort) { var controller = - new StreamChannelController(allowForeignErrors: false, sync: true); + StreamChannelController(allowForeignErrors: false, sync: true); receivePort.cast().pipe(controller.local.sink); controller.local.stream .listen((data) => sendPort.send(data), onDone: receivePort.close); - return new IsolateChannel._( - controller.foreign.stream, controller.foreign.sink); + return IsolateChannel._(controller.foreign.stream, controller.foreign.sink); } IsolateChannel._(this.stream, this.sink); diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index 6377eeda7..2a3a86f3e 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -10,7 +10,7 @@ import '../stream_channel.dart'; import 'stream_channel_transformer.dart'; /// The canonical instance of [JsonDocumentTransformer]. -final jsonDocument = new JsonDocumentTransformer(); +final jsonDocument = JsonDocumentTransformer(); /// A [StreamChannelTransformer] that transforms JSON documents—strings that /// contain individual objects encoded as JSON—into decoded Dart objects. @@ -31,16 +31,16 @@ class JsonDocumentTransformer /// The [reviver] and [toEncodable] arguments work the same way as the /// corresponding arguments to [new JsonCodec]. JsonDocumentTransformer({reviver(key, value), toEncodable(object)}) - : _codec = new JsonCodec(reviver: reviver, toEncodable: toEncodable); + : _codec = JsonCodec(reviver: reviver, toEncodable: toEncodable); JsonDocumentTransformer._(this._codec); StreamChannel bind(StreamChannel channel) { var stream = channel.stream.map(_codec.decode); - var sink = new StreamSinkTransformer.fromHandlers( + var sink = StreamSinkTransformer.fromHandlers( handleData: (data, sink) { sink.add(_codec.encode(data)); }).bind(channel.sink); - return new StreamChannel.withCloseGuarantee(stream, sink); + return StreamChannel.withCloseGuarantee(stream, sink); } } diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index a6d684a13..139c9aefa 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -58,8 +58,7 @@ abstract class MultiChannel implements StreamChannel { /// [inner]. /// /// The inner channel must take JSON-like objects. - factory MultiChannel(StreamChannel inner) => - new _MultiChannel(inner); + factory MultiChannel(StreamChannel inner) => _MultiChannel(inner); /// Creates a new virtual channel. /// @@ -93,7 +92,7 @@ class _MultiChannel extends StreamChannelMixin StreamSink get sink => _mainController.foreign.sink; /// The controller for this channel. - final _mainController = new StreamChannelController(sync: true); + final _mainController = StreamChannelController(sync: true); /// A map from input IDs to [StreamChannelController]s that should be used to /// communicate over those channels. @@ -101,11 +100,11 @@ class _MultiChannel extends StreamChannelMixin /// Input IDs of controllers in [_controllers] that we've received messages /// for but that have not yet had a local [virtualChannel] created. - final _pendingIds = new Set(); + final _pendingIds = Set(); /// Input IDs of virtual channels that used to exist but have since been /// closed. - final _closedIds = new Set(); + final _closedIds = Set(); /// The next id to use for a local virtual channel. /// @@ -149,7 +148,7 @@ class _MultiChannel extends StreamChannelMixin // counterpart yet, create a controller for it to buffer incoming // messages for when a local connection is created. _pendingIds.add(id); - return new StreamChannelController(sync: true); + return StreamChannelController(sync: true); }); if (message.length > 1) { @@ -187,8 +186,7 @@ class _MultiChannel extends StreamChannelMixin // If the inner channel has already closed, create new virtual channels in a // closed state. if (_inner == null) { - return new VirtualChannel._( - this, inputId, new Stream.empty(), new NullStreamSink()); + return VirtualChannel._(this, inputId, Stream.empty(), NullStreamSink()); } StreamChannelController controller; @@ -198,16 +196,16 @@ class _MultiChannel extends StreamChannelMixin controller = _controllers[inputId]; } else if (_controllers.containsKey(inputId) || _closedIds.contains(inputId)) { - throw new ArgumentError("A virtual channel with id $id already exists."); + throw ArgumentError("A virtual channel with id $id already exists."); } else { - controller = new StreamChannelController(sync: true); + controller = StreamChannelController(sync: true); _controllers[inputId] = controller; } controller.local.stream.listen( (message) => _inner.sink.add([outputId, message]), onDone: () => _closeChannel(inputId, outputId)); - return new VirtualChannel._( + return VirtualChannel._( this, outputId, controller.foreign.stream, controller.foreign.sink); } @@ -234,7 +232,7 @@ class _MultiChannel extends StreamChannelMixin // Convert this to a list because the close is dispatched synchronously, and // that could conceivably remove a controller from [_controllers]. - for (var controller in new List.from(_controllers.values)) { + for (var controller in List.from(_controllers.values)) { controller.local.sink.close(); } _controllers.clear(); diff --git a/pkgs/stream_channel/lib/src/stream_channel_completer.dart b/pkgs/stream_channel/lib/src/stream_channel_completer.dart index b9881b913..e94eda66e 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_completer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_completer.dart @@ -15,10 +15,10 @@ import '../stream_channel.dart'; /// any events and all events added to it will be buffered. class StreamChannelCompleter { /// The completer for this channel's stream. - final _streamCompleter = new StreamCompleter(); + final _streamCompleter = StreamCompleter(); /// The completer for this channel's sink. - final _sinkCompleter = new StreamSinkCompleter(); + final _sinkCompleter = StreamSinkCompleter(); /// The channel for this completer. StreamChannel get channel => _channel; @@ -36,14 +36,13 @@ class StreamChannelCompleter { /// instead contain just that error. The sink will silently discard all /// events. static StreamChannel fromFuture(Future channelFuture) { - var completer = new StreamChannelCompleter(); + var completer = StreamChannelCompleter(); channelFuture.then(completer.setChannel, onError: completer.setError); return completer.channel; } StreamChannelCompleter() { - _channel = - new StreamChannel(_streamCompleter.stream, _sinkCompleter.sink); + _channel = StreamChannel(_streamCompleter.stream, _sinkCompleter.sink); } /// Set a channel as the source and destination for [channel]. @@ -53,7 +52,7 @@ class StreamChannelCompleter { /// Either [setChannel] or [setError] may be called at most once. Trying to /// call either of them again will fail. void setChannel(StreamChannel channel) { - if (_set) throw new StateError("The channel has already been set."); + if (_set) throw StateError("The channel has already been set."); _set = true; _streamCompleter.setSourceStream(channel.stream); @@ -68,10 +67,10 @@ class StreamChannelCompleter { /// Either [setChannel] or [setError] may be called at most once. Trying to /// call either of them again will fail. void setError(error, [StackTrace stackTrace]) { - if (_set) throw new StateError("The channel has already been set."); + if (_set) throw StateError("The channel has already been set."); _set = true; _streamCompleter.setError(error, stackTrace); - _sinkCompleter.setDestinationSink(new NullStreamSink()); + _sinkCompleter.setDestinationSink(NullStreamSink()); } } diff --git a/pkgs/stream_channel/lib/src/stream_channel_controller.dart b/pkgs/stream_channel/lib/src/stream_channel_controller.dart index 146e99667..136886df7 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_controller.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_controller.dart @@ -52,12 +52,12 @@ class StreamChannelController { /// the foreign channel's sink. If any are, the connection will close and the /// error will be forwarded to the foreign channel's [StreamSink.done] future. /// This guarantees that the local stream will never emit errors. - StreamChannelController({bool allowForeignErrors: true, bool sync: false}) { - var localToForeignController = new StreamController(sync: sync); - var foreignToLocalController = new StreamController(sync: sync); - _local = new StreamChannel.withGuarantees( + StreamChannelController({bool allowForeignErrors = true, bool sync = false}) { + var localToForeignController = StreamController(sync: sync); + var foreignToLocalController = StreamController(sync: sync); + _local = StreamChannel.withGuarantees( foreignToLocalController.stream, localToForeignController.sink); - _foreign = new StreamChannel.withGuarantees( + _foreign = StreamChannel.withGuarantees( localToForeignController.stream, foreignToLocalController.sink, allowSinkErrors: allowForeignErrors); } diff --git a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart index cc9bad881..32d36b6b0 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart @@ -45,7 +45,7 @@ class StreamChannelTransformer { StreamChannelTransformer transformer) => transformer is StreamChannelTransformer ? transformer - : new TypeSafeStreamChannelTransformer(transformer); + : TypeSafeStreamChannelTransformer(transformer); /// Creates a [StreamChannelTransformer] from existing stream and sink /// transformers. @@ -58,7 +58,7 @@ class StreamChannelTransformer { /// and all output from its stream is decoded using [Codec.decoder]. StreamChannelTransformer.fromCodec(Codec codec) : this(codec.decoder, - new StreamSinkTransformer.fromStreamTransformer(codec.encoder)); + StreamSinkTransformer.fromStreamTransformer(codec.encoder)); /// Transforms the events sent to and emitted by [channel]. /// @@ -68,7 +68,7 @@ class StreamChannelTransformer { /// `channel.straem`, the transformer will transform them and pass the /// transformed versions to the returned channel's stream. StreamChannel bind(StreamChannel channel) => - new StreamChannel.withCloseGuarantee( + StreamChannel.withCloseGuarantee( channel.stream.transform(_streamTransformer), _sinkTransformer.bind(channel.sink)); } diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index ce3cf04a7..b50116044 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -72,7 +72,7 @@ abstract class StreamChannel { /// [StreamChannel] documentation. If they don't do so natively, /// [StreamChannel.withGuarantees] should be used instead. factory StreamChannel(Stream stream, StreamSink sink) => - new _StreamChannel(stream, sink); + _StreamChannel(stream, sink); /// Creates a new [StreamChannel] that communicates over [stream] and [sink]. /// @@ -85,8 +85,8 @@ abstract class StreamChannel { /// [sink]. If any are, the connection will close and the error will be /// forwarded to [sink].done. factory StreamChannel.withGuarantees(Stream stream, StreamSink sink, - {bool allowSinkErrors: true}) => - new GuaranteeChannel(stream, sink, allowSinkErrors: allowSinkErrors); + {bool allowSinkErrors = true}) => + GuaranteeChannel(stream, sink, allowSinkErrors: allowSinkErrors); /// Creates a new [StreamChannel] that communicates over [stream] and [sink]. /// @@ -99,7 +99,7 @@ abstract class StreamChannel { /// [StreamChannel.withGuarantees]. factory StreamChannel.withCloseGuarantee( Stream stream, StreamSink sink) => - new CloseGuaranteeChannel(stream, sink); + CloseGuaranteeChannel(stream, sink); /// Connects this to [other], so that any values emitted by either are sent /// directly to the other. @@ -162,11 +162,11 @@ abstract class StreamChannelMixin implements StreamChannel { changeSink(transformer.bind); StreamChannel changeStream(Stream change(Stream stream)) => - new StreamChannel.withCloseGuarantee(change(stream), sink); + StreamChannel.withCloseGuarantee(change(stream), sink); StreamChannel changeSink(StreamSink change(StreamSink sink)) => - new StreamChannel.withCloseGuarantee(stream, change(sink)); + StreamChannel.withCloseGuarantee(stream, change(sink)); - StreamChannel cast() => new StreamChannel( + StreamChannel cast() => StreamChannel( DelegatingStream.typed(stream), DelegatingStreamSink.typed(sink)); } diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 6b1ace36f..996cd7047 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,12 +1,12 @@ name: stream_channel -version: 1.6.8 +version: 1.6.9 description: An abstraction for two-way communication channels. author: Dart Team homepage: https://github.com/dart-lang/stream_channel environment: - sdk: '>=2.0.0-dev.17.0 <3.0.0' + sdk: '>=2.0.0 <3.0.0' dependencies: async: '>=1.11.0 <3.0.0' diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index 62ef78b54..7b36c29b6 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -14,10 +14,10 @@ void main() { Disconnector disconnector; StreamChannel channel; setUp(() { - streamController = new StreamController(); - sinkController = new StreamController(); - disconnector = new Disconnector(); - channel = new StreamChannel.withGuarantees( + streamController = StreamController(); + sinkController = StreamController(); + disconnector = Disconnector(); + channel = StreamChannel.withGuarantees( streamController.stream, sinkController.sink) .transform(disconnector); }); @@ -47,17 +47,17 @@ void main() { expect(channel.sink.close(), completes); expect(() => channel.sink.add(1), throwsStateError); expect(() => channel.sink.addError("oh no"), throwsStateError); - expect(() => channel.sink.addStream(new Stream.fromIterable([])), + expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); }); test("events can't be added while a stream is being added", () { - var controller = new StreamController(); + var controller = StreamController(); channel.sink.addStream(controller.stream); expect(() => channel.sink.add(1), throwsStateError); expect(() => channel.sink.addError("oh no"), throwsStateError); - expect(() => channel.sink.addStream(new Stream.fromIterable([])), + expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); expect(() => channel.sink.close(), throwsStateError); @@ -67,7 +67,7 @@ void main() { test("cancels addStream when disconnected", () async { var canceled = false; - var controller = new StreamController(onCancel: () { + var controller = StreamController(onCancel: () { canceled = true; }); expect(channel.sink.addStream(controller.stream), completes); @@ -78,11 +78,11 @@ void main() { }); test("disconnect() returns the close future from the inner sink", () async { - var streamController = new StreamController(); - var sinkController = new StreamController(); - var disconnector = new Disconnector(); - var sink = new _CloseCompleterSink(sinkController.sink); - new StreamChannel.withGuarantees(streamController.stream, sink) + var streamController = StreamController(); + var sinkController = StreamController(); + var disconnector = Disconnector(); + var sink = _CloseCompleterSink(sinkController.sink); + StreamChannel.withGuarantees(streamController.stream, sink) .transform(disconnector); var disconnectFutureFired = false; @@ -140,7 +140,7 @@ void main() { /// returned by [close] using [completer]. class _CloseCompleterSink extends DelegatingStreamSink { /// The completer for the future returned by [close]. - final completer = new Completer(); + final completer = Completer(); _CloseCompleterSink(StreamSink inner) : super(inner); diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index 4c73ab090..8971972b5 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -15,10 +15,10 @@ void main() { SendPort sendPort; StreamChannel channel; setUp(() { - receivePort = new ReceivePort(); - var receivePortForSend = new ReceivePort(); + receivePort = ReceivePort(); + var receivePortForSend = ReceivePort(); sendPort = receivePortForSend.sendPort; - channel = new IsolateChannel(receivePortForSend, receivePort.sendPort); + channel = IsolateChannel(receivePortForSend, receivePort.sendPort); }); tearDown(() { @@ -46,17 +46,17 @@ void main() { expect(channel.sink.close(), completes); expect(() => channel.sink.add(1), throwsStateError); expect(() => channel.sink.addError("oh no"), throwsStateError); - expect(() => channel.sink.addStream(new Stream.fromIterable([])), + expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); }); test("events can't be added while a stream is being added", () { - var controller = new StreamController(); + var controller = StreamController(); channel.sink.addStream(controller.stream); expect(() => channel.sink.add(1), throwsStateError); expect(() => channel.sink.addError("oh no"), throwsStateError); - expect(() => channel.sink.addStream(new Stream.fromIterable([])), + expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); expect(() => channel.sink.close(), throwsStateError); @@ -107,7 +107,7 @@ void main() { test("the sink closes as soon as an error is added via addStream", () async { var canceled = false; - var controller = new StreamController(onCancel: () { + var controller = StreamController(onCancel: () { canceled = true; }); @@ -128,7 +128,7 @@ void main() { group("connect constructors", () { ReceivePort connectPort; setUp(() { - connectPort = new ReceivePort(); + connectPort = ReceivePort(); }); tearDown(() { @@ -136,8 +136,8 @@ void main() { }); test("create a connected pair of channels", () { - var channel1 = new IsolateChannel.connectReceive(connectPort); - var channel2 = new IsolateChannel.connectSend(connectPort.sendPort); + var channel1 = IsolateChannel.connectReceive(connectPort); + var channel2 = IsolateChannel.connectSend(connectPort.sendPort); channel1.sink.add(1); channel1.sink.add(2); @@ -152,7 +152,7 @@ void main() { test("the receiving channel produces an error if it gets the wrong message", () { - var connectedChannel = new IsolateChannel.connectReceive(connectPort); + var connectedChannel = IsolateChannel.connectReceive(connectPort); connectPort.sendPort.send("wrong value"); expect(connectedChannel.stream.toList(), throwsStateError); diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index 6cb97f945..83ee09929 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -13,10 +13,10 @@ void main() { StreamController sinkController; StreamChannel channel; setUp(() { - streamController = new StreamController(); - sinkController = new StreamController(); + streamController = StreamController(); + sinkController = StreamController(); channel = - new StreamChannel(streamController.stream, sinkController.sink); + StreamChannel(streamController.stream, sinkController.sink); }); test("decodes JSON emitted by the channel", () { @@ -33,16 +33,16 @@ void main() { }); test("supports the reviver function", () { - var transformed = channel.transform( - new JsonDocumentTransformer(reviver: (key, value) => "decoded")); + var transformed = channel + .transform(JsonDocumentTransformer(reviver: (key, value) => "decoded")); streamController.add('{"foo": "bar"}'); expect(transformed.stream.first, completion(equals("decoded"))); }); test("supports the toEncodable function", () { - var transformed = channel.transform( - new JsonDocumentTransformer(toEncodable: (object) => "encoded")); - transformed.sink.add(new Object()); + var transformed = channel + .transform(JsonDocumentTransformer(toEncodable: (object) => "encoded")); + transformed.sink.add(Object()); expect(sinkController.stream.first, completion(equals('"encoded"'))); }); @@ -54,7 +54,7 @@ void main() { test("synchronously throws if an unencodable object is added", () { var transformed = channel.transform(jsonDocument); - expect(() => transformed.sink.add(new Object()), - throwsA(new TypeMatcher())); + expect(() => transformed.sink.add(Object()), + throwsA(TypeMatcher())); }); } diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index ddc4150bb..80c595a39 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -10,9 +10,9 @@ void main() { MultiChannel channel1; MultiChannel channel2; setUp(() { - controller = new StreamChannelController(); - channel1 = new MultiChannel(controller.local); - channel2 = new MultiChannel(controller.foreign); + controller = StreamChannelController(); + channel1 = MultiChannel(controller.local); + channel2 = MultiChannel(controller.foreign); }); group("the default virtual channel", () { diff --git a/pkgs/stream_channel/test/stream_channel_completer_test.dart b/pkgs/stream_channel/test/stream_channel_completer_test.dart index 666efe9ed..c20f9af11 100644 --- a/pkgs/stream_channel/test/stream_channel_completer_test.dart +++ b/pkgs/stream_channel/test/stream_channel_completer_test.dart @@ -13,11 +13,10 @@ void main() { StreamController sinkController; StreamChannel innerChannel; setUp(() { - completer = new StreamChannelCompleter(); - streamController = new StreamController(); - sinkController = new StreamController(); - innerChannel = - new StreamChannel(streamController.stream, sinkController.sink); + completer = StreamChannelCompleter(); + streamController = StreamController(); + sinkController = StreamController(); + innerChannel = StreamChannel(streamController.stream, sinkController.sink); }); group("when a channel is set before accessing", () { @@ -97,7 +96,7 @@ void main() { group("forFuture", () { test("forwards a StreamChannel", () { var channel = - StreamChannelCompleter.fromFuture(new Future.value(innerChannel)); + StreamChannelCompleter.fromFuture(Future.value(innerChannel)); channel.sink.add(1); channel.sink.close(); streamController.sink.add(2); @@ -108,8 +107,7 @@ void main() { }); test("forwards an error", () { - var channel = - StreamChannelCompleter.fromFuture(new Future.error("oh no")); + var channel = StreamChannelCompleter.fromFuture(Future.error("oh no")); expect(channel.stream.toList(), throwsA("oh no")); }); }); diff --git a/pkgs/stream_channel/test/stream_channel_controller_test.dart b/pkgs/stream_channel/test/stream_channel_controller_test.dart index 483b7f6f1..62f883fa5 100644 --- a/pkgs/stream_channel/test/stream_channel_controller_test.dart +++ b/pkgs/stream_channel/test/stream_channel_controller_test.dart @@ -9,7 +9,7 @@ void main() { group("asynchronously", () { StreamChannelController controller; setUp(() { - controller = new StreamChannelController(); + controller = StreamChannelController(); }); test("forwards events from the local sink to the foreign stream", () { @@ -33,7 +33,7 @@ void main() { test( "with allowForeignErrors: false, shuts down the connection if an " "error is added to the foreign channel", () { - controller = new StreamChannelController(allowForeignErrors: false); + controller = StreamChannelController(allowForeignErrors: false); controller.foreign.sink.addError("oh no"); expect(controller.foreign.sink.done, throwsA("oh no")); @@ -46,7 +46,7 @@ void main() { group("synchronously", () { StreamChannelController controller; setUp(() { - controller = new StreamChannelController(sync: true); + controller = StreamChannelController(sync: true); }); test( diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index dbe421195..2f05a9ef1 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -14,17 +14,17 @@ void main() { StreamController sinkController; StreamChannel channel; setUp(() { - streamController = new StreamController(); - sinkController = new StreamController(); - channel = new StreamChannel(streamController.stream, sinkController.sink); + streamController = StreamController(); + sinkController = StreamController(); + channel = StreamChannel(streamController.stream, sinkController.sink); }); test("pipe() pipes data from each channel's stream into the other's sink", () { - var otherStreamController = new StreamController(); - var otherSinkController = new StreamController(); - var otherChannel = new StreamChannel( - otherStreamController.stream, otherSinkController.sink); + var otherStreamController = StreamController(); + var otherSinkController = StreamController(); + var otherChannel = + StreamChannel(otherStreamController.stream, otherSinkController.sink); channel.pipe(otherChannel); streamController.add(1); @@ -43,7 +43,7 @@ void main() { test("transform() transforms the channel", () async { var transformed = channel .cast>() - .transform(new StreamChannelTransformer.fromCodec(utf8)); + .transform(StreamChannelTransformer.fromCodec(utf8)); streamController.add([102, 111, 111, 98, 97, 114]); streamController.close(); @@ -76,7 +76,7 @@ void main() { test("transformSink() transforms only the sink", () async { var transformed = channel.cast().transformSink( - new StreamSinkTransformer.fromStreamTransformer(const LineSplitter())); + StreamSinkTransformer.fromStreamTransformer(const LineSplitter())); streamController.add("fbl\nthp"); streamController.close(); @@ -91,7 +91,7 @@ void main() { }); test("changeStream() changes the stream", () { - var newController = new StreamController(); + var newController = StreamController(); var changed = channel.changeStream((stream) { expect(stream, equals(channel.stream)); return newController.stream; @@ -107,7 +107,7 @@ void main() { }); test("changeSink() changes the sink", () { - var newController = new StreamController(); + var newController = StreamController(); var changed = channel.changeSink((sink) { expect(sink, equals(channel.sink)); return newController.sink; diff --git a/pkgs/stream_channel/test/with_close_guarantee_test.dart b/pkgs/stream_channel/test/with_close_guarantee_test.dart index 8e1b63119..1749bacb7 100644 --- a/pkgs/stream_channel/test/with_close_guarantee_test.dart +++ b/pkgs/stream_channel/test/with_close_guarantee_test.dart @@ -8,18 +8,18 @@ import 'package:async/async.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; -final _delayTransformer = new StreamTransformer.fromHandlers( - handleData: (data, sink) => new Future.microtask(() => sink.add(data)), - handleDone: (sink) => new Future.microtask(() => sink.close())); +final _delayTransformer = StreamTransformer.fromHandlers( + handleData: (data, sink) => Future.microtask(() => sink.add(data)), + handleDone: (sink) => Future.microtask(() => sink.close())); final _delaySinkTransformer = - new StreamSinkTransformer.fromStreamTransformer(_delayTransformer); + StreamSinkTransformer.fromStreamTransformer(_delayTransformer); void main() { StreamChannelController controller; StreamChannel channel; setUp(() { - controller = new StreamChannelController(); + controller = StreamChannelController(); // Add a bunch of layers of asynchronous dispatch between the channel and // the underlying controllers. @@ -30,7 +30,7 @@ void main() { sink = _delaySinkTransformer.bind(sink); } - channel = new StreamChannel.withCloseGuarantee(stream, sink); + channel = StreamChannel.withCloseGuarantee(stream, sink); }); test( diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index dcdffe089..0ea59525e 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -12,16 +12,16 @@ void main() { StreamController sinkController; StreamChannel channel; setUp(() { - streamController = new StreamController(); - sinkController = new StreamController(); - channel = new StreamChannel.withGuarantees( + streamController = StreamController(); + sinkController = StreamController(); + channel = StreamChannel.withGuarantees( streamController.stream, sinkController.sink); }); group("with a broadcast stream", () { setUp(() { - streamController = new StreamController.broadcast(); - channel = new StreamChannel.withGuarantees( + streamController = StreamController.broadcast(); + channel = StreamChannel.withGuarantees( streamController.stream, sinkController.sink); }); @@ -121,17 +121,17 @@ void main() { expect(channel.sink.close(), completes); expect(() => channel.sink.add(1), throwsStateError); expect(() => channel.sink.addError("oh no"), throwsStateError); - expect(() => channel.sink.addStream(new Stream.fromIterable([])), + expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); }); test("events can't be added while a stream is being added", () { - var controller = new StreamController(); + var controller = StreamController(); channel.sink.addStream(controller.stream); expect(() => channel.sink.add(1), throwsStateError); expect(() => channel.sink.addError("oh no"), throwsStateError); - expect(() => channel.sink.addStream(new Stream.fromIterable([])), + expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); expect(() => channel.sink.close(), throwsStateError); @@ -140,9 +140,9 @@ void main() { group("with allowSinkErrors: false", () { setUp(() { - streamController = new StreamController(); - sinkController = new StreamController(); - channel = new StreamChannel.withGuarantees( + streamController = StreamController(); + sinkController = StreamController(); + channel = StreamChannel.withGuarantees( streamController.stream, sinkController.sink, allowSinkErrors: false); }); @@ -180,7 +180,7 @@ void main() { "adding an error via via addStream causes the stream to emit a done " "event", () async { var canceled = false; - var controller = new StreamController(onCancel: () { + var controller = StreamController(onCancel: () { canceled = true; }); From b86f7a0e74b91682ce3e6889278ea0f7724c4689 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 26 Mar 2019 15:38:48 -0700 Subject: [PATCH 063/138] Add separate import for `IsolateChannel` (dart-lang/stream_channel#40) This will allow us to move to this import in the few packages which are using this class, like test, without having a fully broken state in between, and without required `git` dependency overrides. --- pkgs/stream_channel/CHANGELOG.md | 7 +++++-- pkgs/stream_channel/lib/isolate_channel.dart | 5 +++++ pkgs/stream_channel/pubspec.yaml | 2 +- pkgs/stream_channel/test/isolate_channel_test.dart | 1 + 4 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 pkgs/stream_channel/lib/isolate_channel.dart diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 87ba42fe7..68b68a112 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,7 +1,10 @@ -## 1.6.9 +## 1.7.0 +* Make `IsolateChannel` available through + `package:stream_channel/isolate_channel.dart`. This will be the required + import in the next release. * Require `2.0.0` or newer SDK. -* Drop unnecessary `new` and `const`. +* Internal style changes. ## 1.6.8 diff --git a/pkgs/stream_channel/lib/isolate_channel.dart b/pkgs/stream_channel/lib/isolate_channel.dart new file mode 100644 index 000000000..5d9f6e19f --- /dev/null +++ b/pkgs/stream_channel/lib/isolate_channel.dart @@ -0,0 +1,5 @@ +// Copyright (c) 2019, 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. + +export 'src/isolate_channel.dart' show IsolateChannel; diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 996cd7047..da152fb39 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.6.9 +version: 1.7.0 description: An abstraction for two-way communication channels. author: Dart Team diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index 8971972b5..776928d72 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'dart:isolate'; +import 'package:stream_channel/isolate_channel.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; From c3babdc1bac5cabeda1d41b48fda4840d7a84d3d Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 27 Mar 2019 09:00:36 -0700 Subject: [PATCH 064/138] Enforce override annotations (dart-lang/stream_channel#42) --- pkgs/stream_channel/analysis_options.yaml | 1 + pkgs/stream_channel/lib/src/close_guarantee_channel.dart | 4 ++++ .../lib/src/delegating_stream_channel.dart | 2 ++ pkgs/stream_channel/lib/src/disconnector.dart | 6 ++++++ pkgs/stream_channel/lib/src/guarantee_channel.dart | 7 +++++++ pkgs/stream_channel/lib/src/isolate_channel.dart | 2 ++ .../lib/src/json_document_transformer.dart | 1 + pkgs/stream_channel/lib/src/multi_channel.dart | 8 ++++++++ pkgs/stream_channel/lib/src/transformer/typed.dart | 1 + pkgs/stream_channel/lib/stream_channel.dart | 9 +++++++++ pkgs/stream_channel/test/disconnector_test.dart | 1 + 11 files changed, 42 insertions(+) diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index d19ee843f..866c1585a 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -8,5 +8,6 @@ analyzer: linter: rules: + - annotate_overrides - comment_references - prefer_typing_uninitialized_variables diff --git a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart index b8a3f0289..c534a919e 100644 --- a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart @@ -14,9 +14,11 @@ import '../stream_channel.dart'; /// /// This is exposed via [new StreamChannel.withCloseGuarantee]. class CloseGuaranteeChannel extends StreamChannelMixin { + @override Stream get stream => _stream; _CloseGuaranteeStream _stream; + @override StreamSink get sink => _sink; _CloseGuaranteeSink _sink; @@ -45,6 +47,7 @@ class _CloseGuaranteeStream extends Stream { _CloseGuaranteeStream(this._inner, this._channel); + @override StreamSubscription listen(void onData(T event), {Function onError, void onDone(), bool cancelOnError}) { // If the channel is already disconnected, we shouldn't dispatch anything @@ -73,6 +76,7 @@ class _CloseGuaranteeSink extends DelegatingStreamSink { _CloseGuaranteeSink(StreamSink inner, this._channel) : super(inner); + @override Future close() { var done = super.close(); _channel._disconnected = true; diff --git a/pkgs/stream_channel/lib/src/delegating_stream_channel.dart b/pkgs/stream_channel/lib/src/delegating_stream_channel.dart index 4434cf62a..4484a5989 100644 --- a/pkgs/stream_channel/lib/src/delegating_stream_channel.dart +++ b/pkgs/stream_channel/lib/src/delegating_stream_channel.dart @@ -14,7 +14,9 @@ class DelegatingStreamChannel extends StreamChannelMixin { /// The inner channel to which methods are forwarded. final StreamChannel _inner; + @override Stream get stream => _inner.stream; + @override StreamSink get sink => _inner.sink; DelegatingStreamChannel(this._inner); diff --git a/pkgs/stream_channel/lib/src/disconnector.dart b/pkgs/stream_channel/lib/src/disconnector.dart index 9d35cfc63..83defb8c3 100644 --- a/pkgs/stream_channel/lib/src/disconnector.dart +++ b/pkgs/stream_channel/lib/src/disconnector.dart @@ -40,6 +40,7 @@ class Disconnector implements StreamChannelTransformer { }); final _disconnectMemo = AsyncMemoizer(); + @override StreamChannel bind(StreamChannel channel) { return channel.changeSink((innerSink) { var sink = _DisconnectorSink(innerSink); @@ -62,6 +63,7 @@ class _DisconnectorSink implements StreamSink { /// The inner sink. final StreamSink _inner; + @override Future get done => _inner.done; /// Whether [Disconnector.disconnect] has been called. @@ -83,6 +85,7 @@ class _DisconnectorSink implements StreamSink { _DisconnectorSink(this._inner); + @override void add(T data) { if (_closed) throw StateError("Cannot add event after closing."); if (_inAddStream) { @@ -93,6 +96,7 @@ class _DisconnectorSink implements StreamSink { _inner.add(data); } + @override void addError(error, [StackTrace stackTrace]) { if (_closed) throw StateError("Cannot add event after closing."); if (_inAddStream) { @@ -103,6 +107,7 @@ class _DisconnectorSink implements StreamSink { _inner.addError(error, stackTrace); } + @override Future addStream(Stream stream) { if (_closed) throw StateError("Cannot add stream after closing."); if (_inAddStream) { @@ -119,6 +124,7 @@ class _DisconnectorSink implements StreamSink { }); } + @override Future close() { if (_inAddStream) { throw StateError("Cannot close sink while adding stream."); diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart index e96f5c3c8..ce7f70736 100644 --- a/pkgs/stream_channel/lib/src/guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -12,8 +12,10 @@ import '../stream_channel.dart'; /// /// This is exposed via [new StreamChannel.withGuarantees]. class GuaranteeChannel extends StreamChannelMixin { + @override Stream get stream => _streamController.stream; + @override StreamSink get sink => _sink; _GuaranteeSink _sink; @@ -78,6 +80,7 @@ class _GuaranteeSink implements StreamSink { /// The [GuaranteeChannel] this belongs to. final GuaranteeChannel _channel; + @override Future get done => _doneCompleter.future; final _doneCompleter = Completer(); @@ -110,6 +113,7 @@ class _GuaranteeSink implements StreamSink { _GuaranteeSink(this._inner, this._channel, {bool allowErrors = true}) : _allowErrors = allowErrors; + @override void add(T data) { if (_closed) throw StateError("Cannot add event after closing."); if (_inAddStream) { @@ -120,6 +124,7 @@ class _GuaranteeSink implements StreamSink { _inner.add(data); } + @override void addError(error, [StackTrace stackTrace]) { if (_closed) throw StateError("Cannot add event after closing."); if (_inAddStream) { @@ -151,6 +156,7 @@ class _GuaranteeSink implements StreamSink { _inner.close().catchError((_) {}); } + @override Future addStream(Stream stream) { if (_closed) throw StateError("Cannot add stream after closing."); if (_inAddStream) { @@ -167,6 +173,7 @@ class _GuaranteeSink implements StreamSink { }); } + @override Future close() { if (_inAddStream) { throw StateError("Cannot close sink while adding stream."); diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index c7f573fd2..8c1b56842 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -24,7 +24,9 @@ import '../stream_channel.dart'; /// ensure that they always close the [sink] of every [IsolateChannel] they use /// to avoid leaving dangling [ReceivePort]s. class IsolateChannel extends StreamChannelMixin { + @override final Stream stream; + @override final StreamSink sink; /// Connects to a remote channel that was created with diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index 2a3a86f3e..a53ac92ad 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -35,6 +35,7 @@ class JsonDocumentTransformer JsonDocumentTransformer._(this._codec); + @override StreamChannel bind(StreamChannel channel) { var stream = channel.stream.map(_codec.decode); var sink = StreamSinkTransformer.fromHandlers( diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index 139c9aefa..d729eb7bb 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -45,6 +45,7 @@ abstract class MultiChannel implements StreamChannel { /// The default input stream. /// /// This connects to the remote [sink]. + @override Stream get stream; /// The default output stream. @@ -52,6 +53,7 @@ abstract class MultiChannel implements StreamChannel { /// This connects to the remote [stream]. If this is closed, the remote /// [stream] will close, but other virtual channels will remain open and new /// virtual channels may be opened. + @override StreamSink get sink; /// Creates a new [MultiChannel] that sends and receives messages over @@ -88,7 +90,9 @@ class _MultiChannel extends StreamChannelMixin /// The subscription to [_inner].stream. StreamSubscription _innerStreamSubscription; + @override Stream get stream => _mainController.foreign.stream; + @override StreamSink get sink => _mainController.foreign.sink; /// The controller for this channel. @@ -165,6 +169,7 @@ class _MultiChannel extends StreamChannelMixin onError: _mainController.local.sink.addError); } + @override VirtualChannel virtualChannel([int id]) { int inputId; int outputId; @@ -256,10 +261,13 @@ class VirtualChannel extends StreamChannelMixin /// except that it will be JSON-serializable. final int id; + @override final Stream stream; + @override final StreamSink sink; VirtualChannel._(this._parent, this.id, this.stream, this.sink); + @override VirtualChannel virtualChannel([id]) => _parent.virtualChannel(id); } diff --git a/pkgs/stream_channel/lib/src/transformer/typed.dart b/pkgs/stream_channel/lib/src/transformer/typed.dart index 9c2d72b41..875cdac37 100644 --- a/pkgs/stream_channel/lib/src/transformer/typed.dart +++ b/pkgs/stream_channel/lib/src/transformer/typed.dart @@ -12,6 +12,7 @@ class TypeSafeStreamChannelTransformer TypeSafeStreamChannelTransformer(this._inner); + @override StreamChannel bind(StreamChannel channel) => _inner.bind(channel).cast(); } diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index b50116044..a5cd5849c 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -138,7 +138,9 @@ abstract class StreamChannel { /// This is distinct from [StreamChannel] so that it can use /// [StreamChannelMixin]. class _StreamChannel extends StreamChannelMixin { + @override final Stream stream; + @override final StreamSink sink; _StreamChannel(this.stream, this.sink); @@ -147,26 +149,33 @@ class _StreamChannel extends StreamChannelMixin { /// A mixin that implements the instance methods of [StreamChannel] in terms of /// [stream] and [sink]. abstract class StreamChannelMixin implements StreamChannel { + @override void pipe(StreamChannel other) { stream.pipe(other.sink); other.stream.pipe(sink); } + @override StreamChannel transform(StreamChannelTransformer transformer) => transformer.bind(this); + @override StreamChannel transformStream(StreamTransformer transformer) => changeStream(transformer.bind); + @override StreamChannel transformSink(StreamSinkTransformer transformer) => changeSink(transformer.bind); + @override StreamChannel changeStream(Stream change(Stream stream)) => StreamChannel.withCloseGuarantee(change(stream), sink); + @override StreamChannel changeSink(StreamSink change(StreamSink sink)) => StreamChannel.withCloseGuarantee(stream, change(sink)); + @override StreamChannel cast() => StreamChannel( DelegatingStream.typed(stream), DelegatingStreamSink.typed(sink)); } diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index 7b36c29b6..aefad28d4 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -144,6 +144,7 @@ class _CloseCompleterSink extends DelegatingStreamSink { _CloseCompleterSink(StreamSink inner) : super(inner); + @override Future close() { super.close(); return completer.future; From db09351495a71df5445a627a8b01bd3af23f8073 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 27 Mar 2019 17:26:19 -0700 Subject: [PATCH 065/138] Move isolate_channel to it's own import (dart-lang/stream_channel#39) Closes dart-lang/stream_channel#36 This allows the default import to work without triggering any warnings on the web due to transitively importing `dart:isolate`. This is required to allow restricting imports based on platform. --- pkgs/stream_channel/CHANGELOG.md | 7 +++++++ pkgs/stream_channel/lib/stream_channel.dart | 1 - pkgs/stream_channel/pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 68b68a112..0e125ddae 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,10 @@ +## 2.0.0 + +* **Breaking change** `IsolateChannel` requires a separate import + `package:stram_channel/isolate_channel.dart`. + `package:stream_channel/stream_channel.dart` will now not trigger any platform + concerns due to importing `dart:isolate`. + ## 1.7.0 * Make `IsolateChannel` available through diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index a5cd5849c..e99de08f0 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -12,7 +12,6 @@ import 'src/stream_channel_transformer.dart'; export 'src/delegating_stream_channel.dart'; export 'src/disconnector.dart'; -export 'src/isolate_channel.dart'; export 'src/json_document_transformer.dart'; export 'src/multi_channel.dart'; export 'src/stream_channel_completer.dart'; diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index da152fb39..917f5bc38 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 1.7.0 +version: 2.0.0 description: An abstraction for two-way communication channels. author: Dart Team From 662bcb457877736852df2640998d22cdea7ce9f6 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 28 Mar 2019 08:26:01 -0700 Subject: [PATCH 066/138] Hide JsonDocumentTransformer (dart-lang/stream_channel#43) Closes dart-lang/stream_channel#34 This was only used through the top level variable `jsonDocument` and no use cases have surfaced for being able to pass a `reviver` or `toEncodable` callback. This implementation does not use `StreamChannelTransformer.fromCodec` with a `JsonCodec` since the encoder and decoder are not 1:1. - Remove the `JsonCodec` field and use `jsonEncode` and `jsonDecode` calls directly. - Move the detailed doc to `jsonDocument`. - Make the class private. - Remove the tests constructing the class directly. --- pkgs/stream_channel/CHANGELOG.md | 6 ++++- .../lib/src/json_document_transformer.dart | 23 +++++-------------- .../test/json_document_transformer_test.dart | 14 ----------- 3 files changed, 11 insertions(+), 32 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 0e125ddae..8ebdc2874 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,9 +1,13 @@ ## 2.0.0 -* **Breaking change** `IsolateChannel` requires a separate import +**Breaking changes** + +* `IsolateChannel` requires a separate import `package:stram_channel/isolate_channel.dart`. `package:stream_channel/stream_channel.dart` will now not trigger any platform concerns due to importing `dart:isolate`. +* Remove `JsonDocumentTransformer` class. The `jsonDocument` top level is still + available. ## 1.7.0 diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index a53ac92ad..8bffc8ab9 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -9,9 +9,6 @@ import 'package:async/async.dart'; import '../stream_channel.dart'; import 'stream_channel_transformer.dart'; -/// The canonical instance of [JsonDocumentTransformer]. -final jsonDocument = JsonDocumentTransformer(); - /// A [StreamChannelTransformer] that transforms JSON documents—strings that /// contain individual objects encoded as JSON—into decoded Dart objects. /// @@ -21,26 +18,18 @@ final jsonDocument = JsonDocumentTransformer(); /// If the transformed channel emits invalid JSON, this emits a /// [FormatException]. If an unencodable object is added to the sink, it /// synchronously throws a [JsonUnsupportedObjectError]. -class JsonDocumentTransformer - implements StreamChannelTransformer { - /// The underlying codec that implements the encoding and decoding logic. - final JsonCodec _codec; - - /// Creates a new transformer. - /// - /// The [reviver] and [toEncodable] arguments work the same way as the - /// corresponding arguments to [new JsonCodec]. - JsonDocumentTransformer({reviver(key, value), toEncodable(object)}) - : _codec = JsonCodec(reviver: reviver, toEncodable: toEncodable); +final StreamChannelTransformer jsonDocument = + const _JsonDocument(); - JsonDocumentTransformer._(this._codec); +class _JsonDocument implements StreamChannelTransformer { + const _JsonDocument(); @override StreamChannel bind(StreamChannel channel) { - var stream = channel.stream.map(_codec.decode); + var stream = channel.stream.map(jsonDecode); var sink = StreamSinkTransformer.fromHandlers( handleData: (data, sink) { - sink.add(_codec.encode(data)); + sink.add(jsonEncode(data)); }).bind(channel.sink); return StreamChannel.withCloseGuarantee(stream, sink); } diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index 83ee09929..e6c560ade 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -32,20 +32,6 @@ void main() { completion(equals(jsonEncode({"foo": "bar"})))); }); - test("supports the reviver function", () { - var transformed = channel - .transform(JsonDocumentTransformer(reviver: (key, value) => "decoded")); - streamController.add('{"foo": "bar"}'); - expect(transformed.stream.first, completion(equals("decoded"))); - }); - - test("supports the toEncodable function", () { - var transformed = channel - .transform(JsonDocumentTransformer(toEncodable: (object) => "encoded")); - transformed.sink.add(Object()); - expect(sinkController.stream.first, completion(equals('"encoded"'))); - }); - test("emits a stream error when incoming JSON is malformed", () { var transformed = channel.transform(jsonDocument); streamController.add("{invalid"); From 7c910babe483446f0641fbb398fce4abf66e56e0 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 28 Mar 2019 09:48:58 -0700 Subject: [PATCH 067/138] Remove StreamChannelTransformer.typed (dart-lang/stream_channel#44) Closes dart-lang/stream_channel#41 I cannot find any uses of this and it can be replaced with a call to `cast`. --- pkgs/stream_channel/CHANGELOG.md | 2 ++ .../lib/src/stream_channel_transformer.dart | 16 ---------------- .../lib/src/transformer/typed.dart | 18 ------------------ 3 files changed, 2 insertions(+), 34 deletions(-) delete mode 100644 pkgs/stream_channel/lib/src/transformer/typed.dart diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 8ebdc2874..60400e0df 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -8,6 +8,8 @@ concerns due to importing `dart:isolate`. * Remove `JsonDocumentTransformer` class. The `jsonDocument` top level is still available. +* Remove `StreamChannelTransformer.typed`. Use `.cast` on the transformed + channel instead. ## 1.7.0 diff --git a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart index 32d36b6b0..cf62c76c2 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_transformer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_transformer.dart @@ -8,7 +8,6 @@ import 'dart:convert'; import 'package:async/async.dart'; import '../stream_channel.dart'; -import 'transformer/typed.dart'; /// A [StreamChannelTransformer] transforms the events being passed to and /// emitted by a [StreamChannel]. @@ -32,21 +31,6 @@ class StreamChannelTransformer { /// The transformer to use on the channel's sink. final StreamSinkTransformer _sinkTransformer; - /// Creates a wrapper that coerces the type of [transformer]. - /// - /// This soundly converts a [StreamChannelTransformer] to a - /// `StreamChannelTransformer`, regardless of its original generic type, - /// by asserting that the events emitted by the transformed channel's stream - /// are instances of `T` whenever they're provided. If they're not, the stream - /// throws a [CastError]. This also means that calls to [StreamSink.add] on - /// the transformed channel's sink may throw a [CastError] if the argument - /// type doesn't match the reified type of the sink. - static StreamChannelTransformer typed( - StreamChannelTransformer transformer) => - transformer is StreamChannelTransformer - ? transformer - : TypeSafeStreamChannelTransformer(transformer); - /// Creates a [StreamChannelTransformer] from existing stream and sink /// transformers. const StreamChannelTransformer( diff --git a/pkgs/stream_channel/lib/src/transformer/typed.dart b/pkgs/stream_channel/lib/src/transformer/typed.dart deleted file mode 100644 index 875cdac37..000000000 --- a/pkgs/stream_channel/lib/src/transformer/typed.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2016, 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 '../../stream_channel.dart'; - -/// A wrapper that coerces the generic type of the channel returned by an inner -/// transformer to `S`. -class TypeSafeStreamChannelTransformer - implements StreamChannelTransformer { - final StreamChannelTransformer _inner; - - TypeSafeStreamChannelTransformer(this._inner); - - @override - StreamChannel bind(StreamChannel channel) => - _inner.bind(channel).cast(); -} From e4af414323baea76d971da80e8a48748d3983467 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 28 Mar 2019 11:06:27 -0700 Subject: [PATCH 068/138] Change all bare Future to Future (dart-lang/stream_channel#45) Closes dart-lang/stream_channel#35 It looks less like a potential bug and more explicitly expresses that these functions don't return useful values. --- pkgs/stream_channel/CHANGELOG.md | 1 + .../lib/src/close_guarantee_channel.dart | 2 +- pkgs/stream_channel/lib/src/disconnector.dart | 10 +++++----- pkgs/stream_channel/lib/src/guarantee_channel.dart | 6 +++--- pkgs/stream_channel/test/disconnector_test.dart | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 60400e0df..24564ede1 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -10,6 +10,7 @@ available. * Remove `StreamChannelTransformer.typed`. Use `.cast` on the transformed channel instead. +* Change `Future` returns to `Future`. ## 1.7.0 diff --git a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart index c534a919e..33296da43 100644 --- a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart @@ -77,7 +77,7 @@ class _CloseGuaranteeSink extends DelegatingStreamSink { _CloseGuaranteeSink(StreamSink inner, this._channel) : super(inner); @override - Future close() { + Future close() { var done = super.close(); _channel._disconnected = true; if (_channel._subscription != null) { diff --git a/pkgs/stream_channel/lib/src/disconnector.dart b/pkgs/stream_channel/lib/src/disconnector.dart index 83defb8c3..69fbab727 100644 --- a/pkgs/stream_channel/lib/src/disconnector.dart +++ b/pkgs/stream_channel/lib/src/disconnector.dart @@ -33,7 +33,7 @@ class Disconnector implements StreamChannelTransformer { /// Returns a future that completes when all inner sinks' [StreamSink.close] /// futures have completed. Note that a [StreamController]'s sink won't close /// until the corresponding stream has a listener. - Future disconnect() => _disconnectMemo.runOnce(() { + Future disconnect() => _disconnectMemo.runOnce(() { var futures = _sinks.map((sink) => sink._disconnect()).toList(); _sinks.clear(); return Future.wait(futures, eagerError: true); @@ -64,7 +64,7 @@ class _DisconnectorSink implements StreamSink { final StreamSink _inner; @override - Future get done => _inner.done; + Future get done => _inner.done; /// Whether [Disconnector.disconnect] has been called. var _isDisconnected = false; @@ -108,7 +108,7 @@ class _DisconnectorSink implements StreamSink { } @override - Future addStream(Stream stream) { + Future addStream(Stream stream) { if (_closed) throw StateError("Cannot add stream after closing."); if (_inAddStream) { throw StateError("Cannot add stream while adding stream."); @@ -125,7 +125,7 @@ class _DisconnectorSink implements StreamSink { } @override - Future close() { + Future close() { if (_inAddStream) { throw StateError("Cannot close sink while adding stream."); } @@ -138,7 +138,7 @@ class _DisconnectorSink implements StreamSink { /// /// This closes the underlying sink and stops forwarding events. It returns /// the [StreamSink.close] future for the underlying sink. - Future _disconnect() { + Future _disconnect() { _isDisconnected = true; var future = _inner.close(); diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart index ce7f70736..d8add39e8 100644 --- a/pkgs/stream_channel/lib/src/guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -81,7 +81,7 @@ class _GuaranteeSink implements StreamSink { final GuaranteeChannel _channel; @override - Future get done => _doneCompleter.future; + Future get done => _doneCompleter.future; final _doneCompleter = Completer(); /// Whether connection is disconnected. @@ -157,7 +157,7 @@ class _GuaranteeSink implements StreamSink { } @override - Future addStream(Stream stream) { + Future addStream(Stream stream) { if (_closed) throw StateError("Cannot add stream after closing."); if (_inAddStream) { throw StateError("Cannot add stream while adding stream."); @@ -174,7 +174,7 @@ class _GuaranteeSink implements StreamSink { } @override - Future close() { + Future close() { if (_inAddStream) { throw StateError("Cannot close sink while adding stream."); } diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index aefad28d4..0992b3634 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -145,7 +145,7 @@ class _CloseCompleterSink extends DelegatingStreamSink { _CloseCompleterSink(StreamSink inner) : super(inner); @override - Future close() { + Future close() { super.close(); return completer.future; } From 56ef31eb7647a35d69332249d2051c60a73798c1 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Tue, 23 Jul 2019 12:41:26 -0700 Subject: [PATCH 069/138] Use pedantic lints --- pkgs/stream_channel/analysis_options.yaml | 1 + pkgs/stream_channel/pubspec.yaml | 3 +- .../test/disconnector_test.dart | 3 +- .../test/isolate_channel_test.dart | 3 +- .../test/multi_channel_test.dart | 43 ++++++++++--------- .../test/stream_channel_completer_test.dart | 5 ++- .../test/stream_channel_test.dart | 13 +++--- .../test/with_close_guarantee_test.dart | 5 ++- .../test/with_guarantees_test.dart | 17 ++++---- 9 files changed, 51 insertions(+), 42 deletions(-) diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index 866c1585a..1e02731d7 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -1,3 +1,4 @@ +include: package:pedantic/analysis_options.yaml analyzer: # These are errors when building in Google errors: diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 917f5bc38..dfd3af83d 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 2.0.0 +version: 2.0.1-dev description: An abstraction for two-way communication channels. author: Dart Team @@ -12,4 +12,5 @@ dependencies: async: '>=1.11.0 <3.0.0' dev_dependencies: + pedantic: ^1.8.0 test: ^1.2.0 diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index 0992b3634..a5ea2ebb5 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'package:async/async.dart'; +import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; @@ -71,7 +72,7 @@ void main() { canceled = true; }); expect(channel.sink.addStream(controller.stream), completes); - disconnector.disconnect(); + unawaited(disconnector.disconnect()); await pumpEventQueue(); expect(canceled, isTrue); diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index 776928d72..fd14b8407 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'dart:isolate'; +import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/isolate_channel.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; @@ -82,7 +83,7 @@ void main() { test("cancelling the stream's subscription has no effect on the sink", () async { - channel.stream.listen(null).cancel(); + unawaited(channel.stream.listen(null).cancel()); await pumpEventQueue(); channel.sink.add(1); diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index 80c595a39..b1659a03a 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -2,6 +2,7 @@ // 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:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; @@ -143,13 +144,13 @@ void main() { "virtual channels", () async { // First close the default channel so we can test the new channel as the // last living virtual channel. - channel1.sink.close(); + unawaited(channel1.sink.close()); await channel2.stream.toList(); expect(controller.local.sink.done, completes); expect(controller.foreign.sink.done, completes); - virtual1.sink.close(); + unawaited(virtual1.sink.close()); }); test( @@ -243,13 +244,13 @@ void main() { "virtual channels", () async { // First close the default channel so we can test the new channel as the // last living virtual channel. - channel2.sink.close(); + unawaited(channel2.sink.close()); await channel1.stream.toList(); expect(controller.local.sink.done, completes); expect(controller.foreign.sink.done, completes); - virtual2.sink.close(); + unawaited(virtual2.sink.close()); }); test( @@ -287,7 +288,7 @@ void main() { "created", () async { virtual1 = channel1.virtualChannel(); - virtual1.sink.close(); + unawaited(virtual1.sink.close()); await pumpEventQueue(); expect(channel2.virtualChannel(virtual1.id).stream.toList(), @@ -317,8 +318,8 @@ void main() { }); test("closes, more virtual channels are created closed", () async { - channel2.sink.close(); - virtual2.sink.close(); + unawaited(channel2.sink.close()); + unawaited(virtual2.sink.close()); // Wait for the existing channels to emit done events. await channel1.stream.toList(); @@ -359,14 +360,14 @@ void main() { }); test("after the stream closes, the sink ignores events", () async { - channel1.sink.close(); + unawaited(channel1.sink.close()); // Wait for the done event to be delivered. await channel2.stream.toList(); channel2.sink.add(1); channel2.sink.add(2); channel2.sink.add(3); - channel2.sink.close(); + unawaited(channel2.sink.close()); // None of our channel.sink additions should make it to the other endpoint. channel1.stream.listen(expectAsync1((_) {}, count: 0)); @@ -375,28 +376,28 @@ void main() { test("canceling the stream's subscription has no effect on the sink", () async { - channel1.stream.listen(null).cancel(); + unawaited(channel1.stream.listen(null).cancel()); await pumpEventQueue(); channel1.sink.add(1); channel1.sink.add(2); channel1.sink.add(3); - channel1.sink.close(); + unawaited(channel1.sink.close()); expect(channel2.stream.toList(), completion(equals([1, 2, 3]))); }); test("canceling the stream's subscription doesn't stop a done event", () async { - channel1.stream.listen(null).cancel(); + unawaited(channel1.stream.listen(null).cancel()); await pumpEventQueue(); - channel2.sink.close(); + unawaited(channel2.sink.close()); await pumpEventQueue(); channel1.sink.add(1); channel1.sink.add(2); channel1.sink.add(3); - channel1.sink.close(); + unawaited(channel1.sink.close()); // The sink should be ignoring events because the channel closed. channel2.stream.listen(expectAsync1((_) {}, count: 0)); @@ -426,14 +427,14 @@ void main() { }); test("after the stream closes, the sink ignores events", () async { - virtual1.sink.close(); + unawaited(virtual1.sink.close()); // Wait for the done event to be delivered. await virtual2.stream.toList(); virtual2.sink.add(1); virtual2.sink.add(2); virtual2.sink.add(3); - virtual2.sink.close(); + unawaited(virtual2.sink.close()); // None of our virtual.sink additions should make it to the other endpoint. virtual1.stream.listen(expectAsync1((_) {}, count: 0)); @@ -442,28 +443,28 @@ void main() { test("canceling the stream's subscription has no effect on the sink", () async { - virtual1.stream.listen(null).cancel(); + unawaited(virtual1.stream.listen(null).cancel()); await pumpEventQueue(); virtual1.sink.add(1); virtual1.sink.add(2); virtual1.sink.add(3); - virtual1.sink.close(); + unawaited(virtual1.sink.close()); expect(virtual2.stream.toList(), completion(equals([1, 2, 3]))); }); test("canceling the stream's subscription doesn't stop a done event", () async { - virtual1.stream.listen(null).cancel(); + unawaited(virtual1.stream.listen(null).cancel()); await pumpEventQueue(); - virtual2.sink.close(); + unawaited(virtual2.sink.close()); await pumpEventQueue(); virtual1.sink.add(1); virtual1.sink.add(2); virtual1.sink.add(3); - virtual1.sink.close(); + unawaited(virtual1.sink.close()); // The sink should be ignoring events because the stream closed. virtual2.stream.listen(expectAsync1((_) {}, count: 0)); diff --git a/pkgs/stream_channel/test/stream_channel_completer_test.dart b/pkgs/stream_channel/test/stream_channel_completer_test.dart index c20f9af11..070035e7b 100644 --- a/pkgs/stream_channel/test/stream_channel_completer_test.dart +++ b/pkgs/stream_channel/test/stream_channel_completer_test.dart @@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; @@ -62,14 +63,14 @@ void main() { streamController.add(1); streamController.add(2); streamController.add(3); - streamController.close(); + unawaited(streamController.close()); }); test("forwards events through the sink", () async { completer.channel.sink.add(1); completer.channel.sink.add(2); completer.channel.sink.add(3); - completer.channel.sink.close(); + unawaited(completer.channel.sink.close()); await pumpEventQueue(); completer.setChannel(innerChannel); diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index 2f05a9ef1..3f4e896b3 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:async/async.dart'; +import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; @@ -46,11 +47,11 @@ void main() { .transform(StreamChannelTransformer.fromCodec(utf8)); streamController.add([102, 111, 111, 98, 97, 114]); - streamController.close(); + unawaited(streamController.close()); expect(await transformed.stream.toList(), equals(["foobar"])); transformed.sink.add("fblthp"); - transformed.sink.close(); + unawaited(transformed.sink.close()); expect( sinkController.stream.toList(), completion(equals([ @@ -65,12 +66,12 @@ void main() { streamController.add("hello world"); streamController.add(" what\nis"); streamController.add("\nup"); - streamController.close(); + unawaited(streamController.close()); expect(await transformed.stream.toList(), equals(["hello world what", "is", "up"])); transformed.sink.add("fbl\nthp"); - transformed.sink.close(); + unawaited(transformed.sink.close()); expect(sinkController.stream.toList(), completion(equals(["fbl\nthp"]))); }); @@ -79,13 +80,13 @@ void main() { StreamSinkTransformer.fromStreamTransformer(const LineSplitter())); streamController.add("fbl\nthp"); - streamController.close(); + unawaited(streamController.close()); expect(await transformed.stream.toList(), equals(["fbl\nthp"])); transformed.sink.add("hello world"); transformed.sink.add(" what\nis"); transformed.sink.add("\nup"); - transformed.sink.close(); + unawaited(transformed.sink.close()); expect(sinkController.stream.toList(), completion(equals(["hello world what", "is", "up"]))); }); diff --git a/pkgs/stream_channel/test/with_close_guarantee_test.dart b/pkgs/stream_channel/test/with_close_guarantee_test.dart index 1749bacb7..803dc61f1 100644 --- a/pkgs/stream_channel/test/with_close_guarantee_test.dart +++ b/pkgs/stream_channel/test/with_close_guarantee_test.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'package:async/async.dart'; +import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; @@ -54,7 +55,7 @@ void main() { test( "closing the event sink before events are emitted causes the stream to " "close immediately", () async { - channel.sink.close(); + unawaited(channel.sink.close()); channel.stream.listen(expectAsync1((_) {}, count: 0), onError: expectAsync2((_, __) {}, count: 0), onDone: expectAsync0(() {})); @@ -62,7 +63,7 @@ void main() { controller.local.sink.add(1); controller.local.sink.add(2); controller.local.sink.add(3); - controller.local.sink.close(); + unawaited(controller.local.sink.close()); await pumpEventQueue(); }); diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index 0ea59525e..c9ff59f1e 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; @@ -32,7 +33,7 @@ void main() { await pumpEventQueue(); expect(channel.stream.toList(), completion(equals([1, 2, 3]))); - streamController.close(); + unawaited(streamController.close()); }); test("only allows a single subscription", () { @@ -58,14 +59,14 @@ void main() { }); test("after the stream closes, the sink ignores events", () async { - streamController.close(); + unawaited(streamController.close()); // Wait for the done event to be delivered. await channel.stream.toList(); channel.sink.add(1); channel.sink.add(2); channel.sink.add(3); - channel.sink.close(); + unawaited(channel.sink.close()); // None of our channel.sink additions should make it to the other endpoint. sinkController.stream.listen(expectAsync1((_) {}, count: 0), @@ -75,28 +76,28 @@ void main() { test("canceling the stream's subscription has no effect on the sink", () async { - channel.stream.listen(null).cancel(); + unawaited(channel.stream.listen(null).cancel()); await pumpEventQueue(); channel.sink.add(1); channel.sink.add(2); channel.sink.add(3); - channel.sink.close(); + unawaited(channel.sink.close()); expect(sinkController.stream.toList(), completion(equals([1, 2, 3]))); }); test("canceling the stream's subscription doesn't stop a done event", () async { - channel.stream.listen(null).cancel(); + unawaited(channel.stream.listen(null).cancel()); await pumpEventQueue(); - streamController.close(); + unawaited(streamController.close()); await pumpEventQueue(); channel.sink.add(1); channel.sink.add(2); channel.sink.add(3); - channel.sink.close(); + unawaited(channel.sink.close()); // The sink should be ignoring events because the stream closed. sinkController.stream.listen(expectAsync1((_) {}, count: 0), From 33592843725d99b811c25f942de1edf76c5a69a0 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 25 Jul 2019 09:54:10 -0700 Subject: [PATCH 070/138] Remove unneeded codereview.settings --- pkgs/stream_channel/codereview.settings | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/stream_channel/codereview.settings diff --git a/pkgs/stream_channel/codereview.settings b/pkgs/stream_channel/codereview.settings deleted file mode 100644 index 7b0a9edc6..000000000 --- a/pkgs/stream_channel/codereview.settings +++ /dev/null @@ -1,3 +0,0 @@ -CODE_REVIEW_SERVER: https://codereview.chromium.org/ -VIEW_VC: https://github.com/dart-lang/stream_channel/commit/ -CC_LIST: reviews@dartlang.org \ No newline at end of file From d77f04738c492f95aca41c991c454f99d36bdafc Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 25 Jul 2019 09:54:23 -0700 Subject: [PATCH 071/138] Fix outdated URLs --- pkgs/stream_channel/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/README.md b/pkgs/stream_channel/README.md index 5d6a2b4e0..2ec970b8e 100644 --- a/pkgs/stream_channel/README.md +++ b/pkgs/stream_channel/README.md @@ -7,10 +7,10 @@ protocol. For example, the [`test`][test] package re-uses its test suite communication protocol for both WebSocket connections to browser suites and Isolate connections to VM tests. -[test]: https://pub.dartlang.org/packages/test +[test]: https://pub.dev/packages/test This package also contains utilities for dealing with `StreamChannel`s and with two-way communications in general. For documentation of these utilities, see [the API docs][api]. -[api]: https://www.dartdocs.org/documentation/stream_channel/latest +[api]: https://pub.dev/documentation/stream_channel/latest/ From 077574a8b132d7f9a2199dc9bbbdcb5a23b940f9 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 25 Jul 2019 09:54:34 -0700 Subject: [PATCH 072/138] Add missing dartfmt --fix lint --- pkgs/stream_channel/analysis_options.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index 1e02731d7..df4128a17 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -11,4 +11,5 @@ linter: rules: - annotate_overrides - comment_references + - prefer_generic_function_type_aliases - prefer_typing_uninitialized_variables From 4d81dead936cf59e79334fbc02b404f8f8959edd Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 25 Jul 2019 09:54:55 -0700 Subject: [PATCH 073/138] Test on oldest supported Dart SDK --- pkgs/stream_channel/.travis.yml | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/pkgs/stream_channel/.travis.yml b/pkgs/stream_channel/.travis.yml index 45359fb40..69f24c3fa 100644 --- a/pkgs/stream_channel/.travis.yml +++ b/pkgs/stream_channel/.travis.yml @@ -1,12 +1,23 @@ language: dart dart: - - dev +- 2.0.0 +- dev + dart_task: - - test: --platform vm - - test: --platform firefox -j 1 - - dartfmt - - dartanalyzer +- test: --platform vm,chrome + +matrix: + include: + # Only validate formatting using the dev release + - dart: dev + dart_task: dartfmt + - dart: dev + dart_task: + dartanalyzer: --fatal-infos --fatal-warnings . + - dart: 2.0.0 + dart_task: + dartanalyzer: --fatal-warnings . # Only building master means that we don't run two builds for each pull request. branches: @@ -14,4 +25,4 @@ branches: cache: directories: - - $HOME/.pub-cache + - $HOME/.pub-cache From a3da73812869c4e593b57eb6d04967dee16a949a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 25 Jul 2019 09:56:05 -0700 Subject: [PATCH 074/138] pubspec: Make the description a bit longer --- pkgs/stream_channel/pubspec.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index dfd3af83d..bef50e1cb 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,7 +1,9 @@ name: stream_channel version: 2.0.1-dev -description: An abstraction for two-way communication channels. +description: >- + An abstraction for two-way communication channels based on the Dart Stream + class. author: Dart Team homepage: https://github.com/dart-lang/stream_channel From f1838d9b911a1865eb92c3c968f6d541e24c6fbe Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 25 Jul 2019 10:14:41 -0700 Subject: [PATCH 075/138] =?UTF-8?q?Require=20Dart=202.2=20=E2=80=93=C2=A0b?= =?UTF-8?q?ecause=20pkg:pedantic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkgs/stream_channel/.travis.yml | 4 ++-- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/pubspec.yaml | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pkgs/stream_channel/.travis.yml b/pkgs/stream_channel/.travis.yml index 69f24c3fa..d6a545496 100644 --- a/pkgs/stream_channel/.travis.yml +++ b/pkgs/stream_channel/.travis.yml @@ -1,7 +1,7 @@ language: dart dart: -- 2.0.0 +- 2.2.0 - dev dart_task: @@ -15,7 +15,7 @@ matrix: - dart: dev dart_task: dartanalyzer: --fatal-infos --fatal-warnings . - - dart: 2.0.0 + - dart: 2.2.0 dart_task: dartanalyzer: --fatal-warnings . diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 24564ede1..4f345106a 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.0 + +* Require Dart `2.2.0` or later. + ## 2.0.0 **Breaking changes** diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index bef50e1cb..61e78c0f3 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 2.0.1-dev +version: 2.1.0-dev description: >- An abstraction for two-way communication channels based on the Dart Stream @@ -8,7 +8,7 @@ author: Dart Team homepage: https://github.com/dart-lang/stream_channel environment: - sdk: '>=2.0.0 <3.0.0' + sdk: '>=2.2.0 <3.0.0' dependencies: async: '>=1.11.0 <3.0.0' From 69ec2c61ec9cf38c57bb41756f9a34d2065c9fcc Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 5 Dec 2019 12:45:27 -0800 Subject: [PATCH 076/138] Fix newly enforce package:pedantic lints (dart-lang/stream_channel#48) - use_function_type_syntax_for_parameters - prefer_single_quotes --- .../lib/src/close_guarantee_channel.dart | 4 +- pkgs/stream_channel/lib/src/disconnector.dart | 14 ++-- .../lib/src/guarantee_channel.dart | 14 ++-- .../stream_channel/lib/src/multi_channel.dart | 6 +- .../lib/src/stream_channel_completer.dart | 4 +- pkgs/stream_channel/lib/stream_channel.dart | 8 +- .../test/disconnector_test.dart | 26 +++--- .../test/isolate_channel_test.dart | 34 ++++---- .../test/json_document_transformer_test.dart | 16 ++-- .../test/multi_channel_test.dart | 84 +++++++++---------- .../test/stream_channel_completer_test.dart | 46 +++++----- .../test/stream_channel_controller_test.dart | 32 +++---- .../test/stream_channel_test.dart | 38 ++++----- .../test/with_close_guarantee_test.dart | 8 +- .../test/with_guarantees_test.dart | 52 ++++++------ 15 files changed, 193 insertions(+), 193 deletions(-) diff --git a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart index 33296da43..60916d002 100644 --- a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart @@ -48,8 +48,8 @@ class _CloseGuaranteeStream extends Stream { _CloseGuaranteeStream(this._inner, this._channel); @override - StreamSubscription listen(void onData(T event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void Function(T) onData, + {Function onError, void Function() onDone, bool cancelOnError}) { // If the channel is already disconnected, we shouldn't dispatch anything // but a done event. if (_channel._disconnected) { diff --git a/pkgs/stream_channel/lib/src/disconnector.dart b/pkgs/stream_channel/lib/src/disconnector.dart index 69fbab727..e8835374f 100644 --- a/pkgs/stream_channel/lib/src/disconnector.dart +++ b/pkgs/stream_channel/lib/src/disconnector.dart @@ -87,9 +87,9 @@ class _DisconnectorSink implements StreamSink { @override void add(T data) { - if (_closed) throw StateError("Cannot add event after closing."); + if (_closed) throw StateError('Cannot add event after closing.'); if (_inAddStream) { - throw StateError("Cannot add event while adding stream."); + throw StateError('Cannot add event while adding stream.'); } if (_isDisconnected) return; @@ -98,9 +98,9 @@ class _DisconnectorSink implements StreamSink { @override void addError(error, [StackTrace stackTrace]) { - if (_closed) throw StateError("Cannot add event after closing."); + if (_closed) throw StateError('Cannot add event after closing.'); if (_inAddStream) { - throw StateError("Cannot add event while adding stream."); + throw StateError('Cannot add event while adding stream.'); } if (_isDisconnected) return; @@ -109,9 +109,9 @@ class _DisconnectorSink implements StreamSink { @override Future addStream(Stream stream) { - if (_closed) throw StateError("Cannot add stream after closing."); + if (_closed) throw StateError('Cannot add stream after closing.'); if (_inAddStream) { - throw StateError("Cannot add stream while adding stream."); + throw StateError('Cannot add stream while adding stream.'); } if (_isDisconnected) return Future.value(); @@ -127,7 +127,7 @@ class _DisconnectorSink implements StreamSink { @override Future close() { if (_inAddStream) { - throw StateError("Cannot close sink while adding stream."); + throw StateError('Cannot close sink while adding stream.'); } _closed = true; diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart index d8add39e8..cfee99ee5 100644 --- a/pkgs/stream_channel/lib/src/guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -115,9 +115,9 @@ class _GuaranteeSink implements StreamSink { @override void add(T data) { - if (_closed) throw StateError("Cannot add event after closing."); + if (_closed) throw StateError('Cannot add event after closing.'); if (_inAddStream) { - throw StateError("Cannot add event while adding stream."); + throw StateError('Cannot add event while adding stream.'); } if (_disconnected) return; @@ -126,9 +126,9 @@ class _GuaranteeSink implements StreamSink { @override void addError(error, [StackTrace stackTrace]) { - if (_closed) throw StateError("Cannot add event after closing."); + if (_closed) throw StateError('Cannot add event after closing.'); if (_inAddStream) { - throw StateError("Cannot add event while adding stream."); + throw StateError('Cannot add event while adding stream.'); } if (_disconnected) return; @@ -158,9 +158,9 @@ class _GuaranteeSink implements StreamSink { @override Future addStream(Stream stream) { - if (_closed) throw StateError("Cannot add stream after closing."); + if (_closed) throw StateError('Cannot add stream after closing.'); if (_inAddStream) { - throw StateError("Cannot add stream while adding stream."); + throw StateError('Cannot add stream while adding stream.'); } if (_disconnected) return Future.value(); @@ -176,7 +176,7 @@ class _GuaranteeSink implements StreamSink { @override Future close() { if (_inAddStream) { - throw StateError("Cannot close sink while adding stream."); + throw StateError('Cannot close sink while adding stream.'); } if (_closed) return done; diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index d729eb7bb..e0982ae19 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -104,11 +104,11 @@ class _MultiChannel extends StreamChannelMixin /// Input IDs of controllers in [_controllers] that we've received messages /// for but that have not yet had a local [virtualChannel] created. - final _pendingIds = Set(); + final _pendingIds = {}; /// Input IDs of virtual channels that used to exist but have since been /// closed. - final _closedIds = Set(); + final _closedIds = {}; /// The next id to use for a local virtual channel. /// @@ -201,7 +201,7 @@ class _MultiChannel extends StreamChannelMixin controller = _controllers[inputId]; } else if (_controllers.containsKey(inputId) || _closedIds.contains(inputId)) { - throw ArgumentError("A virtual channel with id $id already exists."); + throw ArgumentError('A virtual channel with id $id already exists.'); } else { controller = StreamChannelController(sync: true); _controllers[inputId] = controller; diff --git a/pkgs/stream_channel/lib/src/stream_channel_completer.dart b/pkgs/stream_channel/lib/src/stream_channel_completer.dart index e94eda66e..a14ffde44 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_completer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_completer.dart @@ -52,7 +52,7 @@ class StreamChannelCompleter { /// Either [setChannel] or [setError] may be called at most once. Trying to /// call either of them again will fail. void setChannel(StreamChannel channel) { - if (_set) throw StateError("The channel has already been set."); + if (_set) throw StateError('The channel has already been set.'); _set = true; _streamCompleter.setSourceStream(channel.stream); @@ -67,7 +67,7 @@ class StreamChannelCompleter { /// Either [setChannel] or [setError] may be called at most once. Trying to /// call either of them again will fail. void setError(error, [StackTrace stackTrace]) { - if (_set) throw StateError("The channel has already been set."); + if (_set) throw StateError('The channel has already been set.'); _set = true; _streamCompleter.setError(error, stackTrace); diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index e99de08f0..c806ec663 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -117,11 +117,11 @@ abstract class StreamChannel { /// Returns a copy of this with [stream] replaced by [change]'s return /// value. - StreamChannel changeStream(Stream change(Stream stream)); + StreamChannel changeStream(Stream Function(Stream) change); /// Returns a copy of this with [sink] replaced by [change]'s return /// value. - StreamChannel changeSink(StreamSink change(StreamSink sink)); + StreamChannel changeSink(StreamSink Function(StreamSink) change); /// Returns a copy of this with the generic type coerced to [S]. /// @@ -167,11 +167,11 @@ abstract class StreamChannelMixin implements StreamChannel { changeSink(transformer.bind); @override - StreamChannel changeStream(Stream change(Stream stream)) => + StreamChannel changeStream(Stream Function(Stream) change) => StreamChannel.withCloseGuarantee(change(stream), sink); @override - StreamChannel changeSink(StreamSink change(StreamSink sink)) => + StreamChannel changeSink(StreamSink Function(StreamSink) change) => StreamChannel.withCloseGuarantee(stream, change(sink)); @override diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index a5ea2ebb5..ec0c64bc0 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -23,8 +23,8 @@ void main() { .transform(disconnector); }); - group("before disconnection", () { - test("forwards events from the sink as normal", () { + group('before disconnection', () { + test('forwards events from the sink as normal', () { channel.sink.add(1); channel.sink.add(2); channel.sink.add(3); @@ -33,7 +33,7 @@ void main() { expect(sinkController.stream.toList(), completion(equals([1, 2, 3]))); }); - test("forwards events to the stream as normal", () { + test('forwards events to the stream as normal', () { streamController.add(1); streamController.add(2); streamController.add(3); @@ -47,7 +47,7 @@ void main() { expect(channel.sink.close(), completes); expect(() => channel.sink.add(1), throwsStateError); - expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addError('oh no'), throwsStateError); expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); }); @@ -57,7 +57,7 @@ void main() { channel.sink.addStream(controller.stream); expect(() => channel.sink.add(1), throwsStateError); - expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addError('oh no'), throwsStateError); expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); expect(() => channel.sink.close(), throwsStateError); @@ -66,7 +66,7 @@ void main() { }); }); - test("cancels addStream when disconnected", () async { + test('cancels addStream when disconnected', () async { var canceled = false; var controller = StreamController(onCancel: () { canceled = true; @@ -78,7 +78,7 @@ void main() { expect(canceled, isTrue); }); - test("disconnect() returns the close future from the inner sink", () async { + test('disconnect() returns the close future from the inner sink', () async { var streamController = StreamController(); var sinkController = StreamController(); var disconnector = Disconnector(); @@ -104,12 +104,12 @@ void main() { expect(disconnectFutureFired, isTrue); }); - group("after disconnection", () { + group('after disconnection', () { setUp(() { disconnector.disconnect(); }); - test("closes the inner sink and ignores events to the outer sink", () { + test('closes the inner sink and ignores events to the outer sink', () { channel.sink.add(1); channel.sink.add(2); channel.sink.add(3); @@ -118,21 +118,21 @@ void main() { expect(sinkController.stream.toList(), completion(isEmpty)); }); - test("closes the stream", () { + test('closes the stream', () { expect(channel.stream.toList(), completion(isEmpty)); }); - test("completes done", () { + test('completes done', () { sinkController.stream.listen(null); // Work around sdk#19095. expect(channel.sink.done, completes); }); - test("still emits state errors after explicit close", () { + test('still emits state errors after explicit close', () { sinkController.stream.listen(null); // Work around sdk#19095. expect(channel.sink.close(), completes); expect(() => channel.sink.add(1), throwsStateError); - expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addError('oh no'), throwsStateError); }); }); } diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index fd14b8407..ab70f749b 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -28,7 +28,7 @@ void main() { channel.sink.close(); }); - test("the channel can send messages", () { + test('the channel can send messages', () { channel.sink.add(1); channel.sink.add(2); channel.sink.add(3); @@ -36,7 +36,7 @@ void main() { expect(receivePort.take(3).toList(), completion(equals([1, 2, 3]))); }); - test("the channel can receive messages", () { + test('the channel can receive messages', () { sendPort.send(1); sendPort.send(2); sendPort.send(3); @@ -47,7 +47,7 @@ void main() { test("events can't be added to an explicitly-closed sink", () { expect(channel.sink.close(), completes); expect(() => channel.sink.add(1), throwsStateError); - expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addError('oh no'), throwsStateError); expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); }); @@ -57,7 +57,7 @@ void main() { channel.sink.addStream(controller.stream); expect(() => channel.sink.add(1), throwsStateError); - expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addError('oh no'), throwsStateError); expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); expect(() => channel.sink.close(), throwsStateError); @@ -65,10 +65,10 @@ void main() { controller.close(); }); - group("stream channel rules", () { + group('stream channel rules', () { test( - "closing the sink causes the stream to close before it emits any more " - "events", () { + 'closing the sink causes the stream to close before it emits any more ' + 'events', () { sendPort.send(1); sendPort.send(2); sendPort.send(3); @@ -92,10 +92,10 @@ void main() { expect(receivePort.take(3).toList(), completion(equals([1, 2, 3]))); }); - test("the sink closes as soon as an error is added", () async { - channel.sink.addError("oh no"); + test('the sink closes as soon as an error is added', () async { + channel.sink.addError('oh no'); channel.sink.add(1); - expect(channel.sink.done, throwsA("oh no")); + expect(channel.sink.done, throwsA('oh no')); // Since the sink is closed, the stream should also be closed. expect(channel.stream.isEmpty, completion(isTrue)); @@ -106,7 +106,7 @@ void main() { await pumpEventQueue(); }); - test("the sink closes as soon as an error is added via addStream", + test('the sink closes as soon as an error is added via addStream', () async { var canceled = false; var controller = StreamController(onCancel: () { @@ -116,8 +116,8 @@ void main() { // This future shouldn't get the error, because it's sent to [Sink.done]. expect(channel.sink.addStream(controller.stream), completes); - controller.addError("oh no"); - expect(channel.sink.done, throwsA("oh no")); + controller.addError('oh no'); + expect(channel.sink.done, throwsA('oh no')); await pumpEventQueue(); expect(canceled, isTrue); @@ -127,7 +127,7 @@ void main() { }); }); - group("connect constructors", () { + group('connect constructors', () { ReceivePort connectPort; setUp(() { connectPort = ReceivePort(); @@ -137,7 +137,7 @@ void main() { connectPort.close(); }); - test("create a connected pair of channels", () { + test('create a connected pair of channels', () { var channel1 = IsolateChannel.connectReceive(connectPort); var channel2 = IsolateChannel.connectSend(connectPort.sendPort); @@ -152,10 +152,10 @@ void main() { expect(channel1.stream.take(3).toList(), completion(equals([4, 5, 6]))); }); - test("the receiving channel produces an error if it gets the wrong message", + test('the receiving channel produces an error if it gets the wrong message', () { var connectedChannel = IsolateChannel.connectReceive(connectPort); - connectPort.sendPort.send("wrong value"); + connectPort.sendPort.send('wrong value'); expect(connectedChannel.stream.toList(), throwsStateError); expect(connectedChannel.sink.done, completes); diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index e6c560ade..3ccce4ead 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -19,26 +19,26 @@ void main() { StreamChannel(streamController.stream, sinkController.sink); }); - test("decodes JSON emitted by the channel", () { + test('decodes JSON emitted by the channel', () { var transformed = channel.transform(jsonDocument); streamController.add('{"foo": "bar"}'); - expect(transformed.stream.first, completion(equals({"foo": "bar"}))); + expect(transformed.stream.first, completion(equals({'foo': 'bar'}))); }); - test("encodes objects added to the channel", () { + test('encodes objects added to the channel', () { var transformed = channel.transform(jsonDocument); - transformed.sink.add({"foo": "bar"}); + transformed.sink.add({'foo': 'bar'}); expect(sinkController.stream.first, - completion(equals(jsonEncode({"foo": "bar"})))); + completion(equals(jsonEncode({'foo': 'bar'})))); }); - test("emits a stream error when incoming JSON is malformed", () { + test('emits a stream error when incoming JSON is malformed', () { var transformed = channel.transform(jsonDocument); - streamController.add("{invalid"); + streamController.add('{invalid'); expect(transformed.stream.first, throwsFormatException); }); - test("synchronously throws if an unencodable object is added", () { + test('synchronously throws if an unencodable object is added', () { var transformed = channel.transform(jsonDocument); expect(() => transformed.sink.add(Object()), throwsA(TypeMatcher())); diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index b1659a03a..0fa1df9ea 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -16,8 +16,8 @@ void main() { channel2 = MultiChannel(controller.foreign); }); - group("the default virtual channel", () { - test("begins connected", () { + group('the default virtual channel', () { + test('begins connected', () { var first = true; channel2.stream.listen(expectAsync1((message) { if (first) { @@ -32,14 +32,14 @@ void main() { channel1.sink.add(2); }); - test("closes the remote virtual channel when it closes", () { + test('closes the remote virtual channel when it closes', () { expect(channel2.stream.toList(), completion(isEmpty)); expect(channel2.sink.done, completes); channel1.sink.close(); }); - test("closes the local virtual channel when it closes", () { + test('closes the local virtual channel when it closes', () { expect(channel1.stream.toList(), completion(isEmpty)); expect(channel1.sink.done, completes); @@ -48,7 +48,7 @@ void main() { test( "doesn't closes the local virtual channel when the stream " - "subscription is canceled", () { + 'subscription is canceled', () { channel1.sink.done.then(expectAsync1((_) {}, count: 0)); channel1.stream.listen((_) {}).cancel(); @@ -59,8 +59,8 @@ void main() { }); test( - "closes the underlying channel when it closes without any other " - "virtual channels", () { + 'closes the underlying channel when it closes without any other ' + 'virtual channels', () { expect(controller.local.sink.done, completes); expect(controller.foreign.sink.done, completes); @@ -69,7 +69,7 @@ void main() { test( "doesn't close the underlying channel when it closes with other " - "virtual channels", () { + 'virtual channels', () { controller.local.sink.done.then(expectAsync1((_) {}, count: 0)); controller.foreign.sink.done.then(expectAsync1((_) {}, count: 0)); @@ -84,7 +84,7 @@ void main() { }); }); - group("a locally-created virtual channel", () { + group('a locally-created virtual channel', () { VirtualChannel virtual1; VirtualChannel virtual2; setUp(() { @@ -92,7 +92,7 @@ void main() { virtual2 = channel2.virtualChannel(virtual1.id); }); - test("sends messages only to the other virtual channel", () { + test('sends messages only to the other virtual channel', () { var first = true; virtual2.stream.listen(expectAsync1((message) { if (first) { @@ -114,14 +114,14 @@ void main() { virtual1.sink.add(2); }); - test("closes the remote virtual channel when it closes", () { + test('closes the remote virtual channel when it closes', () { expect(virtual2.stream.toList(), completion(isEmpty)); expect(virtual2.sink.done, completes); virtual1.sink.close(); }); - test("closes the local virtual channel when it closes", () { + test('closes the local virtual channel when it closes', () { expect(virtual1.stream.toList(), completion(isEmpty)); expect(virtual1.sink.done, completes); @@ -130,7 +130,7 @@ void main() { test( "doesn't closes the local virtual channel when the stream " - "subscription is canceled", () { + 'subscription is canceled', () { virtual1.sink.done.then(expectAsync1((_) {}, count: 0)); virtual1.stream.listen((_) {}).cancel(); @@ -140,8 +140,8 @@ void main() { }); test( - "closes the underlying channel when it closes without any other " - "virtual channels", () async { + 'closes the underlying channel when it closes without any other ' + 'virtual channels', () async { // First close the default channel so we can test the new channel as the // last living virtual channel. unawaited(channel1.sink.close()); @@ -155,7 +155,7 @@ void main() { test( "doesn't close the underlying channel when it closes with other " - "virtual channels", () { + 'virtual channels', () { controller.local.sink.done.then(expectAsync1((_) {}, count: 0)); controller.foreign.sink.done.then(expectAsync1((_) {}, count: 0)); @@ -184,7 +184,7 @@ void main() { }); }); - group("a remotely-created virtual channel", () { + group('a remotely-created virtual channel', () { VirtualChannel virtual1; VirtualChannel virtual2; setUp(() { @@ -192,7 +192,7 @@ void main() { virtual2 = channel2.virtualChannel(virtual1.id); }); - test("sends messages only to the other virtual channel", () { + test('sends messages only to the other virtual channel', () { var first = true; virtual1.stream.listen(expectAsync1((message) { if (first) { @@ -214,14 +214,14 @@ void main() { virtual2.sink.add(2); }); - test("closes the remote virtual channel when it closes", () { + test('closes the remote virtual channel when it closes', () { expect(virtual1.stream.toList(), completion(isEmpty)); expect(virtual1.sink.done, completes); virtual2.sink.close(); }); - test("closes the local virtual channel when it closes", () { + test('closes the local virtual channel when it closes', () { expect(virtual2.stream.toList(), completion(isEmpty)); expect(virtual2.sink.done, completes); @@ -230,7 +230,7 @@ void main() { test( "doesn't closes the local virtual channel when the stream " - "subscription is canceled", () { + 'subscription is canceled', () { virtual2.sink.done.then(expectAsync1((_) {}, count: 0)); virtual2.stream.listen((_) {}).cancel(); @@ -240,8 +240,8 @@ void main() { }); test( - "closes the underlying channel when it closes without any other " - "virtual channels", () async { + 'closes the underlying channel when it closes without any other ' + 'virtual channels', () async { // First close the default channel so we can test the new channel as the // last living virtual channel. unawaited(channel2.sink.close()); @@ -255,7 +255,7 @@ void main() { test( "doesn't close the underlying channel when it closes with other " - "virtual channels", () { + 'virtual channels', () { controller.local.sink.done.then(expectAsync1((_) {}, count: 0)); controller.foreign.sink.done.then(expectAsync1((_) {}, count: 0)); @@ -270,7 +270,7 @@ void main() { expect(() => channel2.virtualChannel(virtual1.id), throwsArgumentError); }); - test("dispatches events received before the virtual channel is created", + test('dispatches events received before the virtual channel is created', () async { virtual1 = channel1.virtualChannel(); @@ -284,8 +284,8 @@ void main() { }); test( - "dispatches close events received before the virtual channel is " - "created", () async { + 'dispatches close events received before the virtual channel is ' + 'created', () async { virtual1 = channel1.virtualChannel(); unawaited(virtual1.sink.close()); @@ -296,7 +296,7 @@ void main() { }); }); - group("when the underlying stream", () { + group('when the underlying stream', () { VirtualChannel virtual1; VirtualChannel virtual2; setUp(() { @@ -304,7 +304,7 @@ void main() { virtual2 = channel2.virtualChannel(virtual1.id); }); - test("closes, all virtual channels close", () { + test('closes, all virtual channels close', () { expect(channel1.stream.toList(), completion(isEmpty)); expect(channel1.sink.done, completes); expect(channel2.stream.toList(), completion(isEmpty)); @@ -317,7 +317,7 @@ void main() { controller.local.sink.close(); }); - test("closes, more virtual channels are created closed", () async { + test('closes, more virtual channels are created closed', () async { unawaited(channel2.sink.close()); unawaited(virtual2.sink.close()); @@ -334,21 +334,21 @@ void main() { expect(virtual.sink.done, completes); }); - test("emits an error, the error is sent only to the default channel", () { + test('emits an error, the error is sent only to the default channel', () { channel1.stream.listen(expectAsync1((_) {}, count: 0), - onError: expectAsync1((error) => expect(error, equals("oh no")))); + onError: expectAsync1((error) => expect(error, equals('oh no')))); virtual1.stream.listen(expectAsync1((_) {}, count: 0), onError: expectAsync1((_) {}, count: 0)); - controller.foreign.sink.addError("oh no"); + controller.foreign.sink.addError('oh no'); }); }); - group("stream channel rules", () { - group("for the main stream:", () { + group('stream channel rules', () { + group('for the main stream:', () { test( - "closing the sink causes the stream to close before it emits any more " - "events", () { + 'closing the sink causes the stream to close before it emits any more ' + 'events', () { channel1.sink.add(1); channel1.sink.add(2); channel1.sink.add(3); @@ -359,7 +359,7 @@ void main() { }, count: 1)); }); - test("after the stream closes, the sink ignores events", () async { + test('after the stream closes, the sink ignores events', () async { unawaited(channel1.sink.close()); // Wait for the done event to be delivered. @@ -405,7 +405,7 @@ void main() { }); }); - group("for a virtual channel:", () { + group('for a virtual channel:', () { VirtualChannel virtual1; VirtualChannel virtual2; setUp(() { @@ -414,8 +414,8 @@ void main() { }); test( - "closing the sink causes the stream to close before it emits any more " - "events", () { + 'closing the sink causes the stream to close before it emits any more ' + 'events', () { virtual1.sink.add(1); virtual1.sink.add(2); virtual1.sink.add(3); @@ -426,7 +426,7 @@ void main() { }, count: 1)); }); - test("after the stream closes, the sink ignores events", () async { + test('after the stream closes, the sink ignores events', () async { unawaited(virtual1.sink.close()); // Wait for the done event to be delivered. diff --git a/pkgs/stream_channel/test/stream_channel_completer_test.dart b/pkgs/stream_channel/test/stream_channel_completer_test.dart index 070035e7b..234f956ef 100644 --- a/pkgs/stream_channel/test/stream_channel_completer_test.dart +++ b/pkgs/stream_channel/test/stream_channel_completer_test.dart @@ -20,8 +20,8 @@ void main() { innerChannel = StreamChannel(streamController.stream, sinkController.sink); }); - group("when a channel is set before accessing", () { - test("forwards events through the stream", () { + group('when a channel is set before accessing', () { + test('forwards events through the stream', () { completer.setChannel(innerChannel); expect(completer.channel.stream.toList(), completion(equals([1, 2, 3]))); @@ -31,7 +31,7 @@ void main() { streamController.close(); }); - test("forwards events through the sink", () { + test('forwards events through the sink', () { completer.setChannel(innerChannel); expect(sinkController.stream.toList(), completion(equals([1, 2, 3]))); @@ -41,21 +41,21 @@ void main() { completer.channel.sink.close(); }); - test("forwards an error through the stream", () { - completer.setError("oh no"); - expect(completer.channel.stream.first, throwsA("oh no")); + test('forwards an error through the stream', () { + completer.setError('oh no'); + expect(completer.channel.stream.first, throwsA('oh no')); }); - test("drops sink events", () { - completer.setError("oh no"); + test('drops sink events', () { + completer.setError('oh no'); expect(completer.channel.sink.done, completes); completer.channel.sink.add(1); - completer.channel.sink.addError("oh no"); + completer.channel.sink.addError('oh no'); }); }); - group("when a channel is set after accessing", () { - test("forwards events through the stream", () async { + group('when a channel is set after accessing', () { + test('forwards events through the stream', () async { expect(completer.channel.stream.toList(), completion(equals([1, 2, 3]))); await pumpEventQueue(); @@ -66,7 +66,7 @@ void main() { unawaited(streamController.close()); }); - test("forwards events through the sink", () async { + test('forwards events through the sink', () async { completer.channel.sink.add(1); completer.channel.sink.add(2); completer.channel.sink.add(3); @@ -77,25 +77,25 @@ void main() { expect(sinkController.stream.toList(), completion(equals([1, 2, 3]))); }); - test("forwards an error through the stream", () async { - expect(completer.channel.stream.first, throwsA("oh no")); + test('forwards an error through the stream', () async { + expect(completer.channel.stream.first, throwsA('oh no')); await pumpEventQueue(); - completer.setError("oh no"); + completer.setError('oh no'); }); - test("drops sink events", () async { + test('drops sink events', () async { expect(completer.channel.sink.done, completes); completer.channel.sink.add(1); - completer.channel.sink.addError("oh no"); + completer.channel.sink.addError('oh no'); await pumpEventQueue(); - completer.setError("oh no"); + completer.setError('oh no'); }); }); - group("forFuture", () { - test("forwards a StreamChannel", () { + group('forFuture', () { + test('forwards a StreamChannel', () { var channel = StreamChannelCompleter.fromFuture(Future.value(innerChannel)); channel.sink.add(1); @@ -107,9 +107,9 @@ void main() { expect(channel.stream.toList(), completion(equals([2]))); }); - test("forwards an error", () { - var channel = StreamChannelCompleter.fromFuture(Future.error("oh no")); - expect(channel.stream.toList(), throwsA("oh no")); + test('forwards an error', () { + var channel = StreamChannelCompleter.fromFuture(Future.error('oh no')); + expect(channel.stream.toList(), throwsA('oh no')); }); }); diff --git a/pkgs/stream_channel/test/stream_channel_controller_test.dart b/pkgs/stream_channel/test/stream_channel_controller_test.dart index 62f883fa5..9b7a851d0 100644 --- a/pkgs/stream_channel/test/stream_channel_controller_test.dart +++ b/pkgs/stream_channel/test/stream_channel_controller_test.dart @@ -6,13 +6,13 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - group("asynchronously", () { + group('asynchronously', () { StreamChannelController controller; setUp(() { controller = StreamChannelController(); }); - test("forwards events from the local sink to the foreign stream", () { + test('forwards events from the local sink to the foreign stream', () { controller.local.sink ..add(1) ..add(2) @@ -21,7 +21,7 @@ void main() { expect(controller.foreign.stream.toList(), completion(equals([1, 2, 3]))); }); - test("forwards events from the foreign sink to the local stream", () { + test('forwards events from the foreign sink to the local stream', () { controller.foreign.sink ..add(1) ..add(2) @@ -31,27 +31,27 @@ void main() { }); test( - "with allowForeignErrors: false, shuts down the connection if an " - "error is added to the foreign channel", () { + 'with allowForeignErrors: false, shuts down the connection if an ' + 'error is added to the foreign channel', () { controller = StreamChannelController(allowForeignErrors: false); - controller.foreign.sink.addError("oh no"); - expect(controller.foreign.sink.done, throwsA("oh no")); + controller.foreign.sink.addError('oh no'); + expect(controller.foreign.sink.done, throwsA('oh no')); expect(controller.foreign.stream.toList(), completion(isEmpty)); expect(controller.local.sink.done, completes); expect(controller.local.stream.toList(), completion(isEmpty)); }); }); - group("synchronously", () { + group('synchronously', () { StreamChannelController controller; setUp(() { controller = StreamChannelController(sync: true); }); test( - "synchronously forwards events from the local sink to the foreign " - "stream", () { + 'synchronously forwards events from the local sink to the foreign ' + 'stream', () { var receivedEvent = false; var receivedError = false; var receivedDone = false; @@ -59,7 +59,7 @@ void main() { expect(event, equals(1)); receivedEvent = true; }), onError: expectAsync1((error) { - expect(error, equals("oh no")); + expect(error, equals('oh no')); receivedError = true; }), onDone: expectAsync0(() { receivedDone = true; @@ -68,7 +68,7 @@ void main() { controller.local.sink.add(1); expect(receivedEvent, isTrue); - controller.local.sink.addError("oh no"); + controller.local.sink.addError('oh no'); expect(receivedError, isTrue); controller.local.sink.close(); @@ -76,8 +76,8 @@ void main() { }); test( - "synchronously forwards events from the foreign sink to the local " - "stream", () { + 'synchronously forwards events from the foreign sink to the local ' + 'stream', () { var receivedEvent = false; var receivedError = false; var receivedDone = false; @@ -85,7 +85,7 @@ void main() { expect(event, equals(1)); receivedEvent = true; }), onError: expectAsync1((error) { - expect(error, equals("oh no")); + expect(error, equals('oh no')); receivedError = true; }), onDone: expectAsync0(() { receivedDone = true; @@ -94,7 +94,7 @@ void main() { controller.foreign.sink.add(1); expect(receivedEvent, isTrue); - controller.foreign.sink.addError("oh no"); + controller.foreign.sink.addError('oh no'); expect(receivedError, isTrue); controller.foreign.sink.close(); diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index 3f4e896b3..9bd5a86f8 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -41,16 +41,16 @@ void main() { expect(sinkController.stream.toList(), completion(equals([4, 5, 6]))); }); - test("transform() transforms the channel", () async { + test('transform() transforms the channel', () async { var transformed = channel .cast>() .transform(StreamChannelTransformer.fromCodec(utf8)); streamController.add([102, 111, 111, 98, 97, 114]); unawaited(streamController.close()); - expect(await transformed.stream.toList(), equals(["foobar"])); + expect(await transformed.stream.toList(), equals(['foobar'])); - transformed.sink.add("fblthp"); + transformed.sink.add('fblthp'); unawaited(transformed.sink.close()); expect( sinkController.stream.toList(), @@ -59,39 +59,39 @@ void main() { ]))); }); - test("transformStream() transforms only the stream", () async { + test('transformStream() transforms only the stream', () async { var transformed = channel.cast().transformStream(const LineSplitter()); - streamController.add("hello world"); - streamController.add(" what\nis"); - streamController.add("\nup"); + streamController.add('hello world'); + streamController.add(' what\nis'); + streamController.add('\nup'); unawaited(streamController.close()); expect(await transformed.stream.toList(), - equals(["hello world what", "is", "up"])); + equals(['hello world what', 'is', 'up'])); - transformed.sink.add("fbl\nthp"); + transformed.sink.add('fbl\nthp'); unawaited(transformed.sink.close()); - expect(sinkController.stream.toList(), completion(equals(["fbl\nthp"]))); + expect(sinkController.stream.toList(), completion(equals(['fbl\nthp']))); }); - test("transformSink() transforms only the sink", () async { + test('transformSink() transforms only the sink', () async { var transformed = channel.cast().transformSink( StreamSinkTransformer.fromStreamTransformer(const LineSplitter())); - streamController.add("fbl\nthp"); + streamController.add('fbl\nthp'); unawaited(streamController.close()); - expect(await transformed.stream.toList(), equals(["fbl\nthp"])); + expect(await transformed.stream.toList(), equals(['fbl\nthp'])); - transformed.sink.add("hello world"); - transformed.sink.add(" what\nis"); - transformed.sink.add("\nup"); + transformed.sink.add('hello world'); + transformed.sink.add(' what\nis'); + transformed.sink.add('\nup'); unawaited(transformed.sink.close()); expect(sinkController.stream.toList(), - completion(equals(["hello world what", "is", "up"]))); + completion(equals(['hello world what', 'is', 'up']))); }); - test("changeStream() changes the stream", () { + test('changeStream() changes the stream', () { var newController = StreamController(); var changed = channel.changeStream((stream) { expect(stream, equals(channel.stream)); @@ -107,7 +107,7 @@ void main() { expect(changed.stream.toList(), completion(equals([10]))); }); - test("changeSink() changes the sink", () { + test('changeSink() changes the sink', () { var newController = StreamController(); var changed = channel.changeSink((sink) { expect(sink, equals(channel.sink)); diff --git a/pkgs/stream_channel/test/with_close_guarantee_test.dart b/pkgs/stream_channel/test/with_close_guarantee_test.dart index 803dc61f1..24aef0338 100644 --- a/pkgs/stream_channel/test/with_close_guarantee_test.dart +++ b/pkgs/stream_channel/test/with_close_guarantee_test.dart @@ -35,8 +35,8 @@ void main() { }); test( - "closing the event sink causes the stream to close before it emits any " - "more events", () async { + 'closing the event sink causes the stream to close before it emits any ' + 'more events', () async { controller.local.sink.add(1); controller.local.sink.add(2); controller.local.sink.add(3); @@ -53,8 +53,8 @@ void main() { }); test( - "closing the event sink before events are emitted causes the stream to " - "close immediately", () async { + 'closing the event sink before events are emitted causes the stream to ' + 'close immediately', () async { unawaited(channel.sink.close()); channel.stream.listen(expectAsync1((_) {}, count: 0), onError: expectAsync2((_, __) {}, count: 0), diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index c9ff59f1e..fa49689af 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -19,14 +19,14 @@ void main() { streamController.stream, sinkController.sink); }); - group("with a broadcast stream", () { + group('with a broadcast stream', () { setUp(() { streamController = StreamController.broadcast(); channel = StreamChannel.withGuarantees( streamController.stream, sinkController.sink); }); - test("buffers events", () async { + test('buffers events', () async { streamController.add(1); streamController.add(2); streamController.add(3); @@ -36,15 +36,15 @@ void main() { unawaited(streamController.close()); }); - test("only allows a single subscription", () { + test('only allows a single subscription', () { channel.stream.listen(null); expect(() => channel.stream.listen(null), throwsStateError); }); }); test( - "closing the event sink causes the stream to close before it emits any " - "more events", () { + 'closing the event sink causes the stream to close before it emits any ' + 'more events', () { streamController.add(1); streamController.add(2); streamController.add(3); @@ -58,7 +58,7 @@ void main() { completes); }); - test("after the stream closes, the sink ignores events", () async { + test('after the stream closes, the sink ignores events', () async { unawaited(streamController.close()); // Wait for the done event to be delivered. @@ -105,12 +105,12 @@ void main() { await pumpEventQueue(); }); - test("forwards errors to the other endpoint", () { - channel.sink.addError("error"); - expect(sinkController.stream.first, throwsA("error")); + test('forwards errors to the other endpoint', () { + channel.sink.addError('error'); + expect(sinkController.stream.first, throwsA('error')); }); - test("Sink.done completes once the stream is done", () { + test('Sink.done completes once the stream is done', () { channel.stream.listen(null); expect(channel.sink.done, completes); streamController.close(); @@ -121,7 +121,7 @@ void main() { expect(channel.sink.close(), completes); expect(() => channel.sink.add(1), throwsStateError); - expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addError('oh no'), throwsStateError); expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); }); @@ -131,7 +131,7 @@ void main() { channel.sink.addStream(controller.stream); expect(() => channel.sink.add(1), throwsStateError); - expect(() => channel.sink.addError("oh no"), throwsStateError); + expect(() => channel.sink.addError('oh no'), throwsStateError); expect(() => channel.sink.addStream(Stream.fromIterable([])), throwsStateError); expect(() => channel.sink.close(), throwsStateError); @@ -139,7 +139,7 @@ void main() { controller.close(); }); - group("with allowSinkErrors: false", () { + group('with allowSinkErrors: false', () { setUp(() { streamController = StreamController(); sinkController = StreamController(); @@ -148,15 +148,15 @@ void main() { allowSinkErrors: false); }); - test("forwards errors to Sink.done but not the stream", () { - channel.sink.addError("oh no"); - expect(channel.sink.done, throwsA("oh no")); + test('forwards errors to Sink.done but not the stream', () { + channel.sink.addError('oh no'); + expect(channel.sink.done, throwsA('oh no')); sinkController.stream .listen(null, onError: expectAsync1((_) {}, count: 0)); }); - test("adding an error causes the stream to emit a done event", () { - expect(channel.sink.done, throwsA("oh no")); + test('adding an error causes the stream to emit a done event', () { + expect(channel.sink.done, throwsA('oh no')); streamController.add(1); streamController.add(2); @@ -165,21 +165,21 @@ void main() { expect( channel.stream .listen(expectAsync1((event) { - if (event == 2) channel.sink.addError("oh no"); + if (event == 2) channel.sink.addError('oh no'); }, count: 2)) .asFuture(), completes); }); - test("adding an error closes the inner sink", () { - channel.sink.addError("oh no"); - expect(channel.sink.done, throwsA("oh no")); + test('adding an error closes the inner sink', () { + channel.sink.addError('oh no'); + expect(channel.sink.done, throwsA('oh no')); expect(sinkController.stream.toList(), completion(isEmpty)); }); test( - "adding an error via via addStream causes the stream to emit a done " - "event", () async { + 'adding an error via via addStream causes the stream to emit a done ' + 'event', () async { var canceled = false; var controller = StreamController(onCancel: () { canceled = true; @@ -188,8 +188,8 @@ void main() { // This future shouldn't get the error, because it's sent to [Sink.done]. expect(channel.sink.addStream(controller.stream), completes); - controller.addError("oh no"); - expect(channel.sink.done, throwsA("oh no")); + controller.addError('oh no'); + expect(channel.sink.done, throwsA('oh no')); await pumpEventQueue(); expect(canceled, isTrue); From 364b71fa00dc3ee711b09d74f74b38c0ea93792a Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 14 Jan 2020 13:35:10 -0800 Subject: [PATCH 077/138] Fix implicit casts (dart-lang/stream_channel#49) - Add some explicit casts. - Cast a `Stream` to `Stream` since we always expect to get a List out. --- pkgs/stream_channel/CHANGELOG.md | 2 +- pkgs/stream_channel/analysis_options.yaml | 2 ++ pkgs/stream_channel/lib/src/multi_channel.dart | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 4f345106a..842129238 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.1.0 +## 2.1.0-dev * Require Dart `2.2.0` or later. diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index df4128a17..b36c8749b 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -1,5 +1,7 @@ include: package:pedantic/analysis_options.yaml analyzer: + strong-mode: + implicit-casts: false # These are errors when building in Google errors: unused_import: error diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index e0982ae19..79f247e08 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -140,8 +140,8 @@ class _MultiChannel extends StreamChannelMixin (message) => _inner.sink.add([0, message]), onDone: () => _closeChannel(0, 0)); - _innerStreamSubscription = _inner.stream.listen((message) { - var id = message[0]; + _innerStreamSubscription = _inner.stream.cast().listen((message) { + var id = message[0] as int; // If the channel was closed before an incoming message was processed, // ignore that message. @@ -156,7 +156,7 @@ class _MultiChannel extends StreamChannelMixin }); if (message.length > 1) { - controller.local.sink.add(message[1]); + controller.local.sink.add(message[1] as T); } else { // A message without data indicates that the channel has been closed. We // can just close the sink here without doing any more cleanup, because From 75f49eee3bd6ecd60d016ee106b38c7a8f9f1415 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 14 Jan 2020 15:11:08 -0800 Subject: [PATCH 078/138] Drop usages of Delegating*.typed (dart-lang/stream_channel#50) --- pkgs/stream_channel/lib/stream_channel.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index c806ec663..56937929a 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -176,5 +176,5 @@ abstract class StreamChannelMixin implements StreamChannel { @override StreamChannel cast() => StreamChannel( - DelegatingStream.typed(stream), DelegatingStreamSink.typed(sink)); + stream.cast(), StreamController(sync: true)..stream.cast().pipe(sink)); } From 8358111d7856a31ac41d98831defd1379c4d43b3 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 18 Mar 2020 13:13:45 -0700 Subject: [PATCH 079/138] Close send channel in test (dart-lang/stream_channel#54) Without closing this channel the VM will not exit. Refactor to `async/await` so that we can close the channel only after receiving the expected items. This allows running the test directly in the VM without the test runner. --- pkgs/stream_channel/test/isolate_channel_test.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index ab70f749b..ec26fb647 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -137,19 +137,21 @@ void main() { connectPort.close(); }); - test('create a connected pair of channels', () { + test('create a connected pair of channels', () async { var channel1 = IsolateChannel.connectReceive(connectPort); var channel2 = IsolateChannel.connectSend(connectPort.sendPort); channel1.sink.add(1); channel1.sink.add(2); channel1.sink.add(3); - expect(channel2.stream.take(3).toList(), completion(equals([1, 2, 3]))); + expect(await channel2.stream.take(3).toList(), equals([1, 2, 3])); channel2.sink.add(4); channel2.sink.add(5); channel2.sink.add(6); - expect(channel1.stream.take(3).toList(), completion(equals([4, 5, 6]))); + expect(await channel1.stream.take(3).toList(), equals([4, 5, 6])); + + await channel2.sink.close(); }); test('the receiving channel produces an error if it gets the wrong message', From eb109aef39742e86328a6d50b763b853484600a4 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 2 Apr 2020 10:25:21 -0700 Subject: [PATCH 080/138] Rewrite doc comment to refer to TypeError (dart-lang/stream_channel#57) This will be the type going forward. Keep a reference to `CastError` for now, we can drop it after a few SDK releases. --- pkgs/stream_channel/lib/stream_channel.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index 56937929a..4722aa39c 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -126,8 +126,9 @@ abstract class StreamChannel { /// Returns a copy of this with the generic type coerced to [S]. /// /// If any events emitted by [stream] aren't of type [S], they're converted - /// into [CastError] events. Similarly, if any events are added to [sink] that - /// aren't of type [S], a [CastError] is thrown. + /// into [TypeError] events (`CastError` on some SDK versions). Similarly, if + /// any events are added to [sink] that aren't of type [S], a [TypeError] is + /// thrown. StreamChannel cast(); } From 1f61afe1f1885427a14a4fc40225382c1844e6a5 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Wed, 15 Jul 2020 18:58:38 -0700 Subject: [PATCH 081/138] Merge the null_safety branch into master (dart-lang/stream_channel#60) --- pkgs/stream_channel/.travis.yml | 17 +--- pkgs/stream_channel/CHANGELOG.md | 4 +- pkgs/stream_channel/analysis_options.yaml | 2 + .../lib/src/close_guarantee_channel.dart | 17 ++-- pkgs/stream_channel/lib/src/disconnector.dart | 12 +-- .../lib/src/guarantee_channel.dart | 23 +++--- .../lib/src/isolate_channel.dart | 2 +- .../lib/src/json_document_transformer.dart | 6 +- .../stream_channel/lib/src/multi_channel.dart | 28 +++---- .../lib/src/stream_channel_completer.dart | 4 +- .../lib/src/stream_channel_controller.dart | 4 +- pkgs/stream_channel/pubspec.yaml | 81 ++++++++++++++++++- .../test/disconnector_test.dart | 8 +- .../test/isolate_channel_test.dart | 8 +- .../test/json_document_transformer_test.dart | 6 +- .../test/multi_channel_test.dart | 22 ++--- .../test/stream_channel_completer_test.dart | 8 +- .../test/stream_channel_controller_test.dart | 4 +- .../test/stream_channel_test.dart | 6 +- .../test/with_close_guarantee_test.dart | 4 +- .../test/with_guarantees_test.dart | 8 +- 21 files changed, 171 insertions(+), 103 deletions(-) diff --git a/pkgs/stream_channel/.travis.yml b/pkgs/stream_channel/.travis.yml index d6a545496..b4907d5d1 100644 --- a/pkgs/stream_channel/.travis.yml +++ b/pkgs/stream_channel/.travis.yml @@ -1,27 +1,16 @@ language: dart dart: -- 2.2.0 - dev dart_task: - test: --platform vm,chrome - -matrix: - include: - # Only validate formatting using the dev release - - dart: dev - dart_task: dartfmt - - dart: dev - dart_task: - dartanalyzer: --fatal-infos --fatal-warnings . - - dart: 2.2.0 - dart_task: - dartanalyzer: --fatal-warnings . +- dartfmt +- dartanalyzer: --fatal-infos --fatal-warnings . # Only building master means that we don't run two builds for each pull request. branches: - only: [master] + only: [master, null_safety] cache: directories: diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 842129238..2c4a13ce6 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,6 +1,6 @@ -## 2.1.0-dev +## 2.1.0-nullsafety -* Require Dart `2.2.0` or later. +* Migrate to null safety. ## 2.0.0 diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index b36c8749b..8a712df8f 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -8,6 +8,8 @@ analyzer: unused_element: error unused_local_variable: error dead_code: error + enable-experiment: + - non-nullable linter: rules: diff --git a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart index 60916d002..25f502235 100644 --- a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart @@ -16,14 +16,14 @@ import '../stream_channel.dart'; class CloseGuaranteeChannel extends StreamChannelMixin { @override Stream get stream => _stream; - _CloseGuaranteeStream _stream; + late final _CloseGuaranteeStream _stream; @override StreamSink get sink => _sink; - _CloseGuaranteeSink _sink; + late final _CloseGuaranteeSink _sink; /// The subscription to the inner stream. - StreamSubscription _subscription; + StreamSubscription? _subscription; /// Whether the sink has closed, causing the underlying channel to disconnect. bool _disconnected = false; @@ -48,8 +48,8 @@ class _CloseGuaranteeStream extends Stream { _CloseGuaranteeStream(this._inner, this._channel); @override - StreamSubscription listen(void Function(T) onData, - {Function onError, void Function() onDone, bool cancelOnError}) { + StreamSubscription listen(void Function(T)? onData, + {Function? onError, void Function()? onDone, bool? cancelOnError}) { // If the channel is already disconnected, we shouldn't dispatch anything // but a done event. if (_channel._disconnected) { @@ -80,10 +80,11 @@ class _CloseGuaranteeSink extends DelegatingStreamSink { Future close() { var done = super.close(); _channel._disconnected = true; - if (_channel._subscription != null) { + var subscription = _channel._subscription; + if (subscription != null) { // Don't dispatch anything but a done event. - _channel._subscription.onData(null); - _channel._subscription.onError(null); + subscription.onData(null); + subscription.onError(null); } return done; } diff --git a/pkgs/stream_channel/lib/src/disconnector.dart b/pkgs/stream_channel/lib/src/disconnector.dart index e8835374f..a424146b8 100644 --- a/pkgs/stream_channel/lib/src/disconnector.dart +++ b/pkgs/stream_channel/lib/src/disconnector.dart @@ -74,11 +74,11 @@ class _DisconnectorSink implements StreamSink { /// The subscription to the stream passed to [addStream], if a stream is /// currently being added. - StreamSubscription _addStreamSubscription; + StreamSubscription? _addStreamSubscription; /// The completer for the future returned by [addStream], if a stream is /// currently being added. - Completer _addStreamCompleter; + Completer? _addStreamCompleter; /// Whether we're currently adding a stream with [addStream]. bool get _inAddStream => _addStreamSubscription != null; @@ -97,7 +97,7 @@ class _DisconnectorSink implements StreamSink { } @override - void addError(error, [StackTrace stackTrace]) { + void addError(error, [StackTrace? stackTrace]) { if (_closed) throw StateError('Cannot add event after closing.'); if (_inAddStream) { throw StateError('Cannot add event while adding stream.'); @@ -117,8 +117,8 @@ class _DisconnectorSink implements StreamSink { _addStreamCompleter = Completer.sync(); _addStreamSubscription = stream.listen(_inner.add, - onError: _inner.addError, onDone: _addStreamCompleter.complete); - return _addStreamCompleter.future.then((_) { + onError: _inner.addError, onDone: _addStreamCompleter!.complete); + return _addStreamCompleter!.future.then((_) { _addStreamCompleter = null; _addStreamSubscription = null; }); @@ -143,7 +143,7 @@ class _DisconnectorSink implements StreamSink { var future = _inner.close(); if (_inAddStream) { - _addStreamCompleter.complete(_addStreamSubscription.cancel()); + _addStreamCompleter!.complete(_addStreamSubscription!.cancel()); _addStreamCompleter = null; _addStreamSubscription = null; } diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart index cfee99ee5..4780b046f 100644 --- a/pkgs/stream_channel/lib/src/guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -17,17 +17,17 @@ class GuaranteeChannel extends StreamChannelMixin { @override StreamSink get sink => _sink; - _GuaranteeSink _sink; + late final _GuaranteeSink _sink; /// The controller for [stream]. /// /// This intermediate controller allows us to continue listening for a done /// event even after the user has canceled their subscription, and to send our /// own done event when the sink is closed. - StreamController _streamController; + late final StreamController _streamController; /// The subscription to the inner stream. - StreamSubscription _subscription; + StreamSubscription? _subscription; /// Whether the sink has closed, causing the underlying channel to disconnect. bool _disconnected = false; @@ -64,7 +64,8 @@ class GuaranteeChannel extends StreamChannelMixin { /// should stop emitting events. void _onSinkDisconnected() { _disconnected = true; - if (_subscription != null) _subscription.cancel(); + var subscription = _subscription; + if (subscription != null) subscription.cancel(); _streamController.close(); } } @@ -95,11 +96,11 @@ class _GuaranteeSink implements StreamSink { /// The subscription to the stream passed to [addStream], if a stream is /// currently being added. - StreamSubscription _addStreamSubscription; + StreamSubscription? _addStreamSubscription; /// The completer for the future returned by [addStream], if a stream is /// currently being added. - Completer _addStreamCompleter; + Completer? _addStreamCompleter; /// Whether we're currently adding a stream with [addStream]. bool get _inAddStream => _addStreamSubscription != null; @@ -125,7 +126,7 @@ class _GuaranteeSink implements StreamSink { } @override - void addError(error, [StackTrace stackTrace]) { + void addError(error, [StackTrace? stackTrace]) { if (_closed) throw StateError('Cannot add event after closing.'); if (_inAddStream) { throw StateError('Cannot add event while adding stream.'); @@ -139,7 +140,7 @@ class _GuaranteeSink implements StreamSink { /// /// This is called from [addStream], so it shouldn't fail if a stream is being /// added. - void _addError(error, [StackTrace stackTrace]) { + void _addError(Object error, [StackTrace? stackTrace]) { if (_allowErrors) { _inner.addError(error, stackTrace); return; @@ -166,8 +167,8 @@ class _GuaranteeSink implements StreamSink { _addStreamCompleter = Completer.sync(); _addStreamSubscription = stream.listen(_inner.add, - onError: _addError, onDone: _addStreamCompleter.complete); - return _addStreamCompleter.future.then((_) { + onError: _addError, onDone: _addStreamCompleter!.complete); + return _addStreamCompleter!.future.then((_) { _addStreamCompleter = null; _addStreamSubscription = null; }); @@ -199,7 +200,7 @@ class _GuaranteeSink implements StreamSink { if (!_doneCompleter.isCompleted) _doneCompleter.complete(); if (!_inAddStream) return; - _addStreamCompleter.complete(_addStreamSubscription.cancel()); + _addStreamCompleter!.complete(_addStreamSubscription!.cancel()); _addStreamCompleter = null; _addStreamSubscription = null; } diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index 8c1b56842..55c98143f 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -51,7 +51,7 @@ class IsolateChannel extends StreamChannelMixin { // The first message across the ReceivePort should be a SendPort pointing to // the remote end. If it's not, we'll make the stream emit an error // complaining. - StreamSubscription subscription; + late StreamSubscription subscription; subscription = receivePort.listen((message) { if (message is SendPort) { var controller = diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index 8bffc8ab9..237193b86 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -18,14 +18,14 @@ import 'stream_channel_transformer.dart'; /// If the transformed channel emits invalid JSON, this emits a /// [FormatException]. If an unencodable object is added to the sink, it /// synchronously throws a [JsonUnsupportedObjectError]. -final StreamChannelTransformer jsonDocument = +final StreamChannelTransformer jsonDocument = const _JsonDocument(); -class _JsonDocument implements StreamChannelTransformer { +class _JsonDocument implements StreamChannelTransformer { const _JsonDocument(); @override - StreamChannel bind(StreamChannel channel) { + StreamChannel bind(StreamChannel channel) { var stream = channel.stream.map(jsonDecode); var sink = StreamSinkTransformer.fromHandlers( handleData: (data, sink) { diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index 79f247e08..e1e25ea04 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -73,7 +73,7 @@ abstract class MultiChannel implements StreamChannel { /// /// Throws an [ArgumentError] if a virtual channel already exists for [id]. /// Throws a [StateError] if the underlying channel is closed. - VirtualChannel virtualChannel([int id]); + VirtualChannel virtualChannel([int? id]); } /// The implementation of [MultiChannel]. @@ -85,10 +85,10 @@ class _MultiChannel extends StreamChannelMixin /// The inner channel over which all communication is conducted. /// /// This will be `null` if the underlying communication channel is closed. - StreamChannel _inner; + StreamChannel? _inner; /// The subscription to [_inner].stream. - StreamSubscription _innerStreamSubscription; + StreamSubscription? _innerStreamSubscription; @override Stream get stream => _mainController.foreign.stream; @@ -132,15 +132,15 @@ class _MultiChannel extends StreamChannelMixin /// it's coming from a channel that was originally created locally. var _nextId = 1; - _MultiChannel(this._inner) { + _MultiChannel(StreamChannel inner) : _inner = inner { // The default connection is a special case which has id 0 on both ends. // This allows it to begin connected without having to send over an id. _controllers[0] = _mainController; _mainController.local.stream.listen( - (message) => _inner.sink.add([0, message]), + (message) => _inner!.sink.add([0, message]), onDone: () => _closeChannel(0, 0)); - _innerStreamSubscription = _inner.stream.cast().listen((message) { + _innerStreamSubscription = _inner!.stream.cast().listen((message) { var id = message[0] as int; // If the channel was closed before an incoming message was processed, @@ -170,7 +170,7 @@ class _MultiChannel extends StreamChannelMixin } @override - VirtualChannel virtualChannel([int id]) { + VirtualChannel virtualChannel([int? id]) { int inputId; int outputId; if (id != null) { @@ -194,11 +194,11 @@ class _MultiChannel extends StreamChannelMixin return VirtualChannel._(this, inputId, Stream.empty(), NullStreamSink()); } - StreamChannelController controller; + late StreamChannelController controller; if (_pendingIds.remove(inputId)) { // If we've already received messages for this channel, use the controller // where those messages are buffered. - controller = _controllers[inputId]; + controller = _controllers[inputId]!; } else if (_controllers.containsKey(inputId) || _closedIds.contains(inputId)) { throw ArgumentError('A virtual channel with id $id already exists.'); @@ -208,7 +208,7 @@ class _MultiChannel extends StreamChannelMixin } controller.local.stream.listen( - (message) => _inner.sink.add([outputId, message]), + (message) => _inner!.sink.add([outputId, message]), onDone: () => _closeChannel(inputId, outputId)); return VirtualChannel._( this, outputId, controller.foreign.stream, controller.foreign.sink); @@ -218,21 +218,21 @@ class _MultiChannel extends StreamChannelMixin /// outgoing messages have [outputId]. void _closeChannel(int inputId, int outputId) { _closedIds.add(inputId); - var controller = _controllers.remove(inputId); + var controller = _controllers.remove(inputId)!; controller.local.sink.close(); if (_inner == null) return; // A message without data indicates that the virtual channel has been // closed. - _inner.sink.add([outputId]); + _inner!.sink.add([outputId]); if (_controllers.isEmpty) _closeInnerChannel(); } /// Closes the underlying communication channel. void _closeInnerChannel() { - _inner.sink.close(); - _innerStreamSubscription.cancel(); + _inner!.sink.close(); + _innerStreamSubscription!.cancel(); _inner = null; // Convert this to a list because the close is dispatched synchronously, and diff --git a/pkgs/stream_channel/lib/src/stream_channel_completer.dart b/pkgs/stream_channel/lib/src/stream_channel_completer.dart index a14ffde44..f6fef25dc 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_completer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_completer.dart @@ -22,7 +22,7 @@ class StreamChannelCompleter { /// The channel for this completer. StreamChannel get channel => _channel; - StreamChannel _channel; + late final StreamChannel _channel; /// Whether [setChannel] has been called. bool _set = false; @@ -66,7 +66,7 @@ class StreamChannelCompleter { /// /// Either [setChannel] or [setError] may be called at most once. Trying to /// call either of them again will fail. - void setError(error, [StackTrace stackTrace]) { + void setError(Object error, [StackTrace? stackTrace]) { if (_set) throw StateError('The channel has already been set.'); _set = true; diff --git a/pkgs/stream_channel/lib/src/stream_channel_controller.dart b/pkgs/stream_channel/lib/src/stream_channel_controller.dart index 136886df7..5c788667d 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_controller.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_controller.dart @@ -33,14 +33,14 @@ class StreamChannelController { /// This channel should be used directly by the creator of this /// [StreamChannelController] to send and receive events. StreamChannel get local => _local; - StreamChannel _local; + late final StreamChannel _local; /// The foreign channel. /// /// This channel should be returned to external users so they can communicate /// with [local]. StreamChannel get foreign => _foreign; - StreamChannel _foreign; + late final StreamChannel _foreign; /// Creates a [StreamChannelController]. /// diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 61e78c0f3..e4208b953 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 2.1.0-dev +version: 2.1.0-nullsafety description: >- An abstraction for two-way communication channels based on the Dart Stream @@ -8,11 +8,86 @@ author: Dart Team homepage: https://github.com/dart-lang/stream_channel environment: - sdk: '>=2.2.0 <3.0.0' + sdk: '>=2.9.0-18.0 <2.9.0' dependencies: - async: '>=1.11.0 <3.0.0' + async: '>=2.5.0-nullsafety <2.5.0' dev_dependencies: pedantic: ^1.8.0 test: ^1.2.0 + +dependency_overrides: + async: + git: + url: git://github.com/dart-lang/async.git + ref: null_safety + boolean_selector: + git: + url: git://github.com/dart-lang/boolean_selector.git + ref: null_safety + charcode: + git: + url: git://github.com/dart-lang/charcode.git + ref: null_safety + collection: 1.15.0-nullsafety + js: + git: + url: git://github.com/dart-lang/sdk.git + path: pkg/js + matcher: + git: + url: git://github.com/dart-lang/matcher.git + ref: null_safety + meta: 1.3.0-nullsafety + path: + git: + url: git://github.com/dart-lang/path.git + ref: null_safety + pedantic: + git: + url: git://github.com/dart-lang/pedantic.git + ref: null_safety + pool: + git: + url: git://github.com/dart-lang/pool.git + ref: null_safety + source_maps: + git: + url: git://github.com/dart-lang/source_maps.git + ref: null_safety + source_map_stack_trace: + git: + url: git://github.com/dart-lang/source_map_stack_trace.git + ref: null_safety + source_span: + git: + url: git://github.com/dart-lang/source_span.git + ref: null_safety + stack_trace: + git: + url: git://github.com/dart-lang/stack_trace.git + ref: null_safety + string_scanner: + git: + url: git://github.com/dart-lang/string_scanner.git + ref: null_safety + term_glyph: + git: + url: git://github.com/dart-lang/term_glyph.git + ref: null_safety + test: + git: + url: git://github.com/dart-lang/test.git + path: pkgs/test + ref: null_safety + test_api: + git: + url: git://github.com/dart-lang/test.git + ref: null_safety + path: pkgs/test_api + test_core: + git: + url: git://github.com/dart-lang/test.git + path: pkgs/test_core + ref: null_safety diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index ec0c64bc0..4f16012bf 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -10,10 +10,10 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - StreamController streamController; - StreamController sinkController; - Disconnector disconnector; - StreamChannel channel; + late StreamController streamController; + late StreamController sinkController; + late Disconnector disconnector; + late StreamChannel channel; setUp(() { streamController = StreamController(); sinkController = StreamController(); diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index ec26fb647..a1ec37eaf 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -13,9 +13,9 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - ReceivePort receivePort; - SendPort sendPort; - StreamChannel channel; + late ReceivePort receivePort; + late SendPort sendPort; + late StreamChannel channel; setUp(() { receivePort = ReceivePort(); var receivePortForSend = ReceivePort(); @@ -128,7 +128,7 @@ void main() { }); group('connect constructors', () { - ReceivePort connectPort; + late ReceivePort connectPort; setUp(() { connectPort = ReceivePort(); }); diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index 3ccce4ead..48d8f7291 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -9,9 +9,9 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - StreamController streamController; - StreamController sinkController; - StreamChannel channel; + late StreamController streamController; + late StreamController sinkController; + late StreamChannel channel; setUp(() { streamController = StreamController(); sinkController = StreamController(); diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index 0fa1df9ea..00bcabe3b 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -7,9 +7,9 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - StreamChannelController controller; - MultiChannel channel1; - MultiChannel channel2; + late StreamChannelController controller; + late MultiChannel channel1; + late MultiChannel channel2; setUp(() { controller = StreamChannelController(); channel1 = MultiChannel(controller.local); @@ -85,8 +85,8 @@ void main() { }); group('a locally-created virtual channel', () { - VirtualChannel virtual1; - VirtualChannel virtual2; + late VirtualChannel virtual1; + late VirtualChannel virtual2; setUp(() { virtual1 = channel1.virtualChannel(); virtual2 = channel2.virtualChannel(virtual1.id); @@ -185,8 +185,8 @@ void main() { }); group('a remotely-created virtual channel', () { - VirtualChannel virtual1; - VirtualChannel virtual2; + late VirtualChannel virtual1; + late VirtualChannel virtual2; setUp(() { virtual1 = channel1.virtualChannel(); virtual2 = channel2.virtualChannel(virtual1.id); @@ -297,8 +297,8 @@ void main() { }); group('when the underlying stream', () { - VirtualChannel virtual1; - VirtualChannel virtual2; + late VirtualChannel virtual1; + late VirtualChannel virtual2; setUp(() { virtual1 = channel1.virtualChannel(); virtual2 = channel2.virtualChannel(virtual1.id); @@ -406,8 +406,8 @@ void main() { }); group('for a virtual channel:', () { - VirtualChannel virtual1; - VirtualChannel virtual2; + late VirtualChannel virtual1; + late VirtualChannel virtual2; setUp(() { virtual1 = channel1.virtualChannel(); virtual2 = channel2.virtualChannel(virtual1.id); diff --git a/pkgs/stream_channel/test/stream_channel_completer_test.dart b/pkgs/stream_channel/test/stream_channel_completer_test.dart index 234f956ef..a87492500 100644 --- a/pkgs/stream_channel/test/stream_channel_completer_test.dart +++ b/pkgs/stream_channel/test/stream_channel_completer_test.dart @@ -9,10 +9,10 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - StreamChannelCompleter completer; - StreamController streamController; - StreamController sinkController; - StreamChannel innerChannel; + late StreamChannelCompleter completer; + late StreamController streamController; + late StreamController sinkController; + late StreamChannel innerChannel; setUp(() { completer = StreamChannelCompleter(); streamController = StreamController(); diff --git a/pkgs/stream_channel/test/stream_channel_controller_test.dart b/pkgs/stream_channel/test/stream_channel_controller_test.dart index 9b7a851d0..3d661e302 100644 --- a/pkgs/stream_channel/test/stream_channel_controller_test.dart +++ b/pkgs/stream_channel/test/stream_channel_controller_test.dart @@ -7,7 +7,7 @@ import 'package:test/test.dart'; void main() { group('asynchronously', () { - StreamChannelController controller; + late StreamChannelController controller; setUp(() { controller = StreamChannelController(); }); @@ -44,7 +44,7 @@ void main() { }); group('synchronously', () { - StreamChannelController controller; + late StreamChannelController controller; setUp(() { controller = StreamChannelController(sync: true); }); diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index 9bd5a86f8..e101d206d 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -11,9 +11,9 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - StreamController streamController; - StreamController sinkController; - StreamChannel channel; + late StreamController streamController; + late StreamController sinkController; + late StreamChannel channel; setUp(() { streamController = StreamController(); sinkController = StreamController(); diff --git a/pkgs/stream_channel/test/with_close_guarantee_test.dart b/pkgs/stream_channel/test/with_close_guarantee_test.dart index 24aef0338..decc2b448 100644 --- a/pkgs/stream_channel/test/with_close_guarantee_test.dart +++ b/pkgs/stream_channel/test/with_close_guarantee_test.dart @@ -17,8 +17,8 @@ final _delaySinkTransformer = StreamSinkTransformer.fromStreamTransformer(_delayTransformer); void main() { - StreamChannelController controller; - StreamChannel channel; + late StreamChannelController controller; + late StreamChannel channel; setUp(() { controller = StreamChannelController(); diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index fa49689af..a19dc58c2 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -9,9 +9,9 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - StreamController streamController; - StreamController sinkController; - StreamChannel channel; + late StreamController streamController; + late StreamController sinkController; + late StreamChannel channel; setUp(() { streamController = StreamController(); sinkController = StreamController(); @@ -152,7 +152,7 @@ void main() { channel.sink.addError('oh no'); expect(channel.sink.done, throwsA('oh no')); sinkController.stream - .listen(null, onError: expectAsync1((_) {}, count: 0)); + .listen(null, onError: expectAsync1((dynamic _) {}, count: 0)); }); test('adding an error causes the stream to emit a done event', () { From e61fb5e430f83db5101a749239d2b4eb214ab8b9 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 21 Jul 2020 19:41:41 -0700 Subject: [PATCH 082/138] update for the 2.10 dev sdk (dart-lang/stream_channel#61) This is in preparation for the actual 2.10 dev sdk release. --- pkgs/stream_channel/.travis.yml | 4 +- pkgs/stream_channel/pubspec.yaml | 76 ++++++++++++-------------------- 2 files changed, 30 insertions(+), 50 deletions(-) diff --git a/pkgs/stream_channel/.travis.yml b/pkgs/stream_channel/.travis.yml index b4907d5d1..176814674 100644 --- a/pkgs/stream_channel/.travis.yml +++ b/pkgs/stream_channel/.travis.yml @@ -1,7 +1,7 @@ language: dart dart: -- dev +- preview/raw/2.10.0-0.2-dev dart_task: - test: --platform vm,chrome @@ -10,7 +10,7 @@ dart_task: # Only building master means that we don't run two builds for each pull request. branches: - only: [master, null_safety] + only: [master] cache: directories: diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index e4208b953..0dc7c9939 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -8,7 +8,8 @@ author: Dart Team homepage: https://github.com/dart-lang/stream_channel environment: - sdk: '>=2.9.0-18.0 <2.9.0' + # This must remain a tight constraint until nnbd is stable + sdk: '>=2.10.0-0 <2.10.0' dependencies: async: '>=2.5.0-nullsafety <2.5.0' @@ -19,75 +20,54 @@ dev_dependencies: dependency_overrides: async: - git: - url: git://github.com/dart-lang/async.git - ref: null_safety + git: git://github.com/dart-lang/async.git boolean_selector: - git: - url: git://github.com/dart-lang/boolean_selector.git - ref: null_safety + git: git://github.com/dart-lang/boolean_selector.git charcode: - git: - url: git://github.com/dart-lang/charcode.git - ref: null_safety - collection: 1.15.0-nullsafety + git: git://github.com/dart-lang/charcode.git + collection: + git: git://github.com/dart-lang/collection.git js: git: url: git://github.com/dart-lang/sdk.git path: pkg/js + ref: 2-10-pkgs matcher: + git: git://github.com/dart-lang/matcher.git + meta: git: - url: git://github.com/dart-lang/matcher.git - ref: null_safety - meta: 1.3.0-nullsafety + url: git://github.com/dart-lang/sdk.git + path: pkg/meta + ref: 2-10-pkgs path: - git: - url: git://github.com/dart-lang/path.git - ref: null_safety + git: git://github.com/dart-lang/path.git pedantic: - git: - url: git://github.com/dart-lang/pedantic.git - ref: null_safety + git: git://github.com/dart-lang/pedantic.git pool: - git: - url: git://github.com/dart-lang/pool.git - ref: null_safety + git: git://github.com/dart-lang/pool.git source_maps: - git: - url: git://github.com/dart-lang/source_maps.git - ref: null_safety + git: git://github.com/dart-lang/source_maps.git source_map_stack_trace: - git: - url: git://github.com/dart-lang/source_map_stack_trace.git - ref: null_safety + git: git://github.com/dart-lang/source_map_stack_trace.git source_span: - git: - url: git://github.com/dart-lang/source_span.git - ref: null_safety + git: git://github.com/dart-lang/source_span.git stack_trace: - git: - url: git://github.com/dart-lang/stack_trace.git - ref: null_safety + git: git://github.com/dart-lang/stack_trace.git string_scanner: - git: - url: git://github.com/dart-lang/string_scanner.git - ref: null_safety + git: git://github.com/dart-lang/string_scanner.git term_glyph: - git: - url: git://github.com/dart-lang/term_glyph.git - ref: null_safety - test: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test - ref: null_safety + git: git://github.com/dart-lang/term_glyph.git test_api: git: url: git://github.com/dart-lang/test.git - ref: null_safety path: pkgs/test_api test_core: git: url: git://github.com/dart-lang/test.git path: pkgs/test_core - ref: null_safety + test: + git: + url: git://github.com/dart-lang/test.git + path: pkgs/test + typed_data: + git: git://github.com/dart-lang/typed_data.git From 83c6c48430414ec2fa110e71eeed0bc7d0d20d49 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 28 Jul 2020 13:47:48 -0700 Subject: [PATCH 083/138] Delete .test_config No longer used --- pkgs/stream_channel/.test_config | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/stream_channel/.test_config diff --git a/pkgs/stream_channel/.test_config b/pkgs/stream_channel/.test_config deleted file mode 100644 index 352d2feee..000000000 --- a/pkgs/stream_channel/.test_config +++ /dev/null @@ -1,3 +0,0 @@ -{ - "test_package": true -} From 729a4c6f74a4b5efcd42a5cdd12182c678486db6 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 28 Jul 2020 14:13:08 -0700 Subject: [PATCH 084/138] Update Travis-CI to use dev channel (dart-lang/stream_channel#62) --- pkgs/stream_channel/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/stream_channel/.travis.yml b/pkgs/stream_channel/.travis.yml index 176814674..be2f29d02 100644 --- a/pkgs/stream_channel/.travis.yml +++ b/pkgs/stream_channel/.travis.yml @@ -1,7 +1,7 @@ language: dart dart: -- preview/raw/2.10.0-0.2-dev +- dev dart_task: - test: --platform vm,chrome From dfc6fd73f92f7fdd4ae327b1f31860c89db16baf Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 30 Jul 2020 10:00:20 -0700 Subject: [PATCH 085/138] Remove the author section from pubspec (dart-lang/stream_channel#63) Resolves a warning from the pub tool that this field is no longer used. --- pkgs/stream_channel/CHANGELOG.md | 2 ++ pkgs/stream_channel/pubspec.yaml | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 2c4a13ce6..98c1e6c29 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.1.0-nullsafety.1-dev + ## 2.1.0-nullsafety * Migrate to null safety. diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 0dc7c9939..5895aee59 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,10 +1,9 @@ name: stream_channel -version: 2.1.0-nullsafety +version: 2.1.0-nullsafety.1-dev description: >- An abstraction for two-way communication channels based on the Dart Stream class. -author: Dart Team homepage: https://github.com/dart-lang/stream_channel environment: From bb724781b640a759fbd7384b978310d1c66e00d2 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 22 Sep 2020 09:17:03 -0700 Subject: [PATCH 086/138] Prepare for the 2.11 dev SDKs (dart-lang/stream_channel#64) Bump the upper bound to allow 2.10 stable and 2.11.0 dev SDK versions. --- pkgs/stream_channel/CHANGELOG.md | 4 +++- pkgs/stream_channel/pubspec.yaml | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 98c1e6c29..83da2abec 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,4 +1,6 @@ -## 2.1.0-nullsafety.1-dev +## 2.1.0-nullsafety.1 + +* Allow 2.10 stable and 2.11.0 dev SDK versions. ## 2.1.0-nullsafety diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 5895aee59..b8f0f97f8 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 2.1.0-nullsafety.1-dev +version: 2.1.0-nullsafety.1 description: >- An abstraction for two-way communication channels based on the Dart Stream @@ -8,7 +8,7 @@ homepage: https://github.com/dart-lang/stream_channel environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.10.0' + sdk: '>=2.10.0-0 <2.11.0' dependencies: async: '>=2.5.0-nullsafety <2.5.0' From 18d7aa816c879f767b5b134a3f92d01413e3b772 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Tue, 20 Oct 2020 16:12:08 -0700 Subject: [PATCH 087/138] Remove unused dart:async import The only members of dart:async used here (Future and/or Stream) are exported from dart:core now. --- pkgs/stream_channel/lib/src/stream_channel_completer.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/stream_channel/lib/src/stream_channel_completer.dart b/pkgs/stream_channel/lib/src/stream_channel_completer.dart index f6fef25dc..5a824c1f3 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_completer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_completer.dart @@ -2,8 +2,6 @@ // 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 'package:async/async.dart'; import '../stream_channel.dart'; From 85fcb605844bd414e433993484864c55cabfdb90 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Fri, 23 Oct 2020 13:10:17 -0700 Subject: [PATCH 088/138] allow the 2.12 prerelease sdks (dart-lang/stream_channel#66) --- pkgs/stream_channel/CHANGELOG.md | 4 +++ pkgs/stream_channel/pubspec.yaml | 62 +++----------------------------- 2 files changed, 8 insertions(+), 58 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 83da2abec..95f370c38 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.0-nullsafety.2 + +* Allow prerelease versions of the 2.12 sdk. + ## 2.1.0-nullsafety.1 * Allow 2.10 stable and 2.11.0 dev SDK versions. diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index b8f0f97f8..9259c34c4 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 2.1.0-nullsafety.1 +version: 2.1.0-nullsafety.2 description: >- An abstraction for two-way communication channels based on the Dart Stream @@ -8,65 +8,11 @@ homepage: https://github.com/dart-lang/stream_channel environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.11.0' + sdk: '>=2.10.0-0 <2.12.0' dependencies: async: '>=2.5.0-nullsafety <2.5.0' dev_dependencies: - pedantic: ^1.8.0 - test: ^1.2.0 - -dependency_overrides: - async: - git: git://github.com/dart-lang/async.git - boolean_selector: - git: git://github.com/dart-lang/boolean_selector.git - charcode: - git: git://github.com/dart-lang/charcode.git - collection: - git: git://github.com/dart-lang/collection.git - js: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/js - ref: 2-10-pkgs - matcher: - git: git://github.com/dart-lang/matcher.git - meta: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/meta - ref: 2-10-pkgs - path: - git: git://github.com/dart-lang/path.git - pedantic: - git: git://github.com/dart-lang/pedantic.git - pool: - git: git://github.com/dart-lang/pool.git - source_maps: - git: git://github.com/dart-lang/source_maps.git - source_map_stack_trace: - git: git://github.com/dart-lang/source_map_stack_trace.git - source_span: - git: git://github.com/dart-lang/source_span.git - stack_trace: - git: git://github.com/dart-lang/stack_trace.git - string_scanner: - git: git://github.com/dart-lang/string_scanner.git - term_glyph: - git: git://github.com/dart-lang/term_glyph.git - test_api: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_api - test_core: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_core - test: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test - typed_data: - git: git://github.com/dart-lang/typed_data.git + pedantic: ^1.10.0-nullsafety + test: ^1.16.0-nullsafety From e8efb13bda913507914d61e0c689ca38465c0d2f Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 3 Nov 2020 14:33:09 -0800 Subject: [PATCH 089/138] Bump SDK constraints for pub (dart-lang/stream_channel#67) Use a 2.12.0 lower bound since pub does not understand allowed experiments for earlier versions. Use a 3.0.0 upper bound to avoid a warning in pub and to give some flexibility in publishing for stable. --- pkgs/stream_channel/CHANGELOG.md | 5 +++++ pkgs/stream_channel/pubspec.yaml | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 95f370c38..ea31ffe2c 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.1.0-nullsafety.3 + +* Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release + guidelines. + ## 2.1.0-nullsafety.2 * Allow prerelease versions of the 2.12 sdk. diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 9259c34c4..d11a3567f 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 2.1.0-nullsafety.2 +version: 2.1.0-nullsafety.3 description: >- An abstraction for two-way communication channels based on the Dart Stream @@ -7,8 +7,7 @@ description: >- homepage: https://github.com/dart-lang/stream_channel environment: - # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.12.0' + sdk: ">=2.12.0-0 <3.0.0" dependencies: async: '>=2.5.0-nullsafety <2.5.0' From 87fb3b0c3eb1c2c6f03dda3d73b659d05a6422a1 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 11 Nov 2020 09:33:06 -0800 Subject: [PATCH 090/138] remove redundant experiment --- pkgs/stream_channel/analysis_options.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index 8a712df8f..b36c8749b 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -8,8 +8,6 @@ analyzer: unused_element: error unused_local_variable: error dead_code: error - enable-experiment: - - non-nullable linter: rules: From f2dcd319ec1efca9d01abd5500436e2cb63e4c53 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Tue, 29 Dec 2020 22:31:22 -0800 Subject: [PATCH 091/138] Remove unnecessary import --- pkgs/stream_channel/lib/src/json_document_transformer.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index 237193b86..3feda43fd 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -7,7 +7,6 @@ import 'dart:convert'; import 'package:async/async.dart'; import '../stream_channel.dart'; -import 'stream_channel_transformer.dart'; /// A [StreamChannelTransformer] that transforms JSON documents—strings that /// contain individual objects encoded as JSON—into decoded Dart objects. From 85a211c9fc11741d70310c39c7142cde5d18db5e Mon Sep 17 00:00:00 2001 From: Alexander Thomas Date: Wed, 20 Jan 2021 16:38:42 +0100 Subject: [PATCH 092/138] Migrate to GitHub Actions (dart-lang/stream_channel#70) * Delete .travis.yml --- .../.github/workflows/test-package.yml | 64 +++++++++++++++++++ pkgs/stream_channel/.travis.yml | 17 ----- 2 files changed, 64 insertions(+), 17 deletions(-) create mode 100644 pkgs/stream_channel/.github/workflows/test-package.yml delete mode 100644 pkgs/stream_channel/.travis.yml diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml new file mode 100644 index 000000000..0a2a87433 --- /dev/null +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -0,0 +1,64 @@ +name: Dart CI + +on: + # Run on PRs and pushes to the default branch. + push: + branches: [ master ] + pull_request: + branches: [ master ] + schedule: + - cron: "0 0 * * 0" + +env: + PUB_ENVIRONMENT: bot.github + +jobs: + # Check code formatting and static analysis on a single OS (linux) + # against Dart dev. + analyze: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Check formatting + run: dart format --output=none --set-exit-if-changed . + if: always() && steps.install.outcome == 'success' + - name: Analyze code + run: dart analyze --fatal-infos + if: always() && steps.install.outcome == 'success' + + # Run tests on a matrix consisting of two dimensions: + # 1. OS: ubuntu-latest, (macos-latest, windows-latest) + # 2. release channel: dev + test: + needs: analyze + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Add macos-latest and/or windows-latest if relevant for this package. + os: [ubuntu-latest] + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Run VM tests + run: dart test --platform vm + if: always() && steps.install.outcome == 'success' + - name: Run Chrome tests + run: dart test --platform chrome + if: always() && steps.install.outcome == 'success' diff --git a/pkgs/stream_channel/.travis.yml b/pkgs/stream_channel/.travis.yml deleted file mode 100644 index be2f29d02..000000000 --- a/pkgs/stream_channel/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: dart - -dart: -- dev - -dart_task: -- test: --platform vm,chrome -- dartfmt -- dartanalyzer: --fatal-infos --fatal-warnings . - -# Only building master means that we don't run two builds for each pull request. -branches: - only: [master] - -cache: - directories: - - $HOME/.pub-cache From 8fff9b57e1dc76c9503d15f322da041f651e68a0 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 2 Feb 2021 11:20:18 -0800 Subject: [PATCH 093/138] Revert "Remove unnecessary import" (dart-lang/stream_channel#71) This reverts commit f2dcd319ec1efca9d01abd5500436e2cb63e4c53. Since this has not been published or rolled through to the SDK or Flutter we will hold it back to reduce risk. --- pkgs/stream_channel/lib/src/json_document_transformer.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index 3feda43fd..237193b86 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -7,6 +7,7 @@ import 'dart:convert'; import 'package:async/async.dart'; import '../stream_channel.dart'; +import 'stream_channel_transformer.dart'; /// A [StreamChannelTransformer] that transforms JSON documents—strings that /// contain individual objects encoded as JSON—into decoded Dart objects. From f114ba87d21f5259bd413edb4dffa4f8728cae7b Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 2 Feb 2021 13:31:22 -0800 Subject: [PATCH 094/138] Prepare to publish for stable null safety (dart-lang/stream_channel#72) --- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index ea31ffe2c..2bb6c1f26 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.0 + +* Stable release for null safety. + ## 2.1.0-nullsafety.3 * Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index d11a3567f..e7f6c7a7c 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 2.1.0-nullsafety.3 +version: 2.1.0 description: >- An abstraction for two-way communication channels based on the Dart Stream @@ -10,7 +10,7 @@ environment: sdk: ">=2.12.0-0 <3.0.0" dependencies: - async: '>=2.5.0-nullsafety <2.5.0' + async: ^2.5.0 dev_dependencies: pedantic: ^1.10.0-nullsafety From 2cb754777407c53b3a608f0c87df6645d7f77592 Mon Sep 17 00:00:00 2001 From: Franklin Yow <58489007+franklinyow@users.noreply.github.com> Date: Wed, 31 Mar 2021 15:12:05 -0700 Subject: [PATCH 095/138] Update LICENSE Changes to comply to internal review --- pkgs/stream_channel/LICENSE | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/LICENSE b/pkgs/stream_channel/LICENSE index de31e1a0a..dbd2843a0 100644 --- a/pkgs/stream_channel/LICENSE +++ b/pkgs/stream_channel/LICENSE @@ -1,4 +1,5 @@ -Copyright 2015, the Dart project authors. All rights reserved. +Copyright 2015, the Dart project authors. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -9,7 +10,7 @@ met: copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. From 242cca39e056cbb009a7f28bdca1d8457f811b4a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 24 May 2021 10:44:22 -0700 Subject: [PATCH 096/138] Remove unneeded imports (dart-lang/stream_channel#74) All cleanup null-safety bits from pubspec --- pkgs/stream_channel/lib/src/json_document_transformer.dart | 1 - pkgs/stream_channel/pubspec.yaml | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pkgs/stream_channel/lib/src/json_document_transformer.dart b/pkgs/stream_channel/lib/src/json_document_transformer.dart index 237193b86..3feda43fd 100644 --- a/pkgs/stream_channel/lib/src/json_document_transformer.dart +++ b/pkgs/stream_channel/lib/src/json_document_transformer.dart @@ -7,7 +7,6 @@ import 'dart:convert'; import 'package:async/async.dart'; import '../stream_channel.dart'; -import 'stream_channel_transformer.dart'; /// A [StreamChannelTransformer] that transforms JSON documents—strings that /// contain individual objects encoded as JSON—into decoded Dart objects. diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index e7f6c7a7c..d4a717361 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -7,11 +7,11 @@ description: >- homepage: https://github.com/dart-lang/stream_channel environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: async: ^2.5.0 dev_dependencies: - pedantic: ^1.10.0-nullsafety - test: ^1.16.0-nullsafety + pedantic: ^1.10.0 + test: ^1.16.0 From da7d979f2c3dc1d7262c5d10d0e3960bc0fbd6c5 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sat, 5 Jun 2021 12:55:29 -0700 Subject: [PATCH 097/138] add dependabot --- pkgs/stream_channel/.github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 pkgs/stream_channel/.github/dependabot.yml diff --git a/pkgs/stream_channel/.github/dependabot.yml b/pkgs/stream_channel/.github/dependabot.yml new file mode 100644 index 000000000..430a85e7d --- /dev/null +++ b/pkgs/stream_channel/.github/dependabot.yml @@ -0,0 +1,11 @@ +# Set update schedule for GitHub Actions +# See https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot + +version: 2 +updates: + +- package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every weekday + interval: "daily" From 2c5c7e9b563e3013b30d63fc6ff257f551dd8b97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Jun 2021 13:41:09 -0700 Subject: [PATCH 098/138] Bump dart-lang/setup-dart from 0.3 to 1 (dart-lang/stream_channel#75) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 0.3 to 1. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/v0.3...v1) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kevin Moore --- pkgs/stream_channel/.github/workflows/test-package.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 0a2a87433..bd93fbed8 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} - id: install @@ -47,10 +47,10 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [dev] + sdk: [2.12.0, dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} - id: install From 1996879bda283a1a6672277525046ba54342ec0a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 11 Nov 2021 14:14:13 -0800 Subject: [PATCH 099/138] Migrate to pkg:lints recommended (dart-lang/stream_channel#76) * Migrate to pkg:lints recommended * require dart 2.13, drop prerelease changelog entries --- .../.github/workflows/test-package.yml | 2 +- pkgs/stream_channel/CHANGELOG.md | 21 ++++--------------- pkgs/stream_channel/analysis_options.yaml | 10 +++++---- pkgs/stream_channel/pubspec.yaml | 6 +++--- .../test/disconnector_test.dart | 1 - .../test/isolate_channel_test.dart | 2 -- .../test/multi_channel_test.dart | 3 ++- .../test/stream_channel_completer_test.dart | 1 - .../test/stream_channel_test.dart | 1 - .../test/with_close_guarantee_test.dart | 1 - .../test/with_guarantees_test.dart | 1 - 11 files changed, 16 insertions(+), 33 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index bd93fbed8..17c7d20d2 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.12.0, dev] + sdk: [2.14.0, dev] steps: - uses: actions/checkout@v2 - uses: dart-lang/setup-dart@v1 diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 2bb6c1f26..89736d95f 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,23 +1,10 @@ -## 2.1.0 - -* Stable release for null safety. - -## 2.1.0-nullsafety.3 - -* Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release - guidelines. +## 2.1.1-dev -## 2.1.0-nullsafety.2 +* Require Dart 2.14 -* Allow prerelease versions of the 2.12 sdk. - -## 2.1.0-nullsafety.1 - -* Allow 2.10 stable and 2.11.0 dev SDK versions. - -## 2.1.0-nullsafety +## 2.1.0 -* Migrate to null safety. +* Stable release for null safety. ## 2.0.0 diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index b36c8749b..8465834c4 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -1,4 +1,5 @@ -include: package:pedantic/analysis_options.yaml +include: package:lints/recommended.yaml + analyzer: strong-mode: implicit-casts: false @@ -11,7 +12,8 @@ analyzer: linter: rules: - - annotate_overrides - comment_references - - prefer_generic_function_type_aliases - - prefer_typing_uninitialized_variables + - always_declare_return_types + - omit_local_variable_types + - prefer_single_quotes + - unawaited_futures diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index d4a717361..17948bcfa 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 2.1.0 +version: 2.1.1-dev description: >- An abstraction for two-way communication channels based on the Dart Stream @@ -7,11 +7,11 @@ description: >- homepage: https://github.com/dart-lang/stream_channel environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.14.0 <3.0.0' dependencies: async: ^2.5.0 dev_dependencies: - pedantic: ^1.10.0 + lints: ^1.0.0 test: ^1.16.0 diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index 4f16012bf..66773b59c 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'package:async/async.dart'; -import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index a1ec37eaf..a754421a9 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -3,11 +3,9 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('vm') - import 'dart:async'; import 'dart:isolate'; -import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/isolate_channel.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index 00bcabe3b..763e6b829 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -2,7 +2,8 @@ // 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:pedantic/pedantic.dart'; +import 'dart:async'; + import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; diff --git a/pkgs/stream_channel/test/stream_channel_completer_test.dart b/pkgs/stream_channel/test/stream_channel_completer_test.dart index a87492500..22db01a76 100644 --- a/pkgs/stream_channel/test/stream_channel_completer_test.dart +++ b/pkgs/stream_channel/test/stream_channel_completer_test.dart @@ -4,7 +4,6 @@ import 'dart:async'; -import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index e101d206d..76edbdf91 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'dart:convert'; import 'package:async/async.dart'; -import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; diff --git a/pkgs/stream_channel/test/with_close_guarantee_test.dart b/pkgs/stream_channel/test/with_close_guarantee_test.dart index decc2b448..a18f09fe1 100644 --- a/pkgs/stream_channel/test/with_close_guarantee_test.dart +++ b/pkgs/stream_channel/test/with_close_guarantee_test.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'package:async/async.dart'; -import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index a19dc58c2..849e30491 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -4,7 +4,6 @@ import 'dart:async'; -import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; From 8ebfdaecdabae533af70a6f19391cd08b3faac57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Mar 2022 11:15:55 -0800 Subject: [PATCH 100/138] Bump actions/checkout from 2 to 3 (dart-lang/stream_channel#78) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 17c7d20d2..9de6d54aa 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.14.0, dev] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} From 3ec468e3536cb3f000aa6c9ec57d2c919740b3c0 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 3 May 2022 20:08:41 +0000 Subject: [PATCH 101/138] populate the pubspec repository field --- pkgs/stream_channel/CHANGELOG.md | 2 ++ pkgs/stream_channel/README.md | 4 ++++ pkgs/stream_channel/pubspec.yaml | 3 +-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 89736d95f..0f8da1548 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,6 +1,8 @@ ## 2.1.1-dev * Require Dart 2.14 +* Migrate to `package:lints`. +* Populate the pubspec `repository` field. ## 2.1.0 diff --git a/pkgs/stream_channel/README.md b/pkgs/stream_channel/README.md index 2ec970b8e..ae1ea219d 100644 --- a/pkgs/stream_channel/README.md +++ b/pkgs/stream_channel/README.md @@ -1,3 +1,7 @@ +[![Dart CI](https://github.com/dart-lang/stream_channel/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/stream_channel/actions/workflows/test-package.yml) +[![pub package](https://img.shields.io/pub/v/stream_channel.svg)](https://pub.dev/packages/stream_channel) +[![package publisher](https://img.shields.io/pub/publisher/stream_channel.svg)](https://pub.dev/packages/stream_channel/publisher) + This package exposes the `StreamChannel` interface, which represents a two-way communication channel. Each `StreamChannel` exposes a `Stream` for receiving data and a `StreamSink` for sending it. diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 17948bcfa..5e86fc3eb 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,10 +1,9 @@ name: stream_channel version: 2.1.1-dev - description: >- An abstraction for two-way communication channels based on the Dart Stream class. -homepage: https://github.com/dart-lang/stream_channel +repository: https://github.com/dart-lang/stream_channel environment: sdk: '>=2.14.0 <3.0.0' From 1183418e47c1d28dfa3c5db6f466910cd7c1c87a Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 20 Sep 2022 12:16:54 -0700 Subject: [PATCH 102/138] Handle non-int multichannel message IDs (dart-lang/stream_channel#80) When running in wasm, a number in a `List` will be parsed as a `double`. On the web the `as int` cast succeeds, but in dart2wasm it fails. Cast to `num` and use `toInt()` to more reliably get an `int` value. --- pkgs/stream_channel/CHANGELOG.md | 3 +++ pkgs/stream_channel/lib/src/multi_channel.dart | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 0f8da1548..badeaf737 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -3,6 +3,9 @@ * Require Dart 2.14 * Migrate to `package:lints`. * Populate the pubspec `repository` field. +* Handle multichannel messages where the ID element is a `double` at runtime + instead of an `int`. When reading an array with `dart2wasm` numbers within the + array are parsed as `double`. ## 2.1.0 diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index e1e25ea04..a78ddbcf4 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -141,7 +141,7 @@ class _MultiChannel extends StreamChannelMixin onDone: () => _closeChannel(0, 0)); _innerStreamSubscription = _inner!.stream.cast().listen((message) { - var id = message[0] as int; + var id = (message[0] as num).toInt(); // If the channel was closed before an incoming message was processed, // ignore that message. From 5ad2e2ddf016f54053ea5b7cf880e4d2ac8a4181 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 21 Sep 2022 12:31:46 -0700 Subject: [PATCH 103/138] Prepare to publish (dart-lang/stream_channel#81) Drop changelog entry for non-user-facing change. Drop `-dev` suffix from version. --- pkgs/stream_channel/CHANGELOG.md | 3 +-- pkgs/stream_channel/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index badeaf737..2b90a0a76 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,7 +1,6 @@ -## 2.1.1-dev +## 2.1.1 * Require Dart 2.14 -* Migrate to `package:lints`. * Populate the pubspec `repository` field. * Handle multichannel messages where the ID element is a `double` at runtime instead of an `int`. When reading an array with `dart2wasm` numbers within the diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 5e86fc3eb..ff6a50c68 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 2.1.1-dev +version: 2.1.1 description: >- An abstraction for two-way communication channels based on the Dart Stream class. From 34bf35867217b0df4afde8e5e47b1b9547777dbd Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 10 Nov 2022 03:30:31 -0800 Subject: [PATCH 104/138] blast_repo fixes (dart-lang/stream_channel#82) Dependabot GitHub Action --- pkgs/stream_channel/.github/dependabot.yml | 16 +++++++--------- .../.github/workflows/test-package.yml | 8 ++++---- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/pkgs/stream_channel/.github/dependabot.yml b/pkgs/stream_channel/.github/dependabot.yml index 430a85e7d..1603cdd9e 100644 --- a/pkgs/stream_channel/.github/dependabot.yml +++ b/pkgs/stream_channel/.github/dependabot.yml @@ -1,11 +1,9 @@ -# Set update schedule for GitHub Actions -# See https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot - +# Dependabot configuration file. +# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates version: 2 -updates: -- package-ecosystem: "github-actions" - directory: "/" - schedule: - # Check for updates to GitHub Actions every weekday - interval: "daily" +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 9de6d54aa..4e2ee9d50 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@v3 - - uses: dart-lang/setup-dart@v1 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install @@ -49,8 +49,8 @@ jobs: os: [ubuntu-latest] sdk: [2.14.0, dev] steps: - - uses: actions/checkout@v3 - - uses: dart-lang/setup-dart@v1 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install From d31e1c8b97298fd02144157d2d771165b264a89d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jan 2023 13:04:28 -0800 Subject: [PATCH 105/138] Bump actions/checkout from 3.1.0 to 3.2.0 (dart-lang/stream_channel#83) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8...755da8c3cf115ac066823e79a1e1788f8940201b) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 4e2ee9d50..9c93ba998 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.14.0, dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} From 1e06bc994c9e3d98779e6d25b212da9aa7d65986 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Mon, 9 Jan 2023 21:31:41 -0800 Subject: [PATCH 106/138] Migrate from no-implicit-casts to strict-casts (dart-lang/stream_channel#84) --- pkgs/stream_channel/analysis_options.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index 8465834c4..517b5976f 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -1,8 +1,8 @@ include: package:lints/recommended.yaml analyzer: - strong-mode: - implicit-casts: false + language: + strict-casts: true # These are errors when building in Google errors: unused_import: error From 4a851418acb026f4c1ccde05a04e58017429ceac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Jan 2023 21:54:55 -0800 Subject: [PATCH 107/138] Bump actions/checkout from 3.2.0 to 3.3.0 (dart-lang/stream_channel#86) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/755da8c3cf115ac066823e79a1e1788f8940201b...ac593985615ec2ede58e132d2e21d2b1cbd6127c) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 9c93ba998..bdfd06d55 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.14.0, dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} From b4ae743353e14fcc238ee94042dd497f5d61b185 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Jan 2023 23:37:09 -0800 Subject: [PATCH 108/138] Bump dart-lang/setup-dart from 1.3 to 1.4 (dart-lang/stream_channel#85) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.3 to 1.4. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/6a218f2413a3e78e9087f638a238f6b40893203d...a57a6c04cf7d4840e88432aad6281d1e125f0d46) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index bdfd06d55..8c8f4ab69 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.14.0, dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install From 865feb6c88be01d025234f8e0b43699d8fdf2e75 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 28 Feb 2023 10:01:30 -0800 Subject: [PATCH 109/138] move to pkg:dart_flutter_team_lints lints, fix code, bump min SDK (dart-lang/stream_channel#87) --- .../.github/workflows/test-package.yml | 2 +- pkgs/stream_channel/CHANGELOG.md | 4 ++++ pkgs/stream_channel/analysis_options.yaml | 9 ++------- .../lib/src/close_guarantee_channel.dart | 4 ++-- pkgs/stream_channel/lib/src/disconnector.dart | 2 +- pkgs/stream_channel/lib/src/guarantee_channel.dart | 4 ++-- pkgs/stream_channel/lib/src/multi_channel.dart | 4 ++-- pkgs/stream_channel/lib/stream_channel.dart | 6 +++--- pkgs/stream_channel/pubspec.yaml | 6 +++--- pkgs/stream_channel/test/disconnector_test.dart | 2 +- pkgs/stream_channel/test/isolate_channel_test.dart | 2 ++ pkgs/stream_channel/test/multi_channel_test.dart | 14 ++++++++------ 12 files changed, 31 insertions(+), 28 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 8c8f4ab69..20b28dece 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.14.0, dev] + sdk: [2.19.0, dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 2b90a0a76..0d7382839 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.2-dev + +* Require Dart 2.19 + ## 2.1.1 * Require Dart 2.14 diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index 517b5976f..8e5d4a792 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -1,14 +1,8 @@ -include: package:lints/recommended.yaml +include: package:dart_flutter_team_lints/analysis_options.yaml analyzer: language: strict-casts: true - # These are errors when building in Google - errors: - unused_import: error - unused_element: error - unused_local_variable: error - dead_code: error linter: rules: @@ -17,3 +11,4 @@ linter: - omit_local_variable_types - prefer_single_quotes - unawaited_futures + - use_super_parameters diff --git a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart index 25f502235..13432d17d 100644 --- a/pkgs/stream_channel/lib/src/close_guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/close_guarantee_channel.dart @@ -12,7 +12,7 @@ import '../stream_channel.dart'; /// that closing the sink causes the stream to close before it emits any more /// events /// -/// This is exposed via [new StreamChannel.withCloseGuarantee]. +/// This is exposed via [StreamChannel.withCloseGuarantee]. class CloseGuaranteeChannel extends StreamChannelMixin { @override Stream get stream => _stream; @@ -74,7 +74,7 @@ class _CloseGuaranteeSink extends DelegatingStreamSink { /// The [CloseGuaranteeChannel] this belongs to. final CloseGuaranteeChannel _channel; - _CloseGuaranteeSink(StreamSink inner, this._channel) : super(inner); + _CloseGuaranteeSink(super.inner, this._channel); @override Future close() { diff --git a/pkgs/stream_channel/lib/src/disconnector.dart b/pkgs/stream_channel/lib/src/disconnector.dart index a424146b8..61969cbf8 100644 --- a/pkgs/stream_channel/lib/src/disconnector.dart +++ b/pkgs/stream_channel/lib/src/disconnector.dart @@ -97,7 +97,7 @@ class _DisconnectorSink implements StreamSink { } @override - void addError(error, [StackTrace? stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { if (_closed) throw StateError('Cannot add event after closing.'); if (_inAddStream) { throw StateError('Cannot add event while adding stream.'); diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart index 4780b046f..2aa8b7b97 100644 --- a/pkgs/stream_channel/lib/src/guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -10,7 +10,7 @@ import '../stream_channel.dart'; /// A [StreamChannel] that enforces the stream channel guarantees. /// -/// This is exposed via [new StreamChannel.withGuarantees]. +/// This is exposed via [StreamChannel.withGuarantees]. class GuaranteeChannel extends StreamChannelMixin { @override Stream get stream => _streamController.stream; @@ -126,7 +126,7 @@ class _GuaranteeSink implements StreamSink { } @override - void addError(error, [StackTrace? stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { if (_closed) throw StateError('Cannot add event after closing.'); if (_inAddStream) { throw StateError('Cannot add event while adding stream.'); diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index a78ddbcf4..82f59c7c9 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -237,7 +237,7 @@ class _MultiChannel extends StreamChannelMixin // Convert this to a list because the close is dispatched synchronously, and // that could conceivably remove a controller from [_controllers]. - for (var controller in List.from(_controllers.values)) { + for (var controller in _controllers.values.toList(growable: false)) { controller.local.sink.close(); } _controllers.clear(); @@ -269,5 +269,5 @@ class VirtualChannel extends StreamChannelMixin VirtualChannel._(this._parent, this.id, this.stream, this.sink); @override - VirtualChannel virtualChannel([id]) => _parent.virtualChannel(id); + VirtualChannel virtualChannel([int? id]) => _parent.virtualChannel(id); } diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart index 4722aa39c..85f9a9755 100644 --- a/pkgs/stream_channel/lib/stream_channel.dart +++ b/pkgs/stream_channel/lib/stream_channel.dart @@ -6,8 +6,8 @@ import 'dart:async'; import 'package:async/async.dart'; -import 'src/guarantee_channel.dart'; import 'src/close_guarantee_channel.dart'; +import 'src/guarantee_channel.dart'; import 'src/stream_channel_transformer.dart'; export 'src/delegating_stream_channel.dart'; @@ -75,9 +75,9 @@ abstract class StreamChannel { /// Creates a new [StreamChannel] that communicates over [stream] and [sink]. /// - /// Unlike [new StreamChannel], this enforces the guarantees listed in the + /// Unlike [StreamChannel.new], this enforces the guarantees listed in the /// [StreamChannel] documentation. This makes it somewhat less efficient than - /// just wrapping a stream and a sink directly, so [new StreamChannel] should + /// just wrapping a stream and a sink directly, so [StreamChannel.new] should /// be used when the guarantees are provided natively. /// /// If [allowSinkErrors] is `false`, errors are not allowed to be passed to diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index ff6a50c68..5eb57ae41 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,16 +1,16 @@ name: stream_channel -version: 2.1.1 +version: 2.1.2-dev description: >- An abstraction for two-way communication channels based on the Dart Stream class. repository: https://github.com/dart-lang/stream_channel environment: - sdk: '>=2.14.0 <3.0.0' + sdk: '>=2.19.0 <3.0.0' dependencies: async: ^2.5.0 dev_dependencies: - lints: ^1.0.0 + dart_flutter_team_lints: ^1.0.0 test: ^1.16.0 diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index 66773b59c..28f3fee9a 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -142,7 +142,7 @@ class _CloseCompleterSink extends DelegatingStreamSink { /// The completer for the future returned by [close]. final completer = Completer(); - _CloseCompleterSink(StreamSink inner) : super(inner); + _CloseCompleterSink(super.inner); @override Future close() { diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index a754421a9..1850664cf 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -3,6 +3,8 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('vm') +library; + import 'dart:async'; import 'dart:isolate'; diff --git a/pkgs/stream_channel/test/multi_channel_test.dart b/pkgs/stream_channel/test/multi_channel_test.dart index 763e6b829..ee6f8d2a1 100644 --- a/pkgs/stream_channel/test/multi_channel_test.dart +++ b/pkgs/stream_channel/test/multi_channel_test.dart @@ -348,8 +348,8 @@ void main() { group('stream channel rules', () { group('for the main stream:', () { test( - 'closing the sink causes the stream to close before it emits any more ' - 'events', () { + 'closing the sink causes the stream to close before it emits any ' + 'more events', () { channel1.sink.add(1); channel1.sink.add(2); channel1.sink.add(3); @@ -370,7 +370,8 @@ void main() { channel2.sink.add(3); unawaited(channel2.sink.close()); - // None of our channel.sink additions should make it to the other endpoint. + // None of our channel.sink additions should make it to the other + // endpoint. channel1.stream.listen(expectAsync1((_) {}, count: 0)); await pumpEventQueue(); }); @@ -415,8 +416,8 @@ void main() { }); test( - 'closing the sink causes the stream to close before it emits any more ' - 'events', () { + 'closing the sink causes the stream to close before it emits any ' + 'more events', () { virtual1.sink.add(1); virtual1.sink.add(2); virtual1.sink.add(3); @@ -437,7 +438,8 @@ void main() { virtual2.sink.add(3); unawaited(virtual2.sink.close()); - // None of our virtual.sink additions should make it to the other endpoint. + // None of our virtual.sink additions should make it to the other + // endpoint. virtual1.stream.listen(expectAsync1((_) {}, count: 0)); await pumpEventQueue(); }); From a831fcbdbd7841a42d9d9872f705715e7797014c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Apr 2023 19:52:45 -0700 Subject: [PATCH 110/138] Bump actions/checkout from 3.3.0 to 3.5.0 (dart-lang/stream_channel#89) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.5.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/ac593985615ec2ede58e132d2e21d2b1cbd6127c...8f4b7f84864484a7bf31766abe9204da3cbe65b3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 20b28dece..772d53beb 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.19.0, dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} From 871b223fe6c6f33594240c8942bfae7d436fc42c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 14:30:31 -0700 Subject: [PATCH 111/138] Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (dart-lang/stream_channel#88) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/a57a6c04cf7d4840e88432aad6281d1e125f0d46...d6a63dab3335f427404425de0fbfed4686d93c4f) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 772d53beb..763267350 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.19.0, dev] steps: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install From 73f5b89bbbbae25455d7b366c7386063415d25f9 Mon Sep 17 00:00:00 2001 From: Tobe Osakwe Date: Tue, 11 Apr 2023 15:50:57 -0700 Subject: [PATCH 112/138] Add example/example.dart (dart-lang/stream_channel#52) --- pkgs/stream_channel/CHANGELOG.md | 1 + pkgs/stream_channel/example/example.dart | 110 +++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 pkgs/stream_channel/example/example.dart diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 0d7382839..893218875 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,6 +1,7 @@ ## 2.1.2-dev * Require Dart 2.19 +* Add an example. ## 2.1.1 diff --git a/pkgs/stream_channel/example/example.dart b/pkgs/stream_channel/example/example.dart new file mode 100644 index 000000000..dd16f6750 --- /dev/null +++ b/pkgs/stream_channel/example/example.dart @@ -0,0 +1,110 @@ +// Copyright (c) 2023, 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 'dart:io'; +import 'dart:isolate'; + +import 'package:stream_channel/isolate_channel.dart'; +import 'package:stream_channel/stream_channel.dart'; + +Future main() async { + // A StreamChannel, is in simplest terms, a wrapper around a Stream and + // a StreamSink. For example, you can create a channel that wraps standard + // IO: + var stdioChannel = StreamChannel(stdin, stdout); + stdioChannel.sink.add('Hello!\n'.codeUnits); + + // Like a Stream can be transformed with a StreamTransformer, a + // StreamChannel can be transformed with a StreamChannelTransformer. + // For example, we can handle standard input as strings: + var stringChannel = stdioChannel + .transform(StreamChannelTransformer.fromCodec(utf8)) + .transformStream(LineSplitter()); + stringChannel.sink.add('world!\n'); + + // You can implement StreamChannel by extending StreamChannelMixin, but + // it's much easier to use a StreamChannelController. A controller has two + // StreamChannel members: `local` and `foreign`. The creator of a + // controller should work with the `local` channel, while the recipient should + // work with the `foreign` channel, and usually will not have direct access to + // the underlying controller. + var ctrl = StreamChannelController(); + ctrl.local.stream.listen((event) { + // Do something useful here... + }); + + // You can also pipe events from one channel to another. + ctrl + ..foreign.pipe(stringChannel) + ..local.sink.add('Piped!\n'); + await ctrl.local.sink.close(); + + // The StreamChannel interface provides several guarantees, which can be + // found here: + // https://pub.dev/documentation/stream_channel/latest/stream_channel/StreamChannel-class.html + // + // By calling `StreamChannel.withGuarantees()`, you can create a + // StreamChannel that provides all guarantees. + var dummyCtrl0 = StreamChannelController(); + var guaranteedChannel = StreamChannel.withGuarantees( + dummyCtrl0.foreign.stream, dummyCtrl0.foreign.sink); + + // To close a StreamChannel, use `sink.close()`. + await guaranteedChannel.sink.close(); + + // A MultiChannel multiplexes multiple virtual channels across a single + // underlying transport layer. For example, an application listening over + // standard I/O can still support multiple clients if it has a mechanism to + // separate events from different clients. + // + // A MultiChannel splits events into numbered channels, which are + // instances of VirtualChannel. + var dummyCtrl1 = StreamChannelController(); + var multiChannel = MultiChannel(dummyCtrl1.foreign); + var channel1 = multiChannel.virtualChannel(); + await multiChannel.sink.close(); + + // The client/peer should also create its own MultiChannel, connected to + // the underlying transport, use the corresponding ID's to handle events in + // their respective channels. It is up to you how to communicate channel ID's + // across different endpoints. + var dummyCtrl2 = StreamChannelController(); + var multiChannel2 = MultiChannel(dummyCtrl2.foreign); + var channel2 = multiChannel2.virtualChannel(channel1.id); + await channel2.sink.close(); + await multiChannel2.sink.close(); + + // Multiple instances of a Dart application can communicate easily across + // `SendPort`/`ReceivePort` pairs by means of the `IsolateChannel` class. + // Typically, one endpoint will create a `ReceivePort`, and call the + // `IsolateChannel.connectReceive` constructor. The other endpoint will be + // given the corresponding `SendPort`, and then call + // `IsolateChannel.connectSend`. + var recv = ReceivePort(); + var recvChannel = IsolateChannel.connectReceive(recv); + var sendChannel = IsolateChannel.connectSend(recv.sendPort); + + // You must manually close `IsolateChannel` sinks, however. + await recvChannel.sink.close(); + await sendChannel.sink.close(); + + // You can use the `Disconnector` transformer to cause a channel to act as + // though the remote end of its transport had disconnected. + var disconnector = Disconnector(); + var disconnectable = stringChannel.transform(disconnector); + disconnectable.sink.add('Still connected!'); + await disconnector.disconnect(); + + // Additionally: + // * The `DelegatingStreamController` class can be extended to build a + // basis for wrapping other `StreamChannel` objects. + // * The `jsonDocument` transformer converts events to/from JSON, using + // the `json` codec from `dart:convert`. + // * `package:json_rpc_2` directly builds on top of + // `package:stream_channel`, so any compatible transport can be used to + // create interactive client/server or peer-to-peer applications (i.e. + // language servers, microservices, etc. +} From 28c22df54e650925a904612e7341c255e9188000 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 12:30:00 -0700 Subject: [PATCH 113/138] Bump actions/checkout from 3.5.0 to 3.5.2 (dart-lang/stream_channel#90) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/8f4b7f84864484a7bf31766abe9204da3cbe65b3...8e5e7e5ab8b370d6c329ec480221332ada57f0ab) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 763267350..0874bdd38 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.19.0, dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From eedb3691c7fc61e5899c8e3cabc005dee069bf8e Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Fri, 19 May 2023 09:53:01 -0700 Subject: [PATCH 114/138] blast_repo fixes (dart-lang/stream_channel#91) dependabot --- pkgs/stream_channel/.github/dependabot.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkgs/stream_channel/.github/dependabot.yml b/pkgs/stream_channel/.github/dependabot.yml index 1603cdd9e..725f03af2 100644 --- a/pkgs/stream_channel/.github/dependabot.yml +++ b/pkgs/stream_channel/.github/dependabot.yml @@ -3,7 +3,9 @@ version: 2 updates: - - package-ecosystem: "github-actions" - directory: "/" + - package-ecosystem: github-actions + directory: / schedule: - interval: "monthly" + interval: monthly + labels: + - autosubmit From 67ed073cbf7ef5d99011718e328bfc903ce34e14 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 20 Jun 2023 15:13:45 -0700 Subject: [PATCH 115/138] Fix a race condition in IsolateChannel.connectReceive() (dart-lang/stream_channel#92) --- pkgs/stream_channel/CHANGELOG.md | 4 +++- pkgs/stream_channel/lib/src/isolate_channel.dart | 14 ++++++++++++-- pkgs/stream_channel/pubspec.yaml | 2 +- pkgs/stream_channel/test/isolate_channel_test.dart | 8 ++++++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 893218875..c78f64f0e 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,7 +1,9 @@ -## 2.1.2-dev +## 2.1.2 * Require Dart 2.19 * Add an example. +* Fix a race condition in `IsolateChannel.connectReceive()` where the channel + could hang forever if its sink was closed before the connection was established. ## 2.1.1 diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index 55c98143f..3fbd46d23 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -43,16 +43,26 @@ class IsolateChannel extends StreamChannelMixin { factory IsolateChannel.connectReceive(ReceivePort receivePort) { // We can't use a [StreamChannelCompleter] here because we need the return // value to be an [IsolateChannel]. + var isCompleted = false; var streamCompleter = StreamCompleter(); var sinkCompleter = StreamSinkCompleter(); - var channel = - IsolateChannel._(streamCompleter.stream, sinkCompleter.sink); + + var channel = IsolateChannel._(streamCompleter.stream, sinkCompleter.sink + .transform(StreamSinkTransformer.fromHandlers(handleDone: (sink) { + if (!isCompleted) { + receivePort.close(); + streamCompleter.setSourceStream(Stream.empty()); + sinkCompleter.setDestinationSink(NullStreamSink()); + } + sink.close(); + }))); // The first message across the ReceivePort should be a SendPort pointing to // the remote end. If it's not, we'll make the stream emit an error // complaining. late StreamSubscription subscription; subscription = receivePort.listen((message) { + isCompleted = true; if (message is SendPort) { var controller = StreamChannelController(allowForeignErrors: false, sync: true); diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 5eb57ae41..0b4f62d4e 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 2.1.2-dev +version: 2.1.2 description: >- An abstraction for two-way communication channels based on the Dart Stream class. diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index 1850664cf..10f1fe53e 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -162,5 +162,13 @@ void main() { expect(connectedChannel.stream.toList(), throwsStateError); expect(connectedChannel.sink.done, completes); }); + + test('the receiving channel closes gracefully without a connection', + () async { + var connectedChannel = IsolateChannel.connectReceive(connectPort); + await connectedChannel.sink.close(); + await expectLater(connectedChannel.stream.toList(), completion(isEmpty)); + await expectLater(connectedChannel.sink.done, completes); + }); }); } From ce71194d432b609d263a6d30430117800e1392fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 03:07:24 +0000 Subject: [PATCH 116/138] Bump actions/checkout from 3.5.2 to 3.5.3 (dart-lang/stream_channel#93) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.2 to 3.5.3.
Release notes

Sourced from actions/checkout's releases.

v3.5.3

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v3.5.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

v2.3.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.2&new-version=3.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 0874bdd38..4c8399a81 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.19.0, dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From e98c5bac7d7af172aa40f7ddf745171af7c4bcb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 03:51:18 +0000 Subject: [PATCH 117/138] Bump actions/checkout from 3.5.3 to 3.6.0 (dart-lang/stream_channel#94) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.3 to 3.6.0.
Release notes

Sourced from actions/checkout's releases.

v3.6.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3.5.3...v3.6.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.3&new-version=3.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 4c8399a81..8b1f4d4fb 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.19.0, dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From d00914acc59a8f42fae5d211b06a610b9abce0c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 03:27:12 +0000 Subject: [PATCH 118/138] Bump actions/checkout from 3.6.0 to 4.1.0 (dart-lang/stream_channel#95) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.6.0 to 4.1.0.
Release notes

Sourced from actions/checkout's releases.

v4.1.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.0.0...v4.1.0

v4.0.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v4.0.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.6.0&new-version=4.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 8b1f4d4fb..282ba5006 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.19.0, dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From de516dcb3999a6982670d254334b39b1e7af6589 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 07:14:58 -0700 Subject: [PATCH 119/138] Bump dart-lang/setup-dart from 1.5.0 to 1.5.1 (dart-lang/stream_channel#96) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/d6a63dab3335f427404425de0fbfed4686d93c4f...8a4b97ea2017cc079571daec46542f76189836b1) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 282ba5006..367d5dea3 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.19.0, dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install From ef684398b414ffbe6dd1bfed8a3763d9899ada3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 03:46:35 +0000 Subject: [PATCH 120/138] Bump actions/checkout from 4.1.0 to 4.1.1 (dart-lang/stream_channel#97) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.1.1.
Release notes

Sourced from actions/checkout's releases.

v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.0...v4.1.1

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.0&new-version=4.1.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 367d5dea3..e0d4f73af 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.19.0, dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} From 913e78ca09df450843fb3de10f46fe1902d37305 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 03:50:53 +0000 Subject: [PATCH 121/138] Bump dart-lang/setup-dart from 1.5.1 to 1.6.0 (dart-lang/stream_channel#98) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.1 to 1.6.0.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.1&new-version=1.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index e0d4f73af..02786315a 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.19.0, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install From 1cf10a4534934b70ecb55e442288c8471b51f9e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 03:27:16 +0000 Subject: [PATCH 122/138] Bump dart-lang/setup-dart from 1.6.0 to 1.6.2 (dart-lang/stream_channel#99) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.0 to 1.6.2.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.0&new-version=1.6.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 02786315a..41ca6901b 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.19.0, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install From c7eef23aa9b3bec0b88418612be76997136775c4 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 16 Feb 2024 16:46:43 -0800 Subject: [PATCH 123/138] blast_repo fixes (dart-lang/stream_channel#101) auto-publish, github-actions, no-response --- .../.github/workflows/no-response.yml | 37 +++++++++++++++++++ .../.github/workflows/publish.yaml | 17 +++++++++ 2 files changed, 54 insertions(+) create mode 100644 pkgs/stream_channel/.github/workflows/no-response.yml create mode 100644 pkgs/stream_channel/.github/workflows/publish.yaml diff --git a/pkgs/stream_channel/.github/workflows/no-response.yml b/pkgs/stream_channel/.github/workflows/no-response.yml new file mode 100644 index 000000000..ab1ac4984 --- /dev/null +++ b/pkgs/stream_channel/.github/workflows/no-response.yml @@ -0,0 +1,37 @@ +# A workflow to close issues where the author hasn't responded to a request for +# more information; see https://github.com/actions/stale. + +name: No Response + +# Run as a daily cron. +on: + schedule: + # Every day at 8am + - cron: '0 8 * * *' + +# All permissions not specified are set to 'none'. +permissions: + issues: write + pull-requests: write + +jobs: + no-response: + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'dart-lang' }} + steps: + - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e + with: + # Don't automatically mark inactive issues+PRs as stale. + days-before-stale: -1 + # Close needs-info issues and PRs after 14 days of inactivity. + days-before-close: 14 + stale-issue-label: "needs-info" + close-issue-message: > + Without additional information we're not able to resolve this issue. + Feel free to add more info or respond to any questions above and we + can reopen the case. Thanks for your contribution! + stale-pr-label: "needs-info" + close-pr-message: > + Without additional information we're not able to resolve this PR. + Feel free to add more info or respond to any questions above. + Thanks for your contribution! diff --git a/pkgs/stream_channel/.github/workflows/publish.yaml b/pkgs/stream_channel/.github/workflows/publish.yaml new file mode 100644 index 000000000..27157a046 --- /dev/null +++ b/pkgs/stream_channel/.github/workflows/publish.yaml @@ -0,0 +1,17 @@ +# A CI configuration to auto-publish pub packages. + +name: Publish + +on: + pull_request: + branches: [ master ] + push: + tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ] + +jobs: + publish: + if: ${{ github.repository_owner == 'dart-lang' }} + uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main + permissions: + id-token: write # Required for authentication using OIDC + pull-requests: write # Required for writing the pull request note From 45fbe108fd38b1f1134b76ce85ab56b2f96d48e3 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 16 Feb 2024 17:47:01 -0800 Subject: [PATCH 124/138] Require Dart 3.3, update and fix lints (dart-lang/stream_channel#100) --- .../.github/workflows/test-package.yml | 2 +- pkgs/stream_channel/CHANGELOG.md | 4 ++ pkgs/stream_channel/example/example.dart | 6 +-- pkgs/stream_channel/lib/src/disconnector.dart | 2 +- .../lib/src/guarantee_channel.dart | 2 +- .../lib/src/isolate_channel.dart | 2 +- .../stream_channel/lib/src/multi_channel.dart | 3 +- .../lib/src/stream_channel_completer.dart | 2 +- pkgs/stream_channel/pubspec.yaml | 6 +-- .../test/disconnector_test.dart | 16 +++---- .../test/isolate_channel_test.dart | 8 ++-- .../test/json_document_transformer_test.dart | 2 +- .../test/stream_channel_completer_test.dart | 4 +- .../test/stream_channel_test.dart | 44 +++++++++++++------ .../test/with_close_guarantee_test.dart | 2 +- .../test/with_guarantees_test.dart | 16 +++---- 16 files changed, 71 insertions(+), 50 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 41ca6901b..db6451bcf 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.19.0, dev] + sdk: [3.3, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index c78f64f0e..4b8e2b54a 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.3-wip + +* Require Dart 3.3 + ## 2.1.2 * Require Dart 2.19 diff --git a/pkgs/stream_channel/example/example.dart b/pkgs/stream_channel/example/example.dart index dd16f6750..b41d8d94a 100644 --- a/pkgs/stream_channel/example/example.dart +++ b/pkgs/stream_channel/example/example.dart @@ -22,7 +22,7 @@ Future main() async { // For example, we can handle standard input as strings: var stringChannel = stdioChannel .transform(StreamChannelTransformer.fromCodec(utf8)) - .transformStream(LineSplitter()); + .transformStream(const LineSplitter()); stringChannel.sink.add('world!\n'); // You can implement StreamChannel by extending StreamChannelMixin, but @@ -84,8 +84,8 @@ Future main() async { // given the corresponding `SendPort`, and then call // `IsolateChannel.connectSend`. var recv = ReceivePort(); - var recvChannel = IsolateChannel.connectReceive(recv); - var sendChannel = IsolateChannel.connectSend(recv.sendPort); + var recvChannel = IsolateChannel.connectReceive(recv); + var sendChannel = IsolateChannel.connectSend(recv.sendPort); // You must manually close `IsolateChannel` sinks, however. await recvChannel.sink.close(); diff --git a/pkgs/stream_channel/lib/src/disconnector.dart b/pkgs/stream_channel/lib/src/disconnector.dart index 61969cbf8..3414e9c77 100644 --- a/pkgs/stream_channel/lib/src/disconnector.dart +++ b/pkgs/stream_channel/lib/src/disconnector.dart @@ -38,7 +38,7 @@ class Disconnector implements StreamChannelTransformer { _sinks.clear(); return Future.wait(futures, eagerError: true); }); - final _disconnectMemo = AsyncMemoizer(); + final _disconnectMemo = AsyncMemoizer>(); @override StreamChannel bind(StreamChannel channel) { diff --git a/pkgs/stream_channel/lib/src/guarantee_channel.dart b/pkgs/stream_channel/lib/src/guarantee_channel.dart index 2aa8b7b97..30ebe2ec6 100644 --- a/pkgs/stream_channel/lib/src/guarantee_channel.dart +++ b/pkgs/stream_channel/lib/src/guarantee_channel.dart @@ -83,7 +83,7 @@ class _GuaranteeSink implements StreamSink { @override Future get done => _doneCompleter.future; - final _doneCompleter = Completer(); + final _doneCompleter = Completer(); /// Whether connection is disconnected. /// diff --git a/pkgs/stream_channel/lib/src/isolate_channel.dart b/pkgs/stream_channel/lib/src/isolate_channel.dart index 3fbd46d23..15c68a41d 100644 --- a/pkgs/stream_channel/lib/src/isolate_channel.dart +++ b/pkgs/stream_channel/lib/src/isolate_channel.dart @@ -51,7 +51,7 @@ class IsolateChannel extends StreamChannelMixin { .transform(StreamSinkTransformer.fromHandlers(handleDone: (sink) { if (!isCompleted) { receivePort.close(); - streamCompleter.setSourceStream(Stream.empty()); + streamCompleter.setSourceStream(const Stream.empty()); sinkCompleter.setDestinationSink(NullStreamSink()); } sink.close(); diff --git a/pkgs/stream_channel/lib/src/multi_channel.dart b/pkgs/stream_channel/lib/src/multi_channel.dart index 82f59c7c9..48942392e 100644 --- a/pkgs/stream_channel/lib/src/multi_channel.dart +++ b/pkgs/stream_channel/lib/src/multi_channel.dart @@ -191,7 +191,8 @@ class _MultiChannel extends StreamChannelMixin // If the inner channel has already closed, create new virtual channels in a // closed state. if (_inner == null) { - return VirtualChannel._(this, inputId, Stream.empty(), NullStreamSink()); + return VirtualChannel._( + this, inputId, const Stream.empty(), NullStreamSink()); } late StreamChannelController controller; diff --git a/pkgs/stream_channel/lib/src/stream_channel_completer.dart b/pkgs/stream_channel/lib/src/stream_channel_completer.dart index 5a824c1f3..9d007eb6c 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_completer.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_completer.dart @@ -34,7 +34,7 @@ class StreamChannelCompleter { /// instead contain just that error. The sink will silently discard all /// events. static StreamChannel fromFuture(Future channelFuture) { - var completer = StreamChannelCompleter(); + var completer = StreamChannelCompleter(); channelFuture.then(completer.setChannel, onError: completer.setError); return completer.channel; } diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 0b4f62d4e..0cfd074a5 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,16 +1,16 @@ name: stream_channel -version: 2.1.2 +version: 2.1.3-wip description: >- An abstraction for two-way communication channels based on the Dart Stream class. repository: https://github.com/dart-lang/stream_channel environment: - sdk: '>=2.19.0 <3.0.0' + sdk: ^3.3.0 dependencies: async: ^2.5.0 dev_dependencies: - dart_flutter_team_lints: ^1.0.0 + dart_flutter_team_lints: ^2.0.0 test: ^1.16.0 diff --git a/pkgs/stream_channel/test/disconnector_test.dart b/pkgs/stream_channel/test/disconnector_test.dart index 28f3fee9a..bbba568ed 100644 --- a/pkgs/stream_channel/test/disconnector_test.dart +++ b/pkgs/stream_channel/test/disconnector_test.dart @@ -14,8 +14,8 @@ void main() { late Disconnector disconnector; late StreamChannel channel; setUp(() { - streamController = StreamController(); - sinkController = StreamController(); + streamController = StreamController(); + sinkController = StreamController(); disconnector = Disconnector(); channel = StreamChannel.withGuarantees( streamController.stream, sinkController.sink) @@ -52,7 +52,7 @@ void main() { }); test("events can't be added while a stream is being added", () { - var controller = StreamController(); + var controller = StreamController(); channel.sink.addStream(controller.stream); expect(() => channel.sink.add(1), throwsStateError); @@ -67,7 +67,7 @@ void main() { test('cancels addStream when disconnected', () async { var canceled = false; - var controller = StreamController(onCancel: () { + var controller = StreamController(onCancel: () { canceled = true; }); expect(channel.sink.addStream(controller.stream), completes); @@ -78,9 +78,9 @@ void main() { }); test('disconnect() returns the close future from the inner sink', () async { - var streamController = StreamController(); - var sinkController = StreamController(); - var disconnector = Disconnector(); + var streamController = StreamController(); + var sinkController = StreamController(); + var disconnector = Disconnector(); var sink = _CloseCompleterSink(sinkController.sink); StreamChannel.withGuarantees(streamController.stream, sink) .transform(disconnector); @@ -140,7 +140,7 @@ void main() { /// returned by [close] using [completer]. class _CloseCompleterSink extends DelegatingStreamSink { /// The completer for the future returned by [close]. - final completer = Completer(); + final completer = Completer(); _CloseCompleterSink(super.inner); diff --git a/pkgs/stream_channel/test/isolate_channel_test.dart b/pkgs/stream_channel/test/isolate_channel_test.dart index 10f1fe53e..3a8b42e9b 100644 --- a/pkgs/stream_channel/test/isolate_channel_test.dart +++ b/pkgs/stream_channel/test/isolate_channel_test.dart @@ -53,7 +53,7 @@ void main() { }); test("events can't be added while a stream is being added", () { - var controller = StreamController(); + var controller = StreamController(); channel.sink.addStream(controller.stream); expect(() => channel.sink.add(1), throwsStateError); @@ -109,7 +109,7 @@ void main() { test('the sink closes as soon as an error is added via addStream', () async { var canceled = false; - var controller = StreamController(onCancel: () { + var controller = StreamController(onCancel: () { canceled = true; }); @@ -156,7 +156,7 @@ void main() { test('the receiving channel produces an error if it gets the wrong message', () { - var connectedChannel = IsolateChannel.connectReceive(connectPort); + var connectedChannel = IsolateChannel.connectReceive(connectPort); connectPort.sendPort.send('wrong value'); expect(connectedChannel.stream.toList(), throwsStateError); @@ -165,7 +165,7 @@ void main() { test('the receiving channel closes gracefully without a connection', () async { - var connectedChannel = IsolateChannel.connectReceive(connectPort); + var connectedChannel = IsolateChannel.connectReceive(connectPort); await connectedChannel.sink.close(); await expectLater(connectedChannel.stream.toList(), completion(isEmpty)); await expectLater(connectedChannel.sink.done, completes); diff --git a/pkgs/stream_channel/test/json_document_transformer_test.dart b/pkgs/stream_channel/test/json_document_transformer_test.dart index 48d8f7291..290c4e2c3 100644 --- a/pkgs/stream_channel/test/json_document_transformer_test.dart +++ b/pkgs/stream_channel/test/json_document_transformer_test.dart @@ -41,6 +41,6 @@ void main() { test('synchronously throws if an unencodable object is added', () { var transformed = channel.transform(jsonDocument); expect(() => transformed.sink.add(Object()), - throwsA(TypeMatcher())); + throwsA(const TypeMatcher())); }); } diff --git a/pkgs/stream_channel/test/stream_channel_completer_test.dart b/pkgs/stream_channel/test/stream_channel_completer_test.dart index 22db01a76..c6fddc011 100644 --- a/pkgs/stream_channel/test/stream_channel_completer_test.dart +++ b/pkgs/stream_channel/test/stream_channel_completer_test.dart @@ -14,8 +14,8 @@ void main() { late StreamChannel innerChannel; setUp(() { completer = StreamChannelCompleter(); - streamController = StreamController(); - sinkController = StreamController(); + streamController = StreamController(); + sinkController = StreamController(); innerChannel = StreamChannel(streamController.stream, sinkController.sink); }); diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart index 76edbdf91..c44b6ab6f 100644 --- a/pkgs/stream_channel/test/stream_channel_test.dart +++ b/pkgs/stream_channel/test/stream_channel_test.dart @@ -10,21 +10,17 @@ import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; void main() { - late StreamController streamController; - late StreamController sinkController; - late StreamChannel channel; - setUp(() { - streamController = StreamController(); - sinkController = StreamController(); - channel = StreamChannel(streamController.stream, sinkController.sink); - }); - test("pipe() pipes data from each channel's stream into the other's sink", () { - var otherStreamController = StreamController(); - var otherSinkController = StreamController(); + var otherStreamController = StreamController(); + var otherSinkController = StreamController(); var otherChannel = StreamChannel(otherStreamController.stream, otherSinkController.sink); + + var streamController = StreamController(); + var sinkController = StreamController(); + var channel = StreamChannel(streamController.stream, sinkController.sink); + channel.pipe(otherChannel); streamController.add(1); @@ -41,6 +37,10 @@ void main() { }); test('transform() transforms the channel', () async { + var streamController = StreamController>(); + var sinkController = StreamController>(); + var channel = StreamChannel(streamController.stream, sinkController.sink); + var transformed = channel .cast>() .transform(StreamChannelTransformer.fromCodec(utf8)); @@ -59,6 +59,10 @@ void main() { }); test('transformStream() transforms only the stream', () async { + var streamController = StreamController(); + var sinkController = StreamController(); + var channel = StreamChannel(streamController.stream, sinkController.sink); + var transformed = channel.cast().transformStream(const LineSplitter()); @@ -75,8 +79,12 @@ void main() { }); test('transformSink() transforms only the sink', () async { + var streamController = StreamController(); + var sinkController = StreamController(); + var channel = StreamChannel(streamController.stream, sinkController.sink); + var transformed = channel.cast().transformSink( - StreamSinkTransformer.fromStreamTransformer(const LineSplitter())); + const StreamSinkTransformer.fromStreamTransformer(LineSplitter())); streamController.add('fbl\nthp'); unawaited(streamController.close()); @@ -91,7 +99,11 @@ void main() { }); test('changeStream() changes the stream', () { - var newController = StreamController(); + var streamController = StreamController(); + var sinkController = StreamController(); + var channel = StreamChannel(streamController.stream, sinkController.sink); + + var newController = StreamController(); var changed = channel.changeStream((stream) { expect(stream, equals(channel.stream)); return newController.stream; @@ -107,7 +119,11 @@ void main() { }); test('changeSink() changes the sink', () { - var newController = StreamController(); + var streamController = StreamController(); + var sinkController = StreamController(); + var channel = StreamChannel(streamController.stream, sinkController.sink); + + var newController = StreamController(); var changed = channel.changeSink((sink) { expect(sink, equals(channel.sink)); return newController.sink; diff --git a/pkgs/stream_channel/test/with_close_guarantee_test.dart b/pkgs/stream_channel/test/with_close_guarantee_test.dart index a18f09fe1..9c0b72998 100644 --- a/pkgs/stream_channel/test/with_close_guarantee_test.dart +++ b/pkgs/stream_channel/test/with_close_guarantee_test.dart @@ -45,7 +45,7 @@ void main() { .listen(expectAsync1((event) { if (event == 2) channel.sink.close(); }, count: 2)) - .asFuture(), + .asFuture(), completes); await pumpEventQueue(); diff --git a/pkgs/stream_channel/test/with_guarantees_test.dart b/pkgs/stream_channel/test/with_guarantees_test.dart index 849e30491..f026079fb 100644 --- a/pkgs/stream_channel/test/with_guarantees_test.dart +++ b/pkgs/stream_channel/test/with_guarantees_test.dart @@ -12,8 +12,8 @@ void main() { late StreamController sinkController; late StreamChannel channel; setUp(() { - streamController = StreamController(); - sinkController = StreamController(); + streamController = StreamController(); + sinkController = StreamController(); channel = StreamChannel.withGuarantees( streamController.stream, sinkController.sink); }); @@ -53,7 +53,7 @@ void main() { .listen(expectAsync1((event) { if (event == 2) channel.sink.close(); }, count: 2)) - .asFuture(), + .asFuture(), completes); }); @@ -126,7 +126,7 @@ void main() { }); test("events can't be added while a stream is being added", () { - var controller = StreamController(); + var controller = StreamController(); channel.sink.addStream(controller.stream); expect(() => channel.sink.add(1), throwsStateError); @@ -140,8 +140,8 @@ void main() { group('with allowSinkErrors: false', () { setUp(() { - streamController = StreamController(); - sinkController = StreamController(); + streamController = StreamController(); + sinkController = StreamController(); channel = StreamChannel.withGuarantees( streamController.stream, sinkController.sink, allowSinkErrors: false); @@ -166,7 +166,7 @@ void main() { .listen(expectAsync1((event) { if (event == 2) channel.sink.addError('oh no'); }, count: 2)) - .asFuture(), + .asFuture(), completes); }); @@ -180,7 +180,7 @@ void main() { 'adding an error via via addStream causes the stream to emit a done ' 'event', () async { var canceled = false; - var controller = StreamController(onCancel: () { + var controller = StreamController(onCancel: () { canceled = true; }); From 81110f1163e86a3cc90e2632d61cf6466ea5c269 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 03:21:07 +0000 Subject: [PATCH 125/138] Bump actions/checkout from 4.1.1 to 4.1.2 (dart-lang/stream_channel#102) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.2.
Release notes

Sourced from actions/checkout's releases.

v4.1.2

We are investigating the following issue with this release and have rolled-back the v4 tag to point to v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.1...v4.1.2

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.1&new-version=4.1.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index db6451bcf..b7d7d6e06 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.3, dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} From 9992ce8f4de7d2d7f173ea6a2cb891b4d33cd828 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 03:46:43 +0000 Subject: [PATCH 126/138] Bump dart-lang/setup-dart from 1.6.2 to 1.6.4 (dart-lang/stream_channel#103) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.2 to 1.6.4.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.4

  • Rebuild JS code to include changes from v1.6.3

v1.6.3

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.2&new-version=1.6.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index b7d7d6e06..04dbcd2b3 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.3, dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install From 00f8ce7c416224d30500d84a88f79dcc815d7712 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 15:32:50 +0000 Subject: [PATCH 127/138] Bump actions/checkout from 4.1.2 to 4.1.4 (dart-lang/stream_channel#104) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.2 to 4.1.4.
Release notes

Sourced from actions/checkout's releases.

v4.1.4

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.3...v4.1.4

v4.1.3

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.2...v4.1.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.2&new-version=4.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 04dbcd2b3..811bb8040 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.3, dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 9f26b26aa01b63256d2c009d92c56e1bbfc2d764 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 13 May 2024 10:36:14 -0700 Subject: [PATCH 128/138] blast_repo fixes (dart-lang/stream_channel#105) dependabot --- pkgs/stream_channel/.github/dependabot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/stream_channel/.github/dependabot.yml b/pkgs/stream_channel/.github/dependabot.yml index 725f03af2..cde02ad6a 100644 --- a/pkgs/stream_channel/.github/dependabot.yml +++ b/pkgs/stream_channel/.github/dependabot.yml @@ -9,3 +9,7 @@ updates: interval: monthly labels: - autosubmit + groups: + github-actions: + patterns: + - "*" From cc95d8605d58869f25768f7ad0de4643a175c6eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 17:38:26 +0000 Subject: [PATCH 129/138] Bump actions/checkout from 4.1.4 to 4.1.5 in the github-actions group (dart-lang/stream_channel#106) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.4 to 4.1.5
Release notes

Sourced from actions/checkout's releases.

v4.1.5

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.4...v4.1.5

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.4&new-version=4.1.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 811bb8040..aad5df6f4 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.3, dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 3c38e1fb8e6d286e7da04dcba4fe5f5196da5bd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jun 2024 03:27:23 +0000 Subject: [PATCH 130/138] Bump actions/checkout from 4.1.5 to 4.1.6 in the github-actions group (dart-lang/stream_channel#107) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.5 to 4.1.6
Release notes

Sourced from actions/checkout's releases.

v4.1.6

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.5...v4.1.6

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.5&new-version=4.1.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index aad5df6f4..77eb9e176 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.3, dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 5c400a84b384db62e5bfc3d902480079c1b8cafc Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 24 Jun 2024 11:15:41 -0700 Subject: [PATCH 131/138] bump lints (dart-lang/stream_channel#108) --- pkgs/stream_channel/analysis_options.yaml | 9 --------- pkgs/stream_channel/pubspec.yaml | 4 ++-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/pkgs/stream_channel/analysis_options.yaml b/pkgs/stream_channel/analysis_options.yaml index 8e5d4a792..44cda4da2 100644 --- a/pkgs/stream_channel/analysis_options.yaml +++ b/pkgs/stream_channel/analysis_options.yaml @@ -3,12 +3,3 @@ include: package:dart_flutter_team_lints/analysis_options.yaml analyzer: language: strict-casts: true - -linter: - rules: - - comment_references - - always_declare_return_types - - omit_local_variable_types - - prefer_single_quotes - - unawaited_futures - - use_super_parameters diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 0cfd074a5..652472170 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -12,5 +12,5 @@ dependencies: async: ^2.5.0 dev_dependencies: - dart_flutter_team_lints: ^2.0.0 - test: ^1.16.0 + dart_flutter_team_lints: ^3.0.0 + test: ^1.16.6 From 2d967e90eeb44a54405ec3c4cd51d4f563cb460e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:33:11 +0000 Subject: [PATCH 132/138] Bump the github-actions group with 2 updates (dart-lang/stream_channel#109) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `actions/checkout` from 4.1.6 to 4.1.7
Release notes

Sourced from actions/checkout's releases.

v4.1.7

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.6...v4.1.7

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

... (truncated)

Commits

Updates `dart-lang/setup-dart` from 1.6.4 to 1.6.5
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.5

dart-lang/stream_channel#118: dart-lang/setup-dartdart-lang/stream_channel#118

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.5

dart-lang/stream_channel#118: dart-lang/setup-dartdart-lang/stream_channel#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

... (truncated)

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/stream_channel/.github/workflows/test-package.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 77eb9e176..9d9f1cc08 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install @@ -49,8 +49,8 @@ jobs: os: [ubuntu-latest] sdk: [3.3, dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install From c49c4109c774ec67fd1cb8828e6b2953d914a700 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 29 Jul 2024 11:27:21 -0700 Subject: [PATCH 133/138] Fix some trivial doc comment lints (dart-lang/stream_channel#110) --- pkgs/stream_channel/lib/src/stream_channel_controller.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/stream_channel/lib/src/stream_channel_controller.dart b/pkgs/stream_channel/lib/src/stream_channel_controller.dart index 5c788667d..25d5239b2 100644 --- a/pkgs/stream_channel/lib/src/stream_channel_controller.dart +++ b/pkgs/stream_channel/lib/src/stream_channel_controller.dart @@ -2,6 +2,9 @@ // 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. +/// @docImport 'isolate_channel.dart'; +library; + import 'dart:async'; import '../stream_channel.dart'; @@ -11,7 +14,7 @@ import '../stream_channel.dart'; /// This exposes two connected [StreamChannel]s, [local] and [foreign]. The /// user's code should use [local] to emit and receive events. Then [foreign] /// can be returned for others to use. For example, here's a simplified version -/// of the implementation of [new IsolateChannel]: +/// of the implementation of [IsolateChannel.new]: /// /// ```dart /// StreamChannel isolateChannel(ReceivePort receivePort, SendPort sendPort) { From b820aeba0e772c04d0dc6c188f2814ce20996b08 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 03:17:00 +0000 Subject: [PATCH 134/138] Bump actions/checkout from 4.1.7 to 4.2.0 in the github-actions group (dart-lang/stream_channel#111) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.7 to 4.2.0
Release notes

Sourced from actions/checkout's releases.

v4.2.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.7...v4.2.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.7&new-version=4.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 9d9f1cc08..30feba18c 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.3, dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From ae5aad43d700aa1689580603c55697ff864ca85b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 03:59:06 +0000 Subject: [PATCH 135/138] Bump actions/checkout from 4.2.0 to 4.2.2 in the github-actions group (dart-lang/stream_channel#112) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.2.0 to 4.2.2
Release notes

Sourced from actions/checkout's releases.

v4.2.2

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.2.1...v4.2.2

v4.2.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.2.0...v4.2.1

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.2

v4.2.1

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.2.0&new-version=4.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index 30feba18c..e667e382e 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.3, dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From 7808a8850caae1362e3f583eb81b34fbcb707a8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 03:37:21 +0000 Subject: [PATCH 136/138] Bump dart-lang/setup-dart in the github-actions group (dart-lang/stream_channel#113) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `dart-lang/setup-dart` from 1.6.5 to 1.7.0
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.7.0

What's Changed

  • Install a Flutter SDK in the publish workflow allowing for publication of flutter packages.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.7.0

v1.6.5

dart-lang/stream_channel#118: dart-lang/setup-dartdart-lang/stream_channel#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.5&new-version=1.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/stream_channel/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/pkgs/stream_channel/.github/workflows/test-package.yml index e667e382e..c70b745e2 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/pkgs/stream_channel/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.3, dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install From 8021ff098cefbb3dec93e77a675c5db241c7bf76 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 17:01:55 +0100 Subject: [PATCH 137/138] Add issue template and other fixes --- .github/ISSUE_TEMPLATE/stream_channel.md | 5 ++++ pkgs/stream_channel/CONTRIBUTING.md | 33 ------------------------ pkgs/stream_channel/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 34 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/stream_channel.md delete mode 100644 pkgs/stream_channel/CONTRIBUTING.md diff --git a/.github/ISSUE_TEMPLATE/stream_channel.md b/.github/ISSUE_TEMPLATE/stream_channel.md new file mode 100644 index 000000000..76b599497 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/stream_channel.md @@ -0,0 +1,5 @@ +--- +name: "package:stream_channel" +about: "Create a bug or file a feature request against package:stream_channel." +labels: "package:stream_channel" +--- \ No newline at end of file diff --git a/pkgs/stream_channel/CONTRIBUTING.md b/pkgs/stream_channel/CONTRIBUTING.md deleted file mode 100644 index 6f5e0ea67..000000000 --- a/pkgs/stream_channel/CONTRIBUTING.md +++ /dev/null @@ -1,33 +0,0 @@ -Want to contribute? Great! First, read this page (including the small print at -the end). - -### Before you contribute -Before we can use your code, you must sign the -[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual) -(CLA), which you can do online. The CLA is necessary mainly because you own the -copyright to your changes, even after your contribution becomes part of our -codebase, so we need your permission to use and distribute your code. We also -need to be sure of various other things—for instance that you'll tell us if you -know that your code infringes on other people's patents. You don't have to sign -the CLA until after you've submitted your code for review and a member has -approved it, but you must do it before we can put your code into our codebase. - -Before you start working on a larger contribution, you should get in touch with -us first through the issue tracker with your idea so that we can help out and -possibly guide you. Coordinating up front makes it much easier to avoid -frustration later on. - -### Code reviews -All submissions, including submissions by project members, require review. - -### File headers -All files in the project must start with the following header. - - // Copyright (c) 2015, 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. - -### The small print -Contributions made by corporations are covered by a different agreement than the -one above, the -[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate). diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index 652472170..c1b8e1f19 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -3,7 +3,7 @@ version: 2.1.3-wip description: >- An abstraction for two-way communication channels based on the Dart Stream class. -repository: https://github.com/dart-lang/stream_channel +repository: https://github.com/dart-lang/tools/tree/main/pkgs/stream_channel environment: sdk: ^3.3.0 From e66e313089cd413db345a3ab57db09da45bf2128 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 17:04:34 +0100 Subject: [PATCH 138/138] merge fixes --- .github/labeler.yml | 4 ++ .../workflows/stream_channel.yaml | 16 ++++++-- README.md | 1 + pkgs/stream_channel/.github/dependabot.yml | 15 -------- .../.github/workflows/no-response.yml | 37 ------------------- .../.github/workflows/publish.yaml | 17 --------- pkgs/stream_channel/CHANGELOG.md | 3 +- pkgs/stream_channel/README.md | 2 +- pkgs/stream_channel/pubspec.yaml | 2 +- 9 files changed, 22 insertions(+), 75 deletions(-) rename pkgs/stream_channel/.github/workflows/test-package.yml => .github/workflows/stream_channel.yaml (85%) delete mode 100644 pkgs/stream_channel/.github/dependabot.yml delete mode 100644 pkgs/stream_channel/.github/workflows/no-response.yml delete mode 100644 pkgs/stream_channel/.github/workflows/publish.yaml diff --git a/.github/labeler.yml b/.github/labeler.yml index eca80bbc2..ea9baeba9 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -84,6 +84,10 @@ - changed-files: - any-glob-to-any-file: 'pkgs/source_map_stack_trace/**' +'package:stream_channel': + - changed-files: + - any-glob-to-any-file: 'pkgs/stream_channel/**' + 'package:unified_analytics': - changed-files: - any-glob-to-any-file: 'pkgs/unified_analytics/**' diff --git a/pkgs/stream_channel/.github/workflows/test-package.yml b/.github/workflows/stream_channel.yaml similarity index 85% rename from pkgs/stream_channel/.github/workflows/test-package.yml rename to .github/workflows/stream_channel.yaml index c70b745e2..c39424dc5 100644 --- a/pkgs/stream_channel/.github/workflows/test-package.yml +++ b/.github/workflows/stream_channel.yaml @@ -1,17 +1,27 @@ -name: Dart CI +name: package:stream_channel on: # Run on PRs and pushes to the default branch. push: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/stream_channel.yaml' + - 'pkgs/stream_channel/**' pull_request: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/stream_channel.yaml' + - 'pkgs/stream_channel/**' schedule: - cron: "0 0 * * 0" env: PUB_ENVIRONMENT: bot.github +defaults: + run: + working-directory: pkgs/stream_channel/ + jobs: # Check code formatting and static analysis on a single OS (linux) # against Dart dev. diff --git a/README.md b/README.md index 50517c36e..495f0ea36 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ don't naturally belong to other topic monorepos (like | [mime](pkgs/mime/) | Utilities for handling media (MIME) types, including determining a type from a file extension and file contents. | [![package issues](https://img.shields.io/badge/package:mime-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Amime) | [![pub package](https://img.shields.io/pub/v/mime.svg)](https://pub.dev/packages/mime) | | [oauth2](pkgs/oauth2/) | A client library for authenticating with a remote service via OAuth2 on behalf of a user, and making authorized HTTP requests with the user's OAuth2 credentials. | [![package issues](https://img.shields.io/badge/package:oauth2-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aoauth2) | [![pub package](https://img.shields.io/pub/v/oauth2.svg)](https://pub.dev/packages/oauth2) | | [source_map_stack_trace](pkgs/source_map_stack_trace/) | A package for applying source maps to stack traces. | [![package issues](https://img.shields.io/badge/package:source_map_stack_trace-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asource_map_stack_trace) | [![pub package](https://img.shields.io/pub/v/source_map_stack_trace.svg)](https://pub.dev/packages/source_map_stack_trace) | +| [stream_channel](pkgs/stream_channel/) | An abstraction for two-way communication channels based on the Dart Stream class. | [![package issues](https://img.shields.io/badge/package:stream_channel-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Astream_channel) | [![pub package](https://img.shields.io/pub/v/stream_channel.svg)](https://pub.dev/packages/stream_channel) | | [unified_analytics](pkgs/unified_analytics/) | A package for logging analytics for all Dart and Flutter related tooling to Google Analytics. | [![package issues](https://img.shields.io/badge/package:unified_analytics-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aunified_analytics) | [![pub package](https://img.shields.io/pub/v/unified_analytics.svg)](https://pub.dev/packages/unified_analytics) | ## Publishing automation diff --git a/pkgs/stream_channel/.github/dependabot.yml b/pkgs/stream_channel/.github/dependabot.yml deleted file mode 100644 index cde02ad6a..000000000 --- a/pkgs/stream_channel/.github/dependabot.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Dependabot configuration file. -# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates -version: 2 - -updates: - - package-ecosystem: github-actions - directory: / - schedule: - interval: monthly - labels: - - autosubmit - groups: - github-actions: - patterns: - - "*" diff --git a/pkgs/stream_channel/.github/workflows/no-response.yml b/pkgs/stream_channel/.github/workflows/no-response.yml deleted file mode 100644 index ab1ac4984..000000000 --- a/pkgs/stream_channel/.github/workflows/no-response.yml +++ /dev/null @@ -1,37 +0,0 @@ -# A workflow to close issues where the author hasn't responded to a request for -# more information; see https://github.com/actions/stale. - -name: No Response - -# Run as a daily cron. -on: - schedule: - # Every day at 8am - - cron: '0 8 * * *' - -# All permissions not specified are set to 'none'. -permissions: - issues: write - pull-requests: write - -jobs: - no-response: - runs-on: ubuntu-latest - if: ${{ github.repository_owner == 'dart-lang' }} - steps: - - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e - with: - # Don't automatically mark inactive issues+PRs as stale. - days-before-stale: -1 - # Close needs-info issues and PRs after 14 days of inactivity. - days-before-close: 14 - stale-issue-label: "needs-info" - close-issue-message: > - Without additional information we're not able to resolve this issue. - Feel free to add more info or respond to any questions above and we - can reopen the case. Thanks for your contribution! - stale-pr-label: "needs-info" - close-pr-message: > - Without additional information we're not able to resolve this PR. - Feel free to add more info or respond to any questions above. - Thanks for your contribution! diff --git a/pkgs/stream_channel/.github/workflows/publish.yaml b/pkgs/stream_channel/.github/workflows/publish.yaml deleted file mode 100644 index 27157a046..000000000 --- a/pkgs/stream_channel/.github/workflows/publish.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# A CI configuration to auto-publish pub packages. - -name: Publish - -on: - pull_request: - branches: [ master ] - push: - tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ] - -jobs: - publish: - if: ${{ github.repository_owner == 'dart-lang' }} - uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main - permissions: - id-token: write # Required for authentication using OIDC - pull-requests: write # Required for writing the pull request note diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md index 4b8e2b54a..30f7d32bc 100644 --- a/pkgs/stream_channel/CHANGELOG.md +++ b/pkgs/stream_channel/CHANGELOG.md @@ -1,6 +1,7 @@ -## 2.1.3-wip +## 2.1.3 * Require Dart 3.3 +* Move to `dart-lang/tools` monorepo. ## 2.1.2 diff --git a/pkgs/stream_channel/README.md b/pkgs/stream_channel/README.md index ae1ea219d..3677ccf5e 100644 --- a/pkgs/stream_channel/README.md +++ b/pkgs/stream_channel/README.md @@ -1,4 +1,4 @@ -[![Dart CI](https://github.com/dart-lang/stream_channel/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/stream_channel/actions/workflows/test-package.yml) +[![Build Status](https://github.com/dart-lang/tools/actions/workflows/stream_channel.yaml/badge.svg)](https://github.com/dart-lang/tools/actions/workflows/stream_channel.yaml) [![pub package](https://img.shields.io/pub/v/stream_channel.svg)](https://pub.dev/packages/stream_channel) [![package publisher](https://img.shields.io/pub/publisher/stream_channel.svg)](https://pub.dev/packages/stream_channel/publisher) diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml index c1b8e1f19..eec8c1ba5 100644 --- a/pkgs/stream_channel/pubspec.yaml +++ b/pkgs/stream_channel/pubspec.yaml @@ -1,5 +1,5 @@ name: stream_channel -version: 2.1.3-wip +version: 2.1.3 description: >- An abstraction for two-way communication channels based on the Dart Stream class.