OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 /** |
| 6 * This is a program with various [Intl.message] messages. It just prints |
| 7 * all of them, and is used for testing of message extraction, translation, |
| 8 * and code generation. |
| 9 */ |
| 10 library sample; |
| 11 |
| 12 import "package:intl/intl.dart"; |
| 13 import "foo_messages_all.dart"; |
| 14 import "print_to_list.dart"; |
| 15 import "dart:async"; |
| 16 import "package:unittest/unittest.dart"; |
| 17 |
| 18 part 'part_of_sample_with_messages.dart'; |
| 19 |
| 20 message1() => Intl.message("This is a message", name: 'message1', desc: 'foo'); |
| 21 |
| 22 message2(x) => Intl.message("Another message with parameter $x", |
| 23 name: 'message2', desc: 'Description 2', args: [x], examples: {'x': 3}); |
| 24 |
| 25 // A string with multiple adjacent strings concatenated together, verify |
| 26 // that the parser handles this properly. |
| 27 multiLine() => Intl.message("This " |
| 28 "string " |
| 29 "extends " |
| 30 "across " |
| 31 "multiple " |
| 32 "lines.", name: "multiLine"); |
| 33 |
| 34 // Have types on the enclosing function's arguments. |
| 35 types(int a, String b, List c) => |
| 36 Intl.message("$a, $b, $c", name: 'types', args: [a, b, c]); |
| 37 |
| 38 // This string will be printed with a French locale, so it will always show |
| 39 // up in the French version, regardless of the current locale. |
| 40 alwaysTranslated() => Intl.message("This string is always translated", |
| 41 locale: 'fr', name: 'alwaysTranslated'); |
| 42 |
| 43 // Test interpolation with curly braces around the expression, but it must |
| 44 // still be just a variable reference. |
| 45 trickyInterpolation(s) => Intl.message( |
| 46 "Interpolation is tricky when it ends a sentence like ${s}.", |
| 47 name: 'trickyInterpolation', args: [s]); |
| 48 |
| 49 get leadingQuotes => Intl.message("\"So-called\"", name: 'leadingQuotes'); |
| 50 |
| 51 // A message with characters not in the basic multilingual plane. |
| 52 originalNotInBMP() => Intl.message("Ancient Greek hangman characters: 𐅆𐅇.", |
| 53 name: "originalNotInBMP"); |
| 54 |
| 55 // A string for which we don't provide all translations. |
| 56 notAlwaysTranslated() => Intl.message("This is missing some translations", |
| 57 name: "notAlwaysTranslated"); |
| 58 |
| 59 // This is invalid and should be recognized as such, because the message has |
| 60 // to be a literal. Otherwise, interpolations would be outside of the function |
| 61 // scope. |
| 62 var someString = "No, it has to be a literal string"; |
| 63 noVariables() => Intl.message(someString, name: "noVariables"); |
| 64 |
| 65 // This is unremarkable in English, but the translated versions will contain |
| 66 // characters that ought to be escaped during code generation. |
| 67 escapable() => Intl.message("Escapable characters here: ", name: "escapable"); |
| 68 |
| 69 outerPlural(n) => Intl.plural(n, |
| 70 zero: 'none', |
| 71 one: 'one', |
| 72 other: 'some', |
| 73 name: 'outerPlural', |
| 74 desc: 'A plural with no enclosing message', |
| 75 args: [n]); |
| 76 |
| 77 outerGender(g) => Intl.gender(g, |
| 78 male: 'm', |
| 79 female: 'f', |
| 80 other: 'o', |
| 81 name: 'outerGender', |
| 82 desc: 'A gender with no enclosing message', |
| 83 args: [g]); |
| 84 |
| 85 pluralThatFailsParsing(noOfThings) => Intl.plural(noOfThings, |
| 86 one: "1 thing:", |
| 87 other: "$noOfThings things:", |
| 88 name: "pluralThatFailsParsing", |
| 89 args: [noOfThings], |
| 90 desc: "How many things are there?"); |
| 91 |
| 92 // A standalone gender message where we don't provide name or args. This should |
| 93 // be rejected by validation code. |
| 94 invalidOuterGender(g) => Intl.gender(g, other: 'o'); |
| 95 |
| 96 // A general select |
| 97 outerSelect(currency, amount) => Intl.select(currency, { |
| 98 "CDN": "$amount Canadian dollars", |
| 99 "other": "$amount some currency or other." |
| 100 }, name: "outerSelect", args: [currency, amount]); |
| 101 |
| 102 // A select with a plural inside the expressions. |
| 103 nestedSelect(currency, amount) => Intl.select(currency, { |
| 104 "CDN": """${Intl.plural(amount, one: '$amount Canadian dollar', |
| 105 other: '$amount Canadian dollars')}""", |
| 106 "other": "Whatever", |
| 107 }, name: "nestedSelect", args: [currency, amount]); |
| 108 |
| 109 // A trivial nested plural/gender where both are done directly rather than |
| 110 // in interpolations. |
| 111 nestedOuter(number, gen) => Intl.plural(number, |
| 112 other: Intl.gender(gen, male: "$number male", other: "$number other"), |
| 113 name: 'nestedOuter', |
| 114 args: [number, gen]); |
| 115 |
| 116 sameContentsDifferentName() => Intl.message("Hello World", |
| 117 name: "sameContentsDifferentName", |
| 118 desc: "One of two messages with the same contents, but different names"); |
| 119 |
| 120 differentNameSameContents() => Intl.message("Hello World", |
| 121 name: "differentNameSameContents", |
| 122 desc: "One of two messages with the same contents, but different names"); |
| 123 |
| 124 /// Distinguish two messages with identical text using the meaning parameter. |
| 125 rentToBePaid() => Intl.message("rent", |
| 126 name: "rentToBePaid", |
| 127 meaning: 'Money for rent', |
| 128 desc: "Money to be paid for rent"); |
| 129 |
| 130 rentAsVerb() => Intl.message("rent", |
| 131 name: "rentAsVerb", |
| 132 meaning: 'rent as a verb', |
| 133 desc: "The action of renting, as in rent a car"); |
| 134 |
| 135 printStuff(Intl locale) { |
| 136 |
| 137 // Use a name that's not a literal so this will get skipped. Then we have |
| 138 // a name that's not in the original but we include it in the French |
| 139 // translation. Because it's not in the original it shouldn't get included |
| 140 // in the generated catalog and shouldn't get translated. |
| 141 if (locale.locale == 'fr') { |
| 142 var badName = "thisNameIsNotInTheOriginal"; |
| 143 var notInOriginal = Intl.message("foo", name: badName); |
| 144 if (notInOriginal != "foo") { |
| 145 throw "You shouldn't be able to introduce a new message in a translation"; |
| 146 } |
| 147 } |
| 148 |
| 149 // A function that is assigned to a variable. It's also nested |
| 150 // within another function definition. |
| 151 message3(a, b, c) => Intl.message( |
| 152 "Characters that need escaping, e.g slashes \\ dollars \${ (curly braces " |
| 153 "are ok) and xml reserved characters <& and quotes \" " |
| 154 "parameters $a, $b, and $c", name: 'message3', args: [a, b, c]); |
| 155 var messageVariable = message3; |
| 156 |
| 157 printOut("-------------------------------------------"); |
| 158 printOut("Printing messages for ${locale.locale}"); |
| 159 Intl.withLocale(locale.locale, () { |
| 160 printOut(message1()); |
| 161 printOut(message2("hello")); |
| 162 printOut(messageVariable(1, 2, 3)); |
| 163 printOut(multiLine()); |
| 164 printOut(types(1, "b", ["c", "d"])); |
| 165 printOut(leadingQuotes); |
| 166 printOut(alwaysTranslated()); |
| 167 printOut(trickyInterpolation("this")); |
| 168 var thing = new YouveGotMessages(); |
| 169 printOut(thing.method()); |
| 170 printOut(thing.nonLambda()); |
| 171 printOut(YouveGotMessages.staticMessage()); |
| 172 printOut(notAlwaysTranslated()); |
| 173 printOut(originalNotInBMP()); |
| 174 printOut(escapable()); |
| 175 |
| 176 printOut(thing.plurals(0)); |
| 177 printOut(thing.plurals(1)); |
| 178 printOut(thing.plurals(2)); |
| 179 printOut(thing.plurals(3)); |
| 180 printOut(thing.plurals(4)); |
| 181 printOut(thing.plurals(5)); |
| 182 printOut(thing.plurals(6)); |
| 183 printOut(thing.plurals(7)); |
| 184 printOut(thing.plurals(8)); |
| 185 printOut(thing.plurals(9)); |
| 186 printOut(thing.plurals(10)); |
| 187 printOut(thing.plurals(11)); |
| 188 printOut(thing.plurals(20)); |
| 189 printOut(thing.plurals(100)); |
| 190 printOut(thing.plurals(101)); |
| 191 printOut(thing.plurals(100000)); |
| 192 var alice = new Person("Alice", "female"); |
| 193 var bob = new Person("Bob", "male"); |
| 194 var cat = new Person("cat", null); |
| 195 printOut(thing.whereTheyWent(alice, "house")); |
| 196 printOut(thing.whereTheyWent(bob, "house")); |
| 197 printOut(thing.whereTheyWent(cat, "litter box")); |
| 198 printOut(thing.nested([alice, bob], "magasin")); |
| 199 printOut(thing.nested([alice], "magasin")); |
| 200 printOut(thing.nested([], "magasin")); |
| 201 printOut(thing.nested([bob, bob], "magasin")); |
| 202 printOut(thing.nested([alice, alice], "magasin")); |
| 203 |
| 204 printOut(outerPlural(0)); |
| 205 printOut(outerPlural(1)); |
| 206 printOut(outerGender("male")); |
| 207 printOut(outerGender("female")); |
| 208 printOut(nestedOuter(7, "male")); |
| 209 printOut(outerSelect("CDN", 7)); |
| 210 printOut(outerSelect("EUR", 5)); |
| 211 printOut(nestedSelect("CDN", 1)); |
| 212 printOut(nestedSelect("CDN", 2)); |
| 213 printOut(pluralThatFailsParsing(1)); |
| 214 printOut(pluralThatFailsParsing(2)); |
| 215 printOut(differentNameSameContents()); |
| 216 printOut(sameContentsDifferentName()); |
| 217 printOut(rentAsVerb()); |
| 218 printOut(rentToBePaid()); |
| 219 }); |
| 220 } |
| 221 |
| 222 var localeToUse = 'en_US'; |
| 223 |
| 224 main() { |
| 225 var fr = new Intl("fr"); |
| 226 var english = new Intl("en_US"); |
| 227 var de = new Intl("de_DE"); |
| 228 // Throw in an initialize of a null locale to make sure it doesn't throw. |
| 229 initializeMessages(null); |
| 230 |
| 231 // Verify that a translated message isn't initially present. |
| 232 var messageInGerman = Intl.withLocale('de_DE', message1); |
| 233 expect(messageInGerman, "This is a message"); |
| 234 |
| 235 var f1 = initializeMessages(fr.locale) |
| 236 // Since English has the one message which is always translated, we |
| 237 // can't print it until French is ready. |
| 238 .then((_) => printStuff(english)).then((_) => printStuff(fr)); |
| 239 var f2 = initializeMessages('de-de').then((_) => printStuff(de)); |
| 240 return Future.wait([f1, f2]); |
| 241 } |
OLD | NEW |