@@ -1663,6 +1663,47 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
16631663 ).readAsStringSync ();
16641664 expect (localizationsFile, contains ('String helloWorld(Object name) {' ));
16651665 });
1666+
1667+ testWithoutContext ('placeholder parameter list should be consistent between languages' , () {
1668+ const String messageEn = '''
1669+ {
1670+ "helloWorld": "Hello {name}",
1671+ "@helloWorld": {
1672+ "placeholders": {
1673+ "name": {}
1674+ }
1675+ }
1676+ }''' ;
1677+ const String messageEs = '''
1678+ {
1679+ "helloWorld": "Hola"
1680+ }
1681+ ''' ;
1682+ final Directory l10nDirectory = fs.currentDirectory.childDirectory ('lib' ).childDirectory ('l10n' )
1683+ ..createSync (recursive: true );
1684+ l10nDirectory.childFile (defaultTemplateArbFileName)
1685+ .writeAsStringSync (messageEn);
1686+ l10nDirectory.childFile ('app_es.arb' )
1687+ .writeAsStringSync (messageEs);
1688+ LocalizationsGenerator (
1689+ fileSystem: fs,
1690+ inputPathString: defaultL10nPathString,
1691+ templateArbFileName: defaultTemplateArbFileName,
1692+ outputFileString: defaultOutputFileString,
1693+ classNameString: defaultClassNameString,
1694+ logger: logger,
1695+ )
1696+ ..loadResources ()
1697+ ..writeOutputFiles ();
1698+ final String localizationsFileEn = fs.file (
1699+ fs.path.join (syntheticL10nPackagePath, 'output-localization-file_en.dart' ),
1700+ ).readAsStringSync ();
1701+ final String localizationsFileEs = fs.file (
1702+ fs.path.join (syntheticL10nPackagePath, 'output-localization-file_es.dart' ),
1703+ ).readAsStringSync ();
1704+ expect (localizationsFileEn, contains ('String helloWorld(Object name) {' ));
1705+ expect (localizationsFileEs, contains ('String helloWorld(Object name) {' ));
1706+ });
16661707 });
16671708
16681709 group ('DateTime tests' , () {
@@ -2189,6 +2230,93 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
21892230 });
21902231 });
21912232
2233+ // All error handling for messages should collect errors on a per-error
2234+ // basis and log them out individually. Then, it will throw an L10nException.
2235+ group ('error handling tests' , () {
2236+ testWithoutContext ('syntax/code-gen errors properly logs errors per message' , () {
2237+ // TODO(thkim1011): Fix error handling so that long indents don't get truncated.
2238+ // See https://github.com/flutter/flutter/issues/120490.
2239+ const String messagesWithSyntaxErrors = '''
2240+ {
2241+ "hello": "Hello { name",
2242+ "plural": "This is an incorrectly formatted plural: { count, plural, zero{No frog} one{One frog} other{{count} frogs}",
2243+ "explanationWithLexingError": "The 'string above is incorrect as it forgets to close the brace",
2244+ "pluralWithInvalidCase": "{ count, plural, woohoo{huh?} other{lol} }"
2245+ }''' ;
2246+ try {
2247+ final Directory l10nDirectory = fs.currentDirectory.childDirectory ('lib' ).childDirectory ('l10n' )
2248+ ..createSync (recursive: true );
2249+ l10nDirectory.childFile (defaultTemplateArbFileName)
2250+ .writeAsStringSync (messagesWithSyntaxErrors);
2251+ LocalizationsGenerator (
2252+ fileSystem: fs,
2253+ inputPathString: defaultL10nPathString,
2254+ outputPathString: defaultL10nPathString,
2255+ templateArbFileName: defaultTemplateArbFileName,
2256+ outputFileString: defaultOutputFileString,
2257+ classNameString: defaultClassNameString,
2258+ useEscaping: true ,
2259+ logger: logger,
2260+ )
2261+ ..loadResources ()
2262+ ..writeOutputFiles ();
2263+ } on L10nException {
2264+ expect (logger.errorText, contains ('''
2265+ [app_en.arb:hello] ICU Syntax Error: Expected "}" but found no tokens.
2266+ Hello { name
2267+ ^
2268+ [app_en.arb:plural] ICU Syntax Error: Expected "}" but found no tokens.
2269+ This is an incorrectly formatted plural: { count, plural, zero{No frog} one{One frog} other{{count} frogs}
2270+ ^
2271+ [app_en.arb:explanationWithLexingError] ICU Lexing Error: Unmatched single quotes.
2272+ The 'string above is incorrect as it forgets to close the brace
2273+ ^
2274+ [app_en.arb:pluralWithInvalidCase] ICU Syntax Error: Plural expressions case must be one of "zero", "one", "two", "few", "many", or "other".
2275+ { count, plural, woohoo{huh?} other{lol} }
2276+ ^''' ));
2277+ }
2278+ });
2279+
2280+ testWithoutContext ('errors thrown in multiple languages are all shown' , () {
2281+ const String messageEn = '''
2282+ {
2283+ "hello": "Hello { name"
2284+ }''' ;
2285+ const String messageEs = '''
2286+ {
2287+ "hello": "Hola { name"
2288+ }''' ;
2289+ try {
2290+ final Directory l10nDirectory = fs.currentDirectory.childDirectory ('lib' ).childDirectory ('l10n' )
2291+ ..createSync (recursive: true );
2292+ l10nDirectory.childFile (defaultTemplateArbFileName)
2293+ .writeAsStringSync (messageEn);
2294+ l10nDirectory.childFile ('app_es.arb' )
2295+ .writeAsStringSync (messageEs);
2296+ LocalizationsGenerator (
2297+ fileSystem: fs,
2298+ inputPathString: defaultL10nPathString,
2299+ outputPathString: defaultL10nPathString,
2300+ templateArbFileName: defaultTemplateArbFileName,
2301+ outputFileString: defaultOutputFileString,
2302+ classNameString: defaultClassNameString,
2303+ useEscaping: true ,
2304+ logger: logger,
2305+ )
2306+ ..loadResources ()
2307+ ..writeOutputFiles ();
2308+ } on L10nException {
2309+ expect (logger.errorText, contains ('''
2310+ [app_en.arb:hello] ICU Syntax Error: Expected "}" but found no tokens.
2311+ Hello { name
2312+ ^
2313+ [app_es.arb:hello] ICU Syntax Error: Expected "}" but found no tokens.
2314+ Hola { name
2315+ ^''' ));
2316+ }
2317+ });
2318+ });
2319+
21922320 testWithoutContext ('intl package import should be omitted in subclass files when no plurals are included' , () {
21932321 fs.currentDirectory.childDirectory ('lib' ).childDirectory ('l10n' )..createSync (recursive: true )
21942322 ..childFile (defaultTemplateArbFileName).writeAsStringSync (singleMessageArbFileString)
0 commit comments