Skip to content

Commit 70e1dc7

Browse files
authored
[Clipboard] Assert at least one clipboard data variant is provided (#122446)
[Clipboard] Assert at least one clipboard data variant is provided
1 parent 48c06ad commit 70e1dc7

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

packages/flutter/lib/src/services/clipboard.dart

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

5-
65
import 'package:flutter/foundation.dart';
76

87
import 'system_channels.dart';
@@ -14,9 +13,12 @@ import 'system_channels.dart';
1413
@immutable
1514
class ClipboardData {
1615
/// Creates data for the system clipboard.
17-
const ClipboardData({ this.text });
16+
const ClipboardData({ required String this.text });
1817

1918
/// Plain text variant of this clipboard data.
19+
// This is nullable as other clipboard data variants, like images, may be
20+
// added in the future. Currently, plain text is the only supported variant
21+
// and this is guaranteed to be non-null.
2022
final String? text;
2123
}
2224

@@ -54,7 +56,7 @@ abstract final class Clipboard {
5456
if (result == null) {
5557
return null;
5658
}
57-
return ClipboardData(text: result['text'] as String?);
59+
return ClipboardData(text: result['text'] as String);
5860
}
5961

6062
/// Returns a future that resolves to true iff the clipboard contains string
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2014 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/services.dart';
6+
import 'package:flutter_test/flutter_test.dart';
7+
8+
import '../widgets/clipboard_utils.dart';
9+
10+
void main() {
11+
final MockClipboard mockClipboard = MockClipboard();
12+
TestWidgetsFlutterBinding.ensureInitialized()
13+
.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
14+
15+
test('Clipboard.getData returns text', () async {
16+
mockClipboard.clipboardData = <String, dynamic>{
17+
'text': 'Hello world',
18+
};
19+
20+
final ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain);
21+
22+
expect(data, isNotNull);
23+
expect(data!.text, equals('Hello world'));
24+
});
25+
26+
test('Clipboard.getData returns null', () async {
27+
mockClipboard.clipboardData = null;
28+
29+
final ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain);
30+
31+
expect(data, isNull);
32+
});
33+
34+
test('Clipboard.getData throws if text is missing', () async {
35+
mockClipboard.clipboardData = <String, dynamic>{};
36+
37+
expect(() => Clipboard.getData(Clipboard.kTextPlain), throwsA(isA<TypeError>()));
38+
});
39+
40+
test('Clipboard.getData throws if text is null', () async {
41+
mockClipboard.clipboardData = <String, dynamic>{
42+
'text': null,
43+
};
44+
45+
expect(() => Clipboard.getData(Clipboard.kTextPlain), throwsA(isA<TypeError>()));
46+
});
47+
48+
test('Clipboard.setData sets text', () async {
49+
await Clipboard.setData(const ClipboardData(text: 'Hello world'));
50+
51+
expect(mockClipboard.clipboardData, <String, dynamic>{
52+
'text': 'Hello world',
53+
});
54+
});
55+
}

0 commit comments

Comments
 (0)