[gen_l10n] Support plurals and selects inside string (#86167)
This commit is contained in:
parent
b6419e8e89
commit
f568d929db
@ -229,15 +229,102 @@ String _generatePluralMethod(Message message, String translationForMessage) {
|
||||
|
||||
final String comment = message.description ?? 'No description provided in @${message.resourceId}';
|
||||
|
||||
if (translationForMessage.startsWith('{') && translationForMessage.endsWith('}')) {
|
||||
return pluralMethodTemplate
|
||||
.replaceAll('@(comment)', comment)
|
||||
.replaceAll('@(name)', message.resourceId)
|
||||
.replaceAll('@(parameters)', parameters.join(', '))
|
||||
.replaceAll('@(dateFormatting)', generateDateFormattingLogic(message))
|
||||
.replaceAll('@(numberFormatting)', generateNumberFormattingLogic(message))
|
||||
.replaceAll('@(parameters)', parameters.join(', '))
|
||||
.replaceAll('@(count)', countPlaceholder.name)
|
||||
.replaceAll('@(pluralLogicArgs)', pluralLogicArgs.join(',\n'))
|
||||
.replaceAll('@(none)\n', '');
|
||||
}
|
||||
|
||||
const String variable = 'pluralString';
|
||||
final String string = _replaceWithVariable(translationForMessage, variable);
|
||||
return pluralMethodTemplateInString
|
||||
.replaceAll('@(comment)', comment)
|
||||
.replaceAll('@(name)', message.resourceId)
|
||||
.replaceAll('@(dateFormatting)', generateDateFormattingLogic(message))
|
||||
.replaceAll('@(numberFormatting)', generateNumberFormattingLogic(message))
|
||||
.replaceAll('@(parameters)', parameters.join(', '))
|
||||
.replaceAll('@(variable)', variable)
|
||||
.replaceAll('@(count)', countPlaceholder.name)
|
||||
.replaceAll('@(pluralLogicArgs)', pluralLogicArgs.join(',\n'))
|
||||
.replaceAll('@(none)\n', '')
|
||||
.replaceAll('@(string)', string);
|
||||
}
|
||||
|
||||
String _replaceWithVariable(String translation, String variable) {
|
||||
String prefix = generateString(translation.substring(0, translation.indexOf('{')));
|
||||
prefix = prefix.substring(0, prefix.length - 1);
|
||||
String suffix = generateString(translation.substring(translation.lastIndexOf('}') + 1));
|
||||
suffix = suffix.substring(1);
|
||||
|
||||
// escape variable when the suffix can be combined with the variable
|
||||
if (suffix.isNotEmpty && !suffix.startsWith(' ')) {
|
||||
variable = '{$variable}';
|
||||
}
|
||||
return prefix + r'$' + variable + suffix;
|
||||
}
|
||||
|
||||
String _generateSelectMethod(Message message, String translationForMessage) {
|
||||
if (message.placeholders.isEmpty) {
|
||||
throw L10nException(
|
||||
'Unable to find placeholders for the select message: ${message.resourceId}.\n'
|
||||
'Check to see if the select message is in the proper ICU syntax format '
|
||||
'and ensure that placeholders are properly specified.'
|
||||
);
|
||||
}
|
||||
|
||||
final List<String> cases = <String>[];
|
||||
|
||||
final RegExpMatch? selectMatch =
|
||||
LocalizationsGenerator._selectRE.firstMatch(translationForMessage);
|
||||
String? choice;
|
||||
if (selectMatch != null && selectMatch.groupCount == 2) {
|
||||
choice = selectMatch.group(1);
|
||||
final String pattern = selectMatch.group(2)!;
|
||||
final RegExp patternRE = RegExp(r'\s*([\w\d]+)\s*\{(.*?)\}');
|
||||
for (final RegExpMatch patternMatch in patternRE.allMatches(pattern)) {
|
||||
if (patternMatch.groupCount == 2) {
|
||||
final String value = patternMatch.group(2)!
|
||||
.replaceAll("'", r"\'")
|
||||
.replaceAll('"', r'\"');
|
||||
cases.add(
|
||||
" '${patternMatch.group(1)}': '$value'",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final List<String> parameters = message.placeholders.map((Placeholder placeholder) {
|
||||
final String placeholderType = placeholder.type ?? 'object';
|
||||
return '$placeholderType ${placeholder.name}';
|
||||
}).toList();
|
||||
|
||||
final String description = message.description ?? 'No description provided in @${message.resourceId}';
|
||||
|
||||
if (translationForMessage.startsWith('{') && translationForMessage.endsWith('}')) {
|
||||
return selectMethodTemplate
|
||||
.replaceAll('@(name)', message.resourceId)
|
||||
.replaceAll('@(parameters)', parameters.join(', '))
|
||||
.replaceAll('@(choice)', choice!)
|
||||
.replaceAll('@(cases)', cases.join(',\n').trim())
|
||||
.replaceAll('@(description)', description);
|
||||
}
|
||||
|
||||
const String variable = 'selectString';
|
||||
final String string = _replaceWithVariable(translationForMessage, variable);
|
||||
return selectMethodTemplateInString
|
||||
.replaceAll('@(name)', message.resourceId)
|
||||
.replaceAll('@(parameters)', parameters.join(', '))
|
||||
.replaceAll('@(variable)', variable)
|
||||
.replaceAll('@(choice)', choice!)
|
||||
.replaceAll('@(cases)', cases.join(',\n').trim())
|
||||
.replaceAll('@(description)', description)
|
||||
.replaceAll('@(string)', string);
|
||||
}
|
||||
|
||||
bool _needsCurlyBracketStringInterpolation(String messageString, String placeholder) {
|
||||
@ -305,6 +392,10 @@ String _generateMethod(Message message, String translationForMessage) {
|
||||
return _generatePluralMethod(message, translationForMessage);
|
||||
}
|
||||
|
||||
if (message.isSelect) {
|
||||
return _generateSelectMethod(message, translationForMessage);
|
||||
}
|
||||
|
||||
if (message.placeholdersRequireFormatting) {
|
||||
return formatMethodTemplate
|
||||
.replaceAll('@(name)', message.resourceId)
|
||||
@ -741,6 +832,8 @@ class LocalizationsGenerator {
|
||||
@visibleForTesting
|
||||
final bool areResourceAttributesRequired;
|
||||
|
||||
static final RegExp _selectRE = RegExp(r'\{([\w\s,]*),\s*select\s*,\s*([\w\d]+\s*\{.*\})+\s*\}');
|
||||
|
||||
static bool _isNotReadable(FileStat fileStat) {
|
||||
final String rawStatString = fileStat.modeString();
|
||||
// Removes potential prepended permission bits, such as '(suid)' and '(guid)'.
|
||||
@ -1168,7 +1261,11 @@ class LocalizationsGenerator {
|
||||
.replaceAll('\n\n\n', '\n\n');
|
||||
}
|
||||
|
||||
bool _requiresIntlImport() => _allMessages.any((Message message) => message.isPlural || message.placeholdersRequireFormatting);
|
||||
bool _requiresIntlImport() => _allMessages.any((Message message) {
|
||||
return message.isPlural
|
||||
|| message.isSelect
|
||||
|| message.placeholdersRequireFormatting;
|
||||
});
|
||||
|
||||
void writeOutputFiles(Logger logger, { bool isFromYaml = false }) {
|
||||
// First, generate the string contents of all necessary files.
|
||||
|
@ -156,6 +156,46 @@ const String pluralMethodTemplate = '''
|
||||
);
|
||||
}''';
|
||||
|
||||
const String pluralMethodTemplateInString = '''
|
||||
@override
|
||||
String @(name)(@(parameters)) {
|
||||
@(dateFormatting)
|
||||
@(numberFormatting)
|
||||
final String @(variable) = intl.Intl.pluralLogic(
|
||||
@(count),
|
||||
locale: localeName,
|
||||
@(pluralLogicArgs),
|
||||
);
|
||||
|
||||
return @(string);
|
||||
}''';
|
||||
|
||||
const String selectMethodTemplate = '''
|
||||
@override
|
||||
String @(name)(@(parameters)) {
|
||||
return intl.Intl.select(
|
||||
@(choice),
|
||||
{
|
||||
@(cases)
|
||||
},
|
||||
desc: '@(description)'
|
||||
);
|
||||
}''';
|
||||
|
||||
const String selectMethodTemplateInString = '''
|
||||
@override
|
||||
String @(name)(@(parameters)) {
|
||||
final String @(variable) = intl.Intl.select(
|
||||
@(choice),
|
||||
{
|
||||
@(cases)
|
||||
},
|
||||
desc: '@(description)'
|
||||
);
|
||||
|
||||
return @(string);
|
||||
}''';
|
||||
|
||||
const String classFileTemplate = '''
|
||||
@(header)
|
||||
|
||||
|
@ -273,17 +273,21 @@ class Message {
|
||||
value = _value(bundle, resourceId),
|
||||
description = _description(bundle, resourceId, isResourceAttributeRequired),
|
||||
placeholders = _placeholders(bundle, resourceId, isResourceAttributeRequired),
|
||||
_pluralMatch = _pluralRE.firstMatch(_value(bundle, resourceId));
|
||||
_pluralMatch = _pluralRE.firstMatch(_value(bundle, resourceId)),
|
||||
_selectMatch = _selectRE.firstMatch(_value(bundle, resourceId));
|
||||
|
||||
static final RegExp _pluralRE = RegExp(r'\s*\{([\w\s,]*),\s*plural\s*,');
|
||||
static final RegExp _selectRE = RegExp(r'\s*\{([\w\s,]*),\s*select\s*,');
|
||||
|
||||
final String resourceId;
|
||||
final String value;
|
||||
final String? description;
|
||||
final List<Placeholder> placeholders;
|
||||
final RegExpMatch? _pluralMatch;
|
||||
final RegExpMatch? _selectMatch;
|
||||
|
||||
bool get isPlural => _pluralMatch != null && _pluralMatch!.groupCount == 1;
|
||||
bool get isSelect => _selectMatch != null && _selectMatch!.groupCount == 1;
|
||||
|
||||
bool get placeholdersRequireFormatting => placeholders.any((Placeholder p) => p.requiresFormatting);
|
||||
|
||||
@ -331,14 +335,22 @@ class Message {
|
||||
);
|
||||
}
|
||||
|
||||
final RegExpMatch? pluralRegExp = _pluralRE.firstMatch(_value(bundle, resourceId));
|
||||
final bool isPlural = pluralRegExp != null && pluralRegExp.groupCount == 1;
|
||||
if (attributes == null && isPlural) {
|
||||
if (attributes == null) {
|
||||
|
||||
void _throwEmptyAttributes(final RegExp regExp, final String type) {
|
||||
final RegExpMatch? match = regExp.firstMatch(_value(bundle, resourceId));
|
||||
final bool isMatch = match != null && match.groupCount == 1;
|
||||
if (isMatch) {
|
||||
throw L10nException(
|
||||
'Resource attribute "@$resourceId" was not found. Please '
|
||||
'ensure that plural resources have a corresponding @resource.'
|
||||
'ensure that $type resources have a corresponding @resource.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_throwEmptyAttributes(_pluralRE, 'plural');
|
||||
_throwEmptyAttributes(_selectRE, 'select');
|
||||
}
|
||||
|
||||
return attributes as Map<String, Object?>?;
|
||||
}
|
||||
|
@ -120,7 +120,6 @@ void main() {
|
||||
|
||||
// Run localizations generator in specified absolute path.
|
||||
final String flutterProjectPath = fs.path.join('absolute', 'path', 'to', 'flutter_project');
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
projectPathString: flutterProjectPath,
|
||||
@ -132,11 +131,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
throw TestFailure('Unexpected failure during test setup: ${e.message}');
|
||||
} on Exception catch (e) {
|
||||
throw TestFailure('Unexpected failure during test setup: $e');
|
||||
}
|
||||
|
||||
// Output files should be generated in the provided absolute path.
|
||||
expect(
|
||||
@ -245,9 +239,7 @@ void main() {
|
||||
testWithoutContext('correctly adds a headerString when it is set', () {
|
||||
_standardFlutterDirectoryL10nSetup(fs);
|
||||
|
||||
LocalizationsGenerator generator;
|
||||
try {
|
||||
generator = LocalizationsGenerator(
|
||||
final LocalizationsGenerator generator = LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
@ -256,9 +248,6 @@ void main() {
|
||||
classNameString: defaultClassNameString,
|
||||
headerString: '/// Sample header',
|
||||
);
|
||||
} on L10nException catch (e) {
|
||||
fail('Setting a header through a String should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
expect(generator.header, '/// Sample header');
|
||||
});
|
||||
@ -270,9 +259,7 @@ void main() {
|
||||
..childFile(esArbFileName).writeAsStringSync(singleEsMessageArbFileString)
|
||||
..childFile('header.txt').writeAsStringSync('/// Sample header in a text file');
|
||||
|
||||
LocalizationsGenerator generator;
|
||||
try {
|
||||
generator = LocalizationsGenerator(
|
||||
final LocalizationsGenerator generator = LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
@ -281,9 +268,6 @@ void main() {
|
||||
classNameString: defaultClassNameString,
|
||||
headerFile: 'header.txt',
|
||||
);
|
||||
} on L10nException catch (e) {
|
||||
fail('Setting a header through a file should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
expect(generator.header, '/// Sample header in a text file');
|
||||
});
|
||||
@ -295,7 +279,6 @@ void main() {
|
||||
.writeAsStringSync(singleMessageArbFileString);
|
||||
l10nDirectory.childFile('app_localizations_es.arb')
|
||||
.writeAsStringSync(singleEsMessageArbFileString);
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -305,9 +288,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
final Directory outputDirectory = fs.directory(syntheticL10nPackagePath);
|
||||
expect(outputDirectory.childFile('output-localization-file.dart').existsSync(), isTrue);
|
||||
@ -346,7 +326,6 @@ void main() {
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
|
||||
..childFile(esArbFileName).writeAsStringSync(singleEsMessageArbFileString);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -358,9 +337,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
final File unimplementedOutputFile = fs.file(
|
||||
fs.path.join('lib', 'l10n', 'unimplemented_message_translations.json'),
|
||||
@ -382,7 +358,6 @@ void main() {
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
|
||||
..childFile(esArbFileName).writeAsStringSync(singleEsMessageArbFileString);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -395,9 +370,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
final File unimplementedOutputFile = fs.file(
|
||||
fs.path.join('lib', 'l10n', 'unimplemented_message_translations.json'),
|
||||
@ -423,7 +395,6 @@ void main() {
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
|
||||
..childFile(esArbFileName).writeAsStringSync(singleEsMessageArbFileString);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -435,9 +406,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(testLogger);
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
expect(
|
||||
testLogger.statusText,
|
||||
@ -460,7 +428,6 @@ void main() {
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
|
||||
..childFile(esArbFileName).writeAsStringSync(singleEsMessageArbFileString);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -470,9 +437,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(testLogger, isFromYaml: true);
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
expect(
|
||||
testLogger.statusText,
|
||||
@ -495,7 +459,6 @@ void main() {
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
|
||||
..childFile(esArbFileName).writeAsStringSync(twoMessageArbFileString);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -506,9 +469,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(testLogger);
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
expect(testLogger.statusText, '');
|
||||
},
|
||||
@ -517,7 +477,6 @@ void main() {
|
||||
testWithoutContext('untranslated messages file included in generated JSON list of outputs', () {
|
||||
_standardFlutterDirectoryL10nSetup(fs);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -529,9 +488,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
final File inputsAndOutputsList = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'gen_l10n_inputs_and_outputs.json'),
|
||||
@ -550,7 +506,6 @@ void main() {
|
||||
'null while not using the synthetic package option',
|
||||
() {
|
||||
_standardFlutterDirectoryL10nSetup(fs);
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -562,9 +517,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
final Directory outputDirectory = fs.directory('lib').childDirectory('l10n');
|
||||
expect(outputDirectory.childFile('output-localization-file.dart').existsSync(), isTrue);
|
||||
@ -591,7 +543,6 @@ void main() {
|
||||
.childFile(esArbFileName)
|
||||
.writeAsStringSync(singleEsMessageArbFileString);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -603,9 +554,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
final Directory outputDirectory = fs.directory('lib').childDirectory('l10n').childDirectory('output');
|
||||
expect(outputDirectory.existsSync(), isTrue);
|
||||
@ -621,7 +569,6 @@ void main() {
|
||||
() {
|
||||
_standardFlutterDirectoryL10nSetup(fs);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -633,9 +580,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
final Directory outputDirectory = fs.directory('lib').childDirectory('l10n').childDirectory('output');
|
||||
expect(outputDirectory.existsSync(), isTrue);
|
||||
@ -651,7 +595,6 @@ void main() {
|
||||
() {
|
||||
_standardFlutterDirectoryL10nSetup(fs);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -663,9 +606,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
final Directory outputDirectory = fs.directory('lib').childDirectory('l10n').childDirectory('output');
|
||||
expect(outputDirectory.existsSync(), isTrue);
|
||||
@ -686,7 +626,6 @@ void main() {
|
||||
() {
|
||||
_standardFlutterDirectoryL10nSetup(fs);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -699,9 +638,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
final Directory outputDirectory = fs.directory('lib').childDirectory('l10n').childDirectory('output');
|
||||
expect(outputDirectory.existsSync(), isTrue);
|
||||
@ -720,7 +656,6 @@ void main() {
|
||||
testWithoutContext('creates list of inputs and outputs when file path is specified', () {
|
||||
_standardFlutterDirectoryL10nSetup(fs);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -731,9 +666,6 @@ void main() {
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
final File inputsAndOutputsList = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'gen_l10n_inputs_and_outputs.json'),
|
||||
@ -915,19 +847,15 @@ flutter:
|
||||
testWithoutContext('correctly initializes supportedLocales and supportedLanguageCodes properties', () {
|
||||
_standardFlutterDirectoryL10nSetup(fs);
|
||||
|
||||
LocalizationsGenerator generator;
|
||||
try {
|
||||
generator = LocalizationsGenerator(
|
||||
final LocalizationsGenerator generator = LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
templateArbFileName: defaultTemplateArbFileName,
|
||||
outputFileString: defaultOutputFileString,
|
||||
classNameString: defaultClassNameString,
|
||||
)..loadResources();
|
||||
} on L10nException catch (e) {
|
||||
fail('Setting language and locales should not fail: \n${e.message}');
|
||||
}
|
||||
)
|
||||
..loadResources();
|
||||
|
||||
expect(generator.supportedLocales.contains(LocaleInfo.fromString('en')), true);
|
||||
expect(generator.supportedLocales.contains(LocaleInfo.fromString('es')), true);
|
||||
@ -944,20 +872,15 @@ flutter:
|
||||
l10nDirectory.childFile('app_en.arb')
|
||||
.writeAsStringSync(singleMessageArbFileString);
|
||||
|
||||
LocalizationsGenerator generator;
|
||||
try {
|
||||
generator = LocalizationsGenerator(
|
||||
final LocalizationsGenerator generator = LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
templateArbFileName: defaultTemplateArbFileName,
|
||||
outputFileString: defaultOutputFileString,
|
||||
classNameString: defaultClassNameString,
|
||||
);
|
||||
generator.loadResources();
|
||||
} on L10nException catch (e) {
|
||||
fail('Setting language and locales should not fail: \n${e.message}');
|
||||
}
|
||||
)
|
||||
..loadResources();
|
||||
|
||||
expect(generator.supportedLocales.first, LocaleInfo.fromString('en'));
|
||||
expect(generator.supportedLocales.elementAt(1), LocaleInfo.fromString('es'));
|
||||
@ -975,9 +898,7 @@ flutter:
|
||||
.writeAsStringSync(singleZhMessageArbFileString);
|
||||
|
||||
const List<String> preferredSupportedLocale = <String>['zh', 'es'];
|
||||
LocalizationsGenerator generator;
|
||||
try {
|
||||
generator = LocalizationsGenerator(
|
||||
final LocalizationsGenerator generator = LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
@ -985,11 +906,8 @@ flutter:
|
||||
outputFileString: defaultOutputFileString,
|
||||
classNameString: defaultClassNameString,
|
||||
preferredSupportedLocales: preferredSupportedLocale,
|
||||
);
|
||||
generator.loadResources();
|
||||
} on L10nException catch (e) {
|
||||
fail('Setting language and locales should not fail: \n${e.message}');
|
||||
}
|
||||
)
|
||||
..loadResources();
|
||||
|
||||
expect(generator.supportedLocales.first, LocaleInfo.fromString('zh'));
|
||||
expect(generator.supportedLocales.elementAt(1), LocaleInfo.fromString('es'));
|
||||
@ -1043,20 +961,15 @@ flutter:
|
||||
l10nDirectory.childFile('app_en.arb')
|
||||
.writeAsStringSync(singleMessageArbFileString);
|
||||
|
||||
LocalizationsGenerator generator;
|
||||
try {
|
||||
generator = LocalizationsGenerator(
|
||||
final LocalizationsGenerator generator = LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
templateArbFileName: defaultTemplateArbFileName,
|
||||
outputFileString: defaultOutputFileString,
|
||||
classNameString: defaultClassNameString,
|
||||
);
|
||||
generator.loadResources();
|
||||
} on L10nException catch (e) {
|
||||
fail('Setting language and locales should not fail: \n${e.message}');
|
||||
}
|
||||
)
|
||||
..loadResources();
|
||||
|
||||
expect(generator.arbPathStrings.first, fs.path.join('lib', 'l10n', 'app_en.arb'));
|
||||
expect(generator.arbPathStrings.elementAt(1), fs.path.join('lib', 'l10n', 'app_es.arb'));
|
||||
@ -1089,20 +1002,15 @@ flutter:
|
||||
l10nDirectory.childFile('second_file.arb')
|
||||
.writeAsStringSync(arbFileWithZhLocale);
|
||||
|
||||
LocalizationsGenerator generator;
|
||||
try {
|
||||
generator = LocalizationsGenerator(
|
||||
final LocalizationsGenerator generator = LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
templateArbFileName: 'first_file.arb',
|
||||
outputFileString: defaultOutputFileString,
|
||||
classNameString: defaultClassNameString,
|
||||
);
|
||||
generator.loadResources();
|
||||
} on L10nException catch (e) {
|
||||
fail('Setting language and locales should not fail: \n${e.message}');
|
||||
}
|
||||
)
|
||||
..loadResources();
|
||||
|
||||
expect(generator.supportedLocales.contains(LocaleInfo.fromString('en')), true);
|
||||
expect(generator.supportedLocales.contains(LocaleInfo.fromString('zh')), true);
|
||||
@ -1241,7 +1149,6 @@ flutter:
|
||||
testWithoutContext('message without placeholders - should generate code comment with description and template message translation', () {
|
||||
_standardFlutterDirectoryL10nSetup(fs);
|
||||
final BufferLogger testLogger = BufferLogger.test();
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -1252,9 +1159,6 @@ flutter:
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(testLogger);
|
||||
} on Exception catch (e) {
|
||||
fail('Generating output files should not fail: $e');
|
||||
}
|
||||
|
||||
final File baseLocalizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
|
||||
@ -1286,7 +1190,6 @@ flutter:
|
||||
|
||||
final BufferLogger testLogger = BufferLogger.test();
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -1297,9 +1200,6 @@ flutter:
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(testLogger);
|
||||
} on Exception catch (e) {
|
||||
fail('Generating output files should not fail: $e');
|
||||
}
|
||||
|
||||
final File baseLocalizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
|
||||
@ -1339,7 +1239,6 @@ flutter:
|
||||
}''');
|
||||
|
||||
final BufferLogger testLogger = BufferLogger.test();
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -1350,11 +1249,6 @@ flutter:
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(testLogger);
|
||||
} on Exception catch (e) {
|
||||
final L10nException exception = e as L10nException;
|
||||
print(exception.message);
|
||||
fail('Generating output files should not fail: $e');
|
||||
}
|
||||
|
||||
final File baseLocalizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
|
||||
@ -1379,7 +1273,6 @@ flutter:
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
|
||||
..childFile('app_en_CA.arb').writeAsStringSync(singleEnCaMessageArbFileString);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -1390,9 +1283,6 @@ flutter:
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on Exception catch (e) {
|
||||
fail('Generating output files should not fail: $e');
|
||||
}
|
||||
|
||||
expect(fs.isFileSync(fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart')), true);
|
||||
expect(fs.isFileSync(fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en_US.dart')), false);
|
||||
@ -1411,7 +1301,6 @@ flutter:
|
||||
..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString);
|
||||
|
||||
const List<String> preferredSupportedLocale = <String>['zh'];
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -1423,9 +1312,6 @@ flutter:
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on Exception catch (e) {
|
||||
fail('Generating output files should not fail: $e');
|
||||
}
|
||||
|
||||
final String localizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, defaultOutputFileString),
|
||||
@ -1442,7 +1328,6 @@ import 'output-localization-file_zh.dart';
|
||||
fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -1453,9 +1338,6 @@ import 'output-localization-file_zh.dart';
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on Exception catch (e) {
|
||||
fail('Generating output files should not fail: $e');
|
||||
}
|
||||
|
||||
final String localizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, defaultOutputFileString),
|
||||
@ -1812,12 +1694,23 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
});
|
||||
});
|
||||
|
||||
testWithoutContext('intl package import should be omitted in subclass files when no plurals are included', () {
|
||||
fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
|
||||
..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString);
|
||||
group('select messages', () {
|
||||
testWithoutContext('should throw attempting to generate a select message without placeholders', () {
|
||||
const String selectMessageWithoutPlaceholdersAttribute = '''
|
||||
{
|
||||
"genderSelect": "{gender, select, female {She} male {He} other {they} }",
|
||||
"@genderSelect": {
|
||||
"description": "Improperly formatted since it has no placeholder attribute."
|
||||
}
|
||||
}''';
|
||||
|
||||
try {
|
||||
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
|
||||
..createSync(recursive: true);
|
||||
l10nDirectory.childFile(defaultTemplateArbFileName)
|
||||
.writeAsStringSync(selectMessageWithoutPlaceholdersAttribute);
|
||||
|
||||
expect(
|
||||
() {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -1828,9 +1721,137 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on Exception catch (e) {
|
||||
fail('Generating output files should not fail: $e');
|
||||
},
|
||||
throwsA(isA<L10nException>().having(
|
||||
(L10nException e) => e.message,
|
||||
'message',
|
||||
contains('Check to see if the select message is in the proper ICU syntax format'),
|
||||
)),
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('should throw attempting to generate a select message with an empty placeholders map', () {
|
||||
const String selectMessageWithEmptyPlaceholdersMap = '''
|
||||
{
|
||||
"genderSelect": "{gender, select, female {She} male {He} other {they} }",
|
||||
"@genderSelect": {
|
||||
"description": "Improperly formatted since it has no placeholder attribute.",
|
||||
"placeholders": {}
|
||||
}
|
||||
}''';
|
||||
|
||||
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
|
||||
..createSync(recursive: true);
|
||||
l10nDirectory.childFile(defaultTemplateArbFileName)
|
||||
.writeAsStringSync(selectMessageWithEmptyPlaceholdersMap);
|
||||
|
||||
expect(
|
||||
() {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
templateArbFileName: defaultTemplateArbFileName,
|
||||
outputFileString: defaultOutputFileString,
|
||||
classNameString: defaultClassNameString,
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
},
|
||||
throwsA(isA<L10nException>().having(
|
||||
(L10nException e) => e.message,
|
||||
'message',
|
||||
contains('Check to see if the select message is in the proper ICU syntax format'),
|
||||
)),
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('should throw attempting to generate a select message with no resource attributes', () {
|
||||
const String selectMessageWithoutResourceAttributes = '''
|
||||
{
|
||||
"genderSelect": "{gender, select, female {She} male {He} other {they} }"
|
||||
}''';
|
||||
|
||||
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
|
||||
..createSync(recursive: true);
|
||||
l10nDirectory.childFile(defaultTemplateArbFileName)
|
||||
.writeAsStringSync(selectMessageWithoutResourceAttributes);
|
||||
|
||||
expect(
|
||||
() {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
templateArbFileName: defaultTemplateArbFileName,
|
||||
outputFileString: defaultOutputFileString,
|
||||
classNameString: defaultClassNameString,
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
},
|
||||
throwsA(isA<L10nException>().having(
|
||||
(L10nException e) => e.message,
|
||||
'message',
|
||||
contains('Resource attribute "@genderSelect" was not found'),
|
||||
)),
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('should throw attempting to generate a select message with incorrect format for placeholders', () {
|
||||
const String selectMessageWithIncorrectPlaceholderFormat = '''
|
||||
{
|
||||
"genderSelect": "{gender, select, female {She} male {He} other {they} }",
|
||||
"@genderSelect": {
|
||||
"placeholders": "Incorrectly a string, should be a map."
|
||||
}
|
||||
}''';
|
||||
|
||||
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
|
||||
..createSync(recursive: true);
|
||||
l10nDirectory.childFile(defaultTemplateArbFileName)
|
||||
.writeAsStringSync(selectMessageWithIncorrectPlaceholderFormat);
|
||||
|
||||
expect(
|
||||
() {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
templateArbFileName: defaultTemplateArbFileName,
|
||||
outputFileString: defaultOutputFileString,
|
||||
classNameString: defaultClassNameString,
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
},
|
||||
throwsA(isA<L10nException>().having(
|
||||
(L10nException e) => e.message,
|
||||
'message',
|
||||
allOf(
|
||||
contains('is not properly formatted'),
|
||||
contains('Ensure that it is a map with string valued keys'),
|
||||
),
|
||||
)),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testWithoutContext('intl package import should be omitted in subclass files when no plurals are included', () {
|
||||
fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
|
||||
..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString);
|
||||
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
templateArbFileName: defaultTemplateArbFileName,
|
||||
outputFileString: defaultOutputFileString,
|
||||
classNameString: defaultClassNameString,
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
|
||||
final String localizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'output-localization-file_es.dart'),
|
||||
@ -1861,7 +1882,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(pluralMessageArb)
|
||||
..childFile('app_es.arb').writeAsStringSync(pluralMessageEsArb);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -1872,9 +1892,46 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on Exception catch (e) {
|
||||
fail('Generating output files should not fail: $e');
|
||||
|
||||
final String localizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'output-localization-file_es.dart'),
|
||||
).readAsStringSync();
|
||||
expect(localizationsFile, contains(intlImportDartCode));
|
||||
});
|
||||
|
||||
testWithoutContext('intl package import should be kept in subclass files when select is included', () {
|
||||
const String selectMessageArb = '''
|
||||
{
|
||||
"genderSelect": "{gender, select, female {She} male {He} other {they} }",
|
||||
"@genderSelect": {
|
||||
"description": "A select message",
|
||||
"placeholders": {
|
||||
"gender": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
||||
const String selectMessageEsArb = '''
|
||||
{
|
||||
"genderSelect": "{gender, select, female {ES - She} male {ES - He} other {ES - they} }"
|
||||
}
|
||||
''';
|
||||
|
||||
fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(selectMessageArb)
|
||||
..childFile('app_es.arb').writeAsStringSync(selectMessageEsArb);
|
||||
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
outputPathString: defaultL10nPathString,
|
||||
templateArbFileName: defaultTemplateArbFileName,
|
||||
outputFileString: defaultOutputFileString,
|
||||
classNameString: defaultClassNameString,
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
|
||||
final String localizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'output-localization-file_es.dart'),
|
||||
@ -1885,7 +1942,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
testWithoutContext('check indentation on generated files', () {
|
||||
_standardFlutterDirectoryL10nSetup(fs);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -1897,9 +1953,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on Exception catch (e) {
|
||||
fail('Generating output files should not fail: $e');
|
||||
}
|
||||
|
||||
final String localizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart'),
|
||||
@ -1923,7 +1976,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
|
||||
..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -1935,9 +1987,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on Exception catch (e) {
|
||||
fail('Generating output files should not fail: $e');
|
||||
}
|
||||
|
||||
final String localizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart'),
|
||||
@ -1950,7 +1999,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
|
||||
..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -1962,9 +2010,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on Exception catch (e) {
|
||||
fail('Generating output files should not fail: $e');
|
||||
}
|
||||
|
||||
final String localizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart'),
|
||||
@ -2079,7 +2124,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(enArbCheckList)
|
||||
..childFile('app_es.arb').writeAsStringSync(esArbCheckList);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -2090,12 +2134,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on Exception catch (e) {
|
||||
if (e is L10nException) {
|
||||
print(e.message);
|
||||
}
|
||||
fail('Generating output files should not fail: $e');
|
||||
}
|
||||
|
||||
final String localizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'output-localization-file_es.dart'),
|
||||
@ -2145,7 +2183,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
..childFile(defaultTemplateArbFileName).writeAsStringSync(enArbCheckList)
|
||||
..childFile('app_es.arb').writeAsStringSync(esArbCheckList);
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -2156,12 +2193,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on Exception catch (e) {
|
||||
if (e is L10nException) {
|
||||
print(e.message);
|
||||
}
|
||||
fail('Generating output files should not fail: $e');
|
||||
}
|
||||
|
||||
final String localizationsFile = fs.file(
|
||||
fs.path.join(syntheticL10nPackagePath, 'output-localization-file_es.dart'),
|
||||
@ -2357,7 +2388,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
|
||||
testWithoutContext('should generate a valid pubspec.yaml file when using synthetic package if it does not already exist', () {
|
||||
_standardFlutterDirectoryL10nSetup(fs);
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -2367,9 +2397,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
final Directory outputDirectory = fs.directory(syntheticPackagePath);
|
||||
final File pubspecFile = outputDirectory.childFile('pubspec.yaml');
|
||||
@ -2391,7 +2418,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync('abcd');
|
||||
|
||||
try {
|
||||
LocalizationsGenerator(
|
||||
fileSystem: fs,
|
||||
inputPathString: defaultL10nPathString,
|
||||
@ -2401,9 +2427,6 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
|
||||
)
|
||||
..loadResources()
|
||||
..writeOutputFiles(BufferLogger.test());
|
||||
} on L10nException catch (e) {
|
||||
fail('Generating output should not fail: \n${e.message}');
|
||||
}
|
||||
|
||||
// The original pubspec file should not be overwritten.
|
||||
expect(pubspecFile.readAsStringSync(), 'abcd');
|
||||
|
@ -118,40 +118,50 @@ void main() {
|
||||
"#l10n 63 (Flutter's amazing, times 2!)\n"
|
||||
'#l10n 64 (Flutter is "amazing"!)\n'
|
||||
'#l10n 65 (Flutter is "amazing", times 2!)\n'
|
||||
'#l10n 66 (--- es ---)\n'
|
||||
'#l10n 67 (ES - Hello world)\n'
|
||||
'#l10n 68 (ES - Hello _NEWLINE_ World)\n'
|
||||
'#l10n 69 (ES - Hola \$ Mundo)\n'
|
||||
'#l10n 70 (ES - Hello Mundo)\n'
|
||||
'#l10n 71 (ES - Hola Mundo)\n'
|
||||
'#l10n 72 (ES - Hello World on viernes, 1 de enero de 1960)\n'
|
||||
'#l10n 73 (ES - Hello world argument on 1/1/1960 at 0:00)\n'
|
||||
'#l10n 74 (ES - Hello World from 1960 to 2020)\n'
|
||||
'#l10n 75 (ES - Hello for 123)\n'
|
||||
'#l10n 76 (ES - Hello)\n'
|
||||
'#l10n 77 (ES - Hello World)\n'
|
||||
'#l10n 78 (ES - Hello two worlds)\n'
|
||||
'#l10n 79 (ES - Hello)\n'
|
||||
'#l10n 80 (ES - Hello nuevo World)\n'
|
||||
'#l10n 81 (ES - Hello two nuevo worlds)\n'
|
||||
'#l10n 82 (ES - Hello on viernes, 1 de enero de 1960)\n'
|
||||
'#l10n 83 (ES - Hello World, on viernes, 1 de enero de 1960)\n'
|
||||
'#l10n 84 (ES - Hello two worlds, on viernes, 1 de enero de 1960)\n'
|
||||
'#l10n 85 (ES - Hello other 0 worlds, with a total of 100 citizens)\n'
|
||||
'#l10n 86 (ES - Hello World of 101 citizens)\n'
|
||||
'#l10n 87 (ES - Hello two worlds with 102 total citizens)\n'
|
||||
'#l10n 88 (ES - [Hola] -Mundo- #123#)\n'
|
||||
'#l10n 89 (ES - \$!)\n'
|
||||
'#l10n 90 (ES - One \$)\n'
|
||||
"#l10n 91 (ES - Flutter's amazing!)\n"
|
||||
"#l10n 92 (ES - Flutter's amazing, times 2!)\n"
|
||||
'#l10n 93 (ES - Flutter is "amazing"!)\n'
|
||||
'#l10n 94 (ES - Flutter is "amazing", times 2!)\n'
|
||||
'#l10n 95 (--- es_419 ---)\n'
|
||||
'#l10n 96 (ES 419 - Hello World)\n'
|
||||
'#l10n 97 (ES 419 - Hello)\n'
|
||||
'#l10n 98 (ES 419 - Hello World)\n'
|
||||
'#l10n 99 (ES 419 - Hello two worlds)\n'
|
||||
'#l10n 66 (16 wheel truck)\n'
|
||||
"#l10n 67 (Sedan's elegance)\n"
|
||||
'#l10n 68 (Cabriolet has "acceleration")\n'
|
||||
'#l10n 69 (Oh, she found 1 item!)\n'
|
||||
'#l10n 70 (Indeed, they like Flutter!)\n'
|
||||
'#l10n 71 (--- es ---)\n'
|
||||
'#l10n 72 (ES - Hello world)\n'
|
||||
'#l10n 73 (ES - Hello _NEWLINE_ World)\n'
|
||||
'#l10n 74 (ES - Hola \$ Mundo)\n'
|
||||
'#l10n 75 (ES - Hello Mundo)\n'
|
||||
'#l10n 76 (ES - Hola Mundo)\n'
|
||||
'#l10n 77 (ES - Hello World on viernes, 1 de enero de 1960)\n'
|
||||
'#l10n 78 (ES - Hello world argument on 1/1/1960 at 0:00)\n'
|
||||
'#l10n 79 (ES - Hello World from 1960 to 2020)\n'
|
||||
'#l10n 80 (ES - Hello for 123)\n'
|
||||
'#l10n 81 (ES - Hello)\n'
|
||||
'#l10n 82 (ES - Hello World)\n'
|
||||
'#l10n 83 (ES - Hello two worlds)\n'
|
||||
'#l10n 84 (ES - Hello)\n'
|
||||
'#l10n 85 (ES - Hello nuevo World)\n'
|
||||
'#l10n 86 (ES - Hello two nuevo worlds)\n'
|
||||
'#l10n 87 (ES - Hello on viernes, 1 de enero de 1960)\n'
|
||||
'#l10n 88 (ES - Hello World, on viernes, 1 de enero de 1960)\n'
|
||||
'#l10n 89 (ES - Hello two worlds, on viernes, 1 de enero de 1960)\n'
|
||||
'#l10n 90 (ES - Hello other 0 worlds, with a total of 100 citizens)\n'
|
||||
'#l10n 91 (ES - Hello World of 101 citizens)\n'
|
||||
'#l10n 92 (ES - Hello two worlds with 102 total citizens)\n'
|
||||
'#l10n 93 (ES - [Hola] -Mundo- #123#)\n'
|
||||
'#l10n 94 (ES - \$!)\n'
|
||||
'#l10n 95 (ES - One \$)\n'
|
||||
"#l10n 96 (ES - Flutter's amazing!)\n"
|
||||
"#l10n 97 (ES - Flutter's amazing, times 2!)\n"
|
||||
'#l10n 98 (ES - Flutter is "amazing"!)\n'
|
||||
'#l10n 99 (ES - Flutter is "amazing", times 2!)\n'
|
||||
'#l10n 100 (ES - 16 wheel truck)\n'
|
||||
"#l10n 101 (ES - Sedan's elegance)\n"
|
||||
'#l10n 102 (ES - Cabriolet has "acceleration")\n'
|
||||
'#l10n 103 (ES - Oh, she found ES - 1 itemES - !)\n'
|
||||
'#l10n 104 (ES - Indeed, ES - they like ES - Flutter!)\n'
|
||||
'#l10n 105 (--- es_419 ---)\n'
|
||||
'#l10n 106 (ES 419 - Hello World)\n'
|
||||
'#l10n 107 (ES 419 - Hello)\n'
|
||||
'#l10n 108 (ES 419 - Hello World)\n'
|
||||
'#l10n 109 (ES 419 - Hello two worlds)\n'
|
||||
'#l10n END\n'
|
||||
);
|
||||
}
|
||||
|
@ -225,6 +225,11 @@ class Home extends StatelessWidget {
|
||||
'${localizations.singleQuotePlural(2)}',
|
||||
'${localizations.doubleQuote}',
|
||||
'${localizations.doubleQuotePlural(2)}',
|
||||
"${localizations.vehicleSelect('truck')}",
|
||||
"${localizations.singleQuoteSelect('sedan')}",
|
||||
"${localizations.doubleQuoteSelect('cabriolet')}",
|
||||
"${localizations.pluralInString(1)}",
|
||||
"${localizations.selectInString('he')}",
|
||||
]);
|
||||
},
|
||||
),
|
||||
@ -266,6 +271,11 @@ class Home extends StatelessWidget {
|
||||
'${localizations.singleQuotePlural(2)}',
|
||||
'${localizations.doubleQuote}',
|
||||
'${localizations.doubleQuotePlural(2)}',
|
||||
"${localizations.vehicleSelect('truck')}",
|
||||
"${localizations.singleQuoteSelect('sedan')}",
|
||||
"${localizations.doubleQuoteSelect('cabriolet')}",
|
||||
"${localizations.pluralInString(1)}",
|
||||
"${localizations.selectInString('he')}",
|
||||
]);
|
||||
},
|
||||
),
|
||||
@ -608,6 +618,46 @@ void main() {
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
|
||||
"vehicleSelect": "{vehicleType, select, sedan{Sedan} cabriolet{Solid roof cabriolet} truck{16 wheel truck} other{Other}}",
|
||||
"@vehicleSelect": {
|
||||
"description": "A select message.",
|
||||
"placeholders": {
|
||||
"vehicleType": {}
|
||||
}
|
||||
},
|
||||
|
||||
"singleQuoteSelect": "{vehicleType, select, sedan{Sedan's elegance} cabriolet{Cabriolet' acceleration} truck{truck's heavy duty} other{Other's mirrors!}}",
|
||||
"@singleQuoteSelect": {
|
||||
"description": "A select message with a single quote.",
|
||||
"placeholders": {
|
||||
"vehicleType": {}
|
||||
}
|
||||
},
|
||||
|
||||
"doubleQuoteSelect": "{vehicleType, select, sedan{Sedan has \"elegance\"} cabriolet{Cabriolet has \"acceleration\"} truck{truck is \"heavy duty\"} other{Other have \"mirrors\"!}}",
|
||||
"@doubleQuoteSelect": {
|
||||
"description": "A select message with double quote.",
|
||||
"placeholders": {
|
||||
"vehicleType": {}
|
||||
}
|
||||
},
|
||||
|
||||
"pluralInString": "Oh, she found {count, plural, =1 {1 item} other {all {count} items} }!",
|
||||
"@pluralInString": {
|
||||
"description": "A plural message with prefix and suffix strings.",
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
|
||||
"selectInString": "Indeed, {gender, select, male {he likes} female {she likes} other {they like} } Flutter!",
|
||||
"@selectInString": {
|
||||
"description": "A select message with prefix and suffix strings.",
|
||||
"placeholders": {
|
||||
"gender": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
''';
|
||||
@ -646,13 +696,18 @@ void main() {
|
||||
"helloWorldsOn": "{count,plural, =0{ES - Hello on {date}} =1{ES - Hello World, on {date}} =2{ES - Hello two worlds, on {date}} other{ES - Hello other {count} worlds, on {date}}}",
|
||||
"helloWorldPopulation": "{ES - count,plural, =1{ES - Hello World of {population} citizens} =2{ES - Hello two worlds with {population} total citizens} many{ES - Hello all {count} worlds, with a total of {population} citizens} other{ES - Hello other {count} worlds, with a total of {population} citizens}}",
|
||||
"helloWorldInterpolation": "ES - [{hello}] #{world}#",
|
||||
"helloWorldsInterpolation": "ES - {count,plural, other {ES - [{hello}] -{world}- #{count}#}}",
|
||||
"helloWorldsInterpolation": "{count,plural, other {ES - [{hello}] -{world}- #{count}#}}",
|
||||
"dollarSign": "ES - $!",
|
||||
"dollarSignPlural": "{count,plural, =1{ES - One $} other{ES - Many $}}",
|
||||
"singleQuote": "ES - Flutter's amazing!",
|
||||
"singleQuotePlural": "{count,plural, =1{ES - Flutter's amazing, times 1!} other{ES - Flutter's amazing, times {count}!}}",
|
||||
"doubleQuote": "ES - Flutter is \"amazing\"!",
|
||||
"doubleQuotePlural": "{count,plural, =1{ES - Flutter is \"amazing\", times 1!} other{ES - Flutter is \"amazing\", times {count}!}}"
|
||||
"doubleQuotePlural": "{count,plural, =1{ES - Flutter is \"amazing\", times 1!} other{ES - Flutter is \"amazing\", times {count}!}}",
|
||||
"vehicleSelect": "{vehicleType, select, sedan{ES - Sedan} cabriolet{ES - Solid roof cabriolet} truck{ES - 16 wheel truck} other{ES - Other}}",
|
||||
"singleQuoteSelect": "{vehicleType, select, sedan{ES - Sedan's elegance} cabriolet{ES - Cabriolet' acceleration} truck{ES - truck's heavy duty} other{ES - Other's mirrors!}}",
|
||||
"doubleQuoteSelect": "{vehicleType, select, sedan{ES - Sedan has \"elegance\"} cabriolet{ES - Cabriolet has \"acceleration\"} truck{ES - truck is \"heavy duty\"} other{ES - Other have \"mirrors\"!}}",
|
||||
"pluralInString": "ES - Oh, she found {count, plural, =1 {ES - 1 item} other {ES - all {count} items} }ES - !",
|
||||
"selectInString": "ES - Indeed, {gender, select, male {ES - he likes} female {ES - she likes} other {ES - they like} } ES - Flutter!"
|
||||
}
|
||||
''';
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user