@@ -1733,6 +1733,47 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
17331733 ).readAsStringSync ();
17341734 expect (localizationsFile, contains ('String helloWorld(Object name) {' ));
17351735 });
1736+
1737+ testWithoutContext ('placeholder parameter list should be consistent between languages' , () {
1738+ const String messageEn = '''
1739+ {
1740+ "helloWorld": "Hello {name}",
1741+ "@helloWorld": {
1742+ "placeholders": {
1743+ "name": {}
1744+ }
1745+ }
1746+ }''' ;
1747+ const String messageEs = '''
1748+ {
1749+ "helloWorld": "Hola"
1750+ }
1751+ ''' ;
1752+ final Directory l10nDirectory = fs.currentDirectory.childDirectory ('lib' ).childDirectory ('l10n' )
1753+ ..createSync (recursive: true );
1754+ l10nDirectory.childFile (defaultTemplateArbFileName)
1755+ .writeAsStringSync (messageEn);
1756+ l10nDirectory.childFile ('app_es.arb' )
1757+ .writeAsStringSync (messageEs);
1758+ LocalizationsGenerator (
1759+ fileSystem: fs,
1760+ inputPathString: defaultL10nPathString,
1761+ templateArbFileName: defaultTemplateArbFileName,
1762+ outputFileString: defaultOutputFileString,
1763+ classNameString: defaultClassNameString,
1764+ logger: logger,
1765+ )
1766+ ..loadResources ()
1767+ ..writeOutputFiles ();
1768+ final String localizationsFileEn = fs.file (
1769+ fs.path.join (syntheticL10nPackagePath, 'output-localization-file_en.dart' ),
1770+ ).readAsStringSync ();
1771+ final String localizationsFileEs = fs.file (
1772+ fs.path.join (syntheticL10nPackagePath, 'output-localization-file_es.dart' ),
1773+ ).readAsStringSync ();
1774+ expect (localizationsFileEn, contains ('String helloWorld(Object name) {' ));
1775+ expect (localizationsFileEs, contains ('String helloWorld(Object name) {' ));
1776+ });
17361777 });
17371778
17381779 group ('DateTime tests' , () {
@@ -2258,6 +2299,93 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
22582299 });
22592300 });
22602301
2302+ // All error handling for messages should collect errors on a per-error
2303+ // basis and log them out individually. Then, it will throw an L10nException.
2304+ group ('error handling tests' , () {
2305+ testWithoutContext ('syntax/code-gen errors properly logs errors per message' , () {
2306+ // TODO(thkim1011): Fix error handling so that long indents don't get truncated.
2307+ // See https://github.com/flutter/flutter/issues/120490.
2308+ const String messagesWithSyntaxErrors = '''
2309+ {
2310+ "hello": "Hello { name",
2311+ "plural": "This is an incorrectly formatted plural: { count, plural, zero{No frog} one{One frog} other{{count} frogs}",
2312+ "explanationWithLexingError": "The 'string above is incorrect as it forgets to close the brace",
2313+ "pluralWithInvalidCase": "{ count, plural, woohoo{huh?} other{lol} }"
2314+ }''' ;
2315+ try {
2316+ final Directory l10nDirectory = fs.currentDirectory.childDirectory ('lib' ).childDirectory ('l10n' )
2317+ ..createSync (recursive: true );
2318+ l10nDirectory.childFile (defaultTemplateArbFileName)
2319+ .writeAsStringSync (messagesWithSyntaxErrors);
2320+ LocalizationsGenerator (
2321+ fileSystem: fs,
2322+ inputPathString: defaultL10nPathString,
2323+ outputPathString: defaultL10nPathString,
2324+ templateArbFileName: defaultTemplateArbFileName,
2325+ outputFileString: defaultOutputFileString,
2326+ classNameString: defaultClassNameString,
2327+ useEscaping: true ,
2328+ logger: logger,
2329+ )
2330+ ..loadResources ()
2331+ ..writeOutputFiles ();
2332+ } on L10nException {
2333+ expect (logger.errorText, contains ('''
2334+ [app_en.arb:hello] ICU Syntax Error: Expected "}" but found no tokens.
2335+ Hello { name
2336+ ^
2337+ [app_en.arb:plural] ICU Syntax Error: Expected "}" but found no tokens.
2338+ This is an incorrectly formatted plural: { count, plural, zero{No frog} one{One frog} other{{count} frogs}
2339+ ^
2340+ [app_en.arb:explanationWithLexingError] ICU Lexing Error: Unmatched single quotes.
2341+ The 'string above is incorrect as it forgets to close the brace
2342+ ^
2343+ [app_en.arb:pluralWithInvalidCase] ICU Syntax Error: Plural expressions case must be one of "zero", "one", "two", "few", "many", or "other".
2344+ { count, plural, woohoo{huh?} other{lol} }
2345+ ^''' ));
2346+ }
2347+ });
2348+
2349+ testWithoutContext ('errors thrown in multiple languages are all shown' , () {
2350+ const String messageEn = '''
2351+ {
2352+ "hello": "Hello { name"
2353+ }''' ;
2354+ const String messageEs = '''
2355+ {
2356+ "hello": "Hola { name"
2357+ }''' ;
2358+ try {
2359+ final Directory l10nDirectory = fs.currentDirectory.childDirectory ('lib' ).childDirectory ('l10n' )
2360+ ..createSync (recursive: true );
2361+ l10nDirectory.childFile (defaultTemplateArbFileName)
2362+ .writeAsStringSync (messageEn);
2363+ l10nDirectory.childFile ('app_es.arb' )
2364+ .writeAsStringSync (messageEs);
2365+ LocalizationsGenerator (
2366+ fileSystem: fs,
2367+ inputPathString: defaultL10nPathString,
2368+ outputPathString: defaultL10nPathString,
2369+ templateArbFileName: defaultTemplateArbFileName,
2370+ outputFileString: defaultOutputFileString,
2371+ classNameString: defaultClassNameString,
2372+ useEscaping: true ,
2373+ logger: logger,
2374+ )
2375+ ..loadResources ()
2376+ ..writeOutputFiles ();
2377+ } on L10nException {
2378+ expect (logger.errorText, contains ('''
2379+ [app_en.arb:hello] ICU Syntax Error: Expected "}" but found no tokens.
2380+ Hello { name
2381+ ^
2382+ [app_es.arb:hello] ICU Syntax Error: Expected "}" but found no tokens.
2383+ Hola { name
2384+ ^''' ));
2385+ }
2386+ });
2387+ });
2388+
22612389 testWithoutContext ('intl package import should be omitted in subclass files when no plurals are included' , () {
22622390 fs.currentDirectory.childDirectory ('lib' ).childDirectory ('l10n' )..createSync (recursive: true )
22632391 ..childFile (defaultTemplateArbFileName).writeAsStringSync (singleMessageArbFileString)
0 commit comments