Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit a6ea644

Browse files
authored
Fix cut button creation in 'buttonItemsForToolbarOptions' (#119822)
* Fix cut button creation in buttonItemsForToolbarOptions * Remove extra spaces in tests * Replace fails with expects, Add periods in the comments
1 parent 16441f4 commit a6ea644

File tree

2 files changed

+286
-2
lines changed

2 files changed

+286
-2
lines changed

packages/flutter/lib/src/widgets/editable_text.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,9 +2432,9 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
24322432
if (toolbarOptions.cut && cutEnabled)
24332433
ContextMenuButtonItem(
24342434
onPressed: () {
2435-
selectAll(SelectionChangedCause.toolbar);
2435+
cutSelection(SelectionChangedCause.toolbar);
24362436
},
2437-
type: ContextMenuButtonType.selectAll,
2437+
type: ContextMenuButtonType.cut,
24382438
),
24392439
if (toolbarOptions.copy && copyEnabled)
24402440
ContextMenuButtonItem(

packages/flutter/test/widgets/editable_text_test.dart

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,6 +2157,290 @@ void main() {
21572157
expect(state.textEditingValue.selection.isCollapsed, isTrue);
21582158
});
21592159

2160+
group('buttonItemsForToolbarOptions', () {
2161+
testWidgets('returns null when toolbarOptions are empty', (WidgetTester tester) async {
2162+
await tester.pumpWidget(
2163+
MaterialApp(
2164+
home: EditableText(
2165+
controller: TextEditingController(text: 'TEXT'),
2166+
toolbarOptions: ToolbarOptions.empty,
2167+
focusNode: focusNode,
2168+
style: textStyle,
2169+
cursorColor: cursorColor,
2170+
backgroundCursorColor: Colors.grey,
2171+
),
2172+
),
2173+
);
2174+
2175+
final EditableTextState state = tester.state<EditableTextState>(
2176+
find.byType(EditableText),
2177+
);
2178+
2179+
expect(state.buttonItemsForToolbarOptions(), isNull);
2180+
});
2181+
2182+
testWidgets('returns empty array when only cut is selected in toolbarOptions but cut is not enabled', (WidgetTester tester) async {
2183+
await tester.pumpWidget(
2184+
MaterialApp(
2185+
home: EditableText(
2186+
controller: TextEditingController(text: 'TEXT'),
2187+
toolbarOptions: const ToolbarOptions(cut: true),
2188+
readOnly: true,
2189+
focusNode: focusNode,
2190+
style: textStyle,
2191+
cursorColor: cursorColor,
2192+
backgroundCursorColor: Colors.grey,
2193+
),
2194+
),
2195+
);
2196+
2197+
final EditableTextState state = tester.state<EditableTextState>(
2198+
find.byType(EditableText),
2199+
);
2200+
2201+
expect(state.cutEnabled, isFalse);
2202+
expect(state.buttonItemsForToolbarOptions(), isEmpty);
2203+
});
2204+
2205+
testWidgets('returns only cut button when only cut is selected in toolbarOptions and cut is enabled', (WidgetTester tester) async {
2206+
const String text = 'TEXT';
2207+
final TextEditingController controller = TextEditingController(text: text);
2208+
2209+
await tester.pumpWidget(
2210+
MaterialApp(
2211+
home: EditableText(
2212+
controller: controller,
2213+
toolbarOptions: const ToolbarOptions(cut: true),
2214+
focusNode: focusNode,
2215+
style: textStyle,
2216+
cursorColor: cursorColor,
2217+
backgroundCursorColor: Colors.grey,
2218+
),
2219+
),
2220+
);
2221+
2222+
final EditableTextState state = tester.state<EditableTextState>(
2223+
find.byType(EditableText),
2224+
);
2225+
2226+
// Selecting all.
2227+
controller.selection = TextSelection(
2228+
baseOffset: 0,
2229+
extentOffset: controller.text.length,
2230+
);
2231+
expect(state.cutEnabled, isTrue);
2232+
2233+
final List<ContextMenuButtonItem>? items = state.buttonItemsForToolbarOptions();
2234+
2235+
expect(items, isNotNull);
2236+
expect(items, hasLength(1));
2237+
2238+
final ContextMenuButtonItem cutButton = items!.first;
2239+
expect(cutButton.type, ContextMenuButtonType.cut);
2240+
2241+
cutButton.onPressed();
2242+
await tester.pump();
2243+
2244+
expect(controller.text, isEmpty);
2245+
final ClipboardData? data = await Clipboard.getData('text/plain');
2246+
expect(data, isNotNull);
2247+
expect(data!.text, equals(text));
2248+
});
2249+
2250+
testWidgets('returns empty array when only copy is selected in toolbarOptions but copy is not enabled', (WidgetTester tester) async {
2251+
await tester.pumpWidget(
2252+
MaterialApp(
2253+
home: EditableText(
2254+
controller: TextEditingController(text: 'TEXT'),
2255+
toolbarOptions: const ToolbarOptions(copy: true),
2256+
obscureText: true,
2257+
focusNode: focusNode,
2258+
style: textStyle,
2259+
cursorColor: cursorColor,
2260+
backgroundCursorColor: Colors.grey,
2261+
),
2262+
),
2263+
);
2264+
2265+
final EditableTextState state = tester.state<EditableTextState>(
2266+
find.byType(EditableText),
2267+
);
2268+
2269+
expect(state.copyEnabled, isFalse);
2270+
expect(state.buttonItemsForToolbarOptions(), isEmpty);
2271+
});
2272+
2273+
testWidgets('returns only copy button when only copy is selected in toolbarOptions and copy is enabled', (WidgetTester tester) async {
2274+
const String text = 'TEXT';
2275+
final TextEditingController controller = TextEditingController(text: text);
2276+
2277+
await tester.pumpWidget(
2278+
MaterialApp(
2279+
home: EditableText(
2280+
controller: controller,
2281+
toolbarOptions: const ToolbarOptions(copy: true),
2282+
focusNode: focusNode,
2283+
style: textStyle,
2284+
cursorColor: cursorColor,
2285+
backgroundCursorColor: Colors.grey,
2286+
),
2287+
),
2288+
);
2289+
2290+
final EditableTextState state = tester.state<EditableTextState>(
2291+
find.byType(EditableText),
2292+
);
2293+
2294+
// Selecting all.
2295+
controller.selection = TextSelection(
2296+
baseOffset: 0,
2297+
extentOffset: controller.text.length,
2298+
);
2299+
expect(state.copyEnabled, isTrue);
2300+
2301+
final List<ContextMenuButtonItem>? items = state.buttonItemsForToolbarOptions();
2302+
2303+
expect(items, isNotNull);
2304+
expect(items, hasLength(1));
2305+
2306+
final ContextMenuButtonItem copyButton = items!.first;
2307+
expect(copyButton.type, ContextMenuButtonType.copy);
2308+
2309+
copyButton.onPressed();
2310+
await tester.pump();
2311+
2312+
expect(controller.text, equals(text));
2313+
final ClipboardData? data = await Clipboard.getData('text/plain');
2314+
expect(data, isNotNull);
2315+
expect(data!.text, equals(text));
2316+
});
2317+
2318+
testWidgets('returns empty array when only paste is selected in toolbarOptions but paste is not enabled', (WidgetTester tester) async {
2319+
await tester.pumpWidget(
2320+
MaterialApp(
2321+
home: EditableText(
2322+
controller: TextEditingController(text: 'TEXT'),
2323+
toolbarOptions: const ToolbarOptions(paste: true),
2324+
readOnly: true,
2325+
focusNode: focusNode,
2326+
style: textStyle,
2327+
cursorColor: cursorColor,
2328+
backgroundCursorColor: Colors.grey,
2329+
),
2330+
),
2331+
);
2332+
2333+
final EditableTextState state = tester.state<EditableTextState>(
2334+
find.byType(EditableText),
2335+
);
2336+
2337+
expect(state.pasteEnabled, isFalse);
2338+
expect(state.buttonItemsForToolbarOptions(), isEmpty);
2339+
});
2340+
2341+
testWidgets('returns only paste button when only paste is selected in toolbarOptions and paste is enabled', (WidgetTester tester) async {
2342+
const String text = 'TEXT';
2343+
final TextEditingController controller = TextEditingController(text: text);
2344+
2345+
await tester.pumpWidget(
2346+
MaterialApp(
2347+
home: EditableText(
2348+
controller: controller,
2349+
toolbarOptions: const ToolbarOptions(paste: true),
2350+
focusNode: focusNode,
2351+
style: textStyle,
2352+
cursorColor: cursorColor,
2353+
backgroundCursorColor: Colors.grey,
2354+
),
2355+
),
2356+
);
2357+
2358+
final EditableTextState state = tester.state<EditableTextState>(
2359+
find.byType(EditableText),
2360+
);
2361+
2362+
// Moving caret to the end.
2363+
controller.selection = TextSelection.collapsed(offset: controller.text.length);
2364+
expect(state.pasteEnabled, isTrue);
2365+
2366+
final List<ContextMenuButtonItem>? items = state.buttonItemsForToolbarOptions();
2367+
2368+
expect(items, isNotNull);
2369+
expect(items, hasLength(1));
2370+
2371+
final ContextMenuButtonItem pasteButton = items!.first;
2372+
expect(pasteButton.type, ContextMenuButtonType.paste);
2373+
2374+
// Setting data which will be pasted into the clipboard.
2375+
await Clipboard.setData(const ClipboardData(text: text));
2376+
2377+
pasteButton.onPressed();
2378+
await tester.pump();
2379+
2380+
expect(controller.text, equals(text + text));
2381+
});
2382+
2383+
testWidgets('returns empty array when only selectAll is selected in toolbarOptions but selectAll is not enabled', (WidgetTester tester) async {
2384+
await tester.pumpWidget(
2385+
MaterialApp(
2386+
home: EditableText(
2387+
controller: TextEditingController(text: 'TEXT'),
2388+
toolbarOptions: const ToolbarOptions(selectAll: true),
2389+
readOnly: true,
2390+
obscureText: true,
2391+
focusNode: focusNode,
2392+
style: textStyle,
2393+
cursorColor: cursorColor,
2394+
backgroundCursorColor: Colors.grey,
2395+
),
2396+
),
2397+
);
2398+
2399+
final EditableTextState state = tester.state<EditableTextState>(
2400+
find.byType(EditableText),
2401+
);
2402+
2403+
expect(state.selectAllEnabled, isFalse);
2404+
expect(state.buttonItemsForToolbarOptions(), isEmpty);
2405+
});
2406+
2407+
testWidgets('returns only selectAll button when only selectAll is selected in toolbarOptions and selectAll is enabled', (WidgetTester tester) async {
2408+
const String text = 'TEXT';
2409+
final TextEditingController controller = TextEditingController(text: text);
2410+
2411+
await tester.pumpWidget(
2412+
MaterialApp(
2413+
home: EditableText(
2414+
controller: controller,
2415+
toolbarOptions: const ToolbarOptions(selectAll: true),
2416+
focusNode: focusNode,
2417+
style: textStyle,
2418+
cursorColor: cursorColor,
2419+
backgroundCursorColor: Colors.grey,
2420+
),
2421+
),
2422+
);
2423+
2424+
final EditableTextState state = tester.state<EditableTextState>(
2425+
find.byType(EditableText),
2426+
);
2427+
2428+
final List<ContextMenuButtonItem>? items = state.buttonItemsForToolbarOptions();
2429+
2430+
expect(items, isNotNull);
2431+
expect(items, hasLength(1));
2432+
2433+
final ContextMenuButtonItem selectAllButton = items!.first;
2434+
expect(selectAllButton.type, ContextMenuButtonType.selectAll);
2435+
2436+
selectAllButton.onPressed();
2437+
await tester.pump();
2438+
2439+
expect(controller.text, equals(text));
2440+
expect(state.textEditingValue.selection.textInside(text), equals(text));
2441+
});
2442+
});
2443+
21602444
testWidgets('Handles the read-only flag correctly', (WidgetTester tester) async {
21612445
final TextEditingController controller =
21622446
TextEditingController(text: 'Lorem ipsum dolor sit amet');

0 commit comments

Comments
 (0)