diff --git a/packages/flutter/lib/src/cupertino/spell_check_suggestions_toolbar.dart b/packages/flutter/lib/src/cupertino/spell_check_suggestions_toolbar.dart index fbeb4f89fff..5a90459a347 100644 --- a/packages/flutter/lib/src/cupertino/spell_check_suggestions_toolbar.dart +++ b/packages/flutter/lib/src/cupertino/spell_check_suggestions_toolbar.dart @@ -45,7 +45,6 @@ class CupertinoSpellCheckSuggestionsToolbar extends StatelessWidget { /// Builds the button items for the toolbar based on the available /// spell check suggestions. static List? buildButtonItems( - BuildContext context, EditableTextState editableTextState, ) { // Determine if composing region is misspelled. @@ -58,8 +57,9 @@ class CupertinoSpellCheckSuggestionsToolbar extends StatelessWidget { return null; } if (spanAtCursorIndex.suggestions.isEmpty) { - assert(debugCheckHasCupertinoLocalizations(context)); - final CupertinoLocalizations localizations = CupertinoLocalizations.of(context); + assert(debugCheckHasCupertinoLocalizations(editableTextState.context)); + final CupertinoLocalizations localizations = + CupertinoLocalizations.of(editableTextState.context); return [ ContextMenuButtonItem( onPressed: () {}, diff --git a/packages/flutter/lib/src/cupertino/text_field.dart b/packages/flutter/lib/src/cupertino/text_field.dart index 77b0d8e616b..a4e81d0d319 100644 --- a/packages/flutter/lib/src/cupertino/text_field.dart +++ b/packages/flutter/lib/src/cupertino/text_field.dart @@ -802,7 +802,7 @@ class CupertinoTextField extends StatefulWidget { EditableTextState editableTextState, ) { final List? buttonItems = - CupertinoSpellCheckSuggestionsToolbar.buildButtonItems(context, editableTextState); + CupertinoSpellCheckSuggestionsToolbar.buildButtonItems(editableTextState); if (buttonItems == null || buttonItems.isEmpty){ return const SizedBox.shrink(); diff --git a/packages/flutter/lib/src/material/spell_check_suggestions_toolbar.dart b/packages/flutter/lib/src/material/spell_check_suggestions_toolbar.dart index c9f9851a3b7..74fddcb522c 100644 --- a/packages/flutter/lib/src/material/spell_check_suggestions_toolbar.dart +++ b/packages/flutter/lib/src/material/spell_check_suggestions_toolbar.dart @@ -62,7 +62,6 @@ class SpellCheckSuggestionsToolbar extends StatelessWidget { /// Builds the button items for the toolbar based on the available /// spell check suggestions. static List? buildButtonItems( - BuildContext context, EditableTextState editableTextState, ) { // Determine if composing region is misspelled. diff --git a/packages/flutter/lib/src/material/text_field.dart b/packages/flutter/lib/src/material/text_field.dart index 5732be23f02..a8589fbb6da 100644 --- a/packages/flutter/lib/src/material/text_field.dart +++ b/packages/flutter/lib/src/material/text_field.dart @@ -816,7 +816,7 @@ class TextField extends StatefulWidget { final Offset anchor = SpellCheckSuggestionsToolbar.getToolbarAnchor(editableTextState.contextMenuAnchors); final List? buttonItems = - SpellCheckSuggestionsToolbar.buildButtonItems(context, editableTextState); + SpellCheckSuggestionsToolbar.buildButtonItems(editableTextState); if (buttonItems == null){ return const SizedBox.shrink(); diff --git a/packages/flutter/test/cupertino/spell_check_suggestions_toolbar_test.dart b/packages/flutter/test/cupertino/spell_check_suggestions_toolbar_test.dart new file mode 100644 index 00000000000..55f569330ce --- /dev/null +++ b/packages/flutter/test/cupertino/spell_check_suggestions_toolbar_test.dart @@ -0,0 +1,57 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; + +import 'package:flutter_test/flutter_test.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('buildButtonItems builds a "No Replacements Found" button when no suggestions', (WidgetTester tester) async { + await tester.pumpWidget( + CupertinoApp( + home: _FakeEditableText(), + ), + ); + final _FakeEditableTextState editableTextState = + tester.state(find.byType(_FakeEditableText)); + final List? buttonItems = + CupertinoSpellCheckSuggestionsToolbar.buildButtonItems(editableTextState); + + expect(buttonItems, isNotNull); + expect(buttonItems!.length, 1); + expect(buttonItems.first.label, 'No Replacements Found'); + }); +} + +class _FakeEditableText extends EditableText { + _FakeEditableText() : super( + controller: TextEditingController(), + focusNode: FocusNode(), + backgroundCursorColor: CupertinoColors.white, + cursorColor: CupertinoColors.white, + style: const TextStyle(), + ); + + @override + _FakeEditableTextState createState() => _FakeEditableTextState(); +} + +class _FakeEditableTextState extends EditableTextState { + @override + TextEditingValue get currentTextEditingValue => TextEditingValue.empty; + + @override + SuggestionSpan? findSuggestionSpanAtCursorIndex(int cursorIndex) { + return const SuggestionSpan( + TextRange( + start: 0, + end: 0, + ), + [], + ); + } +} diff --git a/packages/flutter/test/material/spell_check_suggestions_toolbar_test.dart b/packages/flutter/test/material/spell_check_suggestions_toolbar_test.dart index 440deda1b72..78d1569baeb 100644 --- a/packages/flutter/test/material/spell_check_suggestions_toolbar_test.dart +++ b/packages/flutter/test/material/spell_check_suggestions_toolbar_test.dart @@ -4,6 +4,7 @@ import 'package:flutter/cupertino.dart' show CupertinoTextSelectionToolbar; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; // Vertical position at which to anchor the toolbar for testing. @@ -85,4 +86,29 @@ void main() { final double toolbarY = tester.getTopLeft(findSpellCheckSuggestionsToolbar()).dy; expect(toolbarY, equals(expectedToolbarY)); }); + + test('buildButtonItems builds only a delete button when no suggestions', () { + final _FakeEditableTextState editableTextState = _FakeEditableTextState(); + final List? buttonItems = + SpellCheckSuggestionsToolbar.buildButtonItems(editableTextState); + + expect(buttonItems, hasLength(1)); + expect(buttonItems!.first.type, ContextMenuButtonType.delete); + }); +} + +class _FakeEditableTextState extends EditableTextState { + @override + TextEditingValue get currentTextEditingValue => TextEditingValue.empty; + + @override + SuggestionSpan? findSuggestionSpanAtCursorIndex(int cursorIndex) { + return const SuggestionSpan( + TextRange( + start: 0, + end: 0, + ), + [], + ); + } }