Unverified Commit c525988c authored by Shi-Hao Hong's avatar Shi-Hao Hong Committed by GitHub

Reorganize tests in l10n tool (#47704)

parent f65f7f01
...@@ -50,7 +50,7 @@ void main() { ...@@ -50,7 +50,7 @@ void main() {
); );
}); });
group('LocalizationsGenerator setters:', () { group('Setters', () {
test('happy path', () { test('happy path', () {
_standardFlutterDirectoryL10nSetup(fs); _standardFlutterDirectoryL10nSetup(fs);
expect(() { expect(() {
...@@ -174,7 +174,7 @@ void main() { ...@@ -174,7 +174,7 @@ void main() {
); );
}); });
group('className should only take valid Dart class names:', () { group('className should only take valid Dart class names', () {
LocalizationsGenerator generator; LocalizationsGenerator generator;
setUp(() { setUp(() {
_standardFlutterDirectoryL10nSetup(fs); _standardFlutterDirectoryL10nSetup(fs);
...@@ -242,7 +242,7 @@ void main() { ...@@ -242,7 +242,7 @@ void main() {
}); });
}); });
group('LocalizationsGenerator.parseArbFiles:', () { group('parseArbFiles', () {
test('correctly initializes supportedLocales and supportedLanguageCodes properties', () { test('correctly initializes supportedLocales and supportedLanguageCodes properties', () {
_standardFlutterDirectoryL10nSetup(fs); _standardFlutterDirectoryL10nSetup(fs);
...@@ -484,7 +484,7 @@ void main() { ...@@ -484,7 +484,7 @@ void main() {
expect(generator.supportedLocales.contains(LocaleInfo.fromString('zh')), true); expect(generator.supportedLocales.contains(LocaleInfo.fromString('zh')), true);
}); });
test('correctly parses @@locale property in arb file', () { test('correctly prioritizes @@locale property in arb file over filename', () {
const String arbFileWithEnLocale = '''{ const String arbFileWithEnLocale = '''{
"@@locale": "en", "@@locale": "en",
"title": "Stocks", "title": "Stocks",
...@@ -589,8 +589,8 @@ void main() { ...@@ -589,8 +589,8 @@ void main() {
}); });
}); });
group('LocalizationsGenerator.generateClassMethods:', () { group('generateClassMethods', () {
test('correctly generates a simple message with getter:', () { test('correctly generates a simple message with getter', () {
_standardFlutterDirectoryL10nSetup(fs); _standardFlutterDirectoryL10nSetup(fs);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
...@@ -666,8 +666,9 @@ void main() { ...@@ -666,8 +666,9 @@ void main() {
'''); ''');
}); });
test('correctly generates simple message with dates', () { group('DateTime tests', () {
const String singleDateMessageArbFileString = '''{ test('correctly generates simple message with dates', () {
const String singleDateMessageArbFileString = '''{
"springBegins": "Spring begins on {springStartDate}", "springBegins": "Spring begins on {springStartDate}",
"@springBegins": { "@springBegins": {
"description": "The first day of spring", "description": "The first day of spring",
...@@ -679,29 +680,29 @@ void main() { ...@@ -679,29 +680,29 @@ void main() {
} }
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(singleDateMessageArbFileString); .writeAsStringSync(singleDateMessageArbFileString);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on Exception catch (e) { } on Exception catch (e) {
fail('Parsing template arb file should succeed: \n$e'); fail('Parsing template arb file should succeed: \n$e');
} }
expect(generator.classMethods, isNotEmpty); expect(generator.classMethods, isNotEmpty);
expect( expect(
generator.classMethods.first, generator.classMethods.first,
''' String springBegins(Object springStartDate) { ''' String springBegins(Object springStartDate) {
final DateFormat springStartDateDateFormat = DateFormat.yMMMMEEEEd(_localeName); final DateFormat springStartDateDateFormat = DateFormat.yMMMMEEEEd(_localeName);
final String springStartDateString = springStartDateDateFormat.format(springStartDate); final String springStartDateString = springStartDateDateFormat.format(springStartDate);
...@@ -714,10 +715,10 @@ void main() { ...@@ -714,10 +715,10 @@ void main() {
); );
} }
'''); ''');
}); });
test('throws an exception when improperly formatted date is passed in', () { test('throws an exception when improperly formatted date is passed in', () {
const String singleDateMessageArbFileString = '''{ const String singleDateMessageArbFileString = '''{
"springBegins": "Spring begins on {springStartDate}", "springBegins": "Spring begins on {springStartDate}",
"@springBegins": { "@springBegins": {
"description": "The first day of spring", "description": "The first day of spring",
...@@ -729,33 +730,33 @@ void main() { ...@@ -729,33 +730,33 @@ void main() {
} }
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(singleDateMessageArbFileString); .writeAsStringSync(singleDateMessageArbFileString);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on L10nException catch (e) { } on L10nException catch (e) {
expect(e.message, contains('asdf')); expect(e.message, contains('asdf'));
expect(e.message, contains('springStartDate')); expect(e.message, contains('springStartDate'));
expect(e.message, contains('does not have a corresponding DateFormat')); expect(e.message, contains('does not have a corresponding DateFormat'));
return; return;
} }
fail('Improper date formatting should throw an exception'); fail('Improper date formatting should throw an exception');
}); });
test('throws an exception when no format attribute is passed in', () { test('throws an exception when no format attribute is passed in', () {
const String singleDateMessageArbFileString = '''{ const String singleDateMessageArbFileString = '''{
"springBegins": "Spring begins on {springStartDate}", "springBegins": "Spring begins on {springStartDate}",
"@springBegins": { "@springBegins": {
"description": "The first day of spring", "description": "The first day of spring",
...@@ -766,31 +767,31 @@ void main() { ...@@ -766,31 +767,31 @@ void main() {
} }
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(singleDateMessageArbFileString); .writeAsStringSync(singleDateMessageArbFileString);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on L10nException catch (e) { } on L10nException catch (e) {
expect(e.message, contains('the "format" attribute needs to be set')); expect(e.message, contains('the "format" attribute needs to be set'));
return; return;
} }
fail('Improper date formatting should throw an exception'); fail('Improper date formatting should throw an exception');
}); });
test('correctly generates simple message with date along with other placeholders', () { test('correctly generates simple message with date along with other placeholders', () {
const String singleDateMessageArbFileString = '''{ const String singleDateMessageArbFileString = '''{
"springGreetings": "Since it's {springStartDate}, it's finally spring! {helloWorld}!", "springGreetings": "Since it's {springStartDate}, it's finally spring! {helloWorld}!",
"@springGreetings": { "@springGreetings": {
"description": "A realization that it's finally the spring season, followed by a greeting.", "description": "A realization that it's finally the spring season, followed by a greeting.",
...@@ -803,29 +804,29 @@ void main() { ...@@ -803,29 +804,29 @@ void main() {
} }
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(singleDateMessageArbFileString); .writeAsStringSync(singleDateMessageArbFileString);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on Exception catch (e) { } on Exception catch (e) {
fail('Parsing template arb file should succeed: \n$e'); fail('Parsing template arb file should succeed: \n$e');
} }
expect(generator.classMethods, isNotEmpty); expect(generator.classMethods, isNotEmpty);
expect( expect(
generator.classMethods.first, generator.classMethods.first,
''' String springGreetings(Object springStartDate, Object helloWorld) { ''' String springGreetings(Object springStartDate, Object helloWorld) {
final DateFormat springStartDateDateFormat = DateFormat.yMMMMEEEEd(_localeName); final DateFormat springStartDateDateFormat = DateFormat.yMMMMEEEEd(_localeName);
final String springStartDateString = springStartDateDateFormat.format(springStartDate); final String springStartDateString = springStartDateDateFormat.format(springStartDate);
...@@ -838,10 +839,10 @@ void main() { ...@@ -838,10 +839,10 @@ void main() {
); );
} }
'''); ''');
}); });
test('correctly generates simple message with multiple dates', () { test('correctly generates simple message with multiple dates', () {
const String singleDateMessageArbFileString = '''{ const String singleDateMessageArbFileString = '''{
"springRange": "Spring begins on {springStartDate} and ends on {springEndDate}", "springRange": "Spring begins on {springStartDate} and ends on {springEndDate}",
"@springRange": { "@springRange": {
"description": "The range of dates for spring in the year", "description": "The range of dates for spring in the year",
...@@ -857,29 +858,29 @@ void main() { ...@@ -857,29 +858,29 @@ void main() {
} }
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(singleDateMessageArbFileString); .writeAsStringSync(singleDateMessageArbFileString);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on Exception catch (e) { } on Exception catch (e) {
fail('Parsing template arb file should succeed: \n$e'); fail('Parsing template arb file should succeed: \n$e');
} }
expect(generator.classMethods, isNotEmpty); expect(generator.classMethods, isNotEmpty);
expect( expect(
generator.classMethods.first, generator.classMethods.first,
''' String springRange(Object springStartDate, Object springEndDate) { ''' String springRange(Object springStartDate, Object springEndDate) {
final DateFormat springStartDateDateFormat = DateFormat.yMMMMEEEEd(_localeName); final DateFormat springStartDateDateFormat = DateFormat.yMMMMEEEEd(_localeName);
final String springStartDateString = springStartDateDateFormat.format(springStartDate); final String springStartDateString = springStartDateDateFormat.format(springStartDate);
...@@ -895,60 +896,66 @@ void main() { ...@@ -895,60 +896,66 @@ void main() {
); );
} }
'''); ''');
}); });
test('correctly generates a plural message:', () { test('correctly generates a plural message with DateTime placeholders', () {
const String singlePluralMessageArbFileString = '''{ const String pluralMessageWithDateTimePlaceholder = '''{
"helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}", "helloWorlds": "{count,plural, =1{Hello World, today is {currentDate}}=2{Hello two worlds, today is {currentDate}}many{Hello all {count} worlds, today is {currentDate}}other{Hello other {count} worlds, today is {currentDate}}}",
"@helloWorlds": { "@helloWorlds": {
"placeholders": { "placeholders": {
"count": {} "count": {},
"currentDate": {
"type": "DateTime",
"format": "yMMMMEEEEd"
}
} }
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(singlePluralMessageArbFileString); .writeAsStringSync(pluralMessageWithDateTimePlaceholder);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on Exception catch (e) { } on Exception catch (e) {
fail('Parsing template arb file should succeed: \n$e'); fail('Parsing template arb file should succeed: \n$e');
} }
expect(generator.classMethods, isNotEmpty);
expect(
generator.classMethods.first,
''' String helloWorlds(int count, Object currentDate) {
final DateFormat currentDateDateFormat = DateFormat.yMMMMEEEEd(_localeName);
final String currentDateString = currentDateDateFormat.format(currentDate);
expect(generator.classMethods, isNotEmpty);
expect(
generator.classMethods.first,
''' String helloWorlds(int count) {
return Intl.plural( return Intl.plural(
count, count,
locale: _localeName, locale: _localeName,
name: 'helloWorlds', name: 'helloWorlds',
args: <Object>[count], args: <Object>[count, currentDateString],
zero: 'Hello', one: 'Hello World, today is \$currentDateString',
one: 'Hello World', two: 'Hello two worlds, today is \$currentDateString',
two: 'Hello two worlds', many: 'Hello all \$count worlds, today is \$currentDateString',
few: 'Hello \$count worlds', other: 'Hello other \$count worlds, today is \$currentDateString'
many: 'Hello all \$count worlds',
other: 'Hello other \$count worlds'
); );
} }
''' '''
); );
});
}); });
group('Number tests', () {
test('correctly generates simple message with numbers', () { test('correctly generates simple message with numbers', () {
const String singleNumberMessage = '''{ const String singleNumberMessage = '''{
"courseCompletion": "You have completed {progress} of the course.", "courseCompletion": "You have completed {progress} of the course.",
"@courseCompletion": { "@courseCompletion": {
"description": "The amount of progress the student has made in their class.", "description": "The amount of progress the student has made in their class.",
...@@ -960,29 +967,29 @@ void main() { ...@@ -960,29 +967,29 @@ void main() {
} }
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(singleNumberMessage); .writeAsStringSync(singleNumberMessage);
final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try {
generator.initialize(
l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
);
generator.parseArbFiles();
generator.generateClassMethods();
} on Exception catch (e) {
fail('Parsing template arb file should succeed: \n$e');
}
expect(generator.classMethods, isNotEmpty); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
expect( try {
generator.classMethods.first, generator.initialize(
''' String courseCompletion(Object progress) { l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
);
generator.parseArbFiles();
generator.generateClassMethods();
} on Exception catch (e) {
fail('Parsing template arb file should succeed: \n$e');
}
expect(generator.classMethods, isNotEmpty);
expect(
generator.classMethods.first,
''' String courseCompletion(Object progress) {
final NumberFormat progressNumberFormat = NumberFormat.percentPattern( final NumberFormat progressNumberFormat = NumberFormat.percentPattern(
locale: _localeName, locale: _localeName,
); );
...@@ -997,48 +1004,155 @@ void main() { ...@@ -997,48 +1004,155 @@ void main() {
); );
} }
'''); ''');
}); });
test('throws an exception when improperly formatted number is passed in', () { test('correctly adds optional parameters to numbers', () {
const String singleDateMessageArbFileString = '''{ const String singleNumberMessage = '''{
"courseCompletion": "You have completed {progress} of the course.", "courseCompletion": "You have completed {progress} of the course.",
"@courseCompletion": { "@courseCompletion": {
"description": "The amount of progress the student has made in their class.", "description": "The amount of progress the student has made in their class.",
"placeholders": { "placeholders": {
"progress": { "progress": {
"type": "Number", "type": "Number",
"format": "asdf" "format": "decimalPercentPattern",
"optionalParameters": {
"decimalDigits": 2
}
} }
} }
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(singleDateMessageArbFileString); .writeAsStringSync(singleNumberMessage);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on L10nException catch (e) { } on Exception catch (e) {
expect(e.message, contains('asdf')); fail('Parsing template arb file should succeed: \n$e');
expect(e.message, contains('progress')); }
expect(e.message, contains('does not have a corresponding NumberFormat'));
return; expect(generator.classMethods, isNotEmpty);
expect(
generator.classMethods.first,
''' String courseCompletion(Object progress) {
final NumberFormat progressNumberFormat = NumberFormat.decimalPercentPattern(
locale: _localeName,
decimalDigits: 2,
);
final String progressString = progressNumberFormat.format(progress);
return Intl.message(
r'You have completed \$progressString of the course.',
locale: _localeName,
name: 'courseCompletion',
desc: r'The amount of progress the student has made in their class.',
args: <Object>[progressString]
);
}
''');
});
test('throws an exception when improperly formatted number is passed in', () {
const String singleDateMessageArbFileString = '''{
"courseCompletion": "You have completed {progress} of the course.",
"@courseCompletion": {
"description": "The amount of progress the student has made in their class.",
"placeholders": {
"progress": {
"type": "Number",
"format": "asdf"
} }
}
}
}''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(singleDateMessageArbFileString);
final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try {
generator.initialize(
l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
);
generator.parseArbFiles();
generator.generateClassMethods();
} on L10nException catch (e) {
expect(e.message, contains('asdf'));
expect(e.message, contains('progress'));
expect(e.message, contains('does not have a corresponding NumberFormat'));
return;
}
fail('Improper date formatting should throw an exception'); fail('Improper date formatting should throw an exception');
});
}); });
test('correctly generates a plural message with placeholders:', () { group('plural messages', () {
const String pluralMessageWithMultiplePlaceholders = '''{ test('correctly generates a plural message', () {
const String singlePluralMessageArbFileString = '''{
"helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}",
"@helloWorlds": {
"placeholders": {
"count": {}
}
}
}''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(singlePluralMessageArbFileString);
final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try {
generator.initialize(
l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
);
generator.parseArbFiles();
generator.generateClassMethods();
} on Exception catch (e) {
fail('Parsing template arb file should succeed: \n$e');
}
expect(generator.classMethods, isNotEmpty);
expect(
generator.classMethods.first,
''' String helloWorlds(int count) {
return Intl.plural(
count,
locale: _localeName,
name: 'helloWorlds',
args: <Object>[count],
zero: 'Hello',
one: 'Hello World',
two: 'Hello two worlds',
few: 'Hello \$count worlds',
many: 'Hello all \$count worlds',
other: 'Hello other \$count worlds'
);
}
'''
);
});
test('correctly generates a plural message with placeholders', () {
const String pluralMessageWithMultiplePlaceholders = '''{
"helloWorlds": "{count,plural, =0{Hello}=1{Hello {adjective} World}=2{Hello two {adjective} worlds}few{Hello {count} {adjective} worlds}many{Hello all {count} {adjective} worlds}other{Hello other {count} {adjective} worlds}}", "helloWorlds": "{count,plural, =0{Hello}=1{Hello {adjective} World}=2{Hello two {adjective} worlds}few{Hello {count} {adjective} worlds}many{Hello all {count} {adjective} worlds}other{Hello other {count} {adjective} worlds}}",
"@helloWorlds": { "@helloWorlds": {
"placeholders": { "placeholders": {
...@@ -1047,28 +1161,28 @@ void main() { ...@@ -1047,28 +1161,28 @@ void main() {
} }
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(pluralMessageWithMultiplePlaceholders); .writeAsStringSync(pluralMessageWithMultiplePlaceholders);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on Exception catch (e) { } on Exception catch (e) {
fail('Parsing template arb file should succeed: \n$e'); fail('Parsing template arb file should succeed: \n$e');
} }
expect(generator.classMethods, isNotEmpty); expect(generator.classMethods, isNotEmpty);
expect( expect(
generator.classMethods.first, generator.classMethods.first,
''' String helloWorlds(int count, Object adjective) { ''' String helloWorlds(int count, Object adjective) {
return Intl.plural( return Intl.plural(
count, count,
...@@ -1084,11 +1198,11 @@ void main() { ...@@ -1084,11 +1198,11 @@ void main() {
); );
} }
''' '''
); );
}); });
test('correctly generates a plural message with DateTime placeholders:', () { test('correctly generates a plural message with DateTime placeholders', () {
const String pluralMessageWithDateTimePlaceholder = '''{ const String pluralMessageWithDateTimePlaceholder = '''{
"helloWorlds": "{count,plural, =1{Hello World, today is {currentDate}}=2{Hello two worlds, today is {currentDate}}many{Hello all {count} worlds, today is {currentDate}}other{Hello other {count} worlds, today is {currentDate}}}", "helloWorlds": "{count,plural, =1{Hello World, today is {currentDate}}=2{Hello two worlds, today is {currentDate}}many{Hello all {count} worlds, today is {currentDate}}other{Hello other {count} worlds, today is {currentDate}}}",
"@helloWorlds": { "@helloWorlds": {
"placeholders": { "placeholders": {
...@@ -1100,29 +1214,29 @@ void main() { ...@@ -1100,29 +1214,29 @@ void main() {
} }
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(pluralMessageWithDateTimePlaceholder); .writeAsStringSync(pluralMessageWithDateTimePlaceholder);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on Exception catch (e) { } on Exception catch (e) {
fail('Parsing template arb file should succeed: \n$e'); fail('Parsing template arb file should succeed: \n$e');
} }
expect(generator.classMethods, isNotEmpty); expect(generator.classMethods, isNotEmpty);
expect( expect(
generator.classMethods.first, generator.classMethods.first,
''' String helloWorlds(int count, Object currentDate) { ''' String helloWorlds(int count, Object currentDate) {
final DateFormat currentDateDateFormat = DateFormat.yMMMMEEEEd(_localeName); final DateFormat currentDateDateFormat = DateFormat.yMMMMEEEEd(_localeName);
final String currentDateString = currentDateDateFormat.format(currentDate); final String currentDateString = currentDateDateFormat.format(currentDate);
...@@ -1138,11 +1252,11 @@ void main() { ...@@ -1138,11 +1252,11 @@ void main() {
); );
} }
''' '''
); );
}); });
test('correctly generates a plural message with number placeholders:', () { test('correctly generates a plural message with number placeholders', () {
const String pluralMessageWithDateTimePlaceholder = '''{ const String pluralMessageWithDateTimePlaceholder = '''{
"helloWorlds": "{count,plural, =1{Hello World of {population} citizens}=2{Hello two worlds with {population} total citizens}many{Hello all {count} worlds, with a total of {population} citizens}other{Hello other {count} worlds, with a total of {population} citizens}}", "helloWorlds": "{count,plural, =1{Hello World of {population} citizens}=2{Hello two worlds with {population} total citizens}many{Hello all {count} worlds, with a total of {population} citizens}other{Hello other {count} worlds, with a total of {population} citizens}}",
"@helloWorlds": { "@helloWorlds": {
"placeholders": { "placeholders": {
...@@ -1154,29 +1268,29 @@ void main() { ...@@ -1154,29 +1268,29 @@ void main() {
} }
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(pluralMessageWithDateTimePlaceholder); .writeAsStringSync(pluralMessageWithDateTimePlaceholder);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on Exception catch (e) { } on Exception catch (e) {
fail('Parsing template arb file should succeed: \n$e'); fail('Parsing template arb file should succeed: \n$e');
} }
expect(generator.classMethods, isNotEmpty); expect(generator.classMethods, isNotEmpty);
expect( expect(
generator.classMethods.first, generator.classMethods.first,
''' String helloWorlds(int count, Object population) { ''' String helloWorlds(int count, Object population) {
final NumberFormat populationNumberFormat = NumberFormat.compactLong( final NumberFormat populationNumberFormat = NumberFormat.compactLong(
locale: _localeName, locale: _localeName,
); );
...@@ -1194,66 +1308,10 @@ void main() { ...@@ -1194,66 +1308,10 @@ void main() {
); );
} }
''' '''
);
});
test('correctly adds optional parameters to numbers:', () {
const String singleNumberMessage = '''{
"courseCompletion": "You have completed {progress} of the course.",
"@courseCompletion": {
"description": "The amount of progress the student has made in their class.",
"placeholders": {
"progress": {
"type": "Number",
"format": "decimalPercentPattern",
"optionalParameters": {
"decimalDigits": 2
}
}
}
}
}''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(singleNumberMessage);
final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try {
generator.initialize(
l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); });
generator.generateClassMethods();
} on Exception catch (e) {
fail('Parsing template arb file should succeed: \n$e');
}
expect(generator.classMethods, isNotEmpty);
expect(
generator.classMethods.first,
''' String courseCompletion(Object progress) {
final NumberFormat progressNumberFormat = NumberFormat.decimalPercentPattern(
locale: _localeName,
decimalDigits: 2,
);
final String progressString = progressNumberFormat.format(progress);
return Intl.message(
r'You have completed \$progressString of the course.',
locale: _localeName,
name: 'courseCompletion',
desc: r'The amount of progress the student has made in their class.',
args: <Object>[progressString]
);
}
''');
});
test('should throw attempting to generate a plural message without placeholders:', () { test('should throw attempting to generate a plural message without placeholders', () {
const String pluralMessageWithoutPlaceholdersAttribute = '''{ const String pluralMessageWithoutPlaceholdersAttribute = '''{
"helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}", "helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}",
"@helloWorlds": { "@helloWorlds": {
...@@ -1261,30 +1319,30 @@ void main() { ...@@ -1261,30 +1319,30 @@ void main() {
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(pluralMessageWithoutPlaceholdersAttribute); .writeAsStringSync(pluralMessageWithoutPlaceholdersAttribute);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on L10nException catch (e) { } on L10nException catch (e) {
expect(e.message, contains('Check to see if the plural message is in the proper ICU syntax format')); expect(e.message, contains('Check to see if the plural message is in the proper ICU syntax format'));
return; return;
} }
fail('Generating class methods without placeholders should not succeed'); fail('Generating class methods without placeholders should not succeed');
}); });
test('should throw attempting to generate a plural message with empty placeholders map:', () { test('should throw attempting to generate a plural message with an empty placeholders map', () {
const String pluralMessageWithEmptyPlaceholdersMap = '''{ const String pluralMessageWithEmptyPlaceholdersMap = '''{
"helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}", "helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}",
"@helloWorlds": { "@helloWorlds": {
"description": "Improperly formatted since it has no placeholder attribute.", "description": "Improperly formatted since it has no placeholder attribute.",
...@@ -1292,88 +1350,89 @@ void main() { ...@@ -1292,88 +1350,89 @@ void main() {
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(pluralMessageWithEmptyPlaceholdersMap); .writeAsStringSync(pluralMessageWithEmptyPlaceholdersMap);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on L10nException catch (e) { } on L10nException catch (e) {
expect(e.message, contains('Check to see if the plural message is in the proper ICU syntax format')); expect(e.message, contains('Check to see if the plural message is in the proper ICU syntax format'));
return; return;
} }
fail('Generating class methods without placeholders should not succeed'); fail('Generating class methods without placeholders should not succeed');
}); });
test('should throw attempting to generate a plural message with no resource attributes:', () { test('should throw attempting to generate a plural message with no resource attributes', () {
const String pluralMessageWithoutResourceAttributes = '''{ const String pluralMessageWithoutResourceAttributes = '''{
"helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}" "helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}"
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(pluralMessageWithoutResourceAttributes); .writeAsStringSync(pluralMessageWithoutResourceAttributes);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on L10nException catch (e) { } on L10nException catch (e) {
expect(e.message, contains('Resource attribute')); expect(e.message, contains('Resource attribute'));
expect(e.message, contains('does not exist')); expect(e.message, contains('does not exist'));
return; return;
} }
fail('Generating plural class method without resource attributes should not succeed'); fail('Generating plural class method without resource attributes should not succeed');
}); });
test('should throw attempting to generate a plural message with incorrect placeholders format:', () { test('should throw attempting to generate a plural message with incorrect format for placeholders', () {
const String pluralMessageWithIncorrectPlaceholderFormat = '''{ const String pluralMessageWithIncorrectPlaceholderFormat = '''{
"helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}", "helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}",
"@helloWorlds": { "@helloWorlds": {
"placeholders": "Incorrectly a string, should be a map." "placeholders": "Incorrectly a string, should be a map."
} }
}'''; }''';
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true); ..createSync(recursive: true);
l10nDirectory.childFile(defaultTemplateArbFileName) l10nDirectory.childFile(defaultTemplateArbFileName)
.writeAsStringSync(pluralMessageWithIncorrectPlaceholderFormat); .writeAsStringSync(pluralMessageWithIncorrectPlaceholderFormat);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
l10nDirectoryPath: defaultArbPathString, l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
); );
generator.parseArbFiles(); generator.parseArbFiles();
generator.generateClassMethods(); generator.generateClassMethods();
} on L10nException catch (e) { } on L10nException catch (e) {
expect(e.message, contains('is not properly formatted')); expect(e.message, contains('is not properly formatted'));
expect(e.message, contains('Ensure that it is a map with keys that are strings')); expect(e.message, contains('Ensure that it is a map with keys that are strings'));
return; return;
} }
fail('Generating class methods with incorrect placeholder format should not succeed'); fail('Generating class methods with incorrect placeholder format should not succeed');
});
}); });
test('should throw when failing to parse the arb file:', () { test('should throw when failing to parse the arb file', () {
const String arbFileWithTrailingComma = '''{ const String arbFileWithTrailingComma = '''{
"title": "Stocks", "title": "Stocks",
"@title": { "@title": {
...@@ -1406,7 +1465,7 @@ void main() { ...@@ -1406,7 +1465,7 @@ void main() {
); );
}); });
test('should throw when resource is missing resource attribute:', () { test('should throw when resource is missing resource attribute', () {
const String arbFileWithMissingResourceAttribute = '''{ const String arbFileWithMissingResourceAttribute = '''{
"title": "Stocks" "title": "Stocks"
}'''; }''';
...@@ -1529,8 +1588,8 @@ void main() { ...@@ -1529,8 +1588,8 @@ void main() {
}); });
}); });
group('LocalizationsGenerator.generateOutputFile:', () { group('generateOutputFile', () {
test('correctly generates the localizations classes:', () { test('correctly generates the localizations classes', () {
_standardFlutterDirectoryL10nSetup(fs); _standardFlutterDirectoryL10nSetup(fs);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment