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