Skip to content

Commit

Permalink
Merge branch 'develop' into no-key-callback
Browse files Browse the repository at this point in the history
  • Loading branch information
stha-ums authored May 8, 2022
2 parents cb74307 + a90988f commit 8d9cb91
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
run: flutter test --coverage

- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v1.0.1
uses: coverallsapp/github-action@1.1.3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

Expand Down
66 changes: 52 additions & 14 deletions lib/src/easy_localization_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,29 @@ class EasyLocalizationController extends ChangeNotifier {
_locale = _savedLocale!;
} else {
// From Device Locale
_locale = supportedLocales.firstWhere(
(locale) => _checkInitLocale(locale, _deviceLocale),
orElse: () => _getFallbackLocale(supportedLocales, fallbackLocale));
_locale = selectLocaleFrom(
supportedLocales,
_deviceLocale,
fallbackLocale: fallbackLocale,
);
}
}

@visibleForTesting
static Locale selectLocaleFrom(
List<Locale> supportedLocales,
Locale deviceLocale, {
Locale? fallbackLocale,
}) {
final selectedLocale = supportedLocales.firstWhere(
(locale) => locale.supports(deviceLocale),
orElse: () => _getFallbackLocale(supportedLocales, fallbackLocale),
);
return selectedLocale;
}

