Skip to content

Commit 96faf2c

Browse files
SirusCodesditman
andauthored
[file_selector_web] Migrated to null-safety (flutter#3550)
Co-authored-by: David Iglesias Teixeira <ditman@gmail.com>
1 parent 499156e commit 96faf2c

File tree

15 files changed

+199
-87
lines changed

15 files changed

+199
-87
lines changed

packages/file_selector/file_selector_web/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 0.8.0
2+
3+
- Migrated to null-safety
4+
15
# 0.7.0+1
26

37
- Add dummy `ios` dir, so flutter sdk can be lower than 1.20
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Testing
2+
3+
This package utilizes the `integration_test` package to run its tests in a web browser.
4+
5+
See [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) for more info.
6+
7+
## Running the tests
8+
9+
Make sure you have updated to the latest Flutter master.
10+
11+
1. Check what version of Chrome is running on the machine you're running tests on.
12+
13+
2. Download and install driver for that version from here:
14+
* <https://chromedriver.chromium.org/downloads>
15+
16+
3. Start the driver using `chromedriver --port=4444`
17+
18+
4. Run tests: `flutter drive -d web-server --browser-name=chrome --driver=test_driver/integration_test.dart --target=integration_test/TEST_NAME.dart`, or (in Linux):
19+
20+
* Single: `./run_test.sh integration_test/TEST_NAME.dart`
21+
* All: `./run_test.sh`

packages/file_selector/file_selector_web/integration_test/dom_helper_test.dart renamed to packages/file_selector/file_selector_web/example/integration_test/dom_helper_test.dart

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,26 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.9
6-
75
import 'dart:html';
86
import 'package:flutter_test/flutter_test.dart';
97
import 'package:integration_test/integration_test.dart';
108
import 'package:file_selector_web/src/dom_helper.dart';
119
import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
1210

1311
void main() {
14-
group('FileSelectorWeb', () {
12+
group('dom_helper', () {
1513
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
16-
DomHelper domHelper;
17-
FileUploadInputElement input;
14+
late DomHelper domHelper;
15+
late FileUploadInputElement input;
1816

19-
FileList FileListItems(List<File> files) {
17+
FileList? createFileList(List<File> files) {
2018
final dataTransfer = DataTransfer();
21-
files.forEach(dataTransfer.items.add);
22-
return dataTransfer.files;
19+
files.forEach(dataTransfer.items!.add);
20+
return dataTransfer.files as FileList?;
2321
}
2422

2523
void setFilesAndTriggerChange(List<File> files) {
26-
input.files = FileListItems(files);
24+
input.files = createFileList(files);
2725
input.dispatchEvent(Event('change'));
2826
}
2927

packages/file_selector/file_selector_web/integration_test/file_selector_web_test.dart renamed to packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.9
6-
5+
import 'dart:html';
76
import 'dart:typed_data';
87
import 'package:flutter_test/flutter_test.dart';
9-
import 'package:mockito/mockito.dart';
108
import 'package:integration_test/integration_test.dart';
119
import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
1210
import 'package:file_selector_web/file_selector_web.dart';
@@ -15,30 +13,25 @@ import 'package:file_selector_web/src/dom_helper.dart';
1513
void main() {
1614
group('FileSelectorWeb', () {
1715
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
18-
MockDomHelper mockDomHelper;
19-
FileSelectorWeb plugin;
20-
21-
setUp(() {
22-
mockDomHelper = MockDomHelper();
23-
plugin = FileSelectorWeb(domHelper: mockDomHelper);
24-
});
2516

2617
group('openFile', () {
27-
final mockFile = createXFile('1001', 'identity.png');
28-
2918
testWidgets('works', (WidgetTester _) async {
19+
final mockFile = createXFile('1001', 'identity.png');
20+
21+
final mockDomHelper = MockDomHelper()
22+
..setFiles([mockFile])
23+
..expectAccept('.jpg,.jpeg,image/png,image/*')
24+
..expectMultiple(false);
25+
26+
final plugin = FileSelectorWeb(domHelper: mockDomHelper);
27+
3028
final typeGroup = XTypeGroup(
3129
label: 'images',
3230
extensions: ['jpg', 'jpeg'],
3331
mimeTypes: ['image/png'],
3432
webWildCards: ['image/*'],
3533
);
3634

37-
when(mockDomHelper.getFiles(
38-
accept: '.jpg,.jpeg,image/png,image/*',
39-
multiple: false,
40-
)).thenAnswer((_) async => [mockFile]);
41-
4235
final file = await plugin.openFile(acceptedTypeGroups: [typeGroup]);
4336

4437
expect(file.name, mockFile.name);
@@ -49,20 +42,22 @@ void main() {
4942
});
5043

5144
group('openFiles', () {
52-
final mockFile1 = createXFile('123456', 'file1.txt');
53-
final mockFile2 = createXFile('', 'file2.txt');
54-
5545
testWidgets('works', (WidgetTester _) async {
46+
final mockFile1 = createXFile('123456', 'file1.txt');
47+
final mockFile2 = createXFile('', 'file2.txt');
48+
49+
final mockDomHelper = MockDomHelper()
50+
..setFiles([mockFile1, mockFile2])
51+
..expectAccept('.txt')
52+
..expectMultiple(true);
53+
54+
final plugin = FileSelectorWeb(domHelper: mockDomHelper);
55+
5656
final typeGroup = XTypeGroup(
5757
label: 'files',
5858
extensions: ['.txt'],
5959
);
6060

61-
when(mockDomHelper.getFiles(
62-
accept: '.txt',
63-
multiple: true,
64-
)).thenAnswer((_) async => [mockFile1, mockFile2]);
65-
6661
final files = await plugin.openFiles(acceptedTypeGroups: [typeGroup]);
6762

6863
expect(files.length, 2);
@@ -81,7 +76,36 @@ void main() {
8176
});
8277
}
8378

84-
class MockDomHelper extends Mock implements DomHelper {}
79+
class MockDomHelper implements DomHelper {
80+
List<XFile> _files = <XFile>[];
81+
String _expectedAccept = '';
82+
bool _expectedMultiple = false;
83+
84+
@override
85+
Future<List<XFile>> getFiles({
86+
String accept = '',
87+
bool multiple = false,
88+
FileUploadInputElement? input,
89+
}) {
90+
expect(accept, _expectedAccept,
91+
reason: 'Expected "accept" value does not match.');
92+
expect(multiple, _expectedMultiple,
93+
reason: 'Expected "multiple" value does not match.');
94+
return Future.value(_files);
95+
}
96+
97+
void setFiles(List<XFile> files) {
98+
_files = files;
99+
}
100+
101+
void expectAccept(String accept) {
102+
_expectedAccept = accept;
103+
}
104+
105+
void expectMultiple(bool multiple) {
106+
_expectedMultiple = multiple;
107+
}
108+
}
85109

86110
XFile createXFile(String content, String name) {
87111
final data = Uint8List.fromList(content.codeUnits);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
7+
void main() {
8+
runApp(MyApp());
9+
}
10+
11+
/// App for testing
12+
class MyApp extends StatefulWidget {
13+
@override
14+
_MyAppState createState() => _MyAppState();
15+
}
16+
17+
class _MyAppState extends State<MyApp> {
18+
@override
19+
Widget build(BuildContext context) {
20+
return Directionality(
21+
textDirection: TextDirection.ltr,
22+
child: Text('Testing... Look at the console output for results!'),
23+
);
24+
}
25+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: file_selector_web_integration_tests
2+
publish_to: none
3+
4+
dependencies:
5+
flutter:
6+
sdk: flutter
7+
8+
dev_dependencies:
9+
build_runner: ^1.10.0
10+
file_selector_web:
11+
path: ../
12+
flutter_driver:
13+
sdk: flutter
14+
flutter_test:
15+
sdk: flutter
16+
integration_test:
17+
sdk: flutter
18+
19+
environment:
20+
sdk: ">=2.12.0-259.9.beta <3.0.0"
21+
flutter: ">=1.27.0-0" # For integration_test from sdk
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<!-- Copyright 2014 The Flutter Authors. All rights reserved.
3+
Use of this source code is governed by a BSD-style license that can be
4+
found in the LICENSE file. -->
5+
<html>
6+
<head>
7+
<title>Browser Tests</title>
8+
</head>
9+
<body>
10+
<script src="main.dart.js"></script>
11+
</body>
12+
</html>

packages/file_selector/file_selector_web/lib/file_selector_web.dart

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import 'package:file_selector_web/src/utils.dart';
1313
///
1414
/// This class implements the `package:file_selector` functionality for the web.
1515
class FileSelectorWeb extends FileSelectorPlatform {
16-
final _domHelper;
16+
final DomHelper _domHelper;
1717

1818
/// Registers this class as the default instance of [FileSelectorPlatform].
1919
static void registerWith(Registrar registrar) {
@@ -23,46 +23,46 @@ class FileSelectorWeb extends FileSelectorPlatform {
2323
/// Default constructor, initializes _domHelper that we can use
2424
/// to interact with the DOM.
2525
/// overrides parameter allows for testing to override functions
26-
FileSelectorWeb({@visibleForTesting DomHelper domHelper})
26+
FileSelectorWeb({@visibleForTesting DomHelper? domHelper})
2727
: _domHelper = domHelper ?? DomHelper();
2828

2929
@override
3030
Future<XFile> openFile({
31-
List<XTypeGroup> acceptedTypeGroups,
32-
String initialDirectory,
33-
String confirmButtonText,
31+
List<XTypeGroup>? acceptedTypeGroups,
32+
String? initialDirectory,
33+
String? confirmButtonText,
3434
}) async {
3535
final files = await _openFiles(acceptedTypeGroups: acceptedTypeGroups);
3636
return files.first;
3737
}
3838

3939
@override
4040
Future<List<XFile>> openFiles({
41-
List<XTypeGroup> acceptedTypeGroups,
42-
String initialDirectory,
43-
String confirmButtonText,
41+
List<XTypeGroup>? acceptedTypeGroups,
42+
String? initialDirectory,
43+
String? confirmButtonText,
4444
}) async {
4545
return _openFiles(acceptedTypeGroups: acceptedTypeGroups, multiple: true);
4646
}
4747

4848
@override
49-
Future<String> getSavePath({
50-
List<XTypeGroup> acceptedTypeGroups,
51-
String initialDirectory,
52-
String suggestedName,
53-
String confirmButtonText,
49+
Future<String?> getSavePath({
50+
List<XTypeGroup>? acceptedTypeGroups,
51+
String? initialDirectory,
52+
String? suggestedName,
53+
String? confirmButtonText,
5454
}) async =>
5555
null;
5656

5757
@override
58-
Future<String> getDirectoryPath({
59-
String initialDirectory,
60-
String confirmButtonText,
58+
Future<String?> getDirectoryPath({
59+
String? initialDirectory,
60+
String? confirmButtonText,
6161
}) async =>
6262
null;
6363

6464
Future<List<XFile>> _openFiles({
65-
List<XTypeGroup> acceptedTypeGroups,
65+
List<XTypeGroup>? acceptedTypeGroups,
6666
bool multiple = false,
6767
}) async {
6868
final accept = acceptedTypesToString(acceptedTypeGroups);

0 commit comments

Comments
 (0)