Jonny Borges

fix internationalization and add tests to tr

1 import 'dart:ui'; 1 import 'dart:ui';
  2 +
2 import '../../../get_core/get_core.dart'; 3 import '../../../get_core/get_core.dart';
3 4
4 -extension Trans on String {  
5 - String get tr {  
6 - // Returns the key if locale is null.  
7 - if (Get.locale?.languageCode == null) return this; 5 +class _IntlHost {
  6 + Locale? locale;
  7 +
  8 + Locale? fallbackLocale;
  9 +
  10 + Map<String, Map<String, String>> translations = {};
  11 +}
  12 +
  13 +extension FirstWhereExt<T> on List<T> {
  14 + /// The first element satisfying [test], or `null` if there are none.
  15 + T? firstWhereOrNull(bool Function(T element) test) {
  16 + for (var element in this) {
  17 + if (test(element)) return element;
  18 + }
  19 + return null;
  20 + }
  21 +}
  22 +
  23 +extension LocalesIntl on GetInterface {
  24 + static final _intlHost = _IntlHost();
  25 +
  26 + Locale? get locale => _intlHost.locale;
  27 +
  28 + Locale? get fallbackLocale => _intlHost.fallbackLocale;
  29 +
  30 + set locale(Locale? newLocale) => _intlHost.locale = newLocale;
  31 +
  32 + set fallbackLocale(Locale? newLocale) => _intlHost.fallbackLocale = newLocale;
  33 +
  34 + Map<String, Map<String, String>> get translations => _intlHost.translations;
  35 +
  36 + void addTranslations(Map<String, Map<String, String>> tr) {
  37 + translations.addAll(tr);
  38 + }
  39 +
  40 + void clearTranslations() {
  41 + translations.clear();
  42 + }
  43 +
  44 + void appendTranslations(Map<String, Map<String, String>> tr) {
  45 + tr.forEach((key, map) {
  46 + if (translations.containsKey(key)) {
  47 + translations[key]!.addAll(map);
  48 + } else {
  49 + translations[key] = map;
  50 + }
  51 + });
  52 + }
  53 +}
8 54
  55 +extension Trans on String {
9 // Checks whether the language code and country code are present, and 56 // Checks whether the language code and country code are present, and
10 // whether the key is also present. 57 // whether the key is also present.
11 - if (Get.translations.containsKey( 58 + bool get _fullLocaleAndKey {
  59 + return Get.translations.containsKey(
12 "${Get.locale!.languageCode}_${Get.locale!.countryCode}") && 60 "${Get.locale!.languageCode}_${Get.locale!.countryCode}") &&
13 Get.translations[ 61 Get.translations[
14 "${Get.locale!.languageCode}_${Get.locale!.countryCode}"]! 62 "${Get.locale!.languageCode}_${Get.locale!.countryCode}"]!
15 - .containsKey(this)) {  
16 - return Get.translations[  
17 - "${Get.locale!.languageCode}_${Get.locale!.countryCode}"]![this]!; 63 + .containsKey(this);
  64 + }
18 65
19 // Checks if there is a callback language in the absence of the specific 66 // Checks if there is a callback language in the absence of the specific
20 // country, and if it contains that key. 67 // country, and if it contains that key.
21 - } else if (Get.translations.containsKey(Get.locale!.languageCode) &&  
22 - Get.translations[Get.locale!.languageCode]!.containsKey(this)) {  
23 - return Get.translations[Get.locale!.languageCode]![this]!; 68 + Map<String, String>? get _getSimilarLanguageTranslation {
  69 + final translationsWithNoCountry = Get.translations
  70 + .map((key, value) => MapEntry(key.split("_").first, value));
  71 + final containsKey =
  72 + translationsWithNoCountry.containsKey(Get.locale!.languageCode);
  73 +
  74 + if (!containsKey) {
  75 + return null;
  76 + }
  77 +
  78 + return translationsWithNoCountry[Get.locale!.languageCode];
  79 + }
  80 +
  81 + String get tr {
  82 + // print('language');
  83 + // print(Get.locale!.languageCode);
  84 + // print('contains');
  85 + // print(Get.translations.containsKey(Get.locale!.languageCode));
  86 + // print(Get.translations.keys);
  87 + // Returns the key if locale is null.
  88 + if (Get.locale?.languageCode == null) return this;
  89 +
  90 + if (_fullLocaleAndKey) {
  91 + return Get.translations[
  92 + "${Get.locale!.languageCode}_${Get.locale!.countryCode}"]![this]!;
  93 + }
  94 + final similarTranslation = _getSimilarLanguageTranslation;
  95 + if (similarTranslation != null && similarTranslation.containsKey(this)) {
  96 + return similarTranslation[this]!;
24 // If there is no corresponding language or corresponding key, return 97 // If there is no corresponding language or corresponding key, return
25 // the key. 98 // the key.
26 } else if (Get.fallbackLocale != null) { 99 } else if (Get.fallbackLocale != null) {
@@ -70,43 +143,3 @@ extension Trans on String { @@ -70,43 +143,3 @@ extension Trans on String {
70 return i == 1 ? trParams(params) : pluralKey!.trParams(params); 143 return i == 1 ? trParams(params) : pluralKey!.trParams(params);
71 } 144 }
72 } 145 }
73 -  
74 -class _IntlHost {  
75 - Locale? locale;  
76 -  
77 - Locale? fallbackLocale;  
78 -  
79 - Map<String, Map<String, String>> translations = {};  
80 -}  
81 -  
82 -extension LocalesIntl on GetInterface {  
83 - static final _intlHost = _IntlHost();  
84 -  
85 - Locale? get locale => _intlHost.locale;  
86 -  
87 - Locale? get fallbackLocale => _intlHost.fallbackLocale;  
88 -  
89 - set locale(Locale? newLocale) => _intlHost.locale = newLocale;  
90 -  
91 - set fallbackLocale(Locale? newLocale) => _intlHost.fallbackLocale = newLocale;  
92 -  
93 - Map<String, Map<String, String>> get translations => _intlHost.translations;  
94 -  
95 - void addTranslations(Map<String, Map<String, String>> tr) {  
96 - translations.addAll(tr);  
97 - }  
98 -  
99 - void clearTranslations() {  
100 - translations.clear();  
101 - }  
102 -  
103 - void appendTranslations(Map<String, Map<String, String>> tr) {  
104 - tr.forEach((key, map) {  
105 - if (translations.containsKey(key)) {  
106 - translations[key]!.addAll(map);  
107 - } else {  
108 - translations[key] = map;  
109 - }  
110 - });  
111 - }  
112 -}  
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_test/flutter_test.dart';
  3 +import 'package:get/get.dart';
  4 +
  5 +import '../navigation/utils/wrapper.dart';
  6 +
  7 +void main() {
  8 + testWidgets("Get.defaultDialog smoke test", (tester) async {
  9 + await tester.pumpWidget(
  10 + Wrapper(child: Container()),
  11 + );
  12 +
  13 + await tester.pumpAndSettle();
  14 +
  15 + expect('covid'.tr, 'Corona Virus');
  16 + expect('total_confirmed'.tr, 'Total Confirmed');
  17 + expect('total_deaths'.tr, 'Total Deaths');
  18 +
  19 + Get.updateLocale(Locale('pt', 'BR'));
  20 +
  21 + await tester.pumpAndSettle();
  22 +
  23 + expect('covid'.tr, 'Corona Vírus');
  24 + expect('total_confirmed'.tr, 'Total confirmado');
  25 + expect('total_deaths'.tr, 'Total de mortes');
  26 +
  27 + Get.updateLocale(Locale('en', 'EN'));
  28 +
  29 + await tester.pumpAndSettle();
  30 +
  31 + expect('covid'.tr, 'Corona Virus');
  32 + expect('total_confirmed'.tr, 'Total Confirmed');
  33 + expect('total_deaths'.tr, 'Total Deaths');
  34 + });
  35 +}
@@ -20,6 +20,8 @@ class Wrapper extends StatelessWidget { @@ -20,6 +20,8 @@ class Wrapper extends StatelessWidget {
20 return GetMaterialApp( 20 return GetMaterialApp(
21 defaultTransition: defaultTransition, 21 defaultTransition: defaultTransition,
22 initialRoute: initialRoute, 22 initialRoute: initialRoute,
  23 + translations: WrapperTranslations(),
  24 + locale: WrapperTranslations.locale,
23 getPages: namedRoutes, 25 getPages: namedRoutes,
24 home: Scaffold( 26 home: Scaffold(
25 body: child, 27 body: child,
@@ -51,3 +53,21 @@ class WrapperNamed extends StatelessWidget { @@ -51,3 +53,21 @@ class WrapperNamed extends StatelessWidget {
51 ); 53 );
52 } 54 }
53 } 55 }
  56 +
  57 +class WrapperTranslations extends Translations {
  58 + static final fallbackLocale = Locale('en', 'US');
  59 + static Locale? get locale => Locale('en', 'US');
  60 + @override
  61 + Map<String, Map<String, String>> get keys => {
  62 + 'en_US': {
  63 + 'covid': 'Corona Virus',
  64 + 'total_confirmed': 'Total Confirmed',
  65 + 'total_deaths': 'Total Deaths',
  66 + },
  67 + 'pt_BR': {
  68 + 'covid': 'Corona Vírus',
  69 + 'total_confirmed': 'Total confirmado',
  70 + 'total_deaths': 'Total de mortes',
  71 + },
  72 + };
  73 +}
  1 +import 'package:flutter/material.dart';
1 import 'package:flutter_test/flutter_test.dart'; 2 import 'package:flutter_test/flutter_test.dart';
  3 +import 'package:get/get.dart';
  4 +
  5 +import '../../navigation/utils/wrapper.dart';
2 6
3 void main() { 7 void main() {
4 - test('', () {}); 8 + testWidgets("Get.defaultDialog smoke test", (tester) async {
  9 + await tester.pumpWidget(Wrapper(child: Container()));
  10 + final BuildContext context = tester.element(find.byType(Container));
  11 +
  12 + var mediaQuery = MediaQuery.of(context);
  13 + expect(mediaQuery, context.mediaQuery);
  14 + var mediaQuerySize = mediaQuery.size;
  15 + expect(mediaQuerySize, context.mediaQuerySize);
  16 + var theme = Theme.of(context);
  17 + expect(theme, context.theme);
  18 + var textTheme = theme.textTheme;
  19 + expect(textTheme, context.textTheme);
  20 + var devicePixelRatio = mediaQuery.devicePixelRatio;
  21 + expect(devicePixelRatio, context.devicePixelRatio);
  22 + var height = mediaQuerySize.height;
  23 + expect(height, context.height);
  24 + final heightTransformer =
  25 + (mediaQuerySize.height - ((mediaQuerySize.height / 100) * 0)) / 1;
  26 + expect(heightTransformer, context.heightTransformer());
  27 + var iconColor = theme.iconTheme.color;
  28 + expect(iconColor, context.iconColor);
  29 + var isDarkMode = (theme.brightness == Brightness.dark);
  30 + expect(isDarkMode, context.isDarkMode);
  31 + var orientation = mediaQuery.orientation;
  32 + expect(orientation, context.orientation);
  33 + var isLandscape = orientation == Orientation.landscape;
  34 + expect(isLandscape, context.isLandscape);
  35 + var mediaQueryShortestSide = mediaQuerySize.shortestSide;
  36 + expect(mediaQueryShortestSide, context.mediaQueryShortestSide);
  37 + var isLargeTablet = (mediaQueryShortestSide >= 720);
  38 + expect(isLargeTablet, context.isLargeTablet);
  39 + var isPhone = (mediaQueryShortestSide < 600);
  40 + expect(isPhone, context.isPhone);
  41 + var isPortrait = orientation == Orientation.portrait;
  42 + expect(isPortrait, context.isPortrait);
  43 + var isSmallTablet = (mediaQueryShortestSide >= 600);
  44 + expect(isSmallTablet, context.isSmallTablet);
  45 + var isTablet = isSmallTablet || isLargeTablet;
  46 + expect(isTablet, context.isTablet);
  47 + var mediaQueryPadding = mediaQuery.padding;
  48 + expect(mediaQueryPadding, context.mediaQueryPadding);
  49 + var mediaQueryViewInsets = mediaQuery.viewInsets;
  50 + expect(mediaQueryViewInsets, context.mediaQueryViewInsets);
  51 + var mediaQueryViewPadding = mediaQuery.viewPadding;
  52 + expect(mediaQueryViewPadding, context.mediaQueryViewPadding);
  53 + var widthTransformer =
  54 + (mediaQuerySize.width - ((mediaQuerySize.width / 100) * 0)) / 1;
  55 + expect(widthTransformer, context.widthTransformer());
  56 + var ratio = heightTransformer / widthTransformer;
  57 + expect(ratio, context.ratio());
  58 + var width = mediaQuerySize.width;
  59 + expect(width, context.width);
  60 + var showNavbar = (width > 800);
  61 + expect(showNavbar, context.showNavbar);
  62 + var textScaleFactor = mediaQuery.textScaleFactor;
  63 + expect(textScaleFactor, context.textScaleFactor);
  64 + });
5 } 65 }