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

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

Issue 14427006: Introduce a Factory for Declarative API objects that performs deduping (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Generalize DeduplicatingFactory so that it can be used for ContentAttributes as well Created 7 years, 8 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
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/deduping_factory.h"
6
7 #include "base/values.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9
10 namespace {
11
12 const char kTypeName[] = "Foo";
13 const char kTypeName2[] = "Foo2";
14
15 // This serves as an example how to use the DedupingFactory.
16 class BaseClass : public base::RefCounted<BaseClass> {
17 public:
18 // The type is introduced so that we can compare derived classes even though
19 // Equals takes a parameter of type BaseClass. Each derived class gets an
20 // entry in Type.
21 enum Type { FOO };
22 virtual Type GetType() const = 0;
23
24 // For BaseClassT template:
25 virtual bool Equals(const BaseClass* other) const = 0;
26
27 protected:
28 friend class base::RefCounted<BaseClass>;
29 virtual ~BaseClass() {}
30 };
31
32 class Foo : public BaseClass {
33 public:
34 explicit Foo(int parameter) : parameter_(parameter) {}
35 virtual Type GetType() const OVERRIDE { return FOO; }
36 virtual bool Equals(const BaseClass* other) const OVERRIDE {
37 return other->GetType() == GetType() &&
38 static_cast<const Foo*>(other)->parameter_ == parameter_;
39 }
40 int parameter() const {
41 return parameter_;
42 }
43
44 private:
45 friend class base::RefCounted<BaseClass>;
46 virtual ~Foo() {}
47
48 // Note that this class must be immutable.
49 const int parameter_;
50 DISALLOW_COPY_AND_ASSIGN(Foo);
51 };
52
53 scoped_refptr<const BaseClass> CreateFoo(const std::string& instance_type,
vabr (Chromium) 2013/04/23 15:47:23 nit: if |instance_type| is unused, it is a good pr
battre 2013/04/29 17:42:34 Done. Teeth-gnashingly.
54 const base::Value* value,
55 std::string* error,
56 bool* bad_message) {
57 const base::DictionaryValue* dict =
58 static_cast<const base::DictionaryValue*>(value);
vabr (Chromium) 2013/04/23 15:47:23 nit: Both for human readability, and also error ch
battre 2013/04/29 17:42:34 Done.
59 int parameter = 0;
60 if (!dict->GetInteger("parameter", &parameter)) {
61 *error = "No parameter";
62 *bad_message = true;
63 return scoped_refptr<const BaseClass>(NULL);
64 }
65 return scoped_refptr<const BaseClass>(new Foo(parameter));
66 }
67
68 scoped_ptr<base::DictionaryValue> CreateDictWithParameter(int parameter) {
69 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
70 dict->SetInteger("parameter", parameter);
71 return dict.Pass();
72 }
73
74 } // namespace
75
76 namespace extensions {
77
78 TEST(DedupingFactoryTest, InstantiationParameterized) {
79 DedupingFactory<BaseClass> factory(2);
80 factory.RegisterFactoryMethod(
81 kTypeName, DedupingFactory<BaseClass>::IS_PARAMETERIZED, &CreateFoo);
82
83 scoped_ptr<base::DictionaryValue> d1(CreateDictWithParameter(1));
84 scoped_ptr<base::DictionaryValue> d2(CreateDictWithParameter(2));
85 scoped_ptr<base::DictionaryValue> d3(CreateDictWithParameter(3));
86 scoped_ptr<base::DictionaryValue> d4(CreateDictWithParameter(4));
87
88 std::string error;
89 bool bad_message;
90
91 // Fill factory with 2 different types.
92 scoped_refptr<const BaseClass> c1(
93 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
94 scoped_refptr<const BaseClass> c2(
95 factory.Instantiate(kTypeName, d2.get(), &error, &bad_message));
96 ASSERT_TRUE(c1);
97 ASSERT_TRUE(c2);
98 EXPECT_EQ(1, static_cast<const Foo*>(c1.get())->parameter());
99 EXPECT_EQ(2, static_cast<const Foo*>(c2.get())->parameter());
100
101 // This one produces an overflow, now the cache contains [2, 3]
102 scoped_refptr<const BaseClass> c3(
103 factory.Instantiate(kTypeName, d3.get(), &error, &bad_message));
104 ASSERT_TRUE(c3);
105 EXPECT_EQ(3, static_cast<const Foo*>(c3.get())->parameter());
106
107 // Reuse 2, this should give the same instance as c2.
108 scoped_refptr<const BaseClass> c2_b(
109 factory.Instantiate(kTypeName, d2.get(), &error, &bad_message));
110 EXPECT_EQ(2, static_cast<const Foo*>(c2_b.get())->parameter());
111 EXPECT_EQ(c2, c2_b);
112
113 // Also check that the reuse of 2 moved it to the end, so that the cache is
114 // now [3, 2] and 3 is discarded before 2.
115 // This discards 3, so the cache becomes [2, 1]
116 scoped_refptr<const BaseClass> c1_b(
117 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
118
119 scoped_refptr<const BaseClass> c2_c(
120 factory.Instantiate(kTypeName, d2.get(), &error, &bad_message));
121 EXPECT_EQ(2, static_cast<const Foo*>(c2_c.get())->parameter());
122 EXPECT_EQ(c2, c2_c);
123 }
124
125 TEST(DedupingFactoryTest, InstantiationNonParameterized) {
126 DedupingFactory<BaseClass> factory(2);
127 factory.RegisterFactoryMethod(
128 kTypeName, DedupingFactory<BaseClass>::IS_NOT_PARAMETERIZED, &CreateFoo);
129
130 scoped_ptr<base::DictionaryValue> d1(CreateDictWithParameter(1));
131 scoped_ptr<base::DictionaryValue> d2(CreateDictWithParameter(2));
132
133 std::string error;
134 bool bad_message;
135
136 // We create two instances with different dictionaries but because the type is
137 // declared to be not parameterized, we should get the same instance.
138 scoped_refptr<const BaseClass> c1(
139 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
140 scoped_refptr<const BaseClass> c2(
141 factory.Instantiate(kTypeName, d2.get(), &error, &bad_message));
142 ASSERT_TRUE(c1);
143 ASSERT_TRUE(c2);
144 EXPECT_EQ(1, static_cast<const Foo*>(c1.get())->parameter());
145 EXPECT_EQ(1, static_cast<const Foo*>(c2.get())->parameter());
146 EXPECT_EQ(c1, c2);
147 }
148
149 TEST(DedupingFactoryTest, TypeNames) {
150 DedupingFactory<BaseClass> factory(2);
151 factory.RegisterFactoryMethod(
152 kTypeName, DedupingFactory<BaseClass>::IS_PARAMETERIZED, &CreateFoo);
153 factory.RegisterFactoryMethod(
154 kTypeName2, DedupingFactory<BaseClass>::IS_PARAMETERIZED, &CreateFoo);
155
156 scoped_ptr<base::DictionaryValue> d1(CreateDictWithParameter(1));
157
158 std::string error;
159 bool bad_message;
160
161 scoped_refptr<const BaseClass> c1_a(
162 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
163 scoped_refptr<const BaseClass> c1_b(
164 factory.Instantiate(kTypeName2, d1.get(), &error, &bad_message));
165
166 ASSERT_TRUE(c1_a);
167 ASSERT_TRUE(c1_b);
168 EXPECT_NE(c1_a, c1_b);
169 }
170
171 TEST(DedupingFactoryTest, Clear) {
172 DedupingFactory<BaseClass> factory(2);
173 factory.RegisterFactoryMethod(
174 kTypeName, DedupingFactory<BaseClass>::IS_PARAMETERIZED, &CreateFoo);
175
176 scoped_ptr<base::DictionaryValue> d1(CreateDictWithParameter(1));
177
178 std::string error;
179 bool bad_message;
180
181 scoped_refptr<const BaseClass> c1_a(
182 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
183
184 factory.ClearPrototypes();
185
186 scoped_refptr<const BaseClass> c1_b(
187 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
188
189 ASSERT_TRUE(c1_a);
190 ASSERT_TRUE(c1_b);
191 EXPECT_NE(c1_a, c1_b);
192 }
193
194 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/declarative/deduping_factory.h ('k') | chrome/chrome_browser_extensions.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698