From 86890ad31e9512082c7c10553d3d24378385cf90 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 26 Feb 2021 16:29:35 -0800 Subject: [PATCH 1/7] First pass at the migration --- .../connectivity_for_web/CHANGELOG.md | 5 +++++ .../lib/src/dart_html_connectivity_plugin.dart | 4 ++-- ...work_information_api_connectivity_plugin.dart | 6 +++--- .../lib/src/utils/connectivity_result.dart | 4 ++-- .../connectivity_for_web/pubspec.yaml | 16 ++++++++-------- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/packages/connectivity/connectivity_for_web/CHANGELOG.md b/packages/connectivity/connectivity_for_web/CHANGELOG.md index f6d83dd3e0cc..ccd689760b84 100644 --- a/packages/connectivity/connectivity_for_web/CHANGELOG.md +++ b/packages/connectivity/connectivity_for_web/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.4.0 + +* Migrate to null-safety +* Run tests using flutter driver + ## 0.3.1+4 * Remove unused `test` dependency. diff --git a/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart index 5caa5679d6ad..c5a7acdc76e4 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart @@ -9,12 +9,12 @@ class DartHtmlConnectivityPlugin extends ConnectivityPlugin { /// Checks the connection status of the device. @override Future checkConnectivity() async { - return html.window.navigator.onLine + return html.window.navigator.onLine ?? false ? ConnectivityResult.wifi : ConnectivityResult.none; } - StreamController _connectivityResult; + late StreamController _connectivityResult; /// Returns a Stream of ConnectivityResults changes. @override diff --git a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart index 99bac2ab8d30..c5ec776b3b58 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart @@ -18,7 +18,7 @@ class NetworkInformationApiConnectivityPlugin extends ConnectivityPlugin { /// The constructor of the plugin. NetworkInformationApiConnectivityPlugin() - : this.withConnection(html.window.navigator.connection); + : this.withConnection(html.window.navigator.connection!); /// Creates the plugin, with an override of the NetworkInformation object. @visibleForTesting @@ -32,8 +32,8 @@ class NetworkInformationApiConnectivityPlugin extends ConnectivityPlugin { return networkInformationToConnectivityResult(_networkInformation); } - StreamController _connectivityResultStreamController; - Stream _connectivityResultStream; + late StreamController _connectivityResultStreamController; + late Stream _connectivityResultStream; /// Returns a Stream of ConnectivityResults changes. @override diff --git a/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart index efefd8d52440..78a70268c158 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart @@ -12,10 +12,10 @@ ConnectivityResult networkInformationToConnectivityResult( return ConnectivityResult.none; } if (info.effectiveType != null) { - return _effectiveTypeToConnectivityResult(info.effectiveType); + return _effectiveTypeToConnectivityResult(info.effectiveType!); } if (info.type != null) { - return _typeToConnectivityResult(info.type); + return _typeToConnectivityResult(info.type!); } return ConnectivityResult.none; } diff --git a/packages/connectivity/connectivity_for_web/pubspec.yaml b/packages/connectivity/connectivity_for_web/pubspec.yaml index 3622b15709b6..4fd61922d7be 100644 --- a/packages/connectivity/connectivity_for_web/pubspec.yaml +++ b/packages/connectivity/connectivity_for_web/pubspec.yaml @@ -1,7 +1,7 @@ name: connectivity_for_web description: An implementation for the web platform of the Flutter `connectivity` plugin. This uses the NetworkInformation Web API, with a fallback to Navigator.onLine. -version: 0.3.1+4 repository: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_for_web +version: 0.4.0 flutter: plugin: @@ -11,21 +11,21 @@ flutter: fileName: connectivity_for_web.dart dependencies: - connectivity_platform_interface: ^1.0.3 + connectivity_platform_interface: ^2.0.0 flutter_web_plugins: sdk: flutter flutter: sdk: flutter dev_dependencies: - flutter_driver: - sdk: flutter flutter_test: sdk: flutter + flutter_driver: + sdk: flutter integration_test: - path: ../../integration_test - mockito: ^4.1.1 + sdk: flutter + mockito: ^5.0.0-0 environment: - sdk: ">=2.6.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" From ad9672ff94036e68a259af4b1e2f0a7aa51a13e2 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 26 Feb 2021 18:12:12 -0800 Subject: [PATCH 2/7] Move integration_tests to the right place --- .../connectivity_for_web/example/README.md | 21 +++++++ .../network_information_test.dart} | 55 ++++++++++--------- .../src/connectivity_mocks.dart | 54 ++++++++++++++++++ .../example/lib/main.dart | 25 +++++++++ .../connectivity_for_web/example/pubspec.yaml | 21 +++++++ .../connectivity_for_web/example/run_test.sh | 18 ++++++ .../test_driver/integration_driver.dart | 7 +++ .../{test => example}/web/index.html | 0 .../connectivity_for_web/test/.gitignore | 8 --- .../test/lib/src/connectivity_mocks.dart | 25 --------- .../connectivity_for_web/test/pubspec.yaml | 25 --------- 11 files changed, 174 insertions(+), 85 deletions(-) create mode 100644 packages/connectivity/connectivity_for_web/example/README.md rename packages/connectivity/connectivity_for_web/{test/lib/main.dart => example/integration_test/network_information_test.dart} (57%) create mode 100644 packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart create mode 100644 packages/connectivity/connectivity_for_web/example/lib/main.dart create mode 100644 packages/connectivity/connectivity_for_web/example/pubspec.yaml create mode 100755 packages/connectivity/connectivity_for_web/example/run_test.sh create mode 100644 packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart rename packages/connectivity/connectivity_for_web/{test => example}/web/index.html (100%) delete mode 100644 packages/connectivity/connectivity_for_web/test/.gitignore delete mode 100644 packages/connectivity/connectivity_for_web/test/lib/src/connectivity_mocks.dart delete mode 100644 packages/connectivity/connectivity_for_web/test/pubspec.yaml diff --git a/packages/connectivity/connectivity_for_web/example/README.md b/packages/connectivity/connectivity_for_web/example/README.md new file mode 100644 index 000000000000..0ec01e025570 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/README.md @@ -0,0 +1,21 @@ +# Testing + +This package utilizes the `integration_test` package to run its tests in a web browser. + +See [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) for more info. + +## Running the tests + +Make sure you have updated to the latest Flutter master. + +1. Check what version of Chrome is running on the machine you're running tests on. + +2. Download and install driver for that version from here: + * + +3. Start the driver using `chromedriver --port=4444` + +4. Run tests: `flutter drive -d web-server --browser-name=chrome --driver=test_driver/integration_driver.dart --target=integration_test/TEST_NAME.dart`, or (in Linux): + + * Single: `./run_test.sh integration_test/TEST_NAME.dart` + * All: `./run_test.sh` diff --git a/packages/connectivity/connectivity_for_web/test/lib/main.dart b/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart similarity index 57% rename from packages/connectivity/connectivity_for_web/test/lib/main.dart rename to packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart index e3473532553e..5c3bbf3e5c8e 100644 --- a/packages/connectivity/connectivity_for_web/test/lib/main.dart +++ b/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart @@ -1,9 +1,7 @@ -import 'package:integration_test/integration_test.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; import 'package:connectivity_for_web/src/network_information_api_connectivity_plugin.dart'; - -import 'package:mockito/mockito.dart'; +import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; import 'src/connectivity_mocks.dart'; @@ -12,66 +10,69 @@ void main() { group('checkConnectivity', () { void testCheckConnectivity({ - String type, - String effectiveType, - num downlink = 10, - num rtt = 50, - ConnectivityResult expected, + String? type, + String? effectiveType, + num? downlink = 10, + int? rtt = 50, + required ConnectivityResult expected, }) { - final connection = MockNetworkInformation(); - when(connection.type).thenReturn(type); - when(connection.effectiveType).thenReturn(effectiveType); - when(connection.downlink).thenReturn(downlink); - when(connection.rtt).thenReturn(downlink); + final connection = FakeNetworkInformation( + type: type, + effectiveType: effectiveType, + downlink: downlink, + rtt: rtt, + ); NetworkInformationApiConnectivityPlugin plugin = NetworkInformationApiConnectivityPlugin.withConnection(connection); expect(plugin.checkConnectivity(), completion(equals(expected))); } - test('0 downlink and rtt -> none', () { + testWidgets('0 downlink and rtt -> none', (WidgetTester tester) async { testCheckConnectivity( effectiveType: '4g', downlink: 0, rtt: 0, expected: ConnectivityResult.none); }); - test('slow-2g -> mobile', () { + testWidgets('slow-2g -> mobile', (WidgetTester tester) async { testCheckConnectivity( effectiveType: 'slow-2g', expected: ConnectivityResult.mobile); }); - test('2g -> mobile', () { + testWidgets('2g -> mobile', (WidgetTester tester) async { testCheckConnectivity( effectiveType: '2g', expected: ConnectivityResult.mobile); }); - test('3g -> mobile', () { + testWidgets('3g -> mobile', (WidgetTester tester) async { testCheckConnectivity( effectiveType: '3g', expected: ConnectivityResult.mobile); }); - test('4g -> wifi', () { + testWidgets('4g -> wifi', (WidgetTester tester) async { testCheckConnectivity( effectiveType: '4g', expected: ConnectivityResult.wifi); }); }); group('get onConnectivityChanged', () { - test('puts change events in a Stream', () async { - final connection = MockNetworkInformation(); + testWidgets('puts change events in a Stream', (WidgetTester tester) async { + final connection = FakeNetworkInformation(); NetworkInformationApiConnectivityPlugin plugin = NetworkInformationApiConnectivityPlugin.withConnection(connection); - Stream results = plugin.onConnectivityChanged; + // The onConnectivityChanged stream is infinite, so we only .take(2) so the test completes. + // We need to do .toList() now, because otherwise the Stream won't be listened to, and + // we'll miss the calls to mockChangeValue below. + final results = plugin.onConnectivityChanged.take(2).toList(); // Fake a disconnect-reconnect await connection.mockChangeValue(downlink: 0, rtt: 0); await connection.mockChangeValue( downlink: 10, rtt: 50, effectiveType: '4g'); - // The stream of results is infinite, so we need to .take(2) for this test to complete. + // Expect to see the disconnect-reconnect in the resulting stream. expect( - results.take(2).toList(), - completion( - equals([ConnectivityResult.none, ConnectivityResult.wifi]))); + results, + completion([ConnectivityResult.none, ConnectivityResult.wifi])); }); }); } diff --git a/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart b/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart new file mode 100644 index 000000000000..126e37aa6de8 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart @@ -0,0 +1,54 @@ +import 'dart:async'; +import 'dart:html'; + +import 'package:flutter_test/flutter_test.dart'; + +/// A Fake implementation of the NetworkInformation API that allows +/// for external modification of its values. +/// +/// Note that the DOM API works by internally mutating and broadcasting +/// 'change' events. +class FakeNetworkInformation extends Fake implements NetworkInformation { + final StreamController _onChangeController = StreamController.broadcast(); + String? _type; + String? _effectiveType; + num? _downlink; + int? _rtt; + + @override + Stream get onChange => _onChangeController.stream; + + @override + String? get type => _type; + + @override + String? get effectiveType => _effectiveType; + + @override + num? get downlink => _downlink; + + @override + int? get rtt => _rtt; + + FakeNetworkInformation({ + String? type, + String? effectiveType, + num? downlink, + int? rtt, + }): this._type = type, this._effectiveType = effectiveType, this._downlink = downlink, this._rtt = rtt; + + /// Changes the desired values, and triggers the change event listener. + Future mockChangeValue({ + String? type, + String? effectiveType, + num? downlink, + int? rtt, + }) async { + this._type = type; + this._effectiveType = effectiveType; + this._downlink = downlink; + this._rtt = rtt; + + _onChangeController.add(Event('change')); + } +} diff --git a/packages/connectivity/connectivity_for_web/example/lib/main.dart b/packages/connectivity/connectivity_for_web/example/lib/main.dart new file mode 100644 index 000000000000..e1a38dcdcd46 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/lib/main.dart @@ -0,0 +1,25 @@ +// Copyright 2013 The Flutter Authors. 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:flutter/material.dart'; + +void main() { + runApp(MyApp()); +} + +/// App for testing +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.ltr, + child: Text('Testing... Look at the console output for results!'), + ); + } +} diff --git a/packages/connectivity/connectivity_for_web/example/pubspec.yaml b/packages/connectivity/connectivity_for_web/example/pubspec.yaml new file mode 100644 index 000000000000..54289bc648ec --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/pubspec.yaml @@ -0,0 +1,21 @@ +name: connectivity_for_web_integration_tests +publish_to: none + +dependencies: + connectivity_for_web: + path: ../ + flutter: + sdk: flutter + +dev_dependencies: + js: ^0.6.3 + flutter_test: + sdk: flutter + flutter_driver: + sdk: flutter + integration_test: + sdk: flutter + +environment: + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.27.0-0" # For integration_test from sdk diff --git a/packages/connectivity/connectivity_for_web/example/run_test.sh b/packages/connectivity/connectivity_for_web/example/run_test.sh new file mode 100755 index 000000000000..8e6f149358c9 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/run_test.sh @@ -0,0 +1,18 @@ +#!/usr/bin/bash +if pgrep -lf chromedriver > /dev/null; then + echo "chromedriver is running." + + if [ $# -eq 0 ]; then + echo "No target specified, running all tests..." + find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target='{}' + else + echo "Running test target: $1..." + set -x + flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target=$1 + fi + + else + echo "chromedriver is not running." + echo "Please, check the README.md for instructions on how to use run_test.sh" +fi + diff --git a/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart b/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart new file mode 100644 index 000000000000..64e2248a4f9b --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart @@ -0,0 +1,7 @@ +// Copyright 2019 The Chromium Authors. 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:integration_test/integration_test_driver.dart'; + +Future main() async => integrationDriver(); diff --git a/packages/connectivity/connectivity_for_web/test/web/index.html b/packages/connectivity/connectivity_for_web/example/web/index.html similarity index 100% rename from packages/connectivity/connectivity_for_web/test/web/index.html rename to packages/connectivity/connectivity_for_web/example/web/index.html diff --git a/packages/connectivity/connectivity_for_web/test/.gitignore b/packages/connectivity/connectivity_for_web/test/.gitignore deleted file mode 100644 index d7dee828a6b9..000000000000 --- a/packages/connectivity/connectivity_for_web/test/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -.dart_tool/ - -.packages -.pub/ - -build/ -lib/generated_plugin_registrant.dart diff --git a/packages/connectivity/connectivity_for_web/test/lib/src/connectivity_mocks.dart b/packages/connectivity/connectivity_for_web/test/lib/src/connectivity_mocks.dart deleted file mode 100644 index 7b82b512065b..000000000000 --- a/packages/connectivity/connectivity_for_web/test/lib/src/connectivity_mocks.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'dart:html'; - -import 'package:mockito/mockito.dart'; - -/// A Mock implementation of the NetworkInformation API that allows -/// for external modification of its values. -class MockNetworkInformation extends Mock implements NetworkInformation { - /// The callback that will fire after the network information values change. - Function onchange; - - /// Changes the desired values, and triggers the change event listener. - void mockChangeValue({ - String type, - String effectiveType, - num downlink, - num rtt, - }) async { - when(this.type).thenAnswer((_) => type); - when(this.effectiveType).thenAnswer((_) => effectiveType); - when(this.downlink).thenAnswer((_) => downlink); - when(this.rtt).thenAnswer((_) => rtt); - - onchange(Event('change')); - } -} diff --git a/packages/connectivity/connectivity_for_web/test/pubspec.yaml b/packages/connectivity/connectivity_for_web/test/pubspec.yaml deleted file mode 100644 index 512b7df8c26e..000000000000 --- a/packages/connectivity/connectivity_for_web/test/pubspec.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: connectivity_web_example -description: Example web app for the connectivity plugin -homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_web - -dependencies: - connectivity_for_web: - path: ../ - js: ^0.6.1+1 - flutter_web_plugins: - sdk: flutter - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - flutter_driver: - sdk: flutter - integration_test: - path: ../../../integration_test - mockito: ^4.1.1 - -environment: - sdk: ">=2.6.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4" From 5677a3f8bbf21abbcca2bb265cb5b79b5fdcc89c Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 26 Feb 2021 18:18:50 -0800 Subject: [PATCH 3/7] Simplify _connectivityResultStream so it uses Stream transformations, instead of an internal subscription to another stream (which was hard to cleanup) --- ...k_information_api_connectivity_plugin.dart | 31 ++++++------------- .../lib/src/utils/connectivity_result.dart | 2 +- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart index c5ec776b3b58..7c4fb113e7b0 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart @@ -1,7 +1,5 @@ import 'dart:async'; import 'dart:html' as html show window, NetworkInformation; -import 'dart:js'; -import 'dart:js_util'; import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; import 'package:connectivity_for_web/connectivity_for_web.dart'; @@ -32,30 +30,19 @@ class NetworkInformationApiConnectivityPlugin extends ConnectivityPlugin { return networkInformationToConnectivityResult(_networkInformation); } - late StreamController _connectivityResultStreamController; - late Stream _connectivityResultStream; + Stream? _connectivityResultStream; /// Returns a Stream of ConnectivityResults changes. @override Stream get onConnectivityChanged { - if (_connectivityResultStreamController == null) { - _connectivityResultStreamController = - StreamController(); - setProperty(_networkInformation, 'onchange', allowInterop((_) { - _connectivityResultStreamController - .add(networkInformationToConnectivityResult(_networkInformation)); - })); - // TODO: Implement the above with _networkInformation.onChange: - // _networkInformation.onChange.listen((_) { - // _connectivityResult - // .add(networkInformationToConnectivityResult(_networkInformation)); - // }); - // Once we can detect when to *cancel* a subscription to the _networkInformation - // onChange Stream upon hot restart. - // https://github.com/dart-lang/sdk/issues/42679 - _connectivityResultStream = - _connectivityResultStreamController.stream.asBroadcastStream(); + if (_connectivityResultStream == null) { + _connectivityResultStream = _networkInformation.onChange.map((_) { + // The incoming event doesn't contain any network information. Instead, + // the values of window.navigator.connection will mutate. + return networkInformationToConnectivityResult(_networkInformation); + }); } - return _connectivityResultStream; + + return _connectivityResultStream!; } } diff --git a/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart index 78a70268c158..e7eb8969231a 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart @@ -3,7 +3,7 @@ import 'package:connectivity_platform_interface/connectivity_platform_interface. /// Converts an incoming NetworkInformation object into the correct ConnectivityResult. ConnectivityResult networkInformationToConnectivityResult( - html.NetworkInformation info, + html.NetworkInformation? info, ) { if (info == null) { return ConnectivityResult.none; From cbfec80f00b2229ca713cc2f3eb9b5350f089703 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 26 Feb 2021 18:19:23 -0800 Subject: [PATCH 4/7] Add root tests to tell the user where the integration tests are --- .../connectivity/connectivity_for_web/test/README.md | 5 +++++ .../test/tests_exist_elsewhere_test.dart | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 packages/connectivity/connectivity_for_web/test/README.md create mode 100644 packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart diff --git a/packages/connectivity/connectivity_for_web/test/README.md b/packages/connectivity/connectivity_for_web/test/README.md new file mode 100644 index 000000000000..7c5b4ad682ba --- /dev/null +++ b/packages/connectivity/connectivity_for_web/test/README.md @@ -0,0 +1,5 @@ +## test + +This package uses integration tests for testing. + +See `example/README.md` for more info. diff --git a/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart b/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart new file mode 100644 index 000000000000..334f52186d9d --- /dev/null +++ b/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart @@ -0,0 +1,10 @@ +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('Tell the user where to find the real tests', () { + print('---'); + print('This package uses integration_test for its tests.'); + print('See `example/README.md` for more info.'); + print('---'); + }); +} From 29aa268b4fbeb65e15d1bc03b988843170f51814 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 26 Feb 2021 18:19:39 -0800 Subject: [PATCH 5/7] pubspec cleanup --- packages/connectivity/connectivity_for_web/pubspec.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/connectivity/connectivity_for_web/pubspec.yaml b/packages/connectivity/connectivity_for_web/pubspec.yaml index 4fd61922d7be..5c673e83b44a 100644 --- a/packages/connectivity/connectivity_for_web/pubspec.yaml +++ b/packages/connectivity/connectivity_for_web/pubspec.yaml @@ -20,11 +20,6 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_driver: - sdk: flutter - integration_test: - sdk: flutter - mockito: ^5.0.0-0 environment: sdk: ">=2.12.0-259.9.beta <3.0.0" From bddbfda38024e344a6b3670fd81b81a22bc63b42 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 1 Mar 2021 16:35:43 -0800 Subject: [PATCH 6/7] Restore writing to onchange directly, instead of using a transform stream, to prevent multiple attachments on hot reload. --- .../network_information_test.dart | 9 ++--- .../src/connectivity_mocks.dart | 16 +++++---- ...k_information_api_connectivity_plugin.dart | 33 ++++++++++++++----- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart b/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart index 5c3bbf3e5c8e..f8e8059e7dba 100644 --- a/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart +++ b/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart @@ -60,8 +60,8 @@ void main() { NetworkInformationApiConnectivityPlugin.withConnection(connection); // The onConnectivityChanged stream is infinite, so we only .take(2) so the test completes. - // We need to do .toList() now, because otherwise the Stream won't be listened to, and - // we'll miss the calls to mockChangeValue below. + // We need to do .toList() now, because otherwise the Stream won't be actually listened to, + // and we'll miss the calls to mockChangeValue below. final results = plugin.onConnectivityChanged.take(2).toList(); // Fake a disconnect-reconnect @@ -71,8 +71,9 @@ void main() { // Expect to see the disconnect-reconnect in the resulting stream. expect( - results, - completion([ConnectivityResult.none, ConnectivityResult.wifi])); + results, + completion([ConnectivityResult.none, ConnectivityResult.wifi]), + ); }); }); } diff --git a/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart b/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart index 126e37aa6de8..fc795595e3f3 100644 --- a/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart +++ b/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart @@ -1,23 +1,20 @@ import 'dart:async'; import 'dart:html'; +import 'dart:js_util' show getProperty; import 'package:flutter_test/flutter_test.dart'; /// A Fake implementation of the NetworkInformation API that allows /// for external modification of its values. -/// +/// /// Note that the DOM API works by internally mutating and broadcasting /// 'change' events. class FakeNetworkInformation extends Fake implements NetworkInformation { - final StreamController _onChangeController = StreamController.broadcast(); String? _type; String? _effectiveType; num? _downlink; int? _rtt; - @override - Stream get onChange => _onChangeController.stream; - @override String? get type => _type; @@ -35,7 +32,10 @@ class FakeNetworkInformation extends Fake implements NetworkInformation { String? effectiveType, num? downlink, int? rtt, - }): this._type = type, this._effectiveType = effectiveType, this._downlink = downlink, this._rtt = rtt; + }) : this._type = type, + this._effectiveType = effectiveType, + this._downlink = downlink, + this._rtt = rtt; /// Changes the desired values, and triggers the change event listener. Future mockChangeValue({ @@ -49,6 +49,8 @@ class FakeNetworkInformation extends Fake implements NetworkInformation { this._downlink = downlink; this._rtt = rtt; - _onChangeController.add(Event('change')); + // This is set by the onConnectivityChanged getter... + final Function onchange = getProperty(this, 'onchange') as Function; + onchange(Event('change')); } } diff --git a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart index 7c4fb113e7b0..800be2ef238f 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart @@ -1,5 +1,7 @@ import 'dart:async'; import 'dart:html' as html show window, NetworkInformation; +import 'dart:js' show allowInterop; +import 'dart:js_util' show setProperty; import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; import 'package:connectivity_for_web/connectivity_for_web.dart'; @@ -30,19 +32,32 @@ class NetworkInformationApiConnectivityPlugin extends ConnectivityPlugin { return networkInformationToConnectivityResult(_networkInformation); } - Stream? _connectivityResultStream; + StreamController? _connectivityResultStreamController; + late Stream _connectivityResultStream; /// Returns a Stream of ConnectivityResults changes. @override Stream get onConnectivityChanged { - if (_connectivityResultStream == null) { - _connectivityResultStream = _networkInformation.onChange.map((_) { - // The incoming event doesn't contain any network information. Instead, - // the values of window.navigator.connection will mutate. - return networkInformationToConnectivityResult(_networkInformation); - }); + if (_connectivityResultStreamController == null) { + _connectivityResultStreamController = + StreamController(); + + // Directly write the 'onchange' function on the networkInformation object. + setProperty(_networkInformation, 'onchange', allowInterop((_) { + _connectivityResultStreamController! + .add(networkInformationToConnectivityResult(_networkInformation)); + })); + // TODO: Implement the above with _networkInformation.onChange: + // _networkInformation.onChange.listen((_) { + // _connectivityResult + // .add(networkInformationToConnectivityResult(_networkInformation)); + // }); + // Once we can detect when to *cancel* a subscription to the _networkInformation + // onChange Stream upon hot restart. + // https://github.com/dart-lang/sdk/issues/42679 + _connectivityResultStream = + _connectivityResultStreamController!.stream.asBroadcastStream(); } - - return _connectivityResultStream!; + return _connectivityResultStream; } } From 6da5bcd31b2e8df1022ed04afb686878a72ff41d Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 2 Mar 2021 10:10:43 -0800 Subject: [PATCH 7/7] Fix null-check in late variable! --- .../lib/src/dart_html_connectivity_plugin.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart index c5a7acdc76e4..950d26804371 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart @@ -14,21 +14,21 @@ class DartHtmlConnectivityPlugin extends ConnectivityPlugin { : ConnectivityResult.none; } - late StreamController _connectivityResult; + StreamController? _connectivityResult; /// Returns a Stream of ConnectivityResults changes. @override Stream get onConnectivityChanged { if (_connectivityResult == null) { - _connectivityResult = StreamController(); + _connectivityResult = StreamController.broadcast(); // Fallback to dart:html window.onOnline / window.onOffline html.window.onOnline.listen((event) { - _connectivityResult.add(ConnectivityResult.wifi); + _connectivityResult!.add(ConnectivityResult.wifi); }); html.window.onOffline.listen((event) { - _connectivityResult.add(ConnectivityResult.none); + _connectivityResult!.add(ConnectivityResult.none); }); } - return _connectivityResult.stream; + return _connectivityResult!.stream; } }