feat(i18n): add English + Chinese localization
All checks were successful
CI / Windows build (push) Successful in 12m34s
All checks were successful
CI / Windows build (push) Successful in 12m34s
The app had zero localization ("软件多语言做了吗" — no). Add Flutter's
official gen-l10n pipeline and localize the core flow the user sees.
- pubspec: flutter_localizations + intl + generate: true
- l10n.yaml + lib/l10n/app_en.arb + app_zh.arb (37 strings)
- main.dart: localizationsDelegates + supportedLocales (follows OS locale)
- pen editor: all tool tooltips, page pill, error states localized
- home: app bar actions + empty-state buttons localized
Proven end-to-end: l10n_test pumps the same widget under Locale('en')
and Locale('zh') and asserts English vs Chinese strings resolve.
flutter analyze: 0 issues. l10n_test: 3/3 pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
55
test/l10n_test.dart
Normal file
55
test/l10n_test.dart
Normal file
@@ -0,0 +1,55 @@
|
||||
// Proves i18n is real, not just wired: the SAME widget resolves English under
|
||||
// Locale('en') and Chinese under Locale('zh'), through the generated
|
||||
// AppLocalizations delegates. Guards against ARB keys drifting out of sync.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:badnote/l10n/app_localizations.dart';
|
||||
|
||||
class _Probe extends StatelessWidget {
|
||||
const _Probe();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l = AppLocalizations.of(context);
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Column(children: [
|
||||
Text(l.settings),
|
||||
Text(l.toolEraser),
|
||||
Text(l.importPdf),
|
||||
]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _pump(WidgetTester tester, Locale locale) {
|
||||
return tester.pumpWidget(MaterialApp(
|
||||
locale: locale,
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: const _Probe(),
|
||||
));
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('English locale resolves English strings', (tester) async {
|
||||
await _pump(tester, const Locale('en'));
|
||||
expect(find.text('Settings'), findsOneWidget);
|
||||
expect(find.text('Eraser'), findsOneWidget);
|
||||
expect(find.text('Import PDF'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Chinese locale resolves Chinese strings', (tester) async {
|
||||
await _pump(tester, const Locale('zh'));
|
||||
expect(find.text('设置'), findsOneWidget);
|
||||
expect(find.text('橡皮擦'), findsOneWidget);
|
||||
expect(find.text('导入 PDF'), findsOneWidget);
|
||||
});
|
||||
|
||||
test('both locales are supported', () {
|
||||
final langs =
|
||||
AppLocalizations.supportedLocales.map((l) => l.languageCode).toSet();
|
||||
expect(langs.containsAll({'en', 'zh'}), isTrue);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user