Skip to content

Commit

Permalink
compose: Message compose box presents a sentence case keyboard
Browse files Browse the repository at this point in the history
  • Loading branch information
sirpengi committed Jan 19, 2024
1 parent 4e9380a commit d2a5766
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 1 deletion.
1 change: 1 addition & 0 deletions lib/widgets/compose_box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ class _ContentInput extends StatelessWidget {
style: TextStyle(color: colorScheme.onSurface),
decoration: InputDecoration.collapsed(hintText: hintText),
maxLines: null,
textCapitalization: TextCapitalization.sentences,
);
}),
));
Expand Down
6 changes: 5 additions & 1 deletion test/flutter_checks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
library;

import 'package:checks/checks.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';

extension AnimationChecks<T> on Subject<Animation<T>> {
Subject<AnimationStatus> get status => has((d) => d.status, 'status');
Expand Down Expand Up @@ -48,6 +48,10 @@ extension TextChecks on Subject<Text> {
Subject<String?> get data => has((t) => t.data, 'data');
}

extension TextFieldChecks on Subject<TextField> {
Subject<TextCapitalization?> get textCapitalization => has((t) => t.textCapitalization, 'textCapitalization');
}

extension TextStyleChecks on Subject<TextStyle> {
Subject<bool> get inherit => has((t) => t.inherit, 'inherit');
Subject<List<FontVariation>?> get fontVariations => has((t) => t.fontVariations, 'fontVariations');
Expand Down
79 changes: 79 additions & 0 deletions test/widgets/compose_box_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
import 'package:checks/checks.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:zulip/api/route/messages.dart';
import 'package:zulip/model/narrow.dart';
import 'package:zulip/widgets/compose_box.dart';
import 'package:zulip/widgets/message_list.dart';
import 'package:zulip/widgets/store.dart';

import '../api/fake_api.dart';
import '../example_data.dart' as eg;
import '../flutter_checks.dart';
import '../model/binding.dart';

void main() {
TestZulipBinding.ensureInitialized();
TestWidgetsFlutterBinding.ensureInitialized();

group('ComposeContentController', () {
group('insertPadded', () {
// Like `parseMarkedText` in test/model/autocomplete_test.dart,
Expand Down Expand Up @@ -105,4 +118,70 @@ void main() {
});
});
});

group('ComposeBox textCapitalization', () {
final message = eg.streamMessage();

Future<void> setupToComposeBox(WidgetTester tester, Narrow narrow) async {
addTearDown(testBinding.reset);
await testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot(
streams: [eg.stream(streamId: message.streamId)],
));
final store = await testBinding.globalStore.perAccount(eg.selfAccount.id);
final connection = store.connection as FakeApiConnection;

// prepare message list data
connection.prepare(json: GetMessagesResult(
anchor: message.id,
foundNewest: true,
foundOldest: true,
foundAnchor: true,
historyLimited: false,
messages: [message],
).toJson());

await tester.pumpWidget(
MaterialApp(
localizationsDelegates: ZulipLocalizations.localizationsDelegates,
supportedLocales: ZulipLocalizations.supportedLocales,
home: GlobalStoreWidget(
child: PerAccountStoreWidget(
accountId: eg.selfAccount.id,
child: MessageListPage(narrow: narrow)))));

// global store, per-account store, and message list get loaded
await tester.pumpAndSettle();
}

void checkComposeBoxTextFields(WidgetTester tester, {required bool expectTopicTextField}) {
final composeBoxController = tester.widget<ComposeBox>(find.byType(ComposeBox))
.controllerKey!.currentState!;

final topicTextField = tester.widgetList(find.byWidgetPredicate(
(widget) => widget is TextField
&& widget.controller == composeBoxController.topicController)).singleOrNull;
if (expectTopicTextField) {
check(topicTextField).isA<TextField>()
.textCapitalization.equals(TextCapitalization.none);
} else {
check(topicTextField).isNull();
}

final contentTextField = tester.widget(find.byWidgetPredicate(
(widget) => widget is TextField
&& widget.controller == composeBoxController.contentController));
check(contentTextField).isA<TextField>()
.textCapitalization.equals(TextCapitalization.sentences);
}

testWidgets('_StreamComposeBox', (tester) async {
await setupToComposeBox(tester, StreamNarrow(message.streamId));
checkComposeBoxTextFields(tester, expectTopicTextField: true);
});

testWidgets('_FixedDestinationComposeBox', (tester) async {
await setupToComposeBox(tester, TopicNarrow.ofMessage(message));
checkComposeBoxTextFields(tester, expectTopicTextField: false);
});
});
}

0 comments on commit d2a5766

Please sign in to comment.