test(localization): add unit tests

Signed-off-by: xsahil03x <xdsahil@gmail.com>
This commit is contained in:
Sahil Kumar
2021-07-21 21:11:08 +05:30
committed by xsahil03x
parent 42ed729a87
commit df834f4c8b
4 changed files with 549 additions and 20 deletions
@@ -0,0 +1,109 @@
// ignore_for_file: omit_local_variable_types
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:stream_chat_localizations/src/stream_chat_localizations.dart';
void main() {
testWidgets('Nested Localizations', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
// Creates the outer Localizations widget.
home: ListView(
children: <Widget>[
const LocalizationTracker(key: ValueKey<String>('outer')),
Localizations(
locale: const Locale('hi'),
delegates: GlobalStreamChatLocalizations.delegates,
child: const LocalizationTracker(key: ValueKey<String>('inner')),
),
],
),
));
final LocalizationTrackerState outerTracker = tester.state(
find.byKey(const ValueKey<String>('outer'), skipOffstage: false));
expect(outerTracker.captionFontSize, 12.0);
final LocalizationTrackerState innerTracker = tester.state(
find.byKey(const ValueKey<String>('inner'), skipOffstage: false));
expect(innerTracker.captionFontSize, 13.0);
});
testWidgets(
'Localizations is compatible with ChangeNotifier.dispose() called '
'during didChangeDependencies',
(WidgetTester tester) async {
// PageView calls ScrollPosition.dispose() during didChangeDependencies.
await tester.pumpWidget(MaterialApp(
supportedLocales: const <Locale>[
Locale('en', 'US'),
Locale('hi', 'IN'),
],
localizationsDelegates: const [
DummyLocalizations.delegate,
GlobalStreamChatLocalizations.delegate,
],
home: PageView(),
));
await tester.binding.setLocale('hi', 'IN');
await tester.pump();
await tester.pumpWidget(Container());
},
);
testWidgets('Locale without countryCode', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/pull/16782
await tester.pumpWidget(MaterialApp(
localizationsDelegates: const <LocalizationsDelegate<dynamic>>[
GlobalStreamChatLocalizations.delegate,
],
supportedLocales: const <Locale>[
Locale('en', 'US'),
Locale('hi'),
],
home: Container(),
));
await tester.binding.setLocale('hi', '');
await tester.pump();
await tester.binding.setLocale('en', 'US');
await tester.pump();
});
}
/// A localizations delegate that does not contain any useful data, and is only
/// used to trigger didChangeDependencies upon locale change.
class _DummyLocalizationsDelegate
extends LocalizationsDelegate<DummyLocalizations> {
const _DummyLocalizationsDelegate();
@override
Future<DummyLocalizations> load(Locale locale) async => DummyLocalizations();
@override
bool isSupported(Locale locale) => true;
@override
bool shouldReload(_DummyLocalizationsDelegate old) => true;
}
class DummyLocalizations {
static const delegate = _DummyLocalizationsDelegate();
}
class LocalizationTracker extends StatefulWidget {
const LocalizationTracker({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => LocalizationTrackerState();
}
class LocalizationTrackerState extends State<LocalizationTracker> {
late double captionFontSize;
@override
Widget build(BuildContext context) {
captionFontSize = Theme.of(context).textTheme.caption!.fontSize!;
return Container();
}
}
@@ -0,0 +1,276 @@
// ignore_for_file: prefer_expression_function_bodies
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:stream_chat_localizations/src/stream_chat_localizations.dart';
import 'package:flutter_test/flutter_test.dart';
class FooStreamChatLocalizations extends StreamChatLocalizationsEn {
FooStreamChatLocalizations(
Locale localeName,
this.launchUrlError,
) : super(localeName: localeName.toString());
@override
final String launchUrlError;
}
class FooStreamChatLocalizationsDelegate
extends LocalizationsDelegate<StreamChatLocalizations> {
const FooStreamChatLocalizationsDelegate({
this.supportedLanguage = 'en',
this.launchUrlError = 'foo',
});
final String supportedLanguage;
final String launchUrlError;
@override
bool isSupported(Locale locale) =>
supportedLanguage == 'allLanguages' ||
locale.languageCode == supportedLanguage;
@override
Future<FooStreamChatLocalizations> load(Locale locale) =>
SynchronousFuture<FooStreamChatLocalizations>(
FooStreamChatLocalizations(locale, launchUrlError),
);
@override
bool shouldReload(FooStreamChatLocalizationsDelegate old) => false;
}
Widget buildFrame({
Locale? locale,
Iterable<LocalizationsDelegate> delegates =
GlobalStreamChatLocalizations.delegates,
required WidgetBuilder buildContent,
LocaleResolutionCallback? localeResolutionCallback,
Iterable<Locale> supportedLocales = const <Locale>[
Locale('en', 'US'),
Locale('hi', 'IN'),
],
}) =>
MaterialApp(
color: const Color(0xFFFFFFFF),
locale: locale,
supportedLocales: supportedLocales,
localizationsDelegates: delegates,
localeResolutionCallback: localeResolutionCallback,
onGenerateRoute: (RouteSettings settings) => MaterialPageRoute<void>(
builder: (BuildContext context) => buildContent(context)),
);
void main() {
testWidgets(
'Locale fallbacks',
(WidgetTester tester) async {
final Key textKey = UniqueKey();
await tester.pumpWidget(
buildFrame(
buildContent: (BuildContext context) => Text(
StreamChatLocalizations.of(context)!.launchUrlError,
key: textKey,
),
),
);
expect(
tester.widget<Text>(find.byKey(textKey)).data,
'Cannot launch the url',
);
// Unrecognized locale falls back to 'en'
await tester.binding.setLocale('foo', 'BAR');
await tester.pump();
expect(
tester.widget<Text>(find.byKey(textKey)).data,
'Cannot launch the url',
);
// Indian hindi locale, falls back to just 'hi'
await tester.binding.setLocale('hi', 'IN');
await tester.pump();
expect(
tester.widget<Text>(find.byKey(textKey)).data,
'यूआरएल लॉन्च नहीं कर सकते',
);
},
);
testWidgets(
"Localizations.override widget tracks parent's locale",
(WidgetTester tester) async {
Widget buildLocaleFrame(Locale locale) => buildFrame(
locale: locale,
supportedLocales: <Locale>[locale],
buildContent: (BuildContext context) => Localizations.override(
context: context,
child: Builder(
builder: (BuildContext context) {
// No StreamChatLocalizations are defined for the first
// Localizations ancestor, so we should get the values from
// the default one, i.e. the one created by WidgetsApp via
// the LocalizationsDelegate provided by MaterialApp.
return Text(
StreamChatLocalizations.of(context)!.launchUrlError,
);
},
),
),
);
await tester.pumpWidget(buildLocaleFrame(const Locale('en', 'US')));
expect(find.text('Cannot launch the url'), findsOneWidget);
await tester.pumpWidget(buildLocaleFrame(const Locale('hi', 'IN')));
expect(find.text('यूआरएल लॉन्च नहीं कर सकते'), findsOneWidget);
},
);
testWidgets('Localizations.override widget with hardwired locale',
(WidgetTester tester) async {
Widget buildLocaleFrame(Locale locale) => buildFrame(
locale: locale,
buildContent: (BuildContext context) {
return Localizations.override(
context: context,
locale: const Locale('en', 'US'),
child: Builder(
builder: (BuildContext context) {
// No StreamChatLocalizations are defined for the first
// Localizations ancestor, so we should get the values from
// the default one, i.e. the one created by WidgetsApp via
// the LocalizationsDelegate provided by MaterialApp.
return Text(
StreamChatLocalizations.of(context)!.launchUrlError,
);
},
),
);
},
);
await tester.pumpWidget(buildLocaleFrame(const Locale('en', 'US')));
expect(find.text('Cannot launch the url'), findsOneWidget);
await tester.pumpWidget(buildLocaleFrame(const Locale('hi', 'IN')));
expect(find.text('Cannot launch the url'), findsOneWidget);
});
testWidgets(
'MaterialApp adds StreamChatLocalizations for additional languages',
(WidgetTester tester) async {
final Key textKey = UniqueKey();
await tester.pumpWidget(buildFrame(
delegates: <LocalizationsDelegate<StreamChatLocalizations>>[
GlobalStreamChatLocalizations.delegate,
const FooStreamChatLocalizationsDelegate(
supportedLanguage: 'fr',
launchUrlError: "Impossible de lancer l'url",
),
const FooStreamChatLocalizationsDelegate(
supportedLanguage: 'de',
launchUrlError: 'Kann die URL nicht starten',
),
],
supportedLocales: const <Locale>[
Locale('en'),
Locale('hi'),
Locale('fr'),
Locale('de'),
],
buildContent: (BuildContext context) => Text(
StreamChatLocalizations.of(context)!.launchUrlError,
key: textKey,
),
));
expect(
tester.widget<Text>(find.byKey(textKey)).data,
'Cannot launch the url',
);
await tester.binding.setLocale('hi', 'IN');
await tester.pump();
expect(find.text('यूआरएल लॉन्च नहीं कर सकते'), findsOneWidget);
await tester.binding.setLocale('fr', 'CA');
await tester.pump();
expect(find.text("Impossible de lancer l'url"), findsOneWidget);
await tester.binding.setLocale('de', 'DE');
await tester.pump();
expect(find.text('Kann die URL nicht starten'), findsOneWidget);
},
);
testWidgets(
'MaterialApp overrides MaterialLocalizations for all locales',
(WidgetTester tester) async {
final Key textKey = UniqueKey();
await tester.pumpWidget(buildFrame(
// Accept whatever locale we're given
localeResolutionCallback:
(Locale? locale, Iterable<Locale> supportedLocales) => locale,
delegates: <FooStreamChatLocalizationsDelegate>[
const FooStreamChatLocalizationsDelegate(
supportedLanguage: 'allLanguages',
),
],
buildContent: (BuildContext context) {
// Should always be 'foo', no matter what the locale is
return Text(
StreamChatLocalizations.of(context)!.launchUrlError,
key: textKey,
);
},
));
expect(tester.widget<Text>(find.byKey(textKey)).data, 'foo');
await tester.binding.setLocale('zh', 'CN');
await tester.pump();
expect(find.text('foo'), findsOneWidget);
await tester.binding.setLocale('de', 'DE');
await tester.pump();
expect(find.text('foo'), findsOneWidget);
},
);
testWidgets(
'MaterialApp overrides MaterialLocalizations for default locale',
(WidgetTester tester) async {
final Key textKey = UniqueKey();
await tester.pumpWidget(buildFrame(
delegates: <FooStreamChatLocalizationsDelegate>[
const FooStreamChatLocalizationsDelegate(),
],
// supportedLocales not specified, so all locales resolve to 'en'
buildContent: (BuildContext context) => Text(
StreamChatLocalizations.of(context)!.launchUrlError,
key: textKey,
),
));
// Unsupported locale '_' (the widget tester's default) resolves to 'en'.
expect(tester.widget<Text>(find.byKey(textKey)).data, 'foo');
// Unsupported locale 'zh' resolves to 'en'.
await tester.binding.setLocale('zh', 'CN');
await tester.pump();
expect(find.text('foo'), findsOneWidget);
// Unsupported locale 'de' resolves to 'en'.
await tester.binding.setLocale('de', 'DE');
await tester.pump();
expect(find.text('foo'), findsOneWidget);
},
);
}
@@ -1,20 +0,0 @@
import 'dart:ui';
import 'package:flutter_test/flutter_test.dart';
import 'package:stream_chat_localizations/stream_chat_localizations.dart';
void main() {
for (final language in kStreamChatSupportedLanguages) {
test('translations exist for $language', () async {
final locale = Locale(language);
expect(
GlobalStreamChatLocalizations.delegate.isSupported(locale),
isTrue,
);
final localizations =
await GlobalStreamChatLocalizations.delegate.load(locale);
expect(localizations.launchUrlError, isNotNull);
});
}
}
@@ -0,0 +1,164 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:stream_chat_localizations/stream_chat_localizations.dart';
void main() {
for (final language in kStreamChatSupportedLanguages) {
test('translations exist for $language', () async {
final locale = Locale(language);
expect(
GlobalStreamChatLocalizations.delegate.isSupported(locale), isTrue);
final localizations =
await GlobalStreamChatLocalizations.delegate.load(locale);
expect(localizations.launchUrlError, isNotNull);
expect(localizations.loadingUsersError, isNotNull);
expect(localizations.noUsersLabel, isNotNull);
expect(localizations.retryLabel, isNotNull);
expect(localizations.userLastOnlineText, isNotNull);
expect(localizations.userOnlineText, isNotNull);
expect(localizations.userOnlineText, isNotNull);
// no users
expect(localizations.userTypingText([]), isNotNull);
// single user
expect(localizations.userTypingText([User(id: 'test-id')]), isNotNull);
// multiple users
expect(
localizations.userTypingText([
User(id: 'test-id-1'),
User(id: 'test-id-2'),
]),
isNotNull,
);
expect(localizations.threadReplyLabel, isNotNull);
expect(localizations.onlyVisibleToYouText, isNotNull);
expect(localizations.threadReplyCountText(3), isNotNull);
expect(
localizations.attachmentsUploadProgressText(remaining: 3, total: 10),
isNotNull,
);
expect(
localizations.pinnedByUserText(
pinnedBy: User(id: 'pinned-by-user-id'),
currentUser: OwnUser(id: 'current-user-id'),
),
isNotNull,
);
expect(localizations.emptyMessagesText, isNotNull);
expect(localizations.genericErrorText, isNotNull);
expect(localizations.loadingMessagesError, isNotNull);
expect(localizations.resultCountText(3), isNotNull);
expect(localizations.messageDeletedText, isNotNull);
expect(localizations.messageDeletedLabel, isNotNull);
expect(localizations.messageReactionsText, isNotNull);
expect(localizations.emptyChatMessagesText, isNotNull);
expect(localizations.threadSeparatorText(3), isNotNull);
expect(localizations.connectedLabel, isNotNull);
expect(localizations.disconnectedLabel, isNotNull);
expect(localizations.reconnectingLabel, isNotNull);
expect(localizations.alsoSendAsDirectMessageLabel, isNotNull);
expect(localizations.addACommentOrSendLabel, isNotNull);
expect(localizations.searchGifLabel, isNotNull);
expect(localizations.writeAMessageLabel, isNotNull);
expect(localizations.instantCommandsLabel, isNotNull);
expect(localizations.fileTooLargeAfterCompressionError, isNotNull);
expect(localizations.fileTooLargeError, isNotNull);
expect(localizations.emojiMatchingQueryText('sahil'), isNotNull);
expect(localizations.addAFileLabel, isNotNull);
expect(localizations.photoFromCameraLabel, isNotNull);
expect(localizations.uploadAFileLabel, isNotNull);
expect(localizations.uploadAPhotoLabel, isNotNull);
expect(localizations.uploadAVideoLabel, isNotNull);
expect(localizations.videoFromCameraLabel, isNotNull);
expect(localizations.okLabel, isNotNull);
expect(localizations.somethingWentWrongLabel, isNotNull);
expect(localizations.addMoreFilesLabel, isNotNull);
expect(localizations.enablePhotoAndVideoAccessMessage, isNotNull);
expect(localizations.allowGalleryAccessMessage, isNotNull);
expect(localizations.flagMessageLabel, isNotNull);
expect(localizations.flagMessageQuestion, isNotNull);
expect(localizations.flagLabel, isNotNull);
expect(localizations.cancelLabel, isNotNull);
expect(localizations.flagMessageSuccessfulLabel, isNotNull);
expect(localizations.flagMessageSuccessfulText, isNotNull);
expect(localizations.deleteLabel, isNotNull);
expect(localizations.deleteMessageLabel, isNotNull);
expect(localizations.deleteMessageQuestion, isNotNull);
expect(localizations.operationCouldNotBeCompletedText, isNotNull);
expect(localizations.replyLabel, isNotNull);
// pinned
expect(localizations.togglePinUnpinText(pinned: true), isNotNull);
// un-pinned
expect(localizations.togglePinUnpinText(pinned: false), isNotNull);
// delete-failed
expect(
localizations.toggleDeleteRetryDeleteMessageText(isDeleteFailed: true),
isNotNull,
);
// first-delete
expect(
localizations.toggleDeleteRetryDeleteMessageText(isDeleteFailed: false),
isNotNull,
);
expect(localizations.copyMessageLabel, isNotNull);
expect(localizations.editMessageLabel, isNotNull);
// resend-failed
expect(
localizations.toggleResendOrResendEditedMessage(isUpdateFailed: true),
isNotNull,
);
// first resend
expect(
localizations.toggleResendOrResendEditedMessage(isUpdateFailed: false),
isNotNull,
);
expect(localizations.photosLabel, isNotNull);
expect(
localizations.sentAtText(
date: DateTime.now(),
time: DateTime.now(),
),
isNotNull,
);
expect(localizations.todayLabel, isNotNull);
expect(localizations.yesterdayLabel, isNotNull);
expect(localizations.channelIsMutedText, isNotNull);
expect(localizations.noTitleText, isNotNull);
expect(localizations.letsStartChattingLabel, isNotNull);
expect(localizations.sendingFirstMessageLabel, isNotNull);
expect(localizations.startAChatLabel, isNotNull);
expect(localizations.loadingChannelsError, isNotNull);
expect(localizations.deleteConversationQuestion, isNotNull);
expect(localizations.streamChatLabel, isNotNull);
expect(localizations.searchingForNetworkLabel, isNotNull);
expect(localizations.offlineLabel, isNotNull);
expect(localizations.tryAgainLabel, isNotNull);
// 1 member
expect(localizations.membersCountText(1), isNotNull);
// 3 members
expect(localizations.membersCountText(3), isNotNull);
// 1 member
expect(localizations.watchersCountText(1), isNotNull);
// 3 members
expect(localizations.watchersCountText(3), isNotNull);
expect(localizations.viewInfoLabel, isNotNull);
expect(localizations.leaveGroupLabel, isNotNull);
expect(localizations.leaveLabel, isNotNull);
expect(localizations.leaveConversationLabel, isNotNull);
expect(localizations.leaveConversationQuestion, isNotNull);
expect(localizations.showInChatLabel, isNotNull);
expect(localizations.saveVideoLabel, isNotNull);
expect(localizations.uploadErrorLabel, isNotNull);
expect(localizations.giphyLabel, isNotNull);
expect(localizations.shuffleLabel, isNotNull);
expect(localizations.sendLabel, isNotNull);
expect(localizations.withText, isNotNull);
expect(localizations.inText, isNotNull);
expect(localizations.youText, isNotNull);
expect(localizations.ofText, isNotNull);
expect(localizations.fileText, isNotNull);
expect(localizations.replyToMessageLabel, isNotNull);
});
}
}