From 46a4b2370eb3ef4da856b7df4852b967224fea7c Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Tue, 20 Oct 2020 14:49:43 +0200 Subject: [PATCH 01/21] Add null safety to web implementation --- .../url_launcher/url_launcher/pubspec.yaml | 5 ++-- .../url_launcher_web/CHANGELOG.md | 4 +++ .../lib/url_launcher_web.dart | 20 ++++++------- .../url_launcher_web/pubspec.yaml | 4 +-- .../url_launcher_web_integration.dart | 30 ++----------------- 5 files changed, 21 insertions(+), 42 deletions(-) diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 2fdfd8caf217..a525b0ae2a39 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -12,9 +12,8 @@ flutter: pluginClass: UrlLauncherPlugin ios: pluginClass: FLTURLLauncherPlugin - # TODO(mvanbeusekom): Temporary disabled until web is migrated to nnbd (advised by @blasten). - #web: - # default_package: url_launcher_web + web: + default_package: url_launcher_web linux: default_package: url_laucher_linux macos: diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md index 0416c033bf2b..69e32b2d8ea6 100644 --- a/packages/url_launcher/url_launcher_web/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.2.0-nullsafety + +- Migrate to null safety. + # 0.1.5+3 - Fix Link misalignment [issue](https://github.com/flutter/flutter/issues/70053). diff --git a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart index 969cfbaa2dfd..e4d2116445cf 100644 --- a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart +++ b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart @@ -19,7 +19,7 @@ const _safariTargetTopSchemes = { 'tel', 'sms', }; -String _getUrlScheme(String url) => Uri.tryParse(url)?.scheme; +String? _getUrlScheme(String url) => Uri.tryParse(url)?.scheme; bool _isSafariTargetTopScheme(String url) => _safariTargetTopSchemes.contains(_getUrlScheme(url)); @@ -38,7 +38,7 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { }.union(_safariTargetTopSchemes); /// A constructor that allows tests to override the window object used by the plugin. - UrlLauncherPlugin({@visibleForTesting html.Window debugWindow}) + UrlLauncherPlugin({@visibleForTesting html.Window? debugWindow}) : _window = debugWindow ?? html.window { _isSafari = navigatorIsSafari(_window.navigator); } @@ -58,7 +58,7 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { /// /// Returns the newly created window. @visibleForTesting - html.WindowBase openNewWindow(String url, {String webOnlyWindowName}) { + html.WindowBase openNewWindow(String url, {String? webOnlyWindowName}) { // We need to open mailto, tel and sms urls on the _top window context on safari browsers. // See https://github.com/flutter/flutter/issues/51461 for reference. final target = webOnlyWindowName ?? @@ -74,13 +74,13 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { @override Future launch( String url, { - @required bool useSafariVC, - @required bool useWebView, - @required bool enableJavaScript, - @required bool enableDomStorage, - @required bool universalLinksOnly, - @required Map headers, - String webOnlyWindowName, + bool useSafariVC = false, + bool useWebView = false, + bool enableJavaScript = false, + bool enableDomStorage = false, + bool universalLinksOnly = false, + Map headers = const {}, + String? webOnlyWindowName, }) { return Future.value( openNewWindow(url, webOnlyWindowName: webOnlyWindowName) != null); diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 77a958677015..3523aa5853ba 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.1.7 + meta: ^1.3.0-nullsafety.3 dev_dependencies: flutter_test: @@ -34,7 +34,7 @@ dev_dependencies: # TODO(mvanbeusekom): Update to use pub.dev once null safety version is published. # url_launcher: # path: ../url_launcher - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety.1 mockito: ^4.1.1 integration_test: path: ../../integration_test diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart index bfa94821e41a..1e346f818439 100644 --- a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart +++ b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart @@ -21,10 +21,10 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('UrlLauncherPlugin', () { - _MockWindow mockWindow; - _MockNavigator mockNavigator; + late _MockWindow mockWindow; + late _MockNavigator mockNavigator; - UrlLauncherPlugin plugin; + late UrlLauncherPlugin plugin; setUp(() { mockWindow = _MockWindow(); @@ -75,12 +75,6 @@ void main() { expect( plugin.launch( 'https://www.google.com', - useSafariVC: null, - useWebView: null, - universalLinksOnly: null, - enableDomStorage: null, - enableJavaScript: null, - headers: null, ), completion(isTrue)); }); @@ -89,12 +83,6 @@ void main() { expect( plugin.launch( 'mailto:name@mydomain.com', - useSafariVC: null, - useWebView: null, - universalLinksOnly: null, - enableDomStorage: null, - enableJavaScript: null, - headers: null, ), completion(isTrue)); }); @@ -103,12 +91,6 @@ void main() { expect( plugin.launch( 'tel:5551234567', - useSafariVC: null, - useWebView: null, - universalLinksOnly: null, - enableDomStorage: null, - enableJavaScript: null, - headers: null, ), completion(isTrue)); }); @@ -117,12 +99,6 @@ void main() { expect( plugin.launch( 'sms:+19725551212?body=hello%20there', - useSafariVC: null, - useWebView: null, - universalLinksOnly: null, - enableDomStorage: null, - enableJavaScript: null, - headers: null, ), completion(isTrue)); }); From ac7429c2c9d3c6fb58a84177dad5dc117e5106dc Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 3 Feb 2021 10:55:20 -0800 Subject: [PATCH 02/21] Migrate Link to null safety, and update pubspec.yaml --- .../url_launcher_web/lib/src/link.dart | 48 ++++++++++--------- .../url_launcher_web/pubspec.yaml | 23 +++------ 2 files changed, 32 insertions(+), 39 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/lib/src/link.dart b/packages/url_launcher/url_launcher_web/lib/src/link.dart index 8169a9c11b94..731aa300d874 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/link.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/link.dart @@ -45,16 +45,16 @@ class WebLinkDelegate extends StatefulWidget { /// For external URIs, it lets the browser do its thing. For app route names, it /// pushes the route name to the framework. class WebLinkDelegateState extends State { - LinkViewController _controller; + late LinkViewController _controller; @override void didUpdateWidget(WebLinkDelegate oldWidget) { super.didUpdateWidget(oldWidget); if (widget.link.uri != oldWidget.link.uri) { - _controller?.setUri(widget.link.uri); + _controller.setUri(widget.link.uri!); } if (widget.link.target != oldWidget.link.target) { - _controller?.setTarget(widget.link.target); + _controller.setTarget(widget.link.target); } } @@ -78,7 +78,7 @@ class WebLinkDelegateState extends State { onCreatePlatformView: (PlatformViewCreationParams params) { _controller = LinkViewController.fromParams(params, context); return _controller - ..setUri(widget.link.uri) + ..setUri(widget.link.uri!) ..setTarget(widget.link.target); }, surfaceFactory: @@ -126,15 +126,15 @@ class LinkViewController extends PlatformViewController { static Map _instances = {}; static html.Element _viewFactory(int viewId) { - return _instances[viewId]?._element; + return _instances[viewId]!._element; } - static int _hitTestedViewId; + static int? _hitTestedViewId; - static StreamSubscription _clickSubscription; + static late StreamSubscription _clickSubscription; static void _onGlobalClick(html.MouseEvent event) { - final int viewId = getViewIdFromTarget(event); + final int? viewId = getViewIdFromTarget(event); _instances[viewId]?._onDomClick(event); // After the DOM click event has been received, clean up the hit test state // so we can start fresh on the next click. @@ -161,7 +161,7 @@ class LinkViewController extends PlatformViewController { /// The context of the [Link] widget that created this controller. final BuildContext context; - html.Element _element; + late html.Element _element; bool get _isInitialized => _element != null; Future _initialize() async { @@ -207,7 +207,7 @@ class LinkViewController extends PlatformViewController { pushRouteNameToFramework(context, routeName); } - Uri _uri; + late Uri _uri; /// Set the [Uri] value for this link. void setUri(Uri uri) { @@ -264,8 +264,8 @@ class LinkViewController extends PlatformViewController { } /// Finds the view id of the DOM element targeted by the [event]. -int getViewIdFromTarget(html.Event event) { - final html.Element linkElement = getLinkElementFromTarget(event); +int? getViewIdFromTarget(html.Event event) { + final html.Element? linkElement = getLinkElementFromTarget(event); if (linkElement != null) { return getProperty(linkElement, linkViewIdProperty); } @@ -275,15 +275,17 @@ int getViewIdFromTarget(html.Event event) { /// Finds the targeted DOM element by the [event]. /// /// It handles the case where the target element is inside a shadow DOM too. -html.Element getLinkElementFromTarget(html.Event event) { - final html.Element target = event.target; - if (isLinkElement(target)) { - return target; - } - if (target.shadowRoot != null) { - final html.Element child = target.shadowRoot.lastChild; - if (isLinkElement(child)) { - return child; +html.Element? getLinkElementFromTarget(html.Event event) { + final html.EventTarget? target = event.target; + if (target != null && target is html.Element) { + if (isLinkElement(target)) { + return target; + } + if (target.shadowRoot != null) { + final html.Node? child = target.shadowRoot!.lastChild; + if (child != null && child is html.Element && isLinkElement(child)) { + return child; + } } } return null; @@ -291,6 +293,6 @@ html.Element getLinkElementFromTarget(html.Event event) { /// Checks if the given [element] is a link that was created by /// [LinkViewController]. -bool isLinkElement(html.Element element) { - return element.tagName == 'A' && hasProperty(element, linkViewIdProperty); +bool isLinkElement(html.Element? element) { + return element != null && element.tagName == 'A' && hasProperty(element, linkViewIdProperty); } diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 3523aa5853ba..736bb90ba80c 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -4,7 +4,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/u # 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.1.5+3 +version: 2.0.0-nullsafety flutter: plugin: @@ -14,13 +14,7 @@ flutter: fileName: url_launcher_web.dart dependencies: - url_launcher_platform_interface: ^1.0.9 - # TODO(mvanbeusekom): Update to use pub.dev once null safety version is published. - # url_launcher_platform_interface: - # git: - # url: https://github.com/flutter/plugins.git - # ref: nnbd - # path: packages/url_launcher/url_launcher_platform_interface + url_launcher_platform_interface: ^2.0.0-nullsafety flutter: sdk: flutter flutter_web_plugins: @@ -30,15 +24,12 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - url_launcher: ^5.2.5 - # TODO(mvanbeusekom): Update to use pub.dev once null safety version is published. - # url_launcher: - # path: ../url_launcher + url_launcher: ^6.0.0-nullsafety.6 pedantic: ^1.10.0-nullsafety.1 - mockito: ^4.1.1 + mockito: ^5.0.0-nullsafety.5 integration_test: - path: ../../integration_test + sdk: flutter environment: - sdk: ">=2.2.0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0-0 <3.0.0" + flutter: ">=1.26.0-0" # For integration_test from sdk From 01bde668202266f2b56c3e16e0943f02f87604a5 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 3 Feb 2021 10:55:41 -0800 Subject: [PATCH 03/21] Migrate test to null safety, and update pubspec.yaml (WIP) --- .../url_launcher_web/test/pubspec.yaml | 7 ++++--- .../test_driver/url_launcher_web_integration.dart | 15 +++++++-------- .../url_launcher_web_integration_test.dart | 1 - 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/test/pubspec.yaml b/packages/url_launcher/url_launcher_web/test/pubspec.yaml index b8c541f72986..542df79eeef1 100644 --- a/packages/url_launcher/url_launcher_web/test/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/test/pubspec.yaml @@ -2,7 +2,8 @@ name: regular_integration_tests publish_to: none environment: - sdk: ">=2.10.0-56.0.dev <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" + flutter: ">=1.26.0-0" # For integration_test from sdk dependencies: flutter: @@ -14,9 +15,9 @@ dev_dependencies: flutter_test: sdk: flutter http: ^0.12.2 - mockito: ^4.1.1 + mockito: ^5.0.0-nullsafety.5 url_launcher_web: path: ../ integration_test: - path: ../../../integration_test + sdk: flutter diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart index 1e346f818439..1244b3b5d595 100644 --- a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart +++ b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.9 import 'dart:html' as html; import 'dart:js_util'; import 'package:flutter/widgets.dart'; @@ -219,7 +218,7 @@ void main() { child: WebLinkDelegate(TestLinkInfo( uri: uri, target: LinkTarget.blank, - builder: (BuildContext context, FollowLink followLink) { + builder: (BuildContext context, FollowLink? followLink) { return Container(width: 100, height: 100); }, )), @@ -237,7 +236,7 @@ void main() { child: WebLinkDelegate(TestLinkInfo( uri: uri2, target: LinkTarget.self, - builder: (BuildContext context, FollowLink followLink) { + builder: (BuildContext context, FollowLink? followLink) { return Container(width: 100, height: 100); }, )), @@ -260,7 +259,7 @@ void main() { child: WebLinkDelegate(TestLinkInfo( uri: uri, target: LinkTarget.blank, - builder: (BuildContext context, FollowLink followLink) { + builder: (BuildContext context, FollowLink? followLink) { return Container( key: containerKey, child: SizedBox(width: 50.0, height: 50.0), @@ -294,7 +293,7 @@ html.Element _findSingleAnchor() { // Search inside platform views with shadow roots as well. for (final html.Element platformView in html.document.querySelectorAll('flt-platform-view')) { - final html.ShadowRoot shadowRoot = platformView.shadowRoot; + final html.ShadowRoot shadowRoot = platformView.shadowRoot!; if (shadowRoot != null) { for (final html.Element anchor in shadowRoot.querySelectorAll('a')) { if (hasProperty(anchor, linkViewIdProperty)) { @@ -321,8 +320,8 @@ class TestLinkInfo extends LinkInfo { bool get isDisabled => uri == null; TestLinkInfo({ - @required this.uri, - @required this.target, - @required this.builder, + required this.uri, + required this.target, + required this.builder, }); } diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart index 2d68bb93e9a7..64e2248a4f9b 100644 --- a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart +++ b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.9 import 'package:integration_test/integration_test_driver.dart'; Future main() async => integrationDriver(); From 5c9910f6fc9c1ed622b06732be1c6a58077a3386 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 3 Feb 2021 11:02:43 -0800 Subject: [PATCH 04/21] Split LinkWidget tests from plugin tests. --- .../test_driver/link_widget_integration.dart | 131 ++++++++++++++++++ .../link_widget_integration_test.dart | 7 + .../url_launcher_web_integration.dart | 120 ---------------- 3 files changed, 138 insertions(+), 120 deletions(-) create mode 100644 packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration.dart create mode 100644 packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration_test.dart diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration.dart b/packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration.dart new file mode 100644 index 000000000000..56a45cd459ee --- /dev/null +++ b/packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration.dart @@ -0,0 +1,131 @@ +// 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 'dart:html' as html; +import 'dart:js_util'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:url_launcher_platform_interface/link.dart'; +import 'package:url_launcher_web/src/link.dart'; +import 'package:integration_test/integration_test.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('Link Widget', () { + testWidgets('creates anchor with correct attributes', + (WidgetTester tester) async { + final Uri uri = Uri.parse('http://foobar/example?q=1'); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: WebLinkDelegate(TestLinkInfo( + uri: uri, + target: LinkTarget.blank, + builder: (BuildContext context, FollowLink? followLink) { + return Container(width: 100, height: 100); + }, + )), + )); + // Platform view creation happens asynchronously. + await tester.pumpAndSettle(); + + final html.Element anchor = _findSingleAnchor(); + expect(anchor.getAttribute('href'), uri.toString()); + expect(anchor.getAttribute('target'), '_blank'); + + final Uri uri2 = Uri.parse('http://foobar2/example?q=2'); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: WebLinkDelegate(TestLinkInfo( + uri: uri2, + target: LinkTarget.self, + builder: (BuildContext context, FollowLink? followLink) { + return Container(width: 100, height: 100); + }, + )), + )); + await tester.pumpAndSettle(); + + // Check that the same anchor has been updated. + expect(anchor.getAttribute('href'), uri2.toString()); + expect(anchor.getAttribute('target'), '_self'); + }); + + testWidgets('sizes itself correctly', (WidgetTester tester) async { + final Key containerKey = GlobalKey(); + final Uri uri = Uri.parse('http://foobar'); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: ConstrainedBox( + constraints: BoxConstraints.tight(Size(100.0, 100.0)), + child: WebLinkDelegate(TestLinkInfo( + uri: uri, + target: LinkTarget.blank, + builder: (BuildContext context, FollowLink? followLink) { + return Container( + key: containerKey, + child: SizedBox(width: 50.0, height: 50.0), + ); + }, + )), + ), + ), + )); + await tester.pumpAndSettle(); + + final Size containerSize = tester.getSize(find.byKey(containerKey)); + // The Stack widget inserted by the `WebLinkDelegate` shouldn't loosen the + // constraints before passing them to the inner container. So the inner + // container should respect the tight constraints given by the ancestor + // `ConstrainedBox` widget. + expect(containerSize.width, 100.0); + expect(containerSize.height, 100.0); + }); + }); +} + +html.Element _findSingleAnchor() { + final List foundAnchors = []; + for (final html.Element anchor in html.document.querySelectorAll('a')) { + if (hasProperty(anchor, linkViewIdProperty)) { + foundAnchors.add(anchor); + } + } + + // Search inside platform views with shadow roots as well. + for (final html.Element platformView + in html.document.querySelectorAll('flt-platform-view')) { + final html.ShadowRoot shadowRoot = platformView.shadowRoot!; + if (shadowRoot != null) { + for (final html.Element anchor in shadowRoot.querySelectorAll('a')) { + if (hasProperty(anchor, linkViewIdProperty)) { + foundAnchors.add(anchor); + } + } + } + } + + return foundAnchors.single; +} + +class TestLinkInfo extends LinkInfo { + @override + final LinkWidgetBuilder builder; + + @override + final Uri uri; + + @override + final LinkTarget target; + + @override + bool get isDisabled => uri == null; + + TestLinkInfo({ + required this.uri, + required this.target, + required this.builder, + }); +} diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration_test.dart b/packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration_test.dart new file mode 100644 index 000000000000..64e2248a4f9b --- /dev/null +++ b/packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration_test.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/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart index 1244b3b5d595..9ca7e9a82614 100644 --- a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart +++ b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart @@ -3,12 +3,8 @@ // found in the LICENSE file. import 'dart:html' as html; -import 'dart:js_util'; -import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:url_launcher_platform_interface/link.dart'; import 'package:url_launcher_web/url_launcher_web.dart'; -import 'package:url_launcher_web/src/link.dart'; import 'package:mockito/mockito.dart'; import 'package:integration_test/integration_test.dart'; @@ -208,120 +204,4 @@ void main() { }); }); }); - - group('link', () { - testWidgets('creates anchor with correct attributes', - (WidgetTester tester) async { - final Uri uri = Uri.parse('http://foobar/example?q=1'); - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: WebLinkDelegate(TestLinkInfo( - uri: uri, - target: LinkTarget.blank, - builder: (BuildContext context, FollowLink? followLink) { - return Container(width: 100, height: 100); - }, - )), - )); - // Platform view creation happens asynchronously. - await tester.pumpAndSettle(); - - final html.Element anchor = _findSingleAnchor(); - expect(anchor.getAttribute('href'), uri.toString()); - expect(anchor.getAttribute('target'), '_blank'); - - final Uri uri2 = Uri.parse('http://foobar2/example?q=2'); - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: WebLinkDelegate(TestLinkInfo( - uri: uri2, - target: LinkTarget.self, - builder: (BuildContext context, FollowLink? followLink) { - return Container(width: 100, height: 100); - }, - )), - )); - await tester.pumpAndSettle(); - - // Check that the same anchor has been updated. - expect(anchor.getAttribute('href'), uri2.toString()); - expect(anchor.getAttribute('target'), '_self'); - }); - - testWidgets('sizes itself correctly', (WidgetTester tester) async { - final Key containerKey = GlobalKey(); - final Uri uri = Uri.parse('http://foobar'); - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: ConstrainedBox( - constraints: BoxConstraints.tight(Size(100.0, 100.0)), - child: WebLinkDelegate(TestLinkInfo( - uri: uri, - target: LinkTarget.blank, - builder: (BuildContext context, FollowLink? followLink) { - return Container( - key: containerKey, - child: SizedBox(width: 50.0, height: 50.0), - ); - }, - )), - ), - ), - )); - await tester.pumpAndSettle(); - - final Size containerSize = tester.getSize(find.byKey(containerKey)); - // The Stack widget inserted by the `WebLinkDelegate` shouldn't loosen the - // constraints before passing them to the inner container. So the inner - // container should respect the tight constraints given by the ancestor - // `ConstrainedBox` widget. - expect(containerSize.width, 100.0); - expect(containerSize.height, 100.0); - }); - }); -} - -html.Element _findSingleAnchor() { - final List foundAnchors = []; - for (final html.Element anchor in html.document.querySelectorAll('a')) { - if (hasProperty(anchor, linkViewIdProperty)) { - foundAnchors.add(anchor); - } - } - - // Search inside platform views with shadow roots as well. - for (final html.Element platformView - in html.document.querySelectorAll('flt-platform-view')) { - final html.ShadowRoot shadowRoot = platformView.shadowRoot!; - if (shadowRoot != null) { - for (final html.Element anchor in shadowRoot.querySelectorAll('a')) { - if (hasProperty(anchor, linkViewIdProperty)) { - foundAnchors.add(anchor); - } - } - } - } - - return foundAnchors.single; -} - -class TestLinkInfo extends LinkInfo { - @override - final LinkWidgetBuilder builder; - - @override - final Uri uri; - - @override - final LinkTarget target; - - @override - bool get isDisabled => uri == null; - - TestLinkInfo({ - required this.uri, - required this.target, - required this.builder, - }); } From 3a9e3d8127b93bc7c49efabcb9af7eae6dd4a0f0 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 5 Feb 2021 16:48:06 -0800 Subject: [PATCH 05/21] Codegen mocks Move tests to the right directory structure Update run_test script to work with all of the above --- .../url_launcher_web/pubspec.yaml | 1 + .../url_launcher_web/test/.gitignore | 1 + .../url_launcher_web/test/build.yaml | 6 ++++ .../link_widget_test.dart} | 0 .../url_launcher_web_test.dart} | 34 +++++++++---------- .../url_launcher_web/test/pubspec.yaml | 2 +- .../url_launcher_web/test/run_test | 9 +++-- ...test.dart => integration_test_driver.dart} | 0 .../url_launcher_web_integration_test.dart | 7 ---- 9 files changed, 32 insertions(+), 28 deletions(-) create mode 100644 packages/url_launcher/url_launcher_web/test/.gitignore create mode 100644 packages/url_launcher/url_launcher_web/test/build.yaml rename packages/url_launcher/url_launcher_web/test/{test_driver/link_widget_integration.dart => integration_test/link_widget_test.dart} (100%) rename packages/url_launcher/url_launcher_web/test/{test_driver/url_launcher_web_integration.dart => integration_test/url_launcher_web_test.dart} (89%) rename packages/url_launcher/url_launcher_web/test/test_driver/{link_widget_integration_test.dart => integration_test_driver.dart} (100%) delete mode 100644 packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 736bb90ba80c..6884068dfb80 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -29,6 +29,7 @@ dev_dependencies: mockito: ^5.0.0-nullsafety.5 integration_test: sdk: flutter + build_runner: ^1.10.0 environment: sdk: ">=2.12.0-0 <3.0.0" diff --git a/packages/url_launcher/url_launcher_web/test/.gitignore b/packages/url_launcher/url_launcher_web/test/.gitignore new file mode 100644 index 000000000000..b0e815e2d903 --- /dev/null +++ b/packages/url_launcher/url_launcher_web/test/.gitignore @@ -0,0 +1 @@ +integration_test/*.mocks.dart diff --git a/packages/url_launcher/url_launcher_web/test/build.yaml b/packages/url_launcher/url_launcher_web/test/build.yaml new file mode 100644 index 000000000000..db3104bb04c6 --- /dev/null +++ b/packages/url_launcher/url_launcher_web/test/build.yaml @@ -0,0 +1,6 @@ +targets: + $default: + sources: + - integration_test/*.dart + - lib/$lib$ + - $package$ diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration.dart b/packages/url_launcher/url_launcher_web/test/integration_test/link_widget_test.dart similarity index 100% rename from packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration.dart rename to packages/url_launcher/url_launcher_web/test/integration_test/link_widget_test.dart diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart similarity index 89% rename from packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart rename to packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart index 9ca7e9a82614..2c0b78710f65 100644 --- a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart +++ b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart @@ -4,28 +4,37 @@ import 'dart:html' as html; import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; import 'package:url_launcher_web/url_launcher_web.dart'; import 'package:mockito/mockito.dart'; import 'package:integration_test/integration_test.dart'; -class _MockWindow extends Mock implements html.Window {} - -class _MockNavigator extends Mock implements html.Navigator {} +import 'url_launcher_web_test.mocks.dart'; +@GenerateMocks([], customMocks: [ + MockSpec(returnNullOnMissingStub: true), + MockSpec(returnNullOnMissingStub: true) +]) void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('UrlLauncherPlugin', () { - late _MockWindow mockWindow; - late _MockNavigator mockNavigator; + late MockWindow mockWindow; + late MockNavigator mockNavigator; late UrlLauncherPlugin plugin; setUp(() { - mockWindow = _MockWindow(); - mockNavigator = _MockNavigator(); + mockWindow = MockWindow(); + mockNavigator = MockNavigator(); when(mockWindow.navigator).thenReturn(mockNavigator); + // Simulate that window.open does something. + when(mockWindow.open(any, any)).thenReturn(MockWindow()); + + when(mockNavigator.vendor).thenReturn('Google LLC'); + when(mockNavigator.appVersion).thenReturn('Mock version!'); + plugin = UrlLauncherPlugin(debugWindow: mockWindow); }); @@ -55,17 +64,6 @@ void main() { }); group('launch', () { - setUp(() { - // Simulate that window.open does something. - when(mockWindow.open('https://www.google.com', '')) - .thenReturn(_MockWindow()); - when(mockWindow.open('mailto:name@mydomain.com', '')) - .thenReturn(_MockWindow()); - when(mockWindow.open('tel:5551234567', '')).thenReturn(_MockWindow()); - when(mockWindow.open('sms:+19725551212?body=hello%20there', '')) - .thenReturn(_MockWindow()); - }); - testWidgets('launching a URL returns true', (WidgetTester _) async { expect( plugin.launch( diff --git a/packages/url_launcher/url_launcher_web/test/pubspec.yaml b/packages/url_launcher/url_launcher_web/test/pubspec.yaml index 542df79eeef1..35e653285c3a 100644 --- a/packages/url_launcher/url_launcher_web/test/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/test/pubspec.yaml @@ -20,4 +20,4 @@ dev_dependencies: path: ../ integration_test: sdk: flutter - + build_runner: ^1.10.0 diff --git a/packages/url_launcher/url_launcher_web/test/run_test b/packages/url_launcher/url_launcher_web/test/run_test index 74a8526a0fa3..a9789d0faee3 100755 --- a/packages/url_launcher/url_launcher_web/test/run_test +++ b/packages/url_launcher/url_launcher_web/test/run_test @@ -2,13 +2,18 @@ if pgrep -lf chromedriver > /dev/null; then echo "chromedriver is running." + flutter pub get + + echo "(Re)generating mocks." + flutter pub run build_runner build + if [ $# -eq 0 ]; then echo "No target specified, running all tests..." - find test_driver/ -iname *_integration.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --target='{}' + 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_test_driver.dart --target='{}' else echo "Running test target: $1..." set -x - flutter drive -d web-server --web-port=7357 --browser-name=chrome --target=$1 + flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test_driver.dart --target=$1 fi else diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration_test.dart b/packages/url_launcher/url_launcher_web/test/test_driver/integration_test_driver.dart similarity index 100% rename from packages/url_launcher/url_launcher_web/test/test_driver/link_widget_integration_test.dart rename to packages/url_launcher/url_launcher_web/test/test_driver/integration_test_driver.dart diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart deleted file mode 100644 index 64e2248a4f9b..000000000000 --- a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart +++ /dev/null @@ -1,7 +0,0 @@ -// 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(); From ddd7020ba77ee8fda62cf961df6f54d63806764a Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 5 Feb 2021 17:35:36 -0800 Subject: [PATCH 06/21] Fix changelog version. --- packages/url_launcher/url_launcher_web/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md index 69e32b2d8ea6..49d72457ecd9 100644 --- a/packages/url_launcher/url_launcher_web/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.2.0-nullsafety +# 2.0.0-nullsafety - Migrate to null safety. From 04d0f557813b8b37dffc526971753b280bccfce2 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 8 Feb 2021 16:42:37 -0800 Subject: [PATCH 07/21] Add back ignored file, so analyzer doesn't complain about it not existing. --- .../url_launcher_web/test/.gitignore | 1 - .../url_launcher_web_test.mocks.dart | 652 ++++++++++++++++++ 2 files changed, 652 insertions(+), 1 deletion(-) delete mode 100644 packages/url_launcher/url_launcher_web/test/.gitignore create mode 100644 packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart diff --git a/packages/url_launcher/url_launcher_web/test/.gitignore b/packages/url_launcher/url_launcher_web/test/.gitignore deleted file mode 100644 index b0e815e2d903..000000000000 --- a/packages/url_launcher/url_launcher_web/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -integration_test/*.mocks.dart diff --git a/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart new file mode 100644 index 000000000000..5e1e77dcae61 --- /dev/null +++ b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart @@ -0,0 +1,652 @@ +import 'dart:async' as _i4; +import 'dart:html' as _i2; +import 'dart:math' as _i5; +import 'dart:web_sql' as _i3; + +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: comment_references + +// ignore_for_file: unnecessary_parenthesis + +class _FakeDocument extends _i1.Fake implements _i2.Document {} + +class _FakeLocation extends _i1.Fake implements _i2.Location {} + +class _FakeConsole extends _i1.Fake implements _i2.Console {} + +class _FakeHistory extends _i1.Fake implements _i2.History {} + +class _FakeStorage extends _i1.Fake implements _i2.Storage {} + +class _FakeNavigator extends _i1.Fake implements _i2.Navigator {} + +class _FakePerformance extends _i1.Fake implements _i2.Performance {} + +class _FakeEvents extends _i1.Fake implements _i2.Events {} + +class _FakeType extends _i1.Fake implements Type {} + +class _FakeWindowBase extends _i1.Fake implements _i2.WindowBase {} + +class _FakeFileSystem extends _i1.Fake implements _i2.FileSystem {} + +class _FakeStylePropertyMapReadonly extends _i1.Fake + implements _i2.StylePropertyMapReadonly {} + +class _FakeMediaQueryList extends _i1.Fake implements _i2.MediaQueryList {} + +class _FakeEntry extends _i1.Fake implements _i2.Entry {} + +class _FakeSqlDatabase extends _i1.Fake implements _i3.SqlDatabase {} + +class _FakeGeolocation extends _i1.Fake implements _i2.Geolocation {} + +class _FakeMediaStream extends _i1.Fake implements _i2.MediaStream {} + +class _FakeRelatedApplication extends _i1.Fake + implements _i2.RelatedApplication {} + +/// A class which mocks [Window]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockWindow extends _i1.Mock implements _i2.Window { + @override + _i4.Future get animationFrame => + (super.noSuchMethod(Invocation.getter(#animationFrame), Future.value(0)) + as _i4.Future); + @override + _i2.Document get document => + (super.noSuchMethod(Invocation.getter(#document), _FakeDocument()) + as _i2.Document); + @override + _i2.Location get location => + (super.noSuchMethod(Invocation.getter(#location), _FakeLocation()) + as _i2.Location); + @override + set location(_i2.LocationBase? value) => + super.noSuchMethod(Invocation.setter(#location, value)); + @override + _i2.Console get console => + (super.noSuchMethod(Invocation.getter(#console), _FakeConsole()) + as _i2.Console); + @override + num get devicePixelRatio => + (super.noSuchMethod(Invocation.getter(#devicePixelRatio), 0) as num); + @override + _i2.History get history => + (super.noSuchMethod(Invocation.getter(#history), _FakeHistory()) + as _i2.History); + @override + _i2.Storage get localStorage => + (super.noSuchMethod(Invocation.getter(#localStorage), _FakeStorage()) + as _i2.Storage); + @override + _i2.Navigator get navigator => + (super.noSuchMethod(Invocation.getter(#navigator), _FakeNavigator()) + as _i2.Navigator); + @override + int get outerHeight => + (super.noSuchMethod(Invocation.getter(#outerHeight), 0) as int); + @override + int get outerWidth => + (super.noSuchMethod(Invocation.getter(#outerWidth), 0) as int); + @override + _i2.Performance get performance => + (super.noSuchMethod(Invocation.getter(#performance), _FakePerformance()) + as _i2.Performance); + @override + _i2.Storage get sessionStorage => + (super.noSuchMethod(Invocation.getter(#sessionStorage), _FakeStorage()) + as _i2.Storage); + @override + _i4.Stream<_i2.Event> get onContentLoaded => (super.noSuchMethod( + Invocation.getter(#onContentLoaded), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onAbort => (super + .noSuchMethod(Invocation.getter(#onAbort), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onBlur => + (super.noSuchMethod(Invocation.getter(#onBlur), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onCanPlay => (super.noSuchMethod( + Invocation.getter(#onCanPlay), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onCanPlayThrough => (super.noSuchMethod( + Invocation.getter(#onCanPlayThrough), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onChange => (super + .noSuchMethod(Invocation.getter(#onChange), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.MouseEvent> get onClick => (super.noSuchMethod( + Invocation.getter(#onClick), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onContextMenu => (super.noSuchMethod( + Invocation.getter(#onContextMenu), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.Event> get onDoubleClick => (super.noSuchMethod( + Invocation.getter(#onDoubleClick), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.DeviceMotionEvent> get onDeviceMotion => (super.noSuchMethod( + Invocation.getter(#onDeviceMotion), + Stream<_i2.DeviceMotionEvent>.empty()) + as _i4.Stream<_i2.DeviceMotionEvent>); + @override + _i4.Stream<_i2.DeviceOrientationEvent> get onDeviceOrientation => + (super.noSuchMethod(Invocation.getter(#onDeviceOrientation), + Stream<_i2.DeviceOrientationEvent>.empty()) + as _i4.Stream<_i2.DeviceOrientationEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDrag => (super.noSuchMethod( + Invocation.getter(#onDrag), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragEnd => (super.noSuchMethod( + Invocation.getter(#onDragEnd), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragEnter => (super.noSuchMethod( + Invocation.getter(#onDragEnter), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragLeave => (super.noSuchMethod( + Invocation.getter(#onDragLeave), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragOver => (super.noSuchMethod( + Invocation.getter(#onDragOver), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragStart => (super.noSuchMethod( + Invocation.getter(#onDragStart), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDrop => (super.noSuchMethod( + Invocation.getter(#onDrop), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.Event> get onDurationChange => (super.noSuchMethod( + Invocation.getter(#onDurationChange), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onEmptied => (super.noSuchMethod( + Invocation.getter(#onEmptied), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onEnded => (super + .noSuchMethod(Invocation.getter(#onEnded), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onError => (super + .noSuchMethod(Invocation.getter(#onError), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onFocus => (super + .noSuchMethod(Invocation.getter(#onFocus), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onHashChange => (super.noSuchMethod( + Invocation.getter(#onHashChange), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onInput => (super + .noSuchMethod(Invocation.getter(#onInput), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onInvalid => (super.noSuchMethod( + Invocation.getter(#onInvalid), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.KeyboardEvent> get onKeyDown => (super.noSuchMethod( + Invocation.getter(#onKeyDown), Stream<_i2.KeyboardEvent>.empty()) + as _i4.Stream<_i2.KeyboardEvent>); + @override + _i4.Stream<_i2.KeyboardEvent> get onKeyPress => (super.noSuchMethod( + Invocation.getter(#onKeyPress), Stream<_i2.KeyboardEvent>.empty()) + as _i4.Stream<_i2.KeyboardEvent>); + @override + _i4.Stream<_i2.KeyboardEvent> get onKeyUp => (super.noSuchMethod( + Invocation.getter(#onKeyUp), Stream<_i2.KeyboardEvent>.empty()) + as _i4.Stream<_i2.KeyboardEvent>); + @override + _i4.Stream<_i2.Event> get onLoad => + (super.noSuchMethod(Invocation.getter(#onLoad), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onLoadedData => (super.noSuchMethod( + Invocation.getter(#onLoadedData), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onLoadedMetadata => (super.noSuchMethod( + Invocation.getter(#onLoadedMetadata), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onLoadStart => (super.noSuchMethod( + Invocation.getter(#onLoadStart), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.MessageEvent> get onMessage => (super.noSuchMethod( + Invocation.getter(#onMessage), Stream<_i2.MessageEvent>.empty()) + as _i4.Stream<_i2.MessageEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseDown => (super.noSuchMethod( + Invocation.getter(#onMouseDown), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseEnter => (super.noSuchMethod( + Invocation.getter(#onMouseEnter), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseLeave => (super.noSuchMethod( + Invocation.getter(#onMouseLeave), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseMove => (super.noSuchMethod( + Invocation.getter(#onMouseMove), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseOut => (super.noSuchMethod( + Invocation.getter(#onMouseOut), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseOver => (super.noSuchMethod( + Invocation.getter(#onMouseOver), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseUp => (super.noSuchMethod( + Invocation.getter(#onMouseUp), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.WheelEvent> get onMouseWheel => (super.noSuchMethod( + Invocation.getter(#onMouseWheel), Stream<_i2.WheelEvent>.empty()) + as _i4.Stream<_i2.WheelEvent>); + @override + _i4.Stream<_i2.Event> get onOffline => (super.noSuchMethod( + Invocation.getter(#onOffline), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onOnline => (super + .noSuchMethod(Invocation.getter(#onOnline), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPageHide => (super.noSuchMethod( + Invocation.getter(#onPageHide), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPageShow => (super.noSuchMethod( + Invocation.getter(#onPageShow), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPause => (super + .noSuchMethod(Invocation.getter(#onPause), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPlay => + (super.noSuchMethod(Invocation.getter(#onPlay), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPlaying => (super.noSuchMethod( + Invocation.getter(#onPlaying), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.PopStateEvent> get onPopState => (super.noSuchMethod( + Invocation.getter(#onPopState), Stream<_i2.PopStateEvent>.empty()) + as _i4.Stream<_i2.PopStateEvent>); + @override + _i4.Stream<_i2.Event> get onProgress => (super.noSuchMethod( + Invocation.getter(#onProgress), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onRateChange => (super.noSuchMethod( + Invocation.getter(#onRateChange), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onReset => (super + .noSuchMethod(Invocation.getter(#onReset), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onResize => (super + .noSuchMethod(Invocation.getter(#onResize), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onScroll => (super + .noSuchMethod(Invocation.getter(#onScroll), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSearch => (super + .noSuchMethod(Invocation.getter(#onSearch), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSeeked => (super + .noSuchMethod(Invocation.getter(#onSeeked), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSeeking => (super.noSuchMethod( + Invocation.getter(#onSeeking), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSelect => (super + .noSuchMethod(Invocation.getter(#onSelect), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onStalled => (super.noSuchMethod( + Invocation.getter(#onStalled), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.StorageEvent> get onStorage => (super.noSuchMethod( + Invocation.getter(#onStorage), Stream<_i2.StorageEvent>.empty()) + as _i4.Stream<_i2.StorageEvent>); + @override + _i4.Stream<_i2.Event> get onSubmit => (super + .noSuchMethod(Invocation.getter(#onSubmit), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSuspend => (super.noSuchMethod( + Invocation.getter(#onSuspend), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onTimeUpdate => (super.noSuchMethod( + Invocation.getter(#onTimeUpdate), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchCancel => (super.noSuchMethod( + Invocation.getter(#onTouchCancel), Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchEnd => (super.noSuchMethod( + Invocation.getter(#onTouchEnd), Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchMove => (super.noSuchMethod( + Invocation.getter(#onTouchMove), Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchStart => (super.noSuchMethod( + Invocation.getter(#onTouchStart), Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TransitionEvent> get onTransitionEnd => (super.noSuchMethod( + Invocation.getter(#onTransitionEnd), + Stream<_i2.TransitionEvent>.empty()) as _i4.Stream<_i2.TransitionEvent>); + @override + _i4.Stream<_i2.Event> get onUnload => (super + .noSuchMethod(Invocation.getter(#onUnload), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onVolumeChange => (super.noSuchMethod( + Invocation.getter(#onVolumeChange), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onWaiting => (super.noSuchMethod( + Invocation.getter(#onWaiting), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.AnimationEvent> get onAnimationEnd => (super.noSuchMethod( + Invocation.getter(#onAnimationEnd), + Stream<_i2.AnimationEvent>.empty()) as _i4.Stream<_i2.AnimationEvent>); + @override + _i4.Stream<_i2.AnimationEvent> get onAnimationIteration => + (super.noSuchMethod(Invocation.getter(#onAnimationIteration), + Stream<_i2.AnimationEvent>.empty()) + as _i4.Stream<_i2.AnimationEvent>); + @override + _i4.Stream<_i2.AnimationEvent> get onAnimationStart => (super.noSuchMethod( + Invocation.getter(#onAnimationStart), + Stream<_i2.AnimationEvent>.empty()) as _i4.Stream<_i2.AnimationEvent>); + @override + _i4.Stream<_i2.Event> get onBeforeUnload => (super.noSuchMethod( + Invocation.getter(#onBeforeUnload), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.WheelEvent> get onWheel => (super.noSuchMethod( + Invocation.getter(#onWheel), Stream<_i2.WheelEvent>.empty()) + as _i4.Stream<_i2.WheelEvent>); + @override + int get pageXOffset => + (super.noSuchMethod(Invocation.getter(#pageXOffset), 0) as int); + @override + int get pageYOffset => + (super.noSuchMethod(Invocation.getter(#pageYOffset), 0) as int); + @override + int get scrollX => + (super.noSuchMethod(Invocation.getter(#scrollX), 0) as int); + @override + int get scrollY => + (super.noSuchMethod(Invocation.getter(#scrollY), 0) as int); + @override + _i2.Events get on => + (super.noSuchMethod(Invocation.getter(#on), _FakeEvents()) as _i2.Events); + @override + int get hashCode => + (super.noSuchMethod(Invocation.getter(#hashCode), 0) as int); + @override + Type get runtimeType => + (super.noSuchMethod(Invocation.getter(#runtimeType), _FakeType()) + as Type); + @override + _i2.WindowBase open(String? url, String? name, [String? options]) => + (super.noSuchMethod( + Invocation.method(#open, [url, name, options]), _FakeWindowBase()) + as _i2.WindowBase); + @override + int requestAnimationFrame(_i2.FrameRequestCallback? callback) => + (super.noSuchMethod( + Invocation.method(#requestAnimationFrame, [callback]), 0) as int); + @override + void cancelAnimationFrame(int? id) => + super.noSuchMethod(Invocation.method(#cancelAnimationFrame, [id])); + @override + _i4.Future<_i2.FileSystem> requestFileSystem(int? size, {bool? persistent}) => + (super.noSuchMethod( + Invocation.method( + #requestFileSystem, [size], {#persistent: persistent}), + Future.value(_FakeFileSystem())) as _i4.Future<_i2.FileSystem>); + @override + void cancelIdleCallback(int? handle) => + super.noSuchMethod(Invocation.method(#cancelIdleCallback, [handle])); + @override + bool confirm([String? message]) => + (super.noSuchMethod(Invocation.method(#confirm, [message]), false) + as bool); + @override + _i4.Future fetch(dynamic input, [Map? init]) => + (super.noSuchMethod( + Invocation.method(#fetch, [input, init]), Future.value(null)) + as _i4.Future); + @override + bool find(String? string, bool? caseSensitive, bool? backwards, bool? wrap, + bool? wholeWord, bool? searchInFrames, bool? showDialog) => + (super.noSuchMethod( + Invocation.method(#find, [ + string, + caseSensitive, + backwards, + wrap, + wholeWord, + searchInFrames, + showDialog + ]), + false) as bool); + @override + _i2.StylePropertyMapReadonly getComputedStyleMap( + _i2.Element? element, String? pseudoElement) => + (super.noSuchMethod( + Invocation.method(#getComputedStyleMap, [element, pseudoElement]), + _FakeStylePropertyMapReadonly()) as _i2.StylePropertyMapReadonly); + @override + List<_i2.CssRule> getMatchedCssRules( + _i2.Element? element, String? pseudoElement) => + (super.noSuchMethod( + Invocation.method(#getMatchedCssRules, [element, pseudoElement]), + <_i2.CssRule>[]) as List<_i2.CssRule>); + @override + _i2.MediaQueryList matchMedia(String? query) => (super.noSuchMethod( + Invocation.method(#matchMedia, [query]), _FakeMediaQueryList()) + as _i2.MediaQueryList); + @override + void moveBy(int? x, int? y) => + super.noSuchMethod(Invocation.method(#moveBy, [x, y])); + @override + void postMessage(dynamic message, String? targetOrigin, + [List? transfer]) => + super.noSuchMethod( + Invocation.method(#postMessage, [message, targetOrigin, transfer])); + @override + int requestIdleCallback(_i2.IdleRequestCallback? callback, + [Map? options]) => + (super.noSuchMethod( + Invocation.method(#requestIdleCallback, [callback, options]), 0) + as int); + @override + void resizeBy(int? x, int? y) => + super.noSuchMethod(Invocation.method(#resizeBy, [x, y])); + @override + void resizeTo(int? x, int? y) => + super.noSuchMethod(Invocation.method(#resizeTo, [x, y])); + @override + _i4.Future<_i2.Entry> resolveLocalFileSystemUrl(String? url) => + (super.noSuchMethod(Invocation.method(#resolveLocalFileSystemUrl, [url]), + Future.value(_FakeEntry())) as _i4.Future<_i2.Entry>); + @override + String atob(String? atob) => + (super.noSuchMethod(Invocation.method(#atob, [atob]), '') as String); + @override + String btoa(String? btoa) => + (super.noSuchMethod(Invocation.method(#btoa, [btoa]), '') as String); + @override + void moveTo(_i5.Point? p) => + super.noSuchMethod(Invocation.method(#moveTo, [p])); + @override + _i3.SqlDatabase openDatabase(String? name, String? version, + String? displayName, int? estimatedSize, + [_i2.DatabaseCallback? creationCallback]) => + (super.noSuchMethod( + Invocation.method(#openDatabase, + [name, version, displayName, estimatedSize, creationCallback]), + _FakeSqlDatabase()) as _i3.SqlDatabase); + @override + void addEventListener(String? type, _i2.EventListener? listener, + [bool? useCapture]) => + super.noSuchMethod( + Invocation.method(#addEventListener, [type, listener, useCapture])); + @override + void removeEventListener(String? type, _i2.EventListener? listener, + [bool? useCapture]) => + super.noSuchMethod(Invocation.method( + #removeEventListener, [type, listener, useCapture])); + @override + bool dispatchEvent(_i2.Event? event) => + (super.noSuchMethod(Invocation.method(#dispatchEvent, [event]), false) + as bool); + @override + bool operator ==(Object? other) => + (super.noSuchMethod(Invocation.method(#==, [other]), false) as bool); + @override + String toString() => + (super.noSuchMethod(Invocation.method(#toString, []), '') as String); +} + +/// A class which mocks [Navigator]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockNavigator extends _i1.Mock implements _i2.Navigator { + @override + String get language => + (super.noSuchMethod(Invocation.getter(#language), '') as String); + @override + _i2.Geolocation get geolocation => + (super.noSuchMethod(Invocation.getter(#geolocation), _FakeGeolocation()) + as _i2.Geolocation); + @override + String get vendor => + (super.noSuchMethod(Invocation.getter(#vendor), '') as String); + @override + String get vendorSub => + (super.noSuchMethod(Invocation.getter(#vendorSub), '') as String); + @override + String get appCodeName => + (super.noSuchMethod(Invocation.getter(#appCodeName), '') as String); + @override + String get appName => + (super.noSuchMethod(Invocation.getter(#appName), '') as String); + @override + String get appVersion => + (super.noSuchMethod(Invocation.getter(#appVersion), '') as String); + @override + String get product => + (super.noSuchMethod(Invocation.getter(#product), '') as String); + @override + String get userAgent => + (super.noSuchMethod(Invocation.getter(#userAgent), '') as String); + @override + int get hashCode => + (super.noSuchMethod(Invocation.getter(#hashCode), 0) as int); + @override + Type get runtimeType => + (super.noSuchMethod(Invocation.getter(#runtimeType), _FakeType()) + as Type); + @override + List<_i2.Gamepad?> getGamepads() => + (super.noSuchMethod(Invocation.method(#getGamepads, []), <_i2.Gamepad?>[]) + as List<_i2.Gamepad?>); + @override + _i4.Future<_i2.MediaStream> getUserMedia({dynamic audio, dynamic video}) => + (super.noSuchMethod( + Invocation.method(#getUserMedia, [], {#audio: audio, #video: video}), + Future.value(_FakeMediaStream())) as _i4.Future<_i2.MediaStream>); + @override + _i4.Future getBattery() => (super + .noSuchMethod(Invocation.method(#getBattery, []), Future.value(null)) + as _i4.Future); + @override + _i4.Future<_i2.RelatedApplication> getInstalledRelatedApps() => + (super.noSuchMethod(Invocation.method(#getInstalledRelatedApps, []), + Future.value(_FakeRelatedApplication())) + as _i4.Future<_i2.RelatedApplication>); + @override + _i4.Future getVRDisplays() => (super.noSuchMethod( + Invocation.method(#getVRDisplays, []), Future.value(null)) + as _i4.Future); + @override + void registerProtocolHandler(String? scheme, String? url, String? title) => + super.noSuchMethod( + Invocation.method(#registerProtocolHandler, [scheme, url, title])); + @override + _i4.Future requestKeyboardLock([List? keyCodes]) => + (super.noSuchMethod(Invocation.method(#requestKeyboardLock, [keyCodes]), + Future.value(null)) as _i4.Future); + @override + _i4.Future requestMidiAccess([Map? options]) => + (super.noSuchMethod(Invocation.method(#requestMidiAccess, [options]), + Future.value(null)) as _i4.Future); + @override + _i4.Future requestMediaKeySystemAccess(String? keySystem, + List>? supportedConfigurations) => + (super.noSuchMethod( + Invocation.method(#requestMediaKeySystemAccess, + [keySystem, supportedConfigurations]), + Future.value(null)) as _i4.Future); + @override + bool sendBeacon(String? url, Object? data) => + (super.noSuchMethod(Invocation.method(#sendBeacon, [url, data]), false) + as bool); + @override + _i4.Future share([Map? data]) => + (super.noSuchMethod(Invocation.method(#share, [data]), Future.value(null)) + as _i4.Future); + @override + bool operator ==(Object? other) => + (super.noSuchMethod(Invocation.method(#==, [other]), false) as bool); + @override + String toString() => + (super.noSuchMethod(Invocation.method(#toString, []), '') as String); +} From ffaf7d708415462b9f4cee2f63d608530df03aab Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 8 Feb 2021 17:08:55 -0800 Subject: [PATCH 08/21] dartfmt -w . --- packages/url_launcher/url_launcher_web/lib/src/link.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/url_launcher/url_launcher_web/lib/src/link.dart b/packages/url_launcher/url_launcher_web/lib/src/link.dart index 731aa300d874..28e9fcf6d9b0 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/link.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/link.dart @@ -294,5 +294,7 @@ html.Element? getLinkElementFromTarget(html.Event event) { /// Checks if the given [element] is a link that was created by /// [LinkViewController]. bool isLinkElement(html.Element? element) { - return element != null && element.tagName == 'A' && hasProperty(element, linkViewIdProperty); + return element != null && + element.tagName == 'A' && + hasProperty(element, linkViewIdProperty); } From c4c9fd4358a83e7f831800187403e4a98bd153f0 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 8 Feb 2021 17:52:57 -0800 Subject: [PATCH 09/21] Manual changes to generated mocks for analyzer to pass. --- .../url_launcher_web_test.dart | 5 +---- .../url_launcher_web_test.mocks.dart | 21 +++++++++---------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart index 2c0b78710f65..f7ea35667530 100644 --- a/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart +++ b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart @@ -11,10 +11,7 @@ import 'package:integration_test/integration_test.dart'; import 'url_launcher_web_test.mocks.dart'; -@GenerateMocks([], customMocks: [ - MockSpec(returnNullOnMissingStub: true), - MockSpec(returnNullOnMissingStub: true) -]) +@GenerateMocks([html.Window, html.Navigator]) void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart index 5e1e77dcae61..2bbac513643f 100644 --- a/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart +++ b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart @@ -1,7 +1,6 @@ import 'dart:async' as _i4; import 'dart:html' as _i2; import 'dart:math' as _i5; -import 'dart:web_sql' as _i3; import 'package:mockito/mockito.dart' as _i1; @@ -9,6 +8,8 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: unnecessary_parenthesis +// ignore_for_file: extra_positional_arguments_could_be_named + class _FakeDocument extends _i1.Fake implements _i2.Document {} class _FakeLocation extends _i1.Fake implements _i2.Location {} @@ -38,8 +39,6 @@ class _FakeMediaQueryList extends _i1.Fake implements _i2.MediaQueryList {} class _FakeEntry extends _i1.Fake implements _i2.Entry {} -class _FakeSqlDatabase extends _i1.Fake implements _i3.SqlDatabase {} - class _FakeGeolocation extends _i1.Fake implements _i2.Geolocation {} class _FakeMediaStream extends _i1.Fake implements _i2.MediaStream {} @@ -51,6 +50,10 @@ class _FakeRelatedApplication extends _i1.Fake /// /// See the documentation for Mockito's code generation for more information. class MockWindow extends _i1.Mock implements _i2.Window { + MockWindow() { + _i1.throwOnMissingStub(this); + } + @override _i4.Future get animationFrame => (super.noSuchMethod(Invocation.getter(#animationFrame), Future.value(0)) @@ -526,14 +529,6 @@ class MockWindow extends _i1.Mock implements _i2.Window { void moveTo(_i5.Point? p) => super.noSuchMethod(Invocation.method(#moveTo, [p])); @override - _i3.SqlDatabase openDatabase(String? name, String? version, - String? displayName, int? estimatedSize, - [_i2.DatabaseCallback? creationCallback]) => - (super.noSuchMethod( - Invocation.method(#openDatabase, - [name, version, displayName, estimatedSize, creationCallback]), - _FakeSqlDatabase()) as _i3.SqlDatabase); - @override void addEventListener(String? type, _i2.EventListener? listener, [bool? useCapture]) => super.noSuchMethod( @@ -559,6 +554,10 @@ class MockWindow extends _i1.Mock implements _i2.Window { /// /// See the documentation for Mockito's code generation for more information. class MockNavigator extends _i1.Mock implements _i2.Navigator { + MockNavigator() { + _i1.throwOnMissingStub(this); + } + @override String get language => (super.noSuchMethod(Invocation.getter(#language), '') as String); From c24337f780574546383b5b1200e59955cbc6cd24 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 10 Feb 2021 12:15:58 -0800 Subject: [PATCH 10/21] Revert "Manual changes to generated mocks for analyzer to pass." This reverts commit f82c60669ef4aeac355de1e207a2c5c76260a7c1. --- .../url_launcher_web_test.dart | 5 ++++- .../url_launcher_web_test.mocks.dart | 21 ++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart index f7ea35667530..2c0b78710f65 100644 --- a/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart +++ b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart @@ -11,7 +11,10 @@ import 'package:integration_test/integration_test.dart'; import 'url_launcher_web_test.mocks.dart'; -@GenerateMocks([html.Window, html.Navigator]) +@GenerateMocks([], customMocks: [ + MockSpec(returnNullOnMissingStub: true), + MockSpec(returnNullOnMissingStub: true) +]) void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart index 2bbac513643f..5e1e77dcae61 100644 --- a/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart +++ b/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart @@ -1,6 +1,7 @@ import 'dart:async' as _i4; import 'dart:html' as _i2; import 'dart:math' as _i5; +import 'dart:web_sql' as _i3; import 'package:mockito/mockito.dart' as _i1; @@ -8,8 +9,6 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: unnecessary_parenthesis -// ignore_for_file: extra_positional_arguments_could_be_named - class _FakeDocument extends _i1.Fake implements _i2.Document {} class _FakeLocation extends _i1.Fake implements _i2.Location {} @@ -39,6 +38,8 @@ class _FakeMediaQueryList extends _i1.Fake implements _i2.MediaQueryList {} class _FakeEntry extends _i1.Fake implements _i2.Entry {} +class _FakeSqlDatabase extends _i1.Fake implements _i3.SqlDatabase {} + class _FakeGeolocation extends _i1.Fake implements _i2.Geolocation {} class _FakeMediaStream extends _i1.Fake implements _i2.MediaStream {} @@ -50,10 +51,6 @@ class _FakeRelatedApplication extends _i1.Fake /// /// See the documentation for Mockito's code generation for more information. class MockWindow extends _i1.Mock implements _i2.Window { - MockWindow() { - _i1.throwOnMissingStub(this); - } - @override _i4.Future get animationFrame => (super.noSuchMethod(Invocation.getter(#animationFrame), Future.value(0)) @@ -529,6 +526,14 @@ class MockWindow extends _i1.Mock implements _i2.Window { void moveTo(_i5.Point? p) => super.noSuchMethod(Invocation.method(#moveTo, [p])); @override + _i3.SqlDatabase openDatabase(String? name, String? version, + String? displayName, int? estimatedSize, + [_i2.DatabaseCallback? creationCallback]) => + (super.noSuchMethod( + Invocation.method(#openDatabase, + [name, version, displayName, estimatedSize, creationCallback]), + _FakeSqlDatabase()) as _i3.SqlDatabase); + @override void addEventListener(String? type, _i2.EventListener? listener, [bool? useCapture]) => super.noSuchMethod( @@ -554,10 +559,6 @@ class MockWindow extends _i1.Mock implements _i2.Window { /// /// See the documentation for Mockito's code generation for more information. class MockNavigator extends _i1.Mock implements _i2.Navigator { - MockNavigator() { - _i1.throwOnMissingStub(this); - } - @override String get language => (super.noSuchMethod(Invocation.getter(#language), '') as String); From 272079e0f48df27877b33de46ce1396aeb821fcc Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 10 Feb 2021 12:17:14 -0800 Subject: [PATCH 11/21] Rename 'test' to 'example' --- .../url_launcher/url_launcher_web/{test => example}/README.md | 0 .../url_launcher/url_launcher_web/{test => example}/build.yaml | 0 .../{test => example}/integration_test/link_widget_test.dart | 0 .../{test => example}/integration_test/url_launcher_web_test.dart | 0 .../integration_test/url_launcher_web_test.mocks.dart | 0 .../url_launcher/url_launcher_web/{test => example}/lib/main.dart | 0 .../url_launcher/url_launcher_web/{test => example}/pubspec.yaml | 0 packages/url_launcher/url_launcher_web/{test => example}/run_test | 0 .../{test => example}/test_driver/integration_test_driver.dart | 0 .../url_launcher_web/{test => example}/web/index.html | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename packages/url_launcher/url_launcher_web/{test => example}/README.md (100%) rename packages/url_launcher/url_launcher_web/{test => example}/build.yaml (100%) rename packages/url_launcher/url_launcher_web/{test => example}/integration_test/link_widget_test.dart (100%) rename packages/url_launcher/url_launcher_web/{test => example}/integration_test/url_launcher_web_test.dart (100%) rename packages/url_launcher/url_launcher_web/{test => example}/integration_test/url_launcher_web_test.mocks.dart (100%) rename packages/url_launcher/url_launcher_web/{test => example}/lib/main.dart (100%) rename packages/url_launcher/url_launcher_web/{test => example}/pubspec.yaml (100%) rename packages/url_launcher/url_launcher_web/{test => example}/run_test (100%) rename packages/url_launcher/url_launcher_web/{test => example}/test_driver/integration_test_driver.dart (100%) rename packages/url_launcher/url_launcher_web/{test => example}/web/index.html (100%) diff --git a/packages/url_launcher/url_launcher_web/test/README.md b/packages/url_launcher/url_launcher_web/example/README.md similarity index 100% rename from packages/url_launcher/url_launcher_web/test/README.md rename to packages/url_launcher/url_launcher_web/example/README.md diff --git a/packages/url_launcher/url_launcher_web/test/build.yaml b/packages/url_launcher/url_launcher_web/example/build.yaml similarity index 100% rename from packages/url_launcher/url_launcher_web/test/build.yaml rename to packages/url_launcher/url_launcher_web/example/build.yaml diff --git a/packages/url_launcher/url_launcher_web/test/integration_test/link_widget_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart similarity index 100% rename from packages/url_launcher/url_launcher_web/test/integration_test/link_widget_test.dart rename to packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart diff --git a/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart similarity index 100% rename from packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.dart rename to packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart diff --git a/packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart similarity index 100% rename from packages/url_launcher/url_launcher_web/test/integration_test/url_launcher_web_test.mocks.dart rename to packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart diff --git a/packages/url_launcher/url_launcher_web/test/lib/main.dart b/packages/url_launcher/url_launcher_web/example/lib/main.dart similarity index 100% rename from packages/url_launcher/url_launcher_web/test/lib/main.dart rename to packages/url_launcher/url_launcher_web/example/lib/main.dart diff --git a/packages/url_launcher/url_launcher_web/test/pubspec.yaml b/packages/url_launcher/url_launcher_web/example/pubspec.yaml similarity index 100% rename from packages/url_launcher/url_launcher_web/test/pubspec.yaml rename to packages/url_launcher/url_launcher_web/example/pubspec.yaml diff --git a/packages/url_launcher/url_launcher_web/test/run_test b/packages/url_launcher/url_launcher_web/example/run_test similarity index 100% rename from packages/url_launcher/url_launcher_web/test/run_test rename to packages/url_launcher/url_launcher_web/example/run_test diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/integration_test_driver.dart b/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart similarity index 100% rename from packages/url_launcher/url_launcher_web/test/test_driver/integration_test_driver.dart rename to packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart diff --git a/packages/url_launcher/url_launcher_web/test/web/index.html b/packages/url_launcher/url_launcher_web/example/web/index.html similarity index 100% rename from packages/url_launcher/url_launcher_web/test/web/index.html rename to packages/url_launcher/url_launcher_web/example/web/index.html From 69fbf42462c879438959ea8a65ce2e5d98941ecb Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 10 Feb 2021 12:21:56 -0800 Subject: [PATCH 12/21] Exclude Mockito5 mocks from analysis. --- analysis_options.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/analysis_options.yaml b/analysis_options.yaml index 47cdbd2f98dc..2b62a6a9e2b9 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -4,6 +4,7 @@ analyzer: # Ignore generated files - '**/*.g.dart' - 'lib/src/generated/*.dart' + - '**/*.mocks.dart' # Mockito @GenerateMocks errors: always_require_non_null_named_parameters: false # not needed with nnbd unnecessary_null_comparison: false # Turned as long as nnbd mix-mode is supported. From 75d4fec39f6f40e859361c50065083a265893fbd Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 10 Feb 2021 12:40:33 -0800 Subject: [PATCH 13/21] Improve example docs to describe how tests are run better. --- .../url_launcher_web/example/README.md | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/example/README.md b/packages/url_launcher/url_launcher_web/example/README.md index 7c48d024ba57..787f9da02950 100644 --- a/packages/url_launcher/url_launcher_web/example/README.md +++ b/packages/url_launcher/url_launcher_web/example/README.md @@ -1,4 +1,10 @@ -# Running browser_tests +# 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. @@ -9,9 +15,17 @@ Make sure you have updated to the latest Flutter master. 3. Start the driver using `chromedriver --port=4444` -4. Change into the `test` directory of your clone. +4. Run tests: `flutter drive -d web-server --browser-name=chrome --driver=test_driver/integration_test_driver.dart --target=integration_test/TEST_NAME.dart`, or (in Linux): -5. Run tests: `flutter drive -d web-server --browser-name=chrome --target=test_driver/TEST_NAME_integration.dart`, or (in Linux): - - * Single: `./run_test test_driver/TEST_NAME_integration.dart` + * Single: `./run_test integration_test/TEST_NAME.dart` * All: `./run_test` + +## Mocks + +There's `.mocks.dart` files next to the test files that use them. + +They're [generated by Mockito](https://github.com/dart-lang/mockito/blob/master/NULL_SAFETY_README.md#code-generation). + +Mocks might be manually re-generated with the following command: `flutter pub run build_runner build`. If there are any changes in the mocks, feel free to commit them. + +(Mocks will be auto-generated by the `run_test` script as well.) From 4ac7cd97691648c032c0cdab82cfc474800b6670 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 10 Feb 2021 12:40:52 -0800 Subject: [PATCH 14/21] Add a test directory to point users to the correct tests inside the example directory. --- packages/url_launcher/url_launcher_web/test/README.md | 5 +++++ .../test/tests_exist_elsewhere_test.dart | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 packages/url_launcher/url_launcher_web/test/README.md create mode 100644 packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart diff --git a/packages/url_launcher/url_launcher_web/test/README.md b/packages/url_launcher/url_launcher_web/test/README.md new file mode 100644 index 000000000000..7c5b4ad682ba --- /dev/null +++ b/packages/url_launcher/url_launcher_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/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart b/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart new file mode 100644 index 000000000000..334f52186d9d --- /dev/null +++ b/packages/url_launcher/url_launcher_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 ed38b18cded812f0ef9d9fb81108a71c1a2d80db Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 10 Feb 2021 14:43:04 -0800 Subject: [PATCH 15/21] Restore url_launcher pubspec. --- packages/url_launcher/url_launcher/pubspec.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index a525b0ae2a39..2fdfd8caf217 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -12,8 +12,9 @@ flutter: pluginClass: UrlLauncherPlugin ios: pluginClass: FLTURLLauncherPlugin - web: - default_package: url_launcher_web + # TODO(mvanbeusekom): Temporary disabled until web is migrated to nnbd (advised by @blasten). + #web: + # default_package: url_launcher_web linux: default_package: url_laucher_linux macos: From 7b611c7a235f3bb7101088e5955dec6cd0a1ff96 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 10 Feb 2021 14:54:40 -0800 Subject: [PATCH 16/21] pubspec cleanup --- .../url_launcher_web/example/pubspec.yaml | 17 ++++++++--------- .../url_launcher/url_launcher_web/pubspec.yaml | 12 ++---------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/example/pubspec.yaml b/packages/url_launcher/url_launcher_web/example/pubspec.yaml index 35e653285c3a..5fc060fe7abe 100644 --- a/packages/url_launcher/url_launcher_web/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/example/pubspec.yaml @@ -1,23 +1,22 @@ name: regular_integration_tests publish_to: none -environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.26.0-0" # For integration_test from sdk - dependencies: flutter: sdk: flutter dev_dependencies: + build_runner: ^1.10.0 + mockito: ^5.0.0-nullsafety.5 + url_launcher_web: + path: ../ flutter_driver: sdk: flutter flutter_test: sdk: flutter - http: ^0.12.2 - mockito: ^5.0.0-nullsafety.5 - url_launcher_web: - path: ../ integration_test: sdk: flutter - build_runner: ^1.10.0 + +environment: + sdk: ">=2.12.0-0 <3.0.0" + flutter: ">=1.26.0-0" # For integration_test from sdk diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 6884068dfb80..d599bd98230c 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -1,9 +1,6 @@ name: url_launcher_web description: Web platform implementation of url_launcher homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_web -# 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 version: 2.0.0-nullsafety flutter: @@ -15,21 +12,16 @@ flutter: dependencies: url_launcher_platform_interface: ^2.0.0-nullsafety + meta: ^1.3.0-nullsafety.3 flutter: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.3.0-nullsafety.3 dev_dependencies: - flutter_test: - sdk: flutter - url_launcher: ^6.0.0-nullsafety.6 pedantic: ^1.10.0-nullsafety.1 - mockito: ^5.0.0-nullsafety.5 - integration_test: + flutter_test: sdk: flutter - build_runner: ^1.10.0 environment: sdk: ">=2.12.0-0 <3.0.0" From a5e0953337cf3c8ad9d6cbd50bee1c6df63571d1 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Thu, 11 Feb 2021 15:31:11 -0800 Subject: [PATCH 17/21] Having a null 'uri' is valid. --- .../integration_test/link_widget_test.dart | 21 ++++++++++++++++++- .../url_launcher_web/lib/src/link.dart | 12 ++++++----- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart index 56a45cd459ee..3c1dbd8b1b89 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart @@ -83,6 +83,25 @@ void main() { expect(containerSize.width, 100.0); expect(containerSize.height, 100.0); }); + + // See: https://github.com/flutter/plugins/pull/3522#discussion_r574703724 + testWidgets('uri can be null', (WidgetTester tester) async { + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: WebLinkDelegate(TestLinkInfo( + uri: null, + target: LinkTarget.defaultTarget, + builder: (BuildContext context, FollowLink? followLink) { + return Container(width: 100, height: 100); + }, + )), + )); + // Platform view creation happens asynchronously. + await tester.pumpAndSettle(); + + final html.Element anchor = _findSingleAnchor(); + expect(anchor.hasAttribute('href'), false); + }); }); } @@ -115,7 +134,7 @@ class TestLinkInfo extends LinkInfo { final LinkWidgetBuilder builder; @override - final Uri uri; + final Uri? uri; @override final LinkTarget target; diff --git a/packages/url_launcher/url_launcher_web/lib/src/link.dart b/packages/url_launcher/url_launcher_web/lib/src/link.dart index 28e9fcf6d9b0..42c711b7d818 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/link.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/link.dart @@ -51,7 +51,7 @@ class WebLinkDelegateState extends State { void didUpdateWidget(WebLinkDelegate oldWidget) { super.didUpdateWidget(oldWidget); if (widget.link.uri != oldWidget.link.uri) { - _controller.setUri(widget.link.uri!); + _controller.setUri(widget.link.uri); } if (widget.link.target != oldWidget.link.target) { _controller.setTarget(widget.link.target); @@ -78,7 +78,7 @@ class WebLinkDelegateState extends State { onCreatePlatformView: (PlatformViewCreationParams params) { _controller = LinkViewController.fromParams(params, context); return _controller - ..setUri(widget.link.uri!) + ..setUri(widget.link.uri) ..setTarget(widget.link.target); }, surfaceFactory: @@ -193,7 +193,7 @@ class LinkViewController extends PlatformViewController { return; } - if (_uri.hasScheme) { + if (_uri != null && _uri!.hasScheme) { // External links will be handled by the browser, so we don't have to do // anything. return; @@ -207,10 +207,12 @@ class LinkViewController extends PlatformViewController { pushRouteNameToFramework(context, routeName); } - late Uri _uri; + Uri? _uri; /// Set the [Uri] value for this link. - void setUri(Uri uri) { + /// + /// When Uri is null, the `href` attribute of the link is removed. + void setUri(Uri? uri) { assert(_isInitialized); _uri = uri; if (uri == null) { From 3d8a70614bab8a848d2a851b01fc7528e629c22c Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Thu, 11 Feb 2021 16:26:54 -0800 Subject: [PATCH 18/21] Use non-preview versions of null-safe deps. --- packages/url_launcher/url_launcher_web/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index d599bd98230c..0e38d74466ed 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -12,14 +12,14 @@ flutter: dependencies: url_launcher_platform_interface: ^2.0.0-nullsafety - meta: ^1.3.0-nullsafety.3 + meta: ^1.3.0 # null safe flutter: sdk: flutter flutter_web_plugins: sdk: flutter dev_dependencies: - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 # null safe flutter_test: sdk: flutter From 69c7db152d4ee090b68019cc6ea5844d89cd1a29 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 12 Feb 2021 11:35:19 -0800 Subject: [PATCH 19/21] Rename run_test to run_test.sh, update docs. Point users to README.md if chromedriver is not running. --- packages/url_launcher/url_launcher_web/example/README.md | 6 +++--- .../url_launcher_web/example/{run_test => run_test.sh} | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) rename packages/url_launcher/url_launcher_web/example/{run_test => run_test.sh} (89%) diff --git a/packages/url_launcher/url_launcher_web/example/README.md b/packages/url_launcher/url_launcher_web/example/README.md index 787f9da02950..b75df09c33f1 100644 --- a/packages/url_launcher/url_launcher_web/example/README.md +++ b/packages/url_launcher/url_launcher_web/example/README.md @@ -17,8 +17,8 @@ Make sure you have updated to the latest Flutter master. 4. Run tests: `flutter drive -d web-server --browser-name=chrome --driver=test_driver/integration_test_driver.dart --target=integration_test/TEST_NAME.dart`, or (in Linux): - * Single: `./run_test integration_test/TEST_NAME.dart` - * All: `./run_test` + * Single: `./run_test.sh integration_test/TEST_NAME.dart` + * All: `./run_test.sh` ## Mocks @@ -28,4 +28,4 @@ They're [generated by Mockito](https://github.com/dart-lang/mockito/blob/master/ Mocks might be manually re-generated with the following command: `flutter pub run build_runner build`. If there are any changes in the mocks, feel free to commit them. -(Mocks will be auto-generated by the `run_test` script as well.) +(Mocks will be auto-generated by the `run_test.sh` script as well.) diff --git a/packages/url_launcher/url_launcher_web/example/run_test b/packages/url_launcher/url_launcher_web/example/run_test.sh similarity index 89% rename from packages/url_launcher/url_launcher_web/example/run_test rename to packages/url_launcher/url_launcher_web/example/run_test.sh index a9789d0faee3..c935e5b77e09 100755 --- a/packages/url_launcher/url_launcher_web/example/run_test +++ b/packages/url_launcher/url_launcher_web/example/run_test.sh @@ -18,5 +18,6 @@ if pgrep -lf chromedriver > /dev/null; then else echo "chromedriver is not running." + echo "Please, check the README.md for instructions on how to use run_test.sh" fi From 05433db0e7fe4aa208fa6d2a31992565752bc3bd Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 12 Feb 2021 13:56:30 -0800 Subject: [PATCH 20/21] Make the package usable and endorseable in the next stable release. --- packages/url_launcher/url_launcher_web/example/run_test.sh | 2 +- packages/url_launcher/url_launcher_web/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/example/run_test.sh b/packages/url_launcher/url_launcher_web/example/run_test.sh index c935e5b77e09..b243f2938b1f 100755 --- a/packages/url_launcher/url_launcher_web/example/run_test.sh +++ b/packages/url_launcher/url_launcher_web/example/run_test.sh @@ -5,7 +5,7 @@ if pgrep -lf chromedriver > /dev/null; then flutter pub get echo "(Re)generating mocks." - flutter pub run build_runner build + flutter pub run build_runner build --delete-conflicting-outputs if [ $# -eq 0 ]; then echo "No target specified, running all tests..." diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 0e38d74466ed..b9f957a7ee76 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -25,4 +25,4 @@ dev_dependencies: environment: sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.26.0-0" # For integration_test from sdk + flutter: ">=1.12.13+hotfix.5" From bb58825aca593c48730d5ecb09797de8a2defedb Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 12 Feb 2021 14:28:54 -0800 Subject: [PATCH 21/21] Use default mocks. --- .../example/integration_test/url_launcher_web_test.dart | 5 +---- .../integration_test/url_launcher_web_test.mocks.dart | 8 ++++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart index 2c0b78710f65..f7ea35667530 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart @@ -11,10 +11,7 @@ import 'package:integration_test/integration_test.dart'; import 'url_launcher_web_test.mocks.dart'; -@GenerateMocks([], customMocks: [ - MockSpec(returnNullOnMissingStub: true), - MockSpec(returnNullOnMissingStub: true) -]) +@GenerateMocks([html.Window, html.Navigator]) void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart index 5e1e77dcae61..73d3bf355d67 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart @@ -51,6 +51,10 @@ class _FakeRelatedApplication extends _i1.Fake /// /// See the documentation for Mockito's code generation for more information. class MockWindow extends _i1.Mock implements _i2.Window { + MockWindow() { + _i1.throwOnMissingStub(this); + } + @override _i4.Future get animationFrame => (super.noSuchMethod(Invocation.getter(#animationFrame), Future.value(0)) @@ -559,6 +563,10 @@ class MockWindow extends _i1.Mock implements _i2.Window { /// /// See the documentation for Mockito's code generation for more information. class MockNavigator extends _i1.Mock implements _i2.Navigator { + MockNavigator() { + _i1.throwOnMissingStub(this); + } + @override String get language => (super.noSuchMethod(Invocation.getter(#language), '') as String);