Skip to content

Commit 982e1ca

Browse files
[path_provider] Migrate examples to null-safety (#3559)
Allows running the examples in strong mode, even though the integration tests can't yet be. Converts the macOS example to use the platform interface, rather than the app-facing package, to eliminate the circular dependency. Also does some cleanup and simplification of the desktop example pubspecs. Does not update versions/changelogs since this won't be explicitly published, given that it's example-only.
1 parent fa95cde commit 982e1ca

File tree

21 files changed

+162
-239
lines changed

21 files changed

+162
-239
lines changed

packages/path_provider/path_provider/example/integration_test/path_provider_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
// @dart=2.9
6+
57
import 'dart:async';
68

79
import 'dart:io';

packages/path_provider/path_provider/example/lib/main.dart

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,21 @@ class MyApp extends StatelessWidget {
2828
}
2929

3030
class MyHomePage extends StatefulWidget {
31-
MyHomePage({Key key, this.title}) : super(key: key);
31+
MyHomePage({Key? key, required this.title}) : super(key: key);
3232
final String title;
3333

3434
@override
3535
_MyHomePageState createState() => _MyHomePageState();
3636
}
3737

3838
class _MyHomePageState extends State<MyHomePage> {
39-
Future<Directory> _tempDirectory;
40-
Future<Directory> _appSupportDirectory;
41-
Future<Directory> _appLibraryDirectory;
42-
Future<Directory> _appDocumentsDirectory;
43-
Future<Directory> _externalDocumentsDirectory;
44-
Future<List<Directory>> _externalStorageDirectories;
45-
Future<List<Directory>> _externalCacheDirectories;
39+
Future<Directory?>? _tempDirectory;
40+
Future<Directory?>? _appSupportDirectory;
41+
Future<Directory?>? _appLibraryDirectory;
42+
Future<Directory?>? _appDocumentsDirectory;
43+
Future<Directory?>? _externalDocumentsDirectory;
44+
Future<List<Directory>?>? _externalStorageDirectories;
45+
Future<List<Directory>?>? _externalCacheDirectories;
4646

4747
void _requestTempDirectory() {
4848
setState(() {
@@ -51,13 +51,13 @@ class _MyHomePageState extends State<MyHomePage> {
5151
}
5252

5353
Widget _buildDirectory(
54-
BuildContext context, AsyncSnapshot<Directory> snapshot) {
54+
BuildContext context, AsyncSnapshot<Directory?> snapshot) {
5555
Text text = const Text('');
5656
if (snapshot.connectionState == ConnectionState.done) {
5757
if (snapshot.hasError) {
5858
text = Text('Error: ${snapshot.error}');
5959
} else if (snapshot.hasData) {
60-
text = Text('path: ${snapshot.data.path}');
60+
text = Text('path: ${snapshot.data!.path}');
6161
} else {
6262
text = const Text('path unavailable');
6363
}
@@ -66,14 +66,14 @@ class _MyHomePageState extends State<MyHomePage> {
6666
}
6767

6868
Widget _buildDirectories(
69-
BuildContext context, AsyncSnapshot<List<Directory>> snapshot) {
69+
BuildContext context, AsyncSnapshot<List<Directory>?> snapshot) {
7070
Text text = const Text('');
7171
if (snapshot.connectionState == ConnectionState.done) {
7272
if (snapshot.hasError) {
7373
text = Text('Error: ${snapshot.error}');
7474
} else if (snapshot.hasData) {
7575
final String combined =
76-
snapshot.data.map((Directory d) => d.path).join(', ');
76+
snapshot.data!.map((Directory d) => d.path).join(', ');
7777
text = Text('paths: $combined');
7878
} else {
7979
text = const Text('path unavailable');
@@ -134,7 +134,7 @@ class _MyHomePageState extends State<MyHomePage> {
134134
onPressed: _requestTempDirectory,
135135
),
136136
),
137-
FutureBuilder<Directory>(
137+
FutureBuilder<Directory?>(
138138
future: _tempDirectory, builder: _buildDirectory),
139139
Padding(
140140
padding: const EdgeInsets.all(16.0),
@@ -143,7 +143,7 @@ class _MyHomePageState extends State<MyHomePage> {
143143
onPressed: _requestAppDocumentsDirectory,
144144
),
145145
),
146-
FutureBuilder<Directory>(
146+
FutureBuilder<Directory?>(
147147
future: _appDocumentsDirectory, builder: _buildDirectory),
148148
Padding(
149149
padding: const EdgeInsets.all(16.0),
@@ -152,7 +152,7 @@ class _MyHomePageState extends State<MyHomePage> {
152152
onPressed: _requestAppSupportDirectory,
153153
),
154154
),
155-
FutureBuilder<Directory>(
155+
FutureBuilder<Directory?>(
156156
future: _appSupportDirectory, builder: _buildDirectory),
157157
Padding(
158158
padding: const EdgeInsets.all(16.0),
@@ -161,7 +161,7 @@ class _MyHomePageState extends State<MyHomePage> {
161161
onPressed: _requestAppLibraryDirectory,
162162
),
163163
),
164-
FutureBuilder<Directory>(
164+
FutureBuilder<Directory?>(
165165
future: _appLibraryDirectory, builder: _buildDirectory),
166166
Padding(
167167
padding: const EdgeInsets.all(16.0),
@@ -172,7 +172,7 @@ class _MyHomePageState extends State<MyHomePage> {
172172
Platform.isIOS ? null : _requestExternalStorageDirectory,
173173
),
174174
),
175-
FutureBuilder<Directory>(
175+
FutureBuilder<Directory?>(
176176
future: _externalDocumentsDirectory, builder: _buildDirectory),
177177
Column(children: <Widget>[
178178
Padding(
@@ -190,7 +190,7 @@ class _MyHomePageState extends State<MyHomePage> {
190190
),
191191
),
192192
]),
193-
FutureBuilder<List<Directory>>(
193+
FutureBuilder<List<Directory>?>(
194194
future: _externalStorageDirectories,
195195
builder: _buildDirectories),
196196
Column(children: <Widget>[
@@ -204,7 +204,7 @@ class _MyHomePageState extends State<MyHomePage> {
204204
),
205205
),
206206
]),
207-
FutureBuilder<List<Directory>>(
207+
FutureBuilder<List<Directory>?>(
208208
future: _externalCacheDirectories, builder: _buildDirectories),
209209
],
210210
),

packages/path_provider/path_provider/example/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ flutter:
2323
uses-material-design: true
2424

2525
environment:
26-
sdk: ">=2.1.0 <3.0.0"
26+
sdk: ">=2.12.0-0 <3.0.0"
2727
flutter: ">=1.12.13+hotfix.5"

packages/path_provider/path_provider/example/test_driver/integration_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
// @dart=2.9
6+
57
import 'dart:async';
68
import 'dart:convert';
79
import 'dart:io';

packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
// @dart=2.9
6+
57
import 'dart:io';
68
import 'package:flutter_test/flutter_test.dart';
79
import 'package:path_provider_linux/path_provider_linux.dart';

packages/path_provider/path_provider_linux/example/lib/main.dart

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'dart:async';
44
import 'package:flutter/services.dart';
55
import 'package:path_provider_linux/path_provider_linux.dart';
66

7-
void main() async {
7+
void main() {
88
runApp(MyApp());
99
}
1010

@@ -15,10 +15,10 @@ class MyApp extends StatefulWidget {
1515
}
1616

1717
class _MyAppState extends State<MyApp> {
18-
String _tempDirectory = 'Unknown';
19-
String _downloadsDirectory = 'Unknown';
20-
String _appSupportDirectory = 'Unknown';
21-
String _documentsDirectory = 'Unknown';
18+
String? _tempDirectory = 'Unknown';
19+
String? _downloadsDirectory = 'Unknown';
20+
String? _appSupportDirectory = 'Unknown';
21+
String? _documentsDirectory = 'Unknown';
2222
final PathProviderLinux _provider = PathProviderLinux();
2323

2424
@override
@@ -29,10 +29,10 @@ class _MyAppState extends State<MyApp> {
2929

3030
// Platform messages are asynchronous, so we initialize in an async method.
3131
Future<void> initDirectories() async {
32-
String tempDirectory;
33-
String downloadsDirectory;
34-
String appSupportDirectory;
35-
String documentsDirectory;
32+
String? tempDirectory;
33+
String? downloadsDirectory;
34+
String? appSupportDirectory;
35+
String? documentsDirectory;
3636
// Platform messages may fail, so we use a try/catch PlatformException.
3737
try {
3838
tempDirectory = await _provider.getTemporaryPath();

packages/path_provider/path_provider_linux/example/pubspec.yaml

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,13 @@ description: Demonstrates how to use the path_provider_linux plugin.
33
publish_to: "none"
44

55
environment:
6-
sdk: ">=2.1.0 <3.0.0"
6+
sdk: ">=2.12.0-0 <3.0.0"
7+
flutter: ">=1.10.0"
78

89
dependencies:
910
flutter:
1011
sdk: flutter
1112

12-
path_provider_linux: any
13-
14-
# The following adds the Cupertino Icons font to your application.
15-
# Use with the CupertinoIcons class for iOS style icons.
16-
cupertino_icons: ^0.1.3
17-
18-
dependency_overrides:
1913
path_provider_linux:
2014
# When depending on this package from a real application you should use:
2115
# path_provider_linux: ^x.y.z
@@ -32,39 +26,5 @@ dev_dependencies:
3226
integration_test:
3327
path: ../../../integration_test
3428

35-
# For information on the generic Dart part of this file, see the
36-
# following page: https://dart.dev/tools/pub/pubspec
37-
38-
# The following section is specific to Flutter.
3929
flutter:
40-
# The following line ensures that the Material Icons font is
41-
# included with your application, so that you can use the icons in
42-
# the material Icons class.
4330
uses-material-design: true
44-
# To add assets to your application, add an assets section, like this:
45-
# assets:
46-
# - images/a_dot_burr.jpeg
47-
# - images/a_dot_ham.jpeg
48-
# An image asset can refer to one or more resolution-specific "variants", see
49-
# https://flutter.dev/assets-and-images/#resolution-aware.
50-
# For details regarding adding assets from package dependencies, see
51-
# https://flutter.dev/assets-and-images/#from-packages
52-
# To add custom fonts to your application, add a fonts section here,
53-
# in this "flutter" section. Each entry in this list should have a
54-
# "family" key with the font family name, and a "fonts" key with a
55-
# list giving the asset and other descriptors for the font. For
56-
# example:
57-
# fonts:
58-
# - family: Schyler
59-
# fonts:
60-
# - asset: fonts/Schyler-Regular.ttf
61-
# - asset: fonts/Schyler-Italic.ttf
62-
# style: italic
63-
# - family: Trajan Pro
64-
# fonts:
65-
# - asset: fonts/TrajanPro.ttf
66-
# - asset: fonts/TrajanPro_Bold.ttf
67-
# weight: 700
68-
#
69-
# For details regarding fonts from package dependencies,
70-
# see https://flutter.dev/custom-fonts/#from-packages

packages/path_provider/path_provider_linux/example/test/widget_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ void main() {
3030
find.byWidgetPredicate(
3131
(Widget widget) =>
3232
widget is Text &&
33-
widget.data.startsWith('Temp Directory: /tmp'),
33+
widget.data!.startsWith('Temp Directory: /tmp'),
3434
),
3535
findsOneWidget,
3636
);
@@ -48,7 +48,7 @@ void main() {
4848
find.byWidgetPredicate(
4949
(Widget widget) =>
5050
widget is Text &&
51-
widget.data.startsWith('Documents Directory: /'),
51+
widget.data!.startsWith('Documents Directory: /'),
5252
),
5353
findsOneWidget,
5454
);
@@ -66,7 +66,7 @@ void main() {
6666
find.byWidgetPredicate(
6767
(Widget widget) =>
6868
widget is Text &&
69-
widget.data.startsWith('Downloads Directory: /'),
69+
widget.data!.startsWith('Downloads Directory: /'),
7070
),
7171
findsOneWidget,
7272
);
@@ -85,7 +85,7 @@ void main() {
8585
find.byWidgetPredicate(
8686
(Widget widget) =>
8787
widget is Text &&
88-
widget.data.startsWith('Application Support Directory: /'),
88+
widget.data!.startsWith('Application Support Directory: /'),
8989
),
9090
findsOneWidget,
9191
);

packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
// @dart=2.9
6+
57
import 'dart:async';
68
import 'dart:convert';
79
import 'dart:io';

packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,56 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
// @dart=2.9
6+
57
import 'dart:io';
68
import 'package:flutter_test/flutter_test.dart';
7-
import 'package:path_provider/path_provider.dart';
9+
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
810
import 'package:integration_test/integration_test.dart';
911

1012
void main() {
1113
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
1214

1315
testWidgets('getTemporaryDirectory', (WidgetTester tester) async {
14-
final Directory result = await getTemporaryDirectory();
16+
final PathProviderPlatform provider = PathProviderPlatform.instance;
17+
final String result = await provider.getTemporaryPath();
1518
_verifySampleFile(result, 'temporaryDirectory');
1619
});
1720

1821
testWidgets('getApplicationDocumentsDirectory', (WidgetTester tester) async {
19-
final Directory result = await getApplicationDocumentsDirectory();
22+
final PathProviderPlatform provider = PathProviderPlatform.instance;
23+
final String result = await provider.getApplicationDocumentsPath();
2024
_verifySampleFile(result, 'applicationDocuments');
2125
});
2226

2327
testWidgets('getApplicationSupportDirectory', (WidgetTester tester) async {
24-
final Directory result = await getApplicationSupportDirectory();
28+
final PathProviderPlatform provider = PathProviderPlatform.instance;
29+
final String result = await provider.getApplicationSupportPath();
2530
_verifySampleFile(result, 'applicationSupport');
2631
});
2732

2833
testWidgets('getLibraryDirectory', (WidgetTester tester) async {
29-
if (!Platform.isMacOS) {
30-
return;
31-
}
32-
final Directory result = await getLibraryDirectory();
34+
final PathProviderPlatform provider = PathProviderPlatform.instance;
35+
final String result = await provider.getLibraryPath();
3336
_verifySampleFile(result, 'library');
3437
});
38+
39+
testWidgets('getDownloadsDirectory', (WidgetTester tester) async {
40+
final PathProviderPlatform provider = PathProviderPlatform.instance;
41+
final String result = await provider.getDownloadsPath();
42+
// _verifySampleFile causes hangs in driver for some reason, so just
43+
// validate that a non-empty path was returned.
44+
expect(result, isNotEmpty);
45+
});
3546
}
3647

37-
/// Verify a file called [name] in [directory] by recreating it with test
48+
/// Verify a file called [name] in [directoryPath] by recreating it with test
3849
/// contents when necessary.
39-
void _verifySampleFile(Directory directory, String name) {
40-
final File file = File('${directory.path}/$name');
50+
///
51+
/// If [createDirectory] is true, the directory will be created if missing.
52+
void _verifySampleFile(String directoryPath, String name) {
53+
final Directory directory = Directory(directoryPath);
54+
final File file = File('${directory.path}${Platform.pathSeparator}$name');
4155

4256
if (file.existsSync()) {
4357
file.deleteSync();

0 commit comments

Comments
 (0)