| 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 |