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

Side by Side Diff: chrome/browser/extensions/api/declarative/declarative_rule_unittest.cc

Issue 11572061: Create DeclarativeConditionSet, DeclarativeActionSet, and DeclarativeRule templates (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase to Vaclav's CL and fix Dominic's comments Created 8 years 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
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/api/declarative/declarative_rule.h"
6
7 #include "base/message_loop.h"
8 #include "base/test/values_test_util.h"
9 #include "base/values.h"
10 #include "chrome/common/extensions/matcher/url_matcher_constants.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace extensions {
15
16 using json_schema_compiler::any::Any;
17 using base::test::ParseJson;
18
19 struct RecordingCondition {
20 typedef int MatchData;
21
22 URLMatcherConditionFactory* factory;
23 scoped_ptr<base::Value> value;
24
25 URLMatcherConditionSet::ID url_matcher_condition_set_id() const {
26 return 1;
27 }
28
29 bool has_url_matcher_condition_set() const {
30 return false;
31 }
32
33 static scoped_ptr<RecordingCondition> Create(
34 URLMatcherConditionFactory* url_matcher_condition_factory,
35 const base::Value& condition,
36 std::string* error) {
37 const base::DictionaryValue* dict;
38 if (error_on_key &&
39 condition.GetAsDictionary(&dict) &&
40 dict->HasKey(error_on_key)) {
41 *error = "Found error key";
42 return scoped_ptr<RecordingCondition>();
43 }
44
45 scoped_ptr<RecordingCondition> result(new RecordingCondition());
46 result->factory = url_matcher_condition_factory;
47 result->value.reset(condition.DeepCopy());
48 return result.Pass();
49 }
50
51 static const char* error_on_key;
52 };
53 const char* RecordingCondition::error_on_key = NULL;
54 typedef DeclarativeConditionSet<RecordingCondition> RecordingConditionSet;
55
56 TEST(DeclarativeConditionTest, ErrorConditionSet) {
57 URLMatcher matcher;
58 RecordingConditionSet::AnyVector conditions;
59 conditions.push_back(make_linked_ptr(new Any(ParseJson("{\"key\": 1}"))));
60 conditions.push_back(make_linked_ptr(new Any(ParseJson("{\"bad_key\": 2}"))));
61 RecordingCondition::error_on_key = "bad_key";
62
63 std::string error;
64 scoped_ptr<RecordingConditionSet> result =
65 RecordingConditionSet::Create(matcher.condition_factory(),
66 conditions, &error);
67 EXPECT_EQ("Found error key", error);
68 ASSERT_FALSE(result);
69 }
70
71 TEST(DeclarativeConditionTest, CreateConditionSet) {
72 URLMatcher matcher;
73 RecordingConditionSet::AnyVector conditions;
74 conditions.push_back(make_linked_ptr(new Any(ParseJson("{\"key\": 1}"))));
75 conditions.push_back(make_linked_ptr(new Any(ParseJson("[\"val1\", 2]"))));
76 RecordingCondition::error_on_key = NULL;
77
78 // Test insertion
79 std::string error;
80 scoped_ptr<RecordingConditionSet> result =
81 RecordingConditionSet::Create(matcher.condition_factory(),
82 conditions, &error);
83 EXPECT_EQ("", error);
84 ASSERT_TRUE(result);
85 EXPECT_EQ(2u, result->conditions().size());
86
87 EXPECT_EQ(matcher.condition_factory(), result->conditions()[0]->factory);
88 EXPECT_TRUE(ParseJson("{\"key\": 1}")->Equals(
89 result->conditions()[0]->value.get()));
90 }
91
92 struct FulfillableCondition {
93 typedef int MatchData;
94
95 scoped_refptr<URLMatcherConditionSet> condition_set;
96 int condition_set_id;
97 int max_value;
98
99 URLMatcherConditionSet::ID url_matcher_condition_set_id() const {
100 return condition_set_id;
101 }
102
103 bool has_url_matcher_condition_set() const {
104 return true;
105 }
106
107 scoped_refptr<URLMatcherConditionSet> url_matcher_condition_set() const {
108 return condition_set;
109 }
110
111 void GetURLMatcherConditionSets(
112 URLMatcherConditionSet::Vector* condition_sets) const {
113 condition_sets->push_back(condition_set);
114 }
115
116 bool IsFulfilled(int match_data) const {
117 return match_data <= max_value;
118 }
119
120 static scoped_ptr<FulfillableCondition> Create(
121 URLMatcherConditionFactory* url_matcher_condition_factory,
122 const base::Value& condition,
123 std::string* error) {
124 scoped_ptr<FulfillableCondition> result(new FulfillableCondition());
125 const base::ListValue* list;
126 if (!condition.GetAsList(&list)) {
127 *error = "Expected list";
128 return result.Pass();
129 }
130 if (!list->GetInteger(0, &result->condition_set_id))
131 *error = "Expected integer at [0]";
132 if (!list->GetInteger(1, &result->max_value))
133 *error = "Expected integer at [1]";
134 result->condition_set = new URLMatcherConditionSet(
135 result->condition_set_id,
136 URLMatcherConditionSet::Conditions());
137 return result.Pass();
138 }
139 };
140
141 TEST(DeclarativeConditionTest, FulfilConditionSet) {
142 typedef DeclarativeConditionSet<FulfillableCondition> FulfillableConditionSet;
143 FulfillableConditionSet::AnyVector conditions;
144 conditions.push_back(make_linked_ptr(new Any(ParseJson("[1, 3]"))));
145 conditions.push_back(make_linked_ptr(new Any(ParseJson("[2, 5]"))));
146 conditions.push_back(make_linked_ptr(new Any(ParseJson("[3, 1]"))));
147
148 // Test insertion
149 std::string error;
150 scoped_ptr<FulfillableConditionSet> result =
151 FulfillableConditionSet::Create(NULL, conditions, &error);
152 ASSERT_EQ("", error);
153 ASSERT_TRUE(result);
154 EXPECT_EQ(3u, result->conditions().size());
155
156 EXPECT_TRUE(result->IsFulfilled(3));
157 EXPECT_TRUE(result->IsFulfilled(4));
158
159 // Check the condition sets:
160 URLMatcherConditionSet::Vector condition_sets;
161 result->GetURLMatcherConditionSets(&condition_sets);
162 ASSERT_EQ(3U, condition_sets.size());
163 EXPECT_EQ(1, condition_sets[0]->id());
164 EXPECT_EQ(2, condition_sets[1]->id());
165 EXPECT_EQ(3, condition_sets[2]->id());
166 }
167
168 // DeclarativeAction
169
170 struct SummingAction {
171 typedef int ApplyInfo;
172
173 int increment;
174 int min_priority;
175
176 static scoped_ptr<SummingAction> Create(const base::Value& action,
177 std::string* error,
178 bool* bad_message) {
179 scoped_ptr<SummingAction> result(new SummingAction());
180 const base::DictionaryValue* dict = NULL;
181 EXPECT_TRUE(action.GetAsDictionary(&dict));
182 if (dict->HasKey("error")) {
183 EXPECT_TRUE(dict->GetString("error", error));
184 return result.Pass();
185 }
186 if (dict->HasKey("bad")) {
187 *bad_message = true;
188 return result.Pass();
189 }
190
191 EXPECT_TRUE(dict->GetInteger("value", &result->increment));
192 dict->GetInteger("priority", &result->min_priority);
193 return result.Pass();
194 }
195
196 void Apply(const std::string& extension_id,
197 const base::Time& install_time,
198 int* sum) const {
199 *sum += increment;
200 }
201
202 int GetMinimumPriority() const {
203 return min_priority;
204 }
205 };
206 typedef DeclarativeActionSet<SummingAction> SummingActionSet;
207
208 TEST(DeclarativeActionTest, ErrorActionSet) {
209 SummingActionSet::AnyVector actions;
210 actions.push_back(make_linked_ptr(new Any(ParseJson("{\"value\": 1}"))));
211 actions.push_back(make_linked_ptr(new Any(ParseJson(
212 "{\"error\": \"the error\"}"))));
213
214 std::string error;
215 bool bad = false;
216 scoped_ptr<SummingActionSet> result =
217 SummingActionSet::Create(actions, &error, &bad);
218 EXPECT_EQ("the error", error);
219 EXPECT_FALSE(bad);
220 EXPECT_FALSE(result);
221
222 actions.clear();
223 actions.push_back(make_linked_ptr(new Any(ParseJson("{\"value\": 1}"))));
224 actions.push_back(make_linked_ptr(new Any(ParseJson("{\"bad\": 3}"))));
225 result = SummingActionSet::Create(actions, &error, &bad);
226 EXPECT_EQ("", error);
227 EXPECT_TRUE(bad);
228 EXPECT_FALSE(result);
229 }
230
231 TEST(DeclarativeActionTest, ApplyActionSet) {
232 SummingActionSet::AnyVector actions;
233 actions.push_back(make_linked_ptr(new Any(ParseJson(
234 "{\"value\": 1,"
235 " \"priority\": 5}"))));
236 actions.push_back(make_linked_ptr(new Any(ParseJson("{\"value\": 2}"))));
237
238 // Test insertion
239 std::string error;
240 bool bad = false;
241 scoped_ptr<SummingActionSet> result =
242 SummingActionSet::Create(actions, &error, &bad);
243 EXPECT_EQ("", error);
244 EXPECT_FALSE(bad);
245 ASSERT_TRUE(result);
246 EXPECT_EQ(2u, result->actions().size());
247
248 int sum = 0;
249 result->Apply("ext_id", base::Time(), &sum);
250 EXPECT_EQ(3, sum);
251 EXPECT_EQ(5, result->GetMinimumPriority());
252 }
253
254 TEST(DeclarativeRuleTest, Create) {
255 typedef DeclarativeRule<FulfillableCondition, SummingAction> Rule;
256 linked_ptr<Rule::JsonRule> json_rule(new Rule::JsonRule);
257 ASSERT_TRUE(Rule::JsonRule::Populate(
258 *ParseJson("{ \n"
259 " \"id\": \"rule1\", \n"
260 " \"conditions\": [ \n"
261 " [1, 3], \n"
262 " [2, 5], \n"
263 " ], \n"
264 " \"actions\": [ \n"
265 " { \n"
266 " \"value\": 2 \n"
267 " } \n"
268 " ], \n"
269 " \"priority\": 200 \n"
270 "}"),
271 json_rule.get()));
272
273 const char kExtensionId[] = "ext1";
274
275 base::Time install_time = base::Time::Now();
276
277 URLMatcher matcher;
278 std::string error;
279 scoped_ptr<Rule> rule(Rule::Create(matcher.condition_factory(), kExtensionId,
280 install_time, json_rule, NULL, &error));
281 ASSERT_TRUE(rule.get());
282 EXPECT_EQ("", error);
283
284 EXPECT_EQ(kExtensionId, rule->id().first);
285 EXPECT_EQ("rule1", rule->id().second);
286
287 EXPECT_EQ(200, rule->priority());
288
289 const Rule::ConditionSet& condition_set = rule->conditions();
290 const Rule::ConditionSet::Conditions conditions =
291 condition_set.conditions();
292 ASSERT_EQ(2u, conditions.size());
293 EXPECT_EQ(3, conditions[0]->max_value);
294 EXPECT_EQ(5, conditions[1]->max_value);
295
296 const Rule::ActionSet& action_set = rule->actions();
297 const Rule::ActionSet::Actions& actions = action_set.actions();
298 ASSERT_EQ(1u, actions.size());
299 EXPECT_EQ(2, actions[0]->increment);
300
301 int sum = 0;
302 rule->Apply(&sum);
303 EXPECT_EQ(2, sum);
304 }
305
306 bool AtLeastOneConditionAndAction(
307 DeclarativeConditionSet<FulfillableCondition>* conditions,
308 DeclarativeActionSet<SummingAction>* actions,
309 std::string* error) {
310 if (conditions->conditions().size() < 1) {
311 *error = "No conditions";
312 return false;
313 }
314 if (actions->actions().size() < 1) {
315 *error = "No actions";
316 return false;
317 }
318 return true;
319 }
320
321 TEST(DeclarativeRuleTest, CheckConsistency) {
322 typedef DeclarativeRule<FulfillableCondition, SummingAction> Rule;
323 URLMatcher matcher;
324 std::string error;
325 linked_ptr<Rule::JsonRule> json_rule(new Rule::JsonRule);
326 const char kExtensionId[] = "ext1";
327
328 ASSERT_TRUE(Rule::JsonRule::Populate(
329 *ParseJson("{ \n"
330 " \"id\": \"rule1\", \n"
331 " \"conditions\": [ \n"
332 " [1, 3], \n"
333 " [2, 5], \n"
334 " ], \n"
335 " \"actions\": [ \n"
336 " { \n"
337 " \"value\": 2 \n"
338 " } \n"
339 " ], \n"
340 " \"priority\": 200 \n"
341 "}"),
342 json_rule.get()));
343 scoped_ptr<Rule> rule(
344 Rule::Create(matcher.condition_factory(), kExtensionId, base::Time(),
345 json_rule, &AtLeastOneConditionAndAction, &error));
346 EXPECT_TRUE(rule);
347 EXPECT_EQ("", error);
348
349 ASSERT_TRUE(Rule::JsonRule::Populate(
350 *ParseJson("{ \n"
351 " \"id\": \"rule1\", \n"
352 " \"conditions\": [ \n"
353 " ], \n"
354 " \"actions\": [ \n"
355 " { \n"
356 " \"value\": 2 \n"
357 " } \n"
358 " ], \n"
359 " \"priority\": 200 \n"
360 "}"),
361 json_rule.get()));
362 rule = Rule::Create(matcher.condition_factory(), kExtensionId, base::Time(),
363 json_rule, &AtLeastOneConditionAndAction, &error);
364 EXPECT_FALSE(rule);
365 EXPECT_EQ("No conditions", error);
366 }
367
368 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698