22// Use of this source code is governed by a BSD-style license that can be
33// found in the LICENSE file.
44
5- // TODO(egarciad): Remove once Mockito has been migrated to null safety.
6- // @dart = 2.9
7-
85import 'dart:ui' ;
6+
97import 'package:flutter/material.dart' ;
108import 'package:flutter_test/flutter_test.dart' ;
119import 'package:mockito/mockito.dart' ;
1210import 'package:flutter/services.dart' ;
13- import 'package:plugin_platform_interface/plugin_platform_interface.dart' ;
1411import 'package:url_launcher/link.dart' ;
1512import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart' ;
1613
14+ import 'mock_url_launcher_platform.dart' ;
15+
1716final MethodCodec _codec = const JSONMethodCodec ();
1817
1918void main () {
20- final MockUrlLauncher mock = MockUrlLauncher ();
21- UrlLauncherPlatform .instance = mock;
19+ late MockUrlLauncher mock;
2220
23- PlatformMessageCallback realOnPlatformMessage;
21+ PlatformMessageCallback ? realOnPlatformMessage;
2422 setUp (() {
23+ mock = MockUrlLauncher ();
24+ UrlLauncherPlatform .instance = mock;
2525 realOnPlatformMessage = window.onPlatformMessage;
2626 });
2727 tearDown (() {
@@ -31,11 +31,11 @@ void main() {
3131 group ('$Link ' , () {
3232 testWidgets ('handles null uri correctly' , (WidgetTester tester) async {
3333 bool isBuilt = false ;
34- FollowLink followLink;
34+ FollowLink ? followLink;
3535
3636 final Link link = Link (
3737 uri: null ,
38- builder: (BuildContext context, FollowLink followLink2) {
38+ builder: (BuildContext context, FollowLink ? followLink2) {
3939 isBuilt = true ;
4040 followLink = followLink2;
4141 return Container ();
@@ -50,66 +50,62 @@ void main() {
5050
5151 testWidgets ('calls url_launcher for external URLs with blank target' ,
5252 (WidgetTester tester) async {
53- FollowLink followLink;
53+ FollowLink ? followLink;
5454
5555 await tester.pumpWidget (Link (
5656 uri: Uri .parse ('http://example.com/foobar' ),
5757 target: LinkTarget .blank,
58- builder: (BuildContext context, FollowLink followLink2) {
58+ builder: (BuildContext context, FollowLink ? followLink2) {
5959 followLink = followLink2;
6060 return Container ();
6161 },
6262 ));
6363
64- when (mock.canLaunch ('http://example.com/foobar' ))
65- .thenAnswer ((realInvocation) => Future <bool >.value (true ));
66- clearInteractions (mock);
67- await followLink ();
68-
69- verifyInOrder ([
70- mock.canLaunch ('http://example.com/foobar' ),
71- mock.launch (
72- 'http://example.com/foobar' ,
64+ mock
65+ ..setLaunchExpectations (
66+ url: 'http://example.com/foobar' ,
7367 useSafariVC: false ,
7468 useWebView: false ,
7569 universalLinksOnly: false ,
7670 enableJavaScript: false ,
7771 enableDomStorage: false ,
7872 headers: < String , String > {},
73+ webOnlyWindowName: null ,
7974 )
80- ]);
75+ ..setResponse (true );
76+ await followLink !();
77+ expect (mock.canLaunchCalled, isTrue);
78+ expect (mock.launchCalled, isTrue);
8179 });
8280
8381 testWidgets ('calls url_launcher for external URLs with self target' ,
8482 (WidgetTester tester) async {
85- FollowLink followLink;
83+ FollowLink ? followLink;
8684
8785 await tester.pumpWidget (Link (
8886 uri: Uri .parse ('http://example.com/foobar' ),
8987 target: LinkTarget .self,
90- builder: (BuildContext context, FollowLink followLink2) {
88+ builder: (BuildContext context, FollowLink ? followLink2) {
9189 followLink = followLink2;
9290 return Container ();
9391 },
9492 ));
9593
96- when (mock.canLaunch ('http://example.com/foobar' ))
97- .thenAnswer ((realInvocation) => Future <bool >.value (true ));
98- clearInteractions (mock);
99- await followLink ();
100-
101- verifyInOrder ([
102- mock.canLaunch ('http://example.com/foobar' ),
103- mock.launch (
104- 'http://example.com/foobar' ,
94+ mock
95+ ..setLaunchExpectations (
96+ url: 'http://example.com/foobar' ,
10597 useSafariVC: true ,
10698 useWebView: true ,
10799 universalLinksOnly: false ,
108100 enableJavaScript: false ,
109101 enableDomStorage: false ,
110102 headers: < String , String > {},
103+ webOnlyWindowName: null ,
111104 )
112- ]);
105+ ..setResponse (true );
106+ await followLink !();
107+ expect (mock.canLaunchCalled, isTrue);
108+ expect (mock.launchCalled, isTrue);
113109 });
114110
115111 testWidgets ('sends navigation platform messages for internal route names' ,
@@ -125,21 +121,21 @@ void main() {
125121 final List <MethodCall > frameworkCalls = < MethodCall > [];
126122 window.onPlatformMessage = (
127123 String name,
128- ByteData data,
129- PlatformMessageResponseCallback callback,
124+ ByteData ? data,
125+ PlatformMessageResponseCallback ? callback,
130126 ) {
131127 frameworkCalls.add (_codec.decodeMethodCall (data));
132- realOnPlatformMessage (name, data, callback);
128+ realOnPlatformMessage ! (name, data, callback);
133129 };
134130
135131 final Uri uri = Uri .parse ('/foo/bar' );
136- FollowLink followLink;
132+ FollowLink ? followLink;
137133
138134 await tester.pumpWidget (MaterialApp (
139135 routes: < String , WidgetBuilder > {
140136 '/' : (BuildContext context) => Link (
141137 uri: uri,
142- builder: (BuildContext context, FollowLink followLink2) {
138+ builder: (BuildContext context, FollowLink ? followLink2) {
143139 followLink = followLink2;
144140 return Container ();
145141 },
@@ -150,11 +146,11 @@ void main() {
150146
151147 engineCalls.clear ();
152148 frameworkCalls.clear ();
153- clearInteractions (mock);
154- await followLink ();
149+ await followLink !();
155150
156151 // Shouldn't use url_launcher when uri is an internal route name.
157- verifyZeroInteractions (mock);
152+ expect (mock.canLaunchCalled, isFalse);
153+ expect (mock.launchCalled, isFalse);
158154
159155 // A message should've been sent to the engine (by the Navigator, not by
160156 // the Link widget).
@@ -191,19 +187,19 @@ void main() {
191187 final List <MethodCall > frameworkCalls = < MethodCall > [];
192188 window.onPlatformMessage = (
193189 String name,
194- ByteData data,
195- PlatformMessageResponseCallback callback,
190+ ByteData ? data,
191+ PlatformMessageResponseCallback ? callback,
196192 ) {
197193 frameworkCalls.add (_codec.decodeMethodCall (data));
198- realOnPlatformMessage (name, data, callback);
194+ realOnPlatformMessage ! (name, data, callback);
199195 };
200196
201197 final Uri uri = Uri .parse ('/foo/bar' );
202- FollowLink followLink;
198+ FollowLink ? followLink;
203199
204200 final Link link = Link (
205201 uri: uri,
206- builder: (BuildContext context, FollowLink followLink2) {
202+ builder: (BuildContext context, FollowLink ? followLink2) {
207203 followLink = followLink2;
208204 return Container ();
209205 },
@@ -217,11 +213,11 @@ void main() {
217213
218214 engineCalls.clear ();
219215 frameworkCalls.clear ();
220- clearInteractions (mock);
221- await followLink ();
216+ await followLink !();
222217
223218 // Shouldn't use url_launcher when uri is an internal route name.
224- verifyZeroInteractions (mock);
219+ expect (mock.canLaunchCalled, isFalse);
220+ expect (mock.launchCalled, isFalse);
225221
226222 // Sends route information update to the engine.
227223 expect (engineCalls, hasLength (1 ));
@@ -249,10 +245,6 @@ void main() {
249245 });
250246}
251247
252- class MockUrlLauncher extends Mock
253- with MockPlatformInterfaceMixin
254- implements UrlLauncherPlatform {}
255-
256248class MockRouteInformationParser extends Mock
257249 implements RouteInformationParser <bool > {
258250 @override
@@ -261,13 +253,19 @@ class MockRouteInformationParser extends Mock
261253 }
262254}
263255
264- class MockRouterDelegate extends Mock implements RouterDelegate {
265- MockRouterDelegate ({@ required this .builder});
256+ class MockRouterDelegate extends Mock implements RouterDelegate < Object > {
257+ MockRouterDelegate ({required this .builder});
266258
267259 final WidgetBuilder builder;
268260
269261 @override
270262 Widget build (BuildContext context) {
271263 return builder (context);
272264 }
265+
266+ @override
267+ Future <void > setInitialRoutePath (Object configuration) async {}
268+
269+ @override
270+ Future <void > setNewRoutePath (Object configuration) async {}
273271}
0 commit comments