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 |