OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
battre
2013/01/21 17:32:08
Do you want to add a unit test for the new code in
vabr (Chromium)
2013/01/22 08:34:53
Did you mean declarative_rule.h?
Most of the modif
| |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/declarative/declarative_rule.h" | 5 #include "chrome/browser/extensions/api/declarative/declarative_rule.h" |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "base/test/values_test_util.h" | 8 #include "base/test/values_test_util.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "chrome/common/extensions/matcher/url_matcher_constants.h" | 10 #include "chrome/common/extensions/matcher/url_matcher_constants.h" |
11 #include "testing/gmock/include/gmock/gmock.h" | 11 #include "testing/gmock/include/gmock/gmock.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
13 | 13 |
14 namespace extensions { | 14 namespace extensions { |
15 | 15 |
16 using base::test::ParseJson; | 16 using base::test::ParseJson; |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 template<typename T> | 20 template<typename T> |
21 linked_ptr<T> ScopedToLinkedPtr(scoped_ptr<T> ptr) { | 21 linked_ptr<T> ScopedToLinkedPtr(scoped_ptr<T> ptr) { |
22 return linked_ptr<T>(ptr.release()); | 22 return linked_ptr<T>(ptr.release()); |
23 } | 23 } |
24 | 24 |
25 } // namespace | 25 } // namespace |
26 | 26 |
27 struct RecordingCondition { | 27 struct RecordingCondition { |
28 typedef int MatchData; | 28 typedef int MatchData; |
29 | 29 |
30 URLMatcherConditionFactory* factory; | 30 std::vector<URLMatcherConditionFactory*> factories; |
31 scoped_ptr<base::Value> value; | 31 scoped_ptr<base::Value> value; |
32 | 32 |
33 void GetURLMatcherConditionSets( | 33 int GetURLMatcherConditionSets( |
34 URLMatcherConditionSet::Vector* condition_sets) const { | 34 URLMatcherConditionSet::Vector* condition_sets, |
35 int index) const { | |
35 // No condition sets. | 36 // No condition sets. |
36 } | 37 return -1; |
37 | |
38 bool has_url_matcher_condition_set() const { | |
39 return false; | |
40 } | 38 } |
41 | 39 |
42 static scoped_ptr<RecordingCondition> Create( | 40 static scoped_ptr<RecordingCondition> Create( |
43 URLMatcherConditionFactory* url_matcher_condition_factory, | 41 const std::vector<URLMatcherConditionFactory*>& |
42 url_matcher_condition_factories, | |
44 const base::Value& condition, | 43 const base::Value& condition, |
45 std::string* error) { | 44 std::string* error) { |
46 const base::DictionaryValue* dict = NULL; | 45 const base::DictionaryValue* dict = NULL; |
47 if (condition.GetAsDictionary(&dict) && dict->HasKey("bad_key")) { | 46 if (condition.GetAsDictionary(&dict) && dict->HasKey("bad_key")) { |
48 *error = "Found error key"; | 47 *error = "Found error key"; |
49 return scoped_ptr<RecordingCondition>(); | 48 return scoped_ptr<RecordingCondition>(); |
50 } | 49 } |
51 | 50 |
52 scoped_ptr<RecordingCondition> result(new RecordingCondition()); | 51 scoped_ptr<RecordingCondition> result(new RecordingCondition()); |
53 result->factory = url_matcher_condition_factory; | 52 result->factories = url_matcher_condition_factories; |
54 result->value.reset(condition.DeepCopy()); | 53 result->value.reset(condition.DeepCopy()); |
55 return result.Pass(); | 54 return result.Pass(); |
56 } | 55 } |
57 }; | 56 }; |
58 typedef DeclarativeConditionSet<RecordingCondition> RecordingConditionSet; | 57 typedef DeclarativeConditionSet<RecordingCondition> RecordingConditionSet; |
59 | 58 |
60 TEST(DeclarativeConditionTest, ErrorConditionSet) { | 59 TEST(DeclarativeConditionTest, ErrorConditionSet) { |
61 URLMatcher matcher; | 60 URLMatcher matcher; |
62 RecordingConditionSet::AnyVector conditions; | 61 RecordingConditionSet::AnyVector conditions; |
63 conditions.push_back(ScopedToLinkedPtr(ParseJson("{\"key\": 1}"))); | 62 conditions.push_back(ScopedToLinkedPtr(ParseJson("{\"key\": 1}"))); |
64 conditions.push_back(ScopedToLinkedPtr(ParseJson("{\"bad_key\": 2}"))); | 63 conditions.push_back(ScopedToLinkedPtr(ParseJson("{\"bad_key\": 2}"))); |
65 | 64 |
66 std::string error; | 65 std::string error; |
66 std::vector<URLMatcherConditionFactory*> factories; | |
67 factories.push_back(matcher.condition_factory()); | |
67 scoped_ptr<RecordingConditionSet> result = | 68 scoped_ptr<RecordingConditionSet> result = |
68 RecordingConditionSet::Create(matcher.condition_factory(), | 69 RecordingConditionSet::Create(factories, conditions, &error); |
69 conditions, &error); | |
70 EXPECT_EQ("Found error key", error); | 70 EXPECT_EQ("Found error key", error); |
71 ASSERT_FALSE(result); | 71 ASSERT_FALSE(result); |
72 } | 72 } |
73 | 73 |
74 TEST(DeclarativeConditionTest, CreateConditionSet) { | 74 TEST(DeclarativeConditionTest, CreateConditionSet) { |
75 URLMatcher matcher; | 75 URLMatcher matcher; |
76 RecordingConditionSet::AnyVector conditions; | 76 RecordingConditionSet::AnyVector conditions; |
77 conditions.push_back(ScopedToLinkedPtr(ParseJson("{\"key\": 1}"))); | 77 conditions.push_back(ScopedToLinkedPtr(ParseJson("{\"key\": 1}"))); |
78 conditions.push_back(ScopedToLinkedPtr(ParseJson("[\"val1\", 2]"))); | 78 conditions.push_back(ScopedToLinkedPtr(ParseJson("[\"val1\", 2]"))); |
79 | 79 |
80 // Test insertion | 80 // Test insertion |
81 std::string error; | 81 std::string error; |
82 std::vector<URLMatcherConditionFactory*> factories; | |
83 factories.push_back(matcher.condition_factory()); | |
82 scoped_ptr<RecordingConditionSet> result = | 84 scoped_ptr<RecordingConditionSet> result = |
83 RecordingConditionSet::Create(matcher.condition_factory(), | 85 RecordingConditionSet::Create(factories, conditions, &error); |
84 conditions, &error); | |
85 EXPECT_EQ("", error); | 86 EXPECT_EQ("", error); |
86 ASSERT_TRUE(result); | 87 ASSERT_TRUE(result); |
87 EXPECT_EQ(2u, result->conditions().size()); | 88 EXPECT_EQ(2u, result->conditions().size()); |
88 | 89 |
89 EXPECT_EQ(matcher.condition_factory(), result->conditions()[0]->factory); | 90 EXPECT_EQ(1u, result->conditions()[0]->factories.size()); |
91 EXPECT_EQ(matcher.condition_factory(), result->conditions()[0]->factories[0]); | |
90 EXPECT_TRUE(ParseJson("{\"key\": 1}")->Equals( | 92 EXPECT_TRUE(ParseJson("{\"key\": 1}")->Equals( |
91 result->conditions()[0]->value.get())); | 93 result->conditions()[0]->value.get())); |
92 } | 94 } |
93 | 95 |
94 struct FulfillableCondition { | 96 struct FulfillableCondition { |
95 typedef int MatchData; | 97 typedef int MatchData; |
96 | 98 |
97 scoped_refptr<URLMatcherConditionSet> condition_set; | 99 scoped_refptr<URLMatcherConditionSet> condition_set; |
98 int condition_set_id; | 100 int condition_set_id; |
99 int max_value; | 101 int max_value; |
100 | 102 |
101 URLMatcherConditionSet::ID url_matcher_condition_set_id() const { | 103 URLMatcherConditionSet::ID url_matcher_condition_set_id() const { |
102 return condition_set_id; | 104 return condition_set_id; |
103 } | 105 } |
104 | 106 |
105 bool has_url_matcher_condition_set() const { | |
106 return true; | |
107 } | |
108 | |
109 scoped_refptr<URLMatcherConditionSet> url_matcher_condition_set() const { | 107 scoped_refptr<URLMatcherConditionSet> url_matcher_condition_set() const { |
110 return condition_set; | 108 return condition_set; |
111 } | 109 } |
112 | 110 |
113 void GetURLMatcherConditionSets( | 111 int GetURLMatcherConditionSets( |
114 URLMatcherConditionSet::Vector* condition_sets) const { | 112 URLMatcherConditionSet::Vector* condition_sets, |
115 if (condition_set) | 113 int index) const { |
114 if (index == 0 && condition_set) | |
116 condition_sets->push_back(condition_set); | 115 condition_sets->push_back(condition_set); |
116 return -1; | |
117 } | 117 } |
118 | 118 |
119 bool IsFulfilled(const std::set<URLMatcherConditionSet::ID>& url_matches, | 119 bool IsFulfilled(const std::set<URLMatcherConditionSet::ID>& url_matches, |
120 int match_data) const { | 120 int match_data) const { |
121 if (condition_set_id != -1 && !ContainsKey(url_matches, condition_set_id)) | 121 if (condition_set_id != -1 && !ContainsKey(url_matches, condition_set_id)) |
122 return false; | 122 return false; |
123 return match_data <= max_value; | 123 return match_data <= max_value; |
124 } | 124 } |
125 | 125 |
126 static scoped_ptr<FulfillableCondition> Create( | 126 static scoped_ptr<FulfillableCondition> Create( |
127 URLMatcherConditionFactory* url_matcher_condition_factory, | 127 const std::vector<URLMatcherConditionFactory*>& |
128 url_matcher_condition_factories, | |
128 const base::Value& condition, | 129 const base::Value& condition, |
129 std::string* error) { | 130 std::string* error) { |
130 scoped_ptr<FulfillableCondition> result(new FulfillableCondition()); | 131 scoped_ptr<FulfillableCondition> result(new FulfillableCondition()); |
131 const base::DictionaryValue* dict; | 132 const base::DictionaryValue* dict; |
132 if (!condition.GetAsDictionary(&dict)) { | 133 if (!condition.GetAsDictionary(&dict)) { |
133 *error = "Expected dict"; | 134 *error = "Expected dict"; |
134 return result.Pass(); | 135 return result.Pass(); |
135 } | 136 } |
136 if (!dict->GetInteger("url_id", &result->condition_set_id)) | 137 if (!dict->GetInteger("url_id", &result->condition_set_id)) |
137 result->condition_set_id = -1; | 138 result->condition_set_id = -1; |
(...skipping 15 matching lines...) Expand all Loading... | |
153 "{\"url_id\": 1, \"max\": 3}"))); | 154 "{\"url_id\": 1, \"max\": 3}"))); |
154 conditions.push_back(ScopedToLinkedPtr(ParseJson( | 155 conditions.push_back(ScopedToLinkedPtr(ParseJson( |
155 "{\"url_id\": 2, \"max\": 5}"))); | 156 "{\"url_id\": 2, \"max\": 5}"))); |
156 conditions.push_back(ScopedToLinkedPtr(ParseJson( | 157 conditions.push_back(ScopedToLinkedPtr(ParseJson( |
157 "{\"url_id\": 3, \"max\": 1}"))); | 158 "{\"url_id\": 3, \"max\": 1}"))); |
158 conditions.push_back(ScopedToLinkedPtr(ParseJson( | 159 conditions.push_back(ScopedToLinkedPtr(ParseJson( |
159 "{\"max\": -5}"))); // No url. | 160 "{\"max\": -5}"))); // No url. |
160 | 161 |
161 // Test insertion | 162 // Test insertion |
162 std::string error; | 163 std::string error; |
164 std::vector<URLMatcherConditionFactory*> factories; | |
163 scoped_ptr<FulfillableConditionSet> result = | 165 scoped_ptr<FulfillableConditionSet> result = |
164 FulfillableConditionSet::Create(NULL, conditions, &error); | 166 FulfillableConditionSet::Create(factories, conditions, &error); |
165 ASSERT_EQ("", error); | 167 ASSERT_EQ("", error); |
166 ASSERT_TRUE(result); | 168 ASSERT_TRUE(result); |
167 EXPECT_EQ(4u, result->conditions().size()); | 169 EXPECT_EQ(4u, result->conditions().size()); |
168 | 170 |
169 std::set<URLMatcherConditionSet::ID> url_matches; | 171 std::set<URLMatcherConditionSet::ID> url_matches; |
170 EXPECT_FALSE(result->IsFulfilled(1, url_matches, 0)) | 172 EXPECT_FALSE(result->IsFulfilled(1, url_matches, 0)) |
171 << "Testing an ID that's not in url_matches forwards to the Condition, " | 173 << "Testing an ID that's not in url_matches forwards to the Condition, " |
172 << "which doesn't match."; | 174 << "which doesn't match."; |
173 EXPECT_FALSE(result->IsFulfilled(-1, url_matches, 0)) | 175 EXPECT_FALSE(result->IsFulfilled(-1, url_matches, 0)) |
174 << "Testing the 'no ID' value tries to match the 4th condition, but " | 176 << "Testing the 'no ID' value tries to match the 4th condition, but " |
175 << "its max is too low."; | 177 << "its max is too low."; |
176 EXPECT_TRUE(result->IsFulfilled(-1, url_matches, -5)) | 178 EXPECT_TRUE(result->IsFulfilled(-1, url_matches, -5)) |
177 << "Testing the 'no ID' value tries to match the 4th condition, and " | 179 << "Testing the 'no ID' value tries to match the 4th condition, and " |
178 << "this value is low enough."; | 180 << "this value is low enough."; |
179 | 181 |
180 url_matches.insert(1); | 182 url_matches.insert(1); |
181 EXPECT_TRUE(result->IsFulfilled(1, url_matches, 3)) | 183 EXPECT_TRUE(result->IsFulfilled(1, url_matches, 3)) |
182 << "Tests a condition with a url matcher, for a matching value."; | 184 << "Tests a condition with a url matcher, for a matching value."; |
183 EXPECT_FALSE(result->IsFulfilled(1, url_matches, 4)) | 185 EXPECT_FALSE(result->IsFulfilled(1, url_matches, 4)) |
184 << "Tests a condition with a url matcher, for a non-matching value " | 186 << "Tests a condition with a url matcher, for a non-matching value " |
185 << "that would match a different condition."; | 187 << "that would match a different condition."; |
186 url_matches.insert(2); | 188 url_matches.insert(2); |
187 EXPECT_TRUE(result->IsFulfilled(2, url_matches, 4)) | 189 EXPECT_TRUE(result->IsFulfilled(2, url_matches, 4)) |
188 << "Tests with 2 elements in the match set."; | 190 << "Tests with 2 elements in the match set."; |
189 | 191 |
190 // Check the condition sets: | 192 // Check the condition sets: |
191 URLMatcherConditionSet::Vector condition_sets; | 193 URLMatcherConditionSet::Vector condition_sets; |
192 result->GetURLMatcherConditionSets(&condition_sets); | 194 result->GetURLMatcherConditionSets(&condition_sets, 0); |
193 ASSERT_EQ(3U, condition_sets.size()); | 195 ASSERT_EQ(3U, condition_sets.size()); |
194 EXPECT_EQ(1, condition_sets[0]->id()); | 196 EXPECT_EQ(1, condition_sets[0]->id()); |
195 EXPECT_EQ(2, condition_sets[1]->id()); | 197 EXPECT_EQ(2, condition_sets[1]->id()); |
196 EXPECT_EQ(3, condition_sets[2]->id()); | 198 EXPECT_EQ(3, condition_sets[2]->id()); |
197 } | 199 } |
198 | 200 |
199 // DeclarativeAction | 201 // DeclarativeAction |
200 | 202 |
201 struct SummingAction { | 203 struct SummingAction { |
202 typedef int ApplyInfo; | 204 typedef int ApplyInfo; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
298 " ], \n" | 300 " ], \n" |
299 " \"priority\": 200 \n" | 301 " \"priority\": 200 \n" |
300 "}"), | 302 "}"), |
301 json_rule.get())); | 303 json_rule.get())); |
302 | 304 |
303 const char kExtensionId[] = "ext1"; | 305 const char kExtensionId[] = "ext1"; |
304 | 306 |
305 base::Time install_time = base::Time::Now(); | 307 base::Time install_time = base::Time::Now(); |
306 | 308 |
307 URLMatcher matcher; | 309 URLMatcher matcher; |
310 std::vector<URLMatcherConditionFactory*> factories; | |
311 factories.push_back(matcher.condition_factory()); | |
308 std::string error; | 312 std::string error; |
309 scoped_ptr<Rule> rule(Rule::Create(matcher.condition_factory(), kExtensionId, | 313 scoped_ptr<Rule> rule(Rule::Create(factories, kExtensionId, |
310 install_time, json_rule, NULL, &error)); | 314 install_time, json_rule, NULL, &error)); |
311 EXPECT_EQ("", error); | 315 EXPECT_EQ("", error); |
312 ASSERT_TRUE(rule.get()); | 316 ASSERT_TRUE(rule.get()); |
313 | 317 |
314 EXPECT_EQ(kExtensionId, rule->id().first); | 318 EXPECT_EQ(kExtensionId, rule->id().first); |
315 EXPECT_EQ("rule1", rule->id().second); | 319 EXPECT_EQ("rule1", rule->id().second); |
316 | 320 |
317 EXPECT_EQ(200, rule->priority()); | 321 EXPECT_EQ(200, rule->priority()); |
318 | 322 |
319 const Rule::ConditionSet& condition_set = rule->conditions(); | 323 const Rule::ConditionSet& condition_set = rule->conditions(); |
(...skipping 23 matching lines...) Expand all Loading... | |
343 } | 347 } |
344 return true; | 348 return true; |
345 } | 349 } |
346 | 350 |
347 TEST(DeclarativeRuleTest, CheckConsistency) { | 351 TEST(DeclarativeRuleTest, CheckConsistency) { |
348 typedef DeclarativeRule<FulfillableCondition, SummingAction> Rule; | 352 typedef DeclarativeRule<FulfillableCondition, SummingAction> Rule; |
349 URLMatcher matcher; | 353 URLMatcher matcher; |
350 std::string error; | 354 std::string error; |
351 linked_ptr<Rule::JsonRule> json_rule(new Rule::JsonRule); | 355 linked_ptr<Rule::JsonRule> json_rule(new Rule::JsonRule); |
352 const char kExtensionId[] = "ext1"; | 356 const char kExtensionId[] = "ext1"; |
357 std::vector<URLMatcherConditionFactory*> factories; | |
358 factories.push_back(matcher.condition_factory()); | |
353 | 359 |
354 ASSERT_TRUE(Rule::JsonRule::Populate( | 360 ASSERT_TRUE(Rule::JsonRule::Populate( |
355 *ParseJson("{ \n" | 361 *ParseJson("{ \n" |
356 " \"id\": \"rule1\", \n" | 362 " \"id\": \"rule1\", \n" |
357 " \"conditions\": [ \n" | 363 " \"conditions\": [ \n" |
358 " {\"url_id\": 1, \"max\": 3}, \n" | 364 " {\"url_id\": 1, \"max\": 3}, \n" |
359 " {\"url_id\": 2, \"max\": 5}, \n" | 365 " {\"url_id\": 2, \"max\": 5}, \n" |
360 " ], \n" | 366 " ], \n" |
361 " \"actions\": [ \n" | 367 " \"actions\": [ \n" |
362 " { \n" | 368 " { \n" |
363 " \"value\": 2 \n" | 369 " \"value\": 2 \n" |
364 " } \n" | 370 " } \n" |
365 " ], \n" | 371 " ], \n" |
366 " \"priority\": 200 \n" | 372 " \"priority\": 200 \n" |
367 "}"), | 373 "}"), |
368 json_rule.get())); | 374 json_rule.get())); |
369 scoped_ptr<Rule> rule( | 375 scoped_ptr<Rule> rule(Rule::Create(factories, kExtensionId, base::Time(), |
370 Rule::Create(matcher.condition_factory(), kExtensionId, base::Time(), | 376 json_rule, &AtLeastOneCondition, &error)); |
371 json_rule, &AtLeastOneCondition, &error)); | |
372 EXPECT_TRUE(rule); | 377 EXPECT_TRUE(rule); |
373 EXPECT_EQ("", error); | 378 EXPECT_EQ("", error); |
374 | 379 |
375 ASSERT_TRUE(Rule::JsonRule::Populate( | 380 ASSERT_TRUE(Rule::JsonRule::Populate( |
376 *ParseJson("{ \n" | 381 *ParseJson("{ \n" |
377 " \"id\": \"rule1\", \n" | 382 " \"id\": \"rule1\", \n" |
378 " \"conditions\": [ \n" | 383 " \"conditions\": [ \n" |
379 " ], \n" | 384 " ], \n" |
380 " \"actions\": [ \n" | 385 " \"actions\": [ \n" |
381 " { \n" | 386 " { \n" |
382 " \"value\": 2 \n" | 387 " \"value\": 2 \n" |
383 " } \n" | 388 " } \n" |
384 " ], \n" | 389 " ], \n" |
385 " \"priority\": 200 \n" | 390 " \"priority\": 200 \n" |
386 "}"), | 391 "}"), |
387 json_rule.get())); | 392 json_rule.get())); |
388 rule = Rule::Create(matcher.condition_factory(), kExtensionId, base::Time(), | 393 rule = Rule::Create(factories, kExtensionId, base::Time(), |
389 json_rule, &AtLeastOneCondition, &error); | 394 json_rule, &AtLeastOneCondition, &error); |
390 EXPECT_FALSE(rule); | 395 EXPECT_FALSE(rule); |
391 EXPECT_EQ("No conditions", error); | 396 EXPECT_EQ("No conditions", error); |
392 } | 397 } |
393 | 398 |
394 } // namespace extensions | 399 } // namespace extensions |
OLD | NEW |