| // 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 'package:file/file.dart'; |
| |
| import '../test_utils.dart'; |
| import 'project.dart'; |
| |
| class GenL10nProject extends Project { |
| @override |
| Future<void> setUpIn(Directory dir, { |
| bool useDeferredLoading = false, |
| bool useSyntheticPackage = false, |
| }) { |
| this.dir = dir; |
| writeFile(fileSystem.path.join(dir.path, 'lib', 'l10n', 'app_en.arb'), appEn); |
| writeFile(fileSystem.path.join(dir.path, 'lib', 'l10n', 'app_en_CA.arb'), appEnCa); |
| writeFile(fileSystem.path.join(dir.path, 'lib', 'l10n', 'app_en_GB.arb'), appEnGb); |
| writeFile(fileSystem.path.join(dir.path, 'lib', 'l10n', 'app_es.arb'), appEs); |
| writeFile(fileSystem.path.join(dir.path, 'lib', 'l10n', 'app_es_419.arb'), appEs419); |
| writeFile(fileSystem.path.join(dir.path, 'lib', 'l10n', 'app_zh.arb'), appZh); |
| writeFile(fileSystem.path.join(dir.path, 'lib', 'l10n', 'app_zh_Hant.arb'), appZhHant); |
| writeFile(fileSystem.path.join(dir.path, 'lib', 'l10n', 'app_zh_Hans.arb'), appZhHans); |
| writeFile(fileSystem.path.join(dir.path, 'lib', 'l10n', 'app_zh_Hant_TW.arb'), appZhHantTw); |
| writeFile(fileSystem.path.join(dir.path, 'l10n.yaml'), l10nYaml( |
| useDeferredLoading: useDeferredLoading, |
| useSyntheticPackage: useSyntheticPackage, |
| )); |
| return super.setUpIn(dir); |
| } |
| |
| @override |
| final String pubspec = ''' |
| name: test_l10n_project |
| environment: |
| sdk: ">=2.12.0-0 <3.0.0" |
| |
| dependencies: |
| flutter: |
| sdk: flutter |
| flutter_localizations: |
| sdk: flutter |
| intl: any # Pick up the pinned version from flutter_localizations |
| '''; |
| |
| @override |
| final String main = r''' |
| import 'package:flutter/material.dart'; |
| |
| import 'l10n/app_localizations.dart'; |
| |
| class LocaleBuilder extends StatelessWidget { |
| const LocaleBuilder({ |
| Key? key, |
| this.locale, |
| this.test, |
| required this.callback, |
| }) : super(key: key); |
| |
| final Locale? locale; |
| final String? test; |
| final void Function (BuildContext context) callback; |
| |
| @override build(BuildContext context) { |
| return Localizations.override( |
| locale: locale, |
| context: context, |
| child: ResultBuilder( |
| test: test, |
| callback: callback, |
| ), |
| ); |
| } |
| } |
| |
| class ResultBuilder extends StatelessWidget { |
| const ResultBuilder({ |
| Key? key, |
| this.test, |
| required this.callback, |
| }) : super(key: key); |
| |
| final String? test; |
| final void Function (BuildContext context) callback; |
| |
| @override build(BuildContext context) { |
| return Builder( |
| builder: (BuildContext context) { |
| try { |
| callback(context); |
| } on Exception catch (e) { |
| print('#l10n A(n) $e has occurred trying to generate "$test" results.'); |
| print('#l10n END'); |
| } |
| return Container(); |
| }, |
| ); |
| } |
| } |
| |
| class Home extends StatelessWidget { |
| @override |
| Widget build(BuildContext context) { |
| final List<String> results = []; |
| return Row( |
| children: <Widget>[ |
| LocaleBuilder( |
| test: 'supportedLocales', |
| callback: (BuildContext context) { |
| results.add('--- supportedLocales tests ---'); |
| int n = 0; |
| for (Locale locale in AppLocalizations.supportedLocales) { |
| String languageCode = locale.languageCode; |
| String? countryCode = locale.countryCode; |
| String? scriptCode = locale.scriptCode; |
| results.add('supportedLocales[$n]: languageCode: $languageCode, countryCode: $countryCode, scriptCode: $scriptCode'); |
| n += 1; |
| } |
| }, |
| ), |
| LocaleBuilder( |
| locale: Locale('en', 'CA'), |
| test: 'countryCode - en_CA', |
| callback: (BuildContext context) { |
| results.add('--- countryCode (en_CA) tests ---'); |
| results.add(AppLocalizations.of(context)!.helloWorld); |
| results.add(AppLocalizations.of(context)!.hello("CA fallback World")); |
| }, |
| ), |
| LocaleBuilder( |
| locale: Locale('en', 'GB'), |
| test: 'countryCode - en_GB', |
| callback: (BuildContext context) { |
| results.add('--- countryCode (en_GB) tests ---'); |
| results.add(AppLocalizations.of(context)!.helloWorld); |
| results.add(AppLocalizations.of(context)!.hello("GB fallback World")); |
| }, |
| ), |
| LocaleBuilder( |
| locale: Locale('zh'), |
| test: 'zh', |
| callback: (BuildContext context) { |
| results.add('--- zh ---'); |
| results.add(AppLocalizations.of(context)!.helloWorld); |
| results.add(AppLocalizations.of(context)!.helloWorlds(0)); |
| results.add(AppLocalizations.of(context)!.helloWorlds(1)); |
| results.add(AppLocalizations.of(context)!.helloWorlds(2)); |
| // Should use the fallback language, in this case, |
| // "Hello 世界" should be displayed. |
| results.add(AppLocalizations.of(context)!.hello("世界")); |
| // helloCost is tested in 'zh' because 'es' currency format contains a |
| // non-breaking space character (U+00A0), which if removed, |
| // makes it hard to decipher why the test is failing. |
| results.add(AppLocalizations.of(context)!.helloCost("价钱", 123)); |
| }, |
| ), |
| LocaleBuilder( |
| locale: Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans'), |
| test: 'zh', |
| callback: (BuildContext context) { |
| results.add('--- scriptCode: zh_Hans ---'); |
| results.add(AppLocalizations.of(context)!.helloWorld); |
| }, |
| ), |
| LocaleBuilder( |
| locale: Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant'), |
| test: 'scriptCode - zh_Hant', |
| callback: (BuildContext context) { |
| results.add('--- scriptCode - zh_Hant ---'); |
| results.add(AppLocalizations.of(context)!.helloWorld); |
| }, |
| ), |
| LocaleBuilder( |
| locale: Locale.fromSubtags(languageCode: 'zh', countryCode: 'TW', scriptCode: 'Hant'), |
| test: 'scriptCode - zh_TW_Hant', |
| callback: (BuildContext context) { |
| results.add('--- scriptCode - zh_Hant_TW ---'); |
| results.add(AppLocalizations.of(context)!.helloWorld); |
| }, |
| ), |
| LocaleBuilder( |
| locale: Locale('en'), |
| test: 'General formatting', |
| callback: (BuildContext context) { |
| results.add('--- General formatting tests ---'); |
| final AppLocalizations localizations = AppLocalizations.of(context)!; |
| results.addAll(<String>[ |
| '${localizations.helloWorld}', |
| '${localizations.helloNewlineWorld}', |
| '${localizations.testDollarSign}', |
| '${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.helloCostWithOptionalParam("price", .5)}', |
| '${localizations.helloCostWithSpecialCharacter1("price", .5)}', |
| '${localizations.helloCostWithSpecialCharacter2("price", .5)}', |
| '${localizations.helloCostWithSpecialCharacter3("price", .5)}', |
| '${localizations.helloDecimalPattern(1200000)}', |
| '${localizations.helloPercentPattern(1200000)}', |
| '${localizations.helloScientificPattern(1200000)}', |
| '${localizations.helloWorlds(0)}', |
| '${localizations.helloWorlds(1)}', |
| '${localizations.helloWorlds(2)}', |
| '${localizations.helloAdjectiveWorlds(0, "new")}', |
| '${localizations.helloAdjectiveWorlds(1, "new")}', |
| '${localizations.helloAdjectiveWorlds(2, "new")}', |
| '${localizations.helloWorldsOn(0, DateTime(1960))}', |
| '${localizations.helloWorldsOn(1, DateTime(1960))}', |
| '${localizations.helloWorldsOn(2, DateTime(1960))}', |
| '${localizations.helloWorldPopulation(0, 100)}', |
| '${localizations.helloWorldPopulation(1, 101)}', |
| '${localizations.helloWorldPopulation(2, 102)}', |
| '${localizations.helloWorldsInterpolation(123, "Hello", "World")}', |
| '${localizations.dollarSign}', |
| '${localizations.dollarSignPlural(1)}', |
| '${localizations.singleQuote}', |
| '${localizations.singleQuotePlural(2)}', |
| '${localizations.doubleQuote}', |
| '${localizations.doubleQuotePlural(2)}', |
| "${localizations.vehicleSelect('truck')}", |
| "${localizations.singleQuoteSelect('sedan')}", |
| "${localizations.doubleQuoteSelect('cabriolet')}", |
| "${localizations.pluralInString(1)}", |
| "${localizations.selectInString('he')}", |
| "${localizations.selectWithPlaceholder('male', 'ice cream')}", |
| "${localizations.selectWithPlaceholder('female', 'chocolate')}", |
| ]); |
| }, |
| ), |
| LocaleBuilder( |
| locale: Locale('es'), |
| test: '--- es ---', |
| callback: (BuildContext context) { |
| results.add('--- es ---'); |
| final AppLocalizations localizations = AppLocalizations.of(context)!; |
| results.addAll(<String>[ |
| '${localizations.helloWorld}', |
| '${localizations.helloNewlineWorld}', |
| '${localizations.testDollarSign}', |
| '${localizations.hello("Mundo")}', |
| '${localizations.greeting("Hola", "Mundo")}', |
| '${localizations.helloWorldOn(DateTime(1960))}', |
| '${localizations.helloOn("world argument", DateTime(1960), DateTime(1960))}', |
| '${localizations.helloWorldDuring(DateTime(1960), DateTime(2020))}', |
| '${localizations.helloFor(123)}', |
| // helloCost is tested in 'zh' because 'es' currency format contains a |
| // non-breaking space character (U+00A0), which if removed, |
| // makes it hard to decipher why the test is failing. |
| '${localizations.helloWorlds(0)}', |
| '${localizations.helloWorlds(1)}', |
| '${localizations.helloWorlds(2)}', |
| '${localizations.helloAdjectiveWorlds(0, "nuevo")}', |
| '${localizations.helloAdjectiveWorlds(1, "nuevo")}', |
| '${localizations.helloAdjectiveWorlds(2, "nuevo")}', |
| '${localizations.helloWorldsOn(0, DateTime(1960))}', |
| '${localizations.helloWorldsOn(1, DateTime(1960))}', |
| '${localizations.helloWorldsOn(2, DateTime(1960))}', |
| '${localizations.helloWorldPopulation(0, 100)}', |
| '${localizations.helloWorldPopulation(1, 101)}', |
| '${localizations.helloWorldPopulation(2, 102)}', |
| '${localizations.helloWorldsInterpolation(123, "Hola", "Mundo")}', |
| '${localizations.dollarSign}', |
| '${localizations.dollarSignPlural(1)}', |
| '${localizations.singleQuote}', |
| '${localizations.singleQuotePlural(2)}', |
| '${localizations.doubleQuote}', |
| '${localizations.doubleQuotePlural(2)}', |
| "${localizations.vehicleSelect('truck')}", |
| "${localizations.singleQuoteSelect('sedan')}", |
| "${localizations.doubleQuoteSelect('cabriolet')}", |
| "${localizations.pluralInString(1)}", |
| "${localizations.selectInString('he')}", |
| ]); |
| }, |
| ), |
| LocaleBuilder( |
| locale: Locale.fromSubtags(languageCode: 'es', countryCode: '419'), |
| test: 'countryCode - es_419', |
| callback: (BuildContext context) { |
| results.add('--- es_419 ---'); |
| final AppLocalizations localizations = AppLocalizations.of(context)!; |
| results.addAll([ |
| '${localizations.helloWorld}', |
| '${localizations.helloWorlds(0)}', |
| '${localizations.helloWorlds(1)}', |
| '${localizations.helloWorlds(2)}', |
| ]); |
| }, |
| ), |
| LocaleBuilder( |
| callback: (BuildContext context) { |
| try { |
| int n = 0; |
| for (final String result in results) { |
| // Newline character replacement is necessary because |
| // the stream breaks up stdout by new lines. |
| print('#l10n $n (${result.replaceAll('\n', '_NEWLINE_')})'); |
| n += 1; |
| } |
| } |
| finally { |
| print('#l10n END'); |
| } |
| }, |
| ), |
| ], |
| ); |
| } |
| } |
| |
| 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" |
| }, |
| |
| "helloNewlineWorld": "Hello \n World", |
| "@helloNewlineWorld": { |
| "description": "The JSON decoder should convert backslash-n to a newline character in the generated Dart string." |
| }, |
| |
| "testDollarSign": "Hello $ World", |
| "@testDollarSign": { |
| "description": "The generated Dart String should handle the dollar sign correctly." |
| }, |
| |
| "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" |
| } |
| } |
| }, |
| |
| "helloCostWithOptionalParam": "Hello for {price} {value} (with optional param)", |
| "@helloCostWithOptionalParam": { |
| "description": "A message with string and int (currency) parameters", |
| "placeholders": { |
| "price": {}, |
| "value": { |
| "type": "double", |
| "format": "currency", |
| "optionalParameters": { |
| "name": "BTC" |
| } |
| } |
| } |
| }, |
| |
| "helloCostWithSpecialCharacter1": "Hello for {price} {value} (with special character)", |
| "@helloCostWithSpecialCharacter1": { |
| "description": "A message with string and int (currency) parameters", |
| "placeholders": { |
| "price": {}, |
| "value": { |
| "type": "double", |
| "format": "currency", |
| "optionalParameters": { |
| "name": "BTC'" |
| } |
| } |
| } |
| }, |
| |
| "helloCostWithSpecialCharacter2": "Hello for {price} {value} (with special character)", |
| "@helloCostWithSpecialCharacter2": { |
| "description": "A message with string and int (currency) parameters", |
| "placeholders": { |
| "price": {}, |
| "value": { |
| "type": "double", |
| "format": "currency", |
| "optionalParameters": { |
| "name": "BTC\"" |
| } |
| } |
| } |
| }, |
| |
| "helloCostWithSpecialCharacter3": "Hello for {price} {value} (with special character)", |
| "@helloCostWithSpecialCharacter3": { |
| "description": "A message with string and int (currency) parameters", |
| "placeholders": { |
| "price": {}, |
| "value": { |
| "type": "double", |
| "format": "currency", |
| "optionalParameters": { |
| "name": "BTC\"'" |
| } |
| } |
| } |
| }, |
| |
| "helloDecimalPattern": "Hello for Decimal Pattern {value}", |
| "@helloDecimalPattern": { |
| "description": "A message which displays a number in decimal pattern", |
| "placeholders": { |
| "value": { |
| "type": "double", |
| "format": "decimalPattern" |
| } |
| } |
| }, |
| |
| "helloPercentPattern": "Hello for Percent Pattern {value}", |
| "@helloPercentPattern": { |
| "description": "A message which displays a number in percent pattern", |
| "placeholders": { |
| "value": { |
| "type": "double", |
| "format": "percentPattern" |
| } |
| } |
| }, |
| |
| "helloScientificPattern": "Hello for Scientific Pattern {value}", |
| "@helloScientificPattern": { |
| "description": "A message which displays scientific notation of a number", |
| "placeholders": { |
| "value": { |
| "type": "double", |
| "format": "scientificPattern" |
| } |
| } |
| }, |
| |
| "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": {} |
| } |
| }, |
| |
| "dollarSign": "$!", |
| "@dollarSign": { |
| "description": "A message with a dollar sign." |
| }, |
| |
| "dollarSignPlural": "{count,plural, =1{One $} other{Many $}}", |
| "@dollarSignPlural": { |
| "description": "A plural message with a dollar sign.", |
| "placeholders": { |
| "count": {} |
| } |
| }, |
| |
| "singleQuote": "Flutter's amazing!", |
| "@singleQuote": { |
| "description": "A message with a single quote." |
| }, |
| |
| "singleQuotePlural": "{count,plural, =1{Flutter's amazing, times 1!} other{Flutter's amazing, times {count}!}}", |
| "@singleQuotePlural": { |
| "description": "A plural message with a single quote.", |
| "placeholders": { |
| "count": {} |
| } |
| }, |
| |
| "doubleQuote": "Flutter is \"amazing\"!", |
| "@doubleQuote": { |
| "description": "A message with double quotes." |
| }, |
| |
| "doubleQuotePlural": "{count,plural, =1{Flutter is \"amazing\", times 1!} other{Flutter is \"amazing\", times {count}!}}", |
| "@doubleQuotePlural": { |
| "description": "A plural message with double quotes.", |
| "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": {} |
| } |
| }, |
| |
| "selectWithPlaceholder": "Indeed, {gender, select, male {he likes {preference}} female {she likes {preference}} other {they like {preference}}}!", |
| "@selectWithPlaceholder": { |
| "description": "A select message with prefix, suffix strings, and a placeholder.", |
| "placeholders": { |
| "gender": {}, |
| "preference": {} |
| } |
| } |
| } |
| '''; |
| |
| final String appEnCa = r''' |
| { |
| "@@locale": "en_CA", |
| "helloWorld": "CA Hello World" |
| } |
| '''; |
| |
| final String appEnGb = r''' |
| { |
| "@@locale": "en_GB", |
| "helloWorld": "GB Hello World" |
| } |
| '''; |
| |
| /// All messages are simply the template language's message with 'ES - ' |
| /// appended. This makes validating test behavior easier. The interpolated |
| /// messages are different where applicable. |
| final String appEs = r''' |
| { |
| "@@locale": "es", |
| "helloWorld": "ES - Hello world", |
| "helloWorlds": "{count,plural, =0{ES - Hello} =1{ES - Hello World} =2{ES - Hello two worlds} few{ES - Hello {count} worlds} many{ES - Hello all {count} worlds} other{ES - Hello other {count} worlds}}", |
| "helloNewlineWorld": "ES - Hello \n World", |
| "testDollarSign": "ES - Hola $ Mundo", |
| "hello": "ES - Hello {world}", |
| "greeting": "ES - {hello} {world}", |
| "helloWorldOn": "ES - Hello World on {date}", |
| "helloWorldDuring": "ES - Hello World from {startDate} to {endDate}", |
| "helloOn": "ES - Hello {world} on {date} at {time}", |
| "helloFor": "ES - Hello for {value}", |
| "helloAdjectiveWorlds": "{count,plural, =0{ES - Hello} =1{ES - Hello {adjective} World} =2{ES - Hello two {adjective} worlds} other{ES - Hello other {count} {adjective} worlds}}", |
| "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": "{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}!}}", |
| "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!" |
| } |
| '''; |
| |
| final String appEs419 = r''' |
| { |
| "@@locale": "es_419", |
| "helloWorld": "ES 419 - Hello World", |
| "helloWorlds": "{count,plural, =0{ES 419 - Hello} =1{ES 419 - Hello World} =2{ES 419 - Hello two worlds} few{ES 419 - Hello {count} worlds} many{ES 419 - Hello all {count} worlds} other{ES - Hello other {count} worlds}}" |
| } |
| '''; |
| |
| final String appZh = r''' |
| { |
| "@@locale": "zh", |
| "helloWorld": "你好世界", |
| "helloWorlds": "{count,plural, =0{你好} =1{你好世界} other{你好{count}个其他世界}}", |
| "helloCost": "zh - Hello for {price} {value}" |
| } |
| '''; |
| |
| final String appZhHans = r''' |
| { |
| "@@locale": "zh_Hans", |
| "helloWorld": "简体你好世界" |
| } |
| '''; |
| |
| final String appZhHant = r''' |
| { |
| "@@locale": "zh_Hant", |
| "helloWorld": "繁體你好世界" |
| } |
| '''; |
| |
| final String appZhHantTw = r''' |
| { |
| "@@locale": "zh_Hant_TW", |
| "helloWorld": "台灣繁體你好世界" |
| } |
| '''; |
| |
| String l10nYaml({ |
| required bool useDeferredLoading, |
| required bool useSyntheticPackage, |
| }) { |
| String l10nYamlString = ''; |
| |
| if (useDeferredLoading) { |
| l10nYamlString += 'use-deferred-loading: true\n'; |
| } |
| |
| if (!useSyntheticPackage) { |
| l10nYamlString += 'synthetic-package: false\n'; |
| } |
| |
| return l10nYamlString; |
| } |
| } |