//Get fallback Locale
Locale _getFallbackLocale(
static Locale _getFallbackLocale(
List<Locale> supportedLocales, Locale? fallbackLocale) {
//If fallbackLocale not set then return first from supportedLocales
if (fallbackLocale != null) {
Expand All @@ -65,15 +80,6 @@ class EasyLocalizationController extends ChangeNotifier {
}
}

bool _checkInitLocale(Locale locale, Locale? _deviceLocale) {
// If supported locale not contain countryCode then check only languageCode
if (locale.countryCode == null) {
return (locale.languageCode == _deviceLocale!.languageCode);
} else {
return (locale == _deviceLocale);
}
}

Future loadTranslations() async {
Map<String, dynamic> data;
try {
Expand All @@ -82,7 +88,7 @@ class EasyLocalizationController extends ChangeNotifier {
if (useFallbackTranslations && _fallbackLocale != null) {
Map<String, dynamic>? baseLangData;
if (_locale.countryCode != null && _locale.countryCode!.isNotEmpty) {
baseLangData = await loadTranslationData(Locale(locale.languageCode));
baseLangData = await loadBaseLangTranslationData(Locale(locale.languageCode));
}
data = await loadTranslationData(_fallbackLocale!);
if (baseLangData != null) {
Expand All @@ -97,6 +103,16 @@ class EasyLocalizationController extends ChangeNotifier {
}
}

Future<Map<String, dynamic>?> loadBaseLangTranslationData(Locale locale) async {
try {
return await loadTranslationData(Locale(locale.languageCode));
} on FlutterError catch (e) {
// Disregard asset not found FlutterError when attempting to load base language fallback
EasyLocalization.logger.warning(e.message);
}
return null;
}

Future loadTranslationData(Locale locale) async {
if (useOnlyLangCode) {
return assetLoader.load(path, Locale(locale.languageCode));
Expand Down Expand Up @@ -146,3 +162,25 @@ class EasyLocalizationController extends ChangeNotifier {
await setLocale(_deviceLocale);
}
}

@visibleForTesting
extension LocaleExtension on Locale {
bool supports(Locale locale) {
if (this == locale) {
return true;
}
if (languageCode != locale.languageCode) {
return false;
}
if (countryCode != null &&
countryCode!.isNotEmpty &&
countryCode != locale.countryCode) {
return false;
}
if (scriptCode != null && scriptCode != locale.scriptCode) {
return false;
}

return true;
}
}
10 changes: 6 additions & 4 deletions lib/src/localization.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,22 +176,24 @@ class Localization {
}

String _resolvePlural(String key, String subKey) {
if (subKey == 'other') return _resolve('$key.other');

final tag = '$key.$subKey';
var resource = _resolve(tag);
if (resource == tag && subKey != 'other') {
var resource = _resolve(tag, logging: false, fallback: false);
if (resource == tag) {
resource = _resolve('$key.other');
}
return resource;
}

String _resolve(String key, {bool logging = true}) {
String _resolve(String key, {bool logging = true, bool fallback = true}) {
var resource = _translations?.get(key);
if (resource == null) {
if (_onLocaleKeyNotFound != null) _onLocaleKeyNotFound!(key, _locale);
if (logging) {
EasyLocalization.logger.warning('Localization key [$key] not found');
}
if (_fallbackTranslations == null) {
if (_fallbackTranslations == null || !fallback) {
return key;
} else {
resource = _fallbackTranslations?.get(key);
Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ issue_tracker: https://github.com/aissat/easy_localization/issues
version: 3.0.1

environment:
sdk: '>=2.12.0 < 3.0.0'
sdk: '>=2.12.0 <3.0.0'

dependencies:
flutter:
sdk: flutter
shared_preferences: '>=2.0.0 < 3.0.0'
shared_preferences: '>=2.0.0 <3.0.0'
intl: '>=0.17.0-0 <=0.17.0'
args: ^2.0.0
path: '>=1.8.0-0 <=2.0.0'
Expand Down
86 changes: 80 additions & 6 deletions test/easy_localization_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'utils/test_asset_loaders.dart';

var printLog = [];

dynamic overridePrint(Function() testFn) => () {
var spec = ZoneSpecification(print: (_, __, ___, String msg) {
// Add to log instead of printing to stdout
Expand Down Expand Up @@ -112,6 +113,56 @@ void main() {
expect(Localization.instance.tr('path'), 'path/en-us.json');
});

group('locale', () {
test('locale supports device locale', () {
const en = Locale('en');
const en2 = Locale('en', '');
const enUS = Locale('en', 'US');
const enGB = Locale('en', 'GB');
expect(en.supports(enUS), isTrue);
expect(en2.supports(enUS), isTrue);
expect(enUS.supports(enUS), isTrue);
expect(enGB.supports(enUS), isFalse);

const zh = Locale('zh', '');
const zh2 = Locale('zh', '');
const zhCN = Locale('zh', 'CN');
const zhHans =
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans');
const zhHant =
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant');
const zhHansCN = Locale.fromSubtags(
languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN');
expect(zh.supports(zhHansCN), isTrue);
expect(zh2.supports(zhHansCN), isTrue);
expect(zhCN.supports(zhHansCN), isTrue);
expect(zhHans.supports(zhHansCN), isTrue);
expect(zhHant.supports(zhHansCN), isFalse);
expect(zhHansCN.supports(zhHansCN), isTrue);
});

test('select locale from device locale', () {
const en = Locale('en', '');
const zh = Locale('zh', '');
const zhHans =
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans');
const zhHant =
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant');
const zhHansCN = Locale.fromSubtags(
languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN');

expect(
EasyLocalizationController.selectLocaleFrom([en, zh], zhHansCN),
zh,
);
expect(
EasyLocalizationController.selectLocaleFrom(
[zhHant, zhHans], zhHansCN),
zhHans,
);
});
});

group('tr', () {
var r = EasyLocalizationController(
forceLocale: Locale('en'),
Expand Down Expand Up @@ -297,12 +348,25 @@ void main() {
});

group('plural', () {
// setUpAll(() async {
// await Localization.load(Locale('en-US'),
// path: 'path',
// useOnlyLangCode: true,
// assetLoader: JsonAssetLoader());
// });
var r = EasyLocalizationController(
forceLocale: Locale('en'),
supportedLocales: [Locale('en'), Locale('fb')],
fallbackLocale: Locale('fb'),
path: 'path',
useOnlyLangCode: true,
useFallbackTranslations: true,
onLoadError: (FlutterError e) {
log(e.toString());
},
saveLocale: false,
assetLoader: JsonAssetLoader());

setUpAll(() async {
await r.loadTranslations();
Localization.load(Locale('en'),
translations: r.translations,
fallbackTranslations: r.fallbackTranslations);
});

test('zero', () {
expect(Localization.instance.plural('hat', 0), 'no hats');
Expand Down Expand Up @@ -331,6 +395,16 @@ void main() {
expect(Localization.instance.plural('hat_other', 1), 'other hats');
});

test('other as fallback and fallback translations priority',
overridePrint(() {
printLog = [];
expect(
Localization.instance.plural('test_fallback_plurals', 2),
'2 seconds', // isNot('fallback two'),
);
expect(printLog, isEmpty);
}));

test('with number format', () {
expect(
Localization.instance
Expand Down
13 changes: 13 additions & 0 deletions test/utils/test_asset_loaders.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ class JsonAssetLoader extends AssetLoader {
'path': '$fullPath',
'test_missing_fallback':
(locale.languageCode == 'fb' ? 'fallback!' : null),
'test_fallback_plurals': (locale.languageCode == 'fb'
? {
'zero': 'fallback zero',
'one': 'fallback one',
'two': 'fallback two',
'few': 'fallback few',
'many': 'fallback many',
'other': 'fallback other',
}
: {
'one': '{} second',
'other': '{} seconds',
}),
});
}
}

0 comments on commit 8d9cb91

Please sign in to comment.