Integration test for the gen_l10n tool (#49586)
This commit is contained in:
parent
dbaa4c2374
commit
3f2c6ea724
@ -63,6 +63,9 @@ Future<void> main(List<String> arguments) async {
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String flutterRoot = Platform.environment['FLUTTER_ROOT'];
|
||||||
|
final String flutterBin = Platform.isWindows ? 'flutter.bat' : 'flutter';
|
||||||
|
final String flutterPath = flutterRoot == null ? flutterBin : path.join(flutterRoot, 'bin', flutterBin);
|
||||||
final String arbPathString = results['arb-dir'] as String;
|
final String arbPathString = results['arb-dir'] as String;
|
||||||
final String outputFileString = results['output-localization-file'] as String;
|
final String outputFileString = results['output-localization-file'] as String;
|
||||||
final String templateArbFileName = results['template-arb-file'] as String;
|
final String templateArbFileName = results['template-arb-file'] as String;
|
||||||
@ -91,13 +94,13 @@ Future<void> main(List<String> arguments) async {
|
|||||||
exitWithError(e.message);
|
exitWithError(e.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ProcessResult pubGetResult = await Process.run('flutter', <String>['pub', 'get']);
|
final ProcessResult pubGetResult = await Process.run(flutterPath, <String>['pub', 'get']);
|
||||||
if (pubGetResult.exitCode != 0) {
|
if (pubGetResult.exitCode != 0) {
|
||||||
stderr.write(pubGetResult.stderr);
|
stderr.write(pubGetResult.stderr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ProcessResult generateFromArbResult = await Process.run('flutter', <String>[
|
final ProcessResult generateFromArbResult = await Process.run(flutterPath, <String>[
|
||||||
'pub',
|
'pub',
|
||||||
'run',
|
'run',
|
||||||
'intl_translation:generate_from_arb',
|
'intl_translation:generate_from_arb',
|
||||||
|
@ -223,7 +223,7 @@ String genSimpleMethod(Message message) {
|
|||||||
String genSimpleMethodMessage() {
|
String genSimpleMethodMessage() {
|
||||||
String messageValue = message.value;
|
String messageValue = message.value;
|
||||||
for (final Placeholder placeholder in message.placeholders) {
|
for (final Placeholder placeholder in message.placeholders) {
|
||||||
messageValue = messageValue.replaceAll('{${placeholder.name}}', '\$${placeholder.name}');
|
messageValue = messageValue.replaceAll('{${placeholder.name}}', '\${${placeholder.name}}');
|
||||||
}
|
}
|
||||||
final String rawMessage = generateString(messageValue); // "r'...'"
|
final String rawMessage = generateString(messageValue); // "r'...'"
|
||||||
return rawMessage.substring(1);
|
return rawMessage.substring(1);
|
||||||
@ -300,9 +300,9 @@ String generatePluralMethod(Message message) {
|
|||||||
String argValue = match.group(2);
|
String argValue = match.group(2);
|
||||||
for (final Placeholder placeholder in message.placeholders) {
|
for (final Placeholder placeholder in message.placeholders) {
|
||||||
if (placeholder.requiresFormatting) {
|
if (placeholder.requiresFormatting) {
|
||||||
argValue = argValue.replaceAll('#${placeholder.name}#', '\$${placeholder.name}String');
|
argValue = argValue.replaceAll('#${placeholder.name}#', '\${${placeholder.name}String}');
|
||||||
} else {
|
} else {
|
||||||
argValue = argValue.replaceAll('#${placeholder.name}#', '\$${placeholder.name}');
|
argValue = argValue.replaceAll('#${placeholder.name}#', '\${${placeholder.name}}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
intlMethodArgs.add("${pluralIds[pluralKey]}: '$argValue'");
|
intlMethodArgs.add("${pluralIds[pluralKey]}: '$argValue'");
|
||||||
|
@ -113,8 +113,11 @@ import 'messages_all.dart';
|
|||||||
/// Select and expand the newly-created Localizations item then, for each
|
/// Select and expand the newly-created Localizations item then, for each
|
||||||
/// locale your application supports, add a new item and select the locale
|
/// locale your application supports, add a new item and select the locale
|
||||||
/// you wish to add from the pop-up menu in the Value field. This list should
|
/// you wish to add from the pop-up menu in the Value field. This list should
|
||||||
/// be consistent with the languages listed in the @className.supportedLocales
|
/// be consistent with the languages listed in the @(className).supportedLocales
|
||||||
/// property.
|
/// property.
|
||||||
|
|
||||||
|
// ignore_for_file: unnecessary_brace_in_string_interps
|
||||||
|
|
||||||
class @(className) {
|
class @(className) {
|
||||||
@(className)(Locale locale) : _localeName = Intl.canonicalizedLocale(locale.toString());
|
@(className)(Locale locale) : _localeName = Intl.canonicalizedLocale(locale.toString());
|
||||||
|
|
||||||
@ -129,7 +132,7 @@ class @(className) {
|
|||||||
return Localizations.of<@(className)>(context, @(className));
|
return Localizations.of<@(className)>(context, @(className));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const LocalizationsDelegate<@(className)> delegate = _@(classNameDelegate)();
|
static const LocalizationsDelegate<@(className)> delegate = _@(className)Delegate();
|
||||||
|
|
||||||
/// A list of this localizations delegate along with the default localizations
|
/// A list of this localizations delegate along with the default localizations
|
||||||
/// delegates.
|
/// delegates.
|
||||||
|
@ -657,7 +657,7 @@ void main() {
|
|||||||
generator.classMethods.first,
|
generator.classMethods.first,
|
||||||
''' String itemNumber(Object value) {
|
''' String itemNumber(Object value) {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
\'Item \$value\',
|
\'Item \${value}\',
|
||||||
locale: _localeName,
|
locale: _localeName,
|
||||||
name: 'itemNumber',
|
name: 'itemNumber',
|
||||||
desc: r\'Item placement in list.\',
|
desc: r\'Item placement in list.\',
|
||||||
@ -710,7 +710,7 @@ void main() {
|
|||||||
|
|
||||||
String springBegins(Object springStartDate) {
|
String springBegins(Object springStartDate) {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
\'Spring begins on \$springStartDate\',
|
\'Spring begins on \${springStartDate}\',
|
||||||
locale: _localeName,
|
locale: _localeName,
|
||||||
name: \'springBegins\',
|
name: \'springBegins\',
|
||||||
desc: r\'The first day of spring\',
|
desc: r\'The first day of spring\',
|
||||||
@ -837,7 +837,7 @@ void main() {
|
|||||||
|
|
||||||
String springGreetings(Object springStartDate, Object helloWorld) {
|
String springGreetings(Object springStartDate, Object helloWorld) {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
\'Since it\' "\'" r\'s \$springStartDate, it\' "\'" r\'s finally spring! \$helloWorld!\',
|
\'Since it\' "\'" r\'s \${springStartDate}, it\' "\'" r\'s finally spring! \${helloWorld}!\',
|
||||||
locale: _localeName,
|
locale: _localeName,
|
||||||
name: \'springGreetings\',
|
name: \'springGreetings\',
|
||||||
desc: r\'A realization that it\' "\'" r\'s finally the spring season, followed by a greeting.\',
|
desc: r\'A realization that it\' "\'" r\'s finally the spring season, followed by a greeting.\',
|
||||||
@ -897,7 +897,7 @@ void main() {
|
|||||||
|
|
||||||
String springRange(Object springStartDate, Object springEndDate) {
|
String springRange(Object springStartDate, Object springEndDate) {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
\'Spring begins on \$springStartDate and ends on \$springEndDate\',
|
\'Spring begins on \${springStartDate} and ends on \${springEndDate}\',
|
||||||
locale: _localeName,
|
locale: _localeName,
|
||||||
name: \'springRange\',
|
name: \'springRange\',
|
||||||
desc: r\'The range of dates for spring in the year\',
|
desc: r\'The range of dates for spring in the year\',
|
||||||
@ -954,10 +954,10 @@ void main() {
|
|||||||
locale: _localeName,
|
locale: _localeName,
|
||||||
name: \'helloWorlds\',
|
name: \'helloWorlds\',
|
||||||
args: <Object>[count, currentDate],
|
args: <Object>[count, currentDate],
|
||||||
one: \'Hello World, today is \$currentDateString\',
|
one: \'Hello World, today is \${currentDateString}\',
|
||||||
two: \'Hello two worlds, today is \$currentDateString\',
|
two: \'Hello two worlds, today is \${currentDateString}\',
|
||||||
many: \'Hello all \$count worlds, today is \$currentDateString\',
|
many: \'Hello all \${count} worlds, today is \${currentDateString}\',
|
||||||
other: \'Hello other \$count worlds, today is \$currentDateString\'
|
other: \'Hello other \${count} worlds, today is \${currentDateString}\'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return helloWorlds(count, currentDateString);
|
return helloWorlds(count, currentDateString);
|
||||||
@ -1009,7 +1009,7 @@ void main() {
|
|||||||
|
|
||||||
String courseCompletion(Object progress) {
|
String courseCompletion(Object progress) {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
\'You have completed \$progress of the course.\',
|
\'You have completed \${progress} of the course.\',
|
||||||
locale: _localeName,
|
locale: _localeName,
|
||||||
name: \'courseCompletion\',
|
name: \'courseCompletion\',
|
||||||
desc: r\'The amount of progress the student has made in their class.\',
|
desc: r\'The amount of progress the student has made in their class.\',
|
||||||
@ -1079,7 +1079,7 @@ void main() {
|
|||||||
|
|
||||||
String courseCompletion(Object progress) {
|
String courseCompletion(Object progress) {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
\'You have completed \$progress of the course.\',
|
\'You have completed \${progress} of the course.\',
|
||||||
locale: _localeName,
|
locale: _localeName,
|
||||||
name: \'courseCompletion\',
|
name: \'courseCompletion\',
|
||||||
desc: r\'The amount of progress the student has made in their class.\',
|
desc: r\'The amount of progress the student has made in their class.\',
|
||||||
@ -1139,7 +1139,7 @@ void main() {
|
|||||||
|
|
||||||
String courseCompletion(Object progress) {
|
String courseCompletion(Object progress) {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
\'You have completed \$progress of the course.\',
|
\'You have completed \${progress} of the course.\',
|
||||||
locale: _localeName,
|
locale: _localeName,
|
||||||
name: \'courseCompletion\',
|
name: \'courseCompletion\',
|
||||||
desc: r\'The amount of progress the student has made in their class.\',
|
desc: r\'The amount of progress the student has made in their class.\',
|
||||||
@ -1232,9 +1232,9 @@ void main() {
|
|||||||
zero: 'Hello',
|
zero: 'Hello',
|
||||||
one: 'Hello World',
|
one: 'Hello World',
|
||||||
two: 'Hello two worlds',
|
two: 'Hello two worlds',
|
||||||
few: 'Hello \$count worlds',
|
few: 'Hello \${count} worlds',
|
||||||
many: 'Hello all \$count worlds',
|
many: 'Hello all \${count} worlds',
|
||||||
other: 'Hello other \$count worlds'
|
other: 'Hello other \${count} worlds'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
@ -1280,11 +1280,11 @@ void main() {
|
|||||||
name: 'helloWorlds',
|
name: 'helloWorlds',
|
||||||
args: <Object>[count, adjective],
|
args: <Object>[count, adjective],
|
||||||
zero: 'Hello',
|
zero: 'Hello',
|
||||||
one: 'Hello \$adjective World',
|
one: 'Hello \${adjective} World',
|
||||||
two: 'Hello two \$adjective worlds',
|
two: 'Hello two \${adjective} worlds',
|
||||||
few: 'Hello \$count \$adjective worlds',
|
few: 'Hello \${count} \${adjective} worlds',
|
||||||
many: 'Hello all \$count \$adjective worlds',
|
many: 'Hello all \${count} \${adjective} worlds',
|
||||||
other: 'Hello other \$count \$adjective worlds'
|
other: 'Hello other \${count} \${adjective} worlds'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
@ -1336,10 +1336,10 @@ void main() {
|
|||||||
locale: _localeName,
|
locale: _localeName,
|
||||||
name: \'helloWorlds\',
|
name: \'helloWorlds\',
|
||||||
args: <Object>[count, currentDate],
|
args: <Object>[count, currentDate],
|
||||||
one: \'Hello World, today is \$currentDateString\',
|
one: \'Hello World, today is \${currentDateString}\',
|
||||||
two: \'Hello two worlds, today is \$currentDateString\',
|
two: \'Hello two worlds, today is \${currentDateString}\',
|
||||||
many: \'Hello all \$count worlds, today is \$currentDateString\',
|
many: \'Hello all \${count} worlds, today is \${currentDateString}\',
|
||||||
other: \'Hello other \$count worlds, today is \$currentDateString\'
|
other: \'Hello other \${count} worlds, today is \${currentDateString}\'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return helloWorlds(count, currentDateString);
|
return helloWorlds(count, currentDateString);
|
||||||
@ -1395,10 +1395,10 @@ void main() {
|
|||||||
locale: _localeName,
|
locale: _localeName,
|
||||||
name: \'helloWorlds\',
|
name: \'helloWorlds\',
|
||||||
args: <Object>[count, population],
|
args: <Object>[count, population],
|
||||||
one: \'Hello World of \$populationString citizens\',
|
one: \'Hello World of \${populationString} citizens\',
|
||||||
two: \'Hello two worlds with \$populationString total citizens\',
|
two: \'Hello two worlds with \${populationString} total citizens\',
|
||||||
many: \'Hello all \$count worlds, with a total of \$populationString citizens\',
|
many: \'Hello all \${count} worlds, with a total of \${populationString} citizens\',
|
||||||
other: \'Hello other \$count worlds, with a total of \$populationString citizens\'
|
other: \'Hello other \${count} worlds, with a total of \${populationString} citizens\'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return helloWorlds(count, populationString);
|
return helloWorlds(count, populationString);
|
||||||
|
104
packages/flutter_tools/test/integration.shard/gen_l10n_test.dart
Normal file
104
packages/flutter_tools/test/integration.shard/gen_l10n_test.dart
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:file/file.dart';
|
||||||
|
import 'package:flutter_tools/src/base/file_system.dart';
|
||||||
|
import 'package:flutter_tools/src/base/io.dart';
|
||||||
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||||
|
import 'package:process/process.dart';
|
||||||
|
|
||||||
|
import '../src/common.dart';
|
||||||
|
import 'test_data/gen_l10n_project.dart';
|
||||||
|
import 'test_driver.dart';
|
||||||
|
import 'test_utils.dart';
|
||||||
|
|
||||||
|
// Verify that the code generated by gen_l10n executes correctly.
|
||||||
|
// It can fail if gen_l10n produces a lib/l10n/app_localizations.dart that:
|
||||||
|
// - Does not analyze cleanly.
|
||||||
|
// - Can't be processed by the intl_translation:generate_from_arb tool.
|
||||||
|
// The generate_from_arb step can take close to a minute on a lightly
|
||||||
|
// loaded workstation, so the test could time out on a heavily loaded bot.
|
||||||
|
void main() {
|
||||||
|
Directory tempDir;
|
||||||
|
final GenL10nProject _project = GenL10nProject();
|
||||||
|
FlutterRunTestDriver _flutter;
|
||||||
|
|
||||||
|
setUp(() async {
|
||||||
|
tempDir = createResolvedTempDirectorySync('gen_l10n_test.');
|
||||||
|
await _project.setUpIn(tempDir);
|
||||||
|
_flutter = FlutterRunTestDriver(tempDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
tearDown(() async {
|
||||||
|
await _flutter.stop();
|
||||||
|
tryToDelete(tempDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
void runCommand(List<String> command) {
|
||||||
|
final ProcessResult result = const LocalProcessManager().runSync(
|
||||||
|
command,
|
||||||
|
workingDirectory: tempDir.path,
|
||||||
|
environment: <String, String>{ 'FLUTTER_ROOT': getFlutterRoot() },
|
||||||
|
);
|
||||||
|
if (result.exitCode != 0) {
|
||||||
|
throw Exception('FAILED [${result.exitCode}]: ${command.join(' ')}\n${result.stderr}\n${result.stdout}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test('generated l10n classes produce expected localized strings', () async {
|
||||||
|
// Get the intl packages before running gen_l10n.
|
||||||
|
final String flutterBin = globals.platform.isWindows ? 'flutter.bat' : 'flutter';
|
||||||
|
final String flutterPath = globals.fs.path.join(getFlutterRoot(), 'bin', flutterBin);
|
||||||
|
runCommand(<String>[flutterPath, 'pub', 'get']);
|
||||||
|
|
||||||
|
// Generate lib/l10n/app_localizations.dart
|
||||||
|
final String genL10nPath = globals.fs.path.join(getFlutterRoot(), 'dev', 'tools', 'localization', 'bin', 'gen_l10n.dart');
|
||||||
|
final String dartBin = globals.platform.isWindows ? 'dart.exe' : 'dart';
|
||||||
|
final String dartPath = globals.fs.path.join(getFlutterRoot(), 'bin', 'cache', 'dart-sdk', 'bin', dartBin);
|
||||||
|
runCommand(<String>[dartPath, genL10nPath]);
|
||||||
|
|
||||||
|
// Run the app defined in GenL10nProject.main and wait for it to
|
||||||
|
// send '#l10n END' to its stdout.
|
||||||
|
final Completer<void> l10nEnd = Completer<void>();
|
||||||
|
final StringBuffer stdout = StringBuffer();
|
||||||
|
final StreamSubscription<String> subscription = _flutter.stdout.listen((String line) {
|
||||||
|
if (line.contains('#l10n')) {
|
||||||
|
stdout.writeln(line.substring(line.indexOf('#l10n')));
|
||||||
|
}
|
||||||
|
if (line.contains('#l10n END')) {
|
||||||
|
l10nEnd.complete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await _flutter.run();
|
||||||
|
await l10nEnd.future;
|
||||||
|
await subscription.cancel();
|
||||||
|
expect(stdout.toString(),
|
||||||
|
'#l10n 0 (Hello World)\n'
|
||||||
|
'#l10n 1 (Hello World)\n'
|
||||||
|
'#l10n 2 (Hello World)\n'
|
||||||
|
'#l10n 3 (Hello World on Friday, January 1, 1960)\n'
|
||||||
|
'#l10n 4 (Hello world argument on 1/1/1960 at 00:00)\n'
|
||||||
|
'#l10n 5 (Hello World from 1960 to 2020)\n'
|
||||||
|
'#l10n 6 (Hello for 123)\n'
|
||||||
|
'#l10n 7 (Hello for price USD123.00)\n'
|
||||||
|
'#l10n 8 (Hello)\n'
|
||||||
|
'#l10n 9 (Hello World)\n'
|
||||||
|
'#l10n 10 (Hello two worlds)\n'
|
||||||
|
'#l10n 11 (Hello on Friday, January 1, 1960)\n'
|
||||||
|
'#l10n 12 (Hello World, on Friday, January 1, 1960)\n'
|
||||||
|
'#l10n 13 (Hello two worlds, on Friday, January 1, 1960)\n'
|
||||||
|
'#l10n 14 (Hello)\n'
|
||||||
|
'#l10n 15 (Hello new World)\n'
|
||||||
|
'#l10n 16 (Hello two new worlds)\n'
|
||||||
|
'#l10n 17 (Hello other 0 worlds, with a total of 100 citizens)\n'
|
||||||
|
'#l10n 18 (Hello World of 101 citizens)\n'
|
||||||
|
'#l10n 19 (Hello two worlds with 102 total citizens)\n'
|
||||||
|
'#l10n 20 ([Hello] #World#)\n'
|
||||||
|
'#l10n 21 ([Hello] -World- #123#)\n'
|
||||||
|
'#l10n END\n'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,249 @@
|
|||||||
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:file/file.dart';
|
||||||
|
import 'package:flutter_tools/src/base/file_system.dart';
|
||||||
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||||
|
|
||||||
|
import '../test_utils.dart';
|
||||||
|
import 'project.dart';
|
||||||
|
|
||||||
|
class GenL10nProject extends Project {
|
||||||
|
@override
|
||||||
|
Future<void> setUpIn(Directory dir) {
|
||||||
|
this.dir = dir;
|
||||||
|
writeFile(globals.fs.path.join(dir.path, 'lib', 'l10n', 'app_en.arb'), appEn);
|
||||||
|
return super.setUpIn(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String pubspec = '''
|
||||||
|
name: test
|
||||||
|
environment:
|
||||||
|
sdk: ">=2.0.0-dev.68.0 <3.0.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
|
intl: 0.16.1
|
||||||
|
intl_translation: 0.17.8
|
||||||
|
''';
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String main = r'''
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
class Home extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
try {
|
||||||
|
final AppLocalizations localizations = AppLocalizations.of(context);
|
||||||
|
final List<String> results = <String>[
|
||||||
|
'${localizations.helloWorld}',
|
||||||
|
'${localizations.hello("World")}',
|
||||||
|
'${localizations.greeting("Hello", "World")}',
|
||||||
|
'${localizations.helloWorldOn(DateTime(1960))}',
|
||||||
|
'${localizations.helloOn("world argument", DateTime(1960), DateTime(1960))}',
|
||||||
|
'${localizations.helloWorldDuring(DateTime(1960), DateTime(2020))}',
|
||||||
|
'${localizations.helloFor(123)}',
|
||||||
|
'${localizations.helloCost("price", 123)}',
|
||||||
|
'${localizations.helloWorlds(0)}',
|
||||||
|
'${localizations.helloWorlds(1)}',
|
||||||
|
'${localizations.helloWorlds(2)}',
|
||||||
|
'${localizations.helloWorldsOn(0, DateTime(1960))}',
|
||||||
|
'${localizations.helloWorldsOn(1, DateTime(1960))}',
|
||||||
|
'${localizations.helloWorldsOn(2, DateTime(1960))}',
|
||||||
|
'${localizations.helloAdjectiveWorlds(0, "new")}',
|
||||||
|
'${localizations.helloAdjectiveWorlds(1, "new")}',
|
||||||
|
'${localizations.helloAdjectiveWorlds(2, "new")}',
|
||||||
|
'${localizations.helloWorldPopulation(0, 100)}',
|
||||||
|
'${localizations.helloWorldPopulation(1, 101)}',
|
||||||
|
'${localizations.helloWorldPopulation(2, 102)}',
|
||||||
|
'${localizations.helloWorldInterpolation("Hello", "World")}',
|
||||||
|
'${localizations.helloWorldsInterpolation(123, "Hello", "World")}',
|
||||||
|
];
|
||||||
|
int n = 0;
|
||||||
|
for (final String result in results) {
|
||||||
|
print('#l10n $n ($result)\n');
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
print('#l10n END\n');
|
||||||
|
}
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runApp(
|
||||||
|
MaterialApp(
|
||||||
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||||
|
supportedLocales: AppLocalizations.supportedLocales,
|
||||||
|
home: Home(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
final String appEn = r'''
|
||||||
|
{
|
||||||
|
"@@locale": "en",
|
||||||
|
|
||||||
|
"helloWorld": "Hello World",
|
||||||
|
"@helloWorld": {
|
||||||
|
"description": "The conventional newborn programmer greeting"
|
||||||
|
},
|
||||||
|
|
||||||
|
"hello": "Hello {world}",
|
||||||
|
"@hello": {
|
||||||
|
"description": "A message with a single parameter",
|
||||||
|
"placeholders": {
|
||||||
|
"world": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"greeting": "{hello} {world}",
|
||||||
|
"@greeting": {
|
||||||
|
"description": "A message with a two parameters",
|
||||||
|
"placeholders": {
|
||||||
|
"hello": {},
|
||||||
|
"world": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"helloWorldOn": "Hello World on {date}",
|
||||||
|
"@helloWorldOn": {
|
||||||
|
"description": "A message with a date parameter",
|
||||||
|
"placeholders": {
|
||||||
|
"date": {
|
||||||
|
"type": "DateTime",
|
||||||
|
"format": "yMMMMEEEEd"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"helloWorldDuring": "Hello World from {startDate} to {endDate}",
|
||||||
|
"@helloWorldDuring": {
|
||||||
|
"description": "A message with two date parameters",
|
||||||
|
"placeholders": {
|
||||||
|
"startDate": {
|
||||||
|
"type": "DateTime",
|
||||||
|
"format": "y"
|
||||||
|
},
|
||||||
|
"endDate": {
|
||||||
|
"type": "DateTime",
|
||||||
|
"format": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"helloOn": "Hello {world} on {date} at {time}",
|
||||||
|
"@helloOn": {
|
||||||
|
"description": "A message with date and string parameters",
|
||||||
|
"placeholders": {
|
||||||
|
"world": {
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"type": "DateTime",
|
||||||
|
"format": "yMd"
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"type": "DateTime",
|
||||||
|
"format": "Hm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"helloFor": "Hello for {value}",
|
||||||
|
"@helloFor": {
|
||||||
|
"description": "A message with a double parameter",
|
||||||
|
"placeholders": {
|
||||||
|
"value": {
|
||||||
|
"type": "double",
|
||||||
|
"format": "compact"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"helloCost": "Hello for {price} {value}",
|
||||||
|
"@helloCost": {
|
||||||
|
"description": "A message with string and int (currency) parameters",
|
||||||
|
"placeholders": {
|
||||||
|
"price": {
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "int",
|
||||||
|
"format": "currency"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"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": {
|
||||||
|
"description": "A plural message",
|
||||||
|
"placeholders": {
|
||||||
|
"count": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"helloAdjectiveWorlds": "{count,plural, =0{Hello} =1{Hello {adjective} World} =2{Hello two {adjective} worlds} other{Hello other {count} {adjective} worlds}}",
|
||||||
|
"@helloAdjectiveWorlds": {
|
||||||
|
"description": "A plural message with an additional parameter",
|
||||||
|
"placeholders": {
|
||||||
|
"count": {},
|
||||||
|
"adjective": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"helloWorldsOn": "{count,plural, =0{Hello on {date}} =1{Hello World, on {date}} =2{Hello two worlds, on {date}} other{Hello other {count} worlds, on {date}}}",
|
||||||
|
"@helloWorldsOn": {
|
||||||
|
"description": "A plural message with an additional date parameter",
|
||||||
|
"placeholders": {
|
||||||
|
"count": {},
|
||||||
|
"date": {
|
||||||
|
"type": "DateTime",
|
||||||
|
"format": "yMMMMEEEEd"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"helloWorldPopulation": "{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}}",
|
||||||
|
"@helloWorldPopulation": {
|
||||||
|
"description": "A plural message with an additional integer parameter",
|
||||||
|
"placeholders": {
|
||||||
|
"count": {},
|
||||||
|
"population": {
|
||||||
|
"type": "int",
|
||||||
|
"format": "compactLong"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"helloWorldInterpolation": "[{hello}] #{world}#",
|
||||||
|
"@helloWorldInterpolation": {
|
||||||
|
"description": "A message with parameters that need string interpolation braces",
|
||||||
|
"placeholders": {
|
||||||
|
"hello": {},
|
||||||
|
"world": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"helloWorldsInterpolation": "{count,plural, other {[{hello}] -{world}- #{count}#}}",
|
||||||
|
"@helloWorldsInterpolation": {
|
||||||
|
"description": "A plural message with parameters that need string interpolation braces",
|
||||||
|
"placeholders": {
|
||||||
|
"count": {},
|
||||||
|
"hello": {},
|
||||||
|
"world": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user