Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: chrome/browser/extensions/extension_message_bundle_unittest.cc

Issue 202063: Implemented the rest of loading/parsing logic for extension i18n:... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/extension_message_bundle.h"
6
7 #include <string>
8
9 #include "base/scoped_ptr.h"
10 #include "base/string_util.h"
11 #include "base/values.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace {
15
16 // Helper method for dictionary building.
17 void SetDictionary(const std::wstring name,
18 DictionaryValue* target,
19 DictionaryValue* subtree) {
20 target->Set(name, static_cast<Value*>(subtree));
21 }
22
23 void CreateContentTree(const std::wstring& name,
24 const std::string content,
25 DictionaryValue* dict) {
26 DictionaryValue* content_tree = new DictionaryValue;
27 content_tree->SetString(ExtensionMessageBundle::kContentKey, content);
28 SetDictionary(name, dict, content_tree);
29 }
30
31 void CreatePlaceholdersTree(DictionaryValue* dict) {
32 DictionaryValue* placeholders_tree = new DictionaryValue;
33 CreateContentTree(L"a", "A", placeholders_tree);
34 CreateContentTree(L"b", "B", placeholders_tree);
35 CreateContentTree(L"c", "C", placeholders_tree);
36 SetDictionary(ExtensionMessageBundle::kPlaceholdersKey,
37 dict,
38 placeholders_tree);
39 }
40
41 void CreateMessageTree(const std::wstring& name,
42 const std::string& message,
43 bool create_placeholder_subtree,
44 DictionaryValue* dict) {
45 DictionaryValue* message_tree = new DictionaryValue;
46 if (create_placeholder_subtree)
47 CreatePlaceholdersTree(message_tree);
48 message_tree->SetString(ExtensionMessageBundle::kMessageKey, message);
49 SetDictionary(name, dict, message_tree);
50 }
51
52 void CreateGoodDictionary(DictionaryValue* dict) {
53 dict->Clear();
54 CreateMessageTree(L"n1", "message1 $a$ $b$", true, dict);
55 CreateMessageTree(L"n2", "message2 $c$", true, dict);
56 CreateMessageTree(L"n3", "message3", false, dict);
57 }
58
59 enum BadDictionary {
60 INVALID_NAME,
61 NAME_NOT_A_TREE,
62 EMPTY_NAME_TREE,
63 MISSING_MESSAGE,
64 PLACEHOLDER_NOT_A_TREE,
65 EMPTY_PLACEHOLDER_TREE,
66 CONTENT_MISSING,
67 MESSAGE_PLACEHOLDER_DOESNT_MATCH,
68 };
69
70 void CreateBadDictionary(DictionaryValue* dict,
71 enum BadDictionary what_is_bad) {
72 CreateGoodDictionary(dict);
73 // Now remove/break things.
74 switch (what_is_bad) {
75 case INVALID_NAME:
76 CreateMessageTree(L"n 5", "nevermind", false, dict);
77 break;
78 case NAME_NOT_A_TREE:
79 dict->SetString(L"n4", "whatever");
80 break;
81 case EMPTY_NAME_TREE: {
82 DictionaryValue* empty_tree = new DictionaryValue;
83 SetDictionary(L"n4", dict, empty_tree);
84 }
85 break;
86 case MISSING_MESSAGE:
87 dict->Remove(L"n1.message", NULL);
88 break;
89 case PLACEHOLDER_NOT_A_TREE:
90 dict->SetString(L"n1.placeholders", "whatever");
91 break;
92 case EMPTY_PLACEHOLDER_TREE: {
93 DictionaryValue* empty_tree = new DictionaryValue;
94 SetDictionary(L"n1.placeholders", dict, empty_tree);
95 }
96 break;
97 case CONTENT_MISSING:
98 dict->Remove(L"n1.placeholders.a.content", NULL);
99 break;
100 case MESSAGE_PLACEHOLDER_DOESNT_MATCH:
101 DictionaryValue* value;
102 dict->Remove(L"n1.placeholders.a", NULL);
103 dict->GetDictionary(L"n1.placeholders", &value);
104 CreateContentTree(L"x", "X", value);
105 break;
106 }
107 }
108
109 TEST(ExtensionMessageBundle, InitEmptyDictionaries) {
110 DictionaryValue default_dict;
111 DictionaryValue app_dict;
112 std::string error;
113 scoped_ptr<ExtensionMessageBundle> handler(
114 ExtensionMessageBundle::Create(default_dict, app_dict, &error));
115
116 EXPECT_TRUE(handler.get() != NULL);
117 EXPECT_EQ(0U, handler->size());
118 }
119
120 TEST(ExtensionMessageBundle, InitGoodDefaultDictEmptyAppDict) {
121 DictionaryValue default_dict;
122 DictionaryValue app_dict;
123 std::string error;
124
125 CreateGoodDictionary(&default_dict);
126 scoped_ptr<ExtensionMessageBundle> handler(
127 ExtensionMessageBundle::Create(default_dict, app_dict, &error));
128
129 EXPECT_TRUE(handler.get() != NULL);
130 EXPECT_EQ(3U, handler->size());
131
132 EXPECT_EQ("message1 A B", handler->GetL10nMessage("n1"));
133 EXPECT_EQ("message2 C", handler->GetL10nMessage("n2"));
134 EXPECT_EQ("message3", handler->GetL10nMessage("n3"));
135 }
136
137 TEST(ExtensionMessageBundle, InitAppDictConsultedFirst) {
138 DictionaryValue default_dict;
139 DictionaryValue app_dict;
140 std::string error;
141
142 CreateGoodDictionary(&default_dict);
143 CreateGoodDictionary(&app_dict);
144 // Flip placeholders in message of n1 tree.
145 app_dict.SetString(L"n1.message", "message1 $b$ $a$");
146 // Remove one message from app dict.
147 app_dict.Remove(L"n2", NULL);
148 // Replace n3 with N3.
149 app_dict.Remove(L"n3", NULL);
150 CreateMessageTree(L"N3", "message3_app_dict", false, &app_dict);
151
152 scoped_ptr<ExtensionMessageBundle> handler(
153 ExtensionMessageBundle::Create(default_dict, app_dict, &error));
154
155 EXPECT_TRUE(handler.get() != NULL);
156 EXPECT_EQ(3U, handler->size());
157
158 EXPECT_EQ("message1 B A", handler->GetL10nMessage("n1"));
159 EXPECT_EQ("message2 C", handler->GetL10nMessage("n2"));
160 EXPECT_EQ("message3_app_dict", handler->GetL10nMessage("n3"));
161 }
162
163 TEST(ExtensionMessageBundle, InitBadAppDict) {
164 DictionaryValue default_dict;
165 DictionaryValue app_dict;
166 std::string error;
167
168 CreateBadDictionary(&app_dict, INVALID_NAME);
169 scoped_ptr<ExtensionMessageBundle> handler(
170 ExtensionMessageBundle::Create(default_dict, app_dict, &error));
171
172 EXPECT_TRUE(handler.get() == NULL);
173 EXPECT_EQ("Name of a key \"n 5\" is invalid. Only ASCII [a-z], "
174 "[A-Z], [0-9] and \"_\" are allowed.", error);
175
176 CreateBadDictionary(&app_dict, NAME_NOT_A_TREE);
177 handler.reset(ExtensionMessageBundle::Create(default_dict, app_dict, &error));
178 EXPECT_TRUE(handler.get() == NULL);
179 EXPECT_EQ("Not a valid tree for key n4.", error);
180
181 CreateBadDictionary(&app_dict, EMPTY_NAME_TREE);
182 handler.reset(ExtensionMessageBundle::Create(default_dict, app_dict, &error));
183 EXPECT_TRUE(handler.get() == NULL);
184 EXPECT_EQ("There is no \"message\" element for key n4.", error);
185
186 CreateBadDictionary(&app_dict, MISSING_MESSAGE);
187 handler.reset(ExtensionMessageBundle::Create(default_dict, app_dict, &error));
188 EXPECT_TRUE(handler.get() == NULL);
189 EXPECT_EQ("There is no \"message\" element for key n1.", error);
190
191 CreateBadDictionary(&app_dict, PLACEHOLDER_NOT_A_TREE);
192 handler.reset(ExtensionMessageBundle::Create(default_dict, app_dict, &error));
193 EXPECT_TRUE(handler.get() == NULL);
194 EXPECT_EQ("Not a valid \"placeholders\" element for key n1.", error);
195
196 CreateBadDictionary(&app_dict, EMPTY_PLACEHOLDER_TREE);
197 handler.reset(ExtensionMessageBundle::Create(default_dict, app_dict, &error));
198 EXPECT_TRUE(handler.get() == NULL);
199 EXPECT_EQ("Variable $a$ used but not defined.", error);
200
201 CreateBadDictionary(&app_dict, CONTENT_MISSING);
202 handler.reset(ExtensionMessageBundle::Create(default_dict, app_dict, &error));
203 EXPECT_TRUE(handler.get() == NULL);
204 EXPECT_EQ("Invalid \"content\" element for key n1.", error);
205
206 CreateBadDictionary(&app_dict, MESSAGE_PLACEHOLDER_DOESNT_MATCH);
207 handler.reset(ExtensionMessageBundle::Create(default_dict, app_dict, &error));
208 EXPECT_TRUE(handler.get() == NULL);
209 EXPECT_EQ("Variable $a$ used but not defined.", error);
210 }
211
212 struct ReplaceVariables {
213 const char* original;
214 const char* result;
215 const char* error;
216 const char* begin_delimiter;
217 const char* end_delimiter;
218 bool pass;
219 };
220
221 TEST(ExtensionMessageBundle, ReplaceMessagesInText) {
222 const char* kMessageBegin = ExtensionMessageBundle::kMessageBegin;
223 const char* kMessageEnd = ExtensionMessageBundle::kMessageEnd;
224 const char* kPlaceholderBegin = ExtensionMessageBundle::kPlaceholderBegin;
225 const char* kPlaceholderEnd = ExtensionMessageBundle::kPlaceholderEnd;
226
227 static ReplaceVariables test_cases[] = {
228 // Message replacement.
229 { "This is __MSG_siMPle__ message", "This is simple message",
230 "", kMessageBegin, kMessageEnd, true },
231 { "This is __MSG_", "This is __MSG_",
232 "", kMessageBegin, kMessageEnd, true },
233 { "This is __MSG__simple__ message", "This is __MSG__simple__ message",
234 "Variable __MSG__simple__ used but not defined.",
235 kMessageBegin, kMessageEnd, false },
236 { "__MSG_LoNg__", "A pretty long replacement",
237 "", kMessageBegin, kMessageEnd, true },
238 { "A __MSG_SimpLE__MSG_ a", "A simpleMSG_ a",
239 "", kMessageBegin, kMessageEnd, true },
240 { "A __MSG_simple__MSG_long__", "A simpleMSG_long__",
241 "", kMessageBegin, kMessageEnd, true },
242 { "A __MSG_simple____MSG_long__", "A simpleA pretty long replacement",
243 "", kMessageBegin, kMessageEnd, true },
244 { "__MSG_d1g1ts_are_ok__", "I are d1g1t",
245 "", kMessageBegin, kMessageEnd, true },
246 // Placeholder replacement.
247 { "This is $sImpLe$ message", "This is simple message",
248 "", kPlaceholderBegin, kPlaceholderEnd, true },
249 { "This is $", "This is $",
250 "", kPlaceholderBegin, kPlaceholderEnd, true },
251 { "This is $$sIMPle$ message", "This is $simple message",
252 "", kPlaceholderBegin, kPlaceholderEnd, true },
253 { "$LONG_V$", "A pretty long replacement",
254 "", kPlaceholderBegin, kPlaceholderEnd, true },
255 { "A $simple$$ a", "A simple$ a",
256 "", kPlaceholderBegin, kPlaceholderEnd, true },
257 { "A $simple$long_v$", "A simplelong_v$",
258 "", kPlaceholderBegin, kPlaceholderEnd, true },
259 { "A $simple$$long_v$", "A simpleA pretty long replacement",
260 "", kPlaceholderBegin, kPlaceholderEnd, true },
261 { "This is $bad name$", "This is $bad name$",
262 "", kPlaceholderBegin, kPlaceholderEnd, true },
263 { "This is $missing$", "This is $missing$",
264 "Variable $missing$ used but not defined.",
265 kPlaceholderBegin, kPlaceholderEnd, false },
266 };
267
268 ExtensionMessageBundle::SubstitutionMap messages;
269 messages.insert(std::make_pair("simple", "simple"));
270 messages.insert(std::make_pair("long", "A pretty long replacement"));
271 messages.insert(std::make_pair("long_v", "A pretty long replacement"));
272 messages.insert(std::make_pair("bad name", "Doesn't matter"));
273 messages.insert(std::make_pair("d1g1ts_are_ok", "I are d1g1t"));
274
275 for (size_t i = 0; i < arraysize(test_cases); ++i) {
276 std::string text = test_cases[i].original;
277 std::string error;
278 EXPECT_EQ(test_cases[i].pass,
279 ExtensionMessageBundle::ReplaceVariables(messages,
280 test_cases[i].begin_delimiter,
281 test_cases[i].end_delimiter,
282 &text,
283 &error));
284 EXPECT_EQ(test_cases[i].result, text);
285 }
286 }
287
288 } // namespace
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_message_bundle.cc ('k') | chrome/browser/extensions/extension_ui_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698