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

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: 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;
vabr (Chromium) 2013/04/23 12:22:12 This is just an accessor of a constant member vari
vabr (Chromium) 2013/04/23 12:22:12 If GetType() (or type()) is only used in Equals, i
vabr (Chromium) 2013/04/23 12:30:43 And if GetType/type is protected, then so should b
battre 2013/04/23 14:20:50 Done.
battre 2013/04/23 14:20:50 If we protect GetType(), Foo::Equals cannot call i
vabr (Chromium) 2013/04/23 15:47:23 Are you sure? All protected parts of a base class
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 base::DictionaryValue* dict,
54 std::string* error,
55 bool* bad_message) {
56 int parameter = 0;
57 if (!dict->GetInteger("parameter", &parameter)) {
58 *error = "No parameter";
59 *bad_message = true;
60 return scoped_refptr<const BaseClass>(NULL);
61 }
62 return scoped_refptr<const BaseClass>(new Foo(parameter));
63 }
64
65 scoped_ptr<base::DictionaryValue> CreateDictWithParameter(int parameter) {
66 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
67 dict->SetInteger("parameter", parameter);
68 return dict.Pass();
69 }
70
71 } // namespace
72
73 namespace extensions {
74
75 TEST(DedupingFactoryTest, InstantiationParameterized) {
76 DedupingFactory<BaseClass> factory(2);
77 factory.RegisterFactoryMethod(
78 kTypeName, DedupingFactory<BaseClass>::IS_PARAMETERIZED, &CreateFoo);
79
80 scoped_ptr<base::DictionaryValue> d1(CreateDictWithParameter(1));
81 scoped_ptr<base::DictionaryValue> d2(CreateDictWithParameter(2));
82 scoped_ptr<base::DictionaryValue> d3(CreateDictWithParameter(3));
83 scoped_ptr<base::DictionaryValue> d4(CreateDictWithParameter(4));
84
85 std::string error;
86 bool bad_message;
87
88 // Fill factory with 2 different types.
89 scoped_refptr<const BaseClass> c1(
90 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
91 scoped_refptr<const BaseClass> c2(
92 factory.Instantiate(kTypeName, d2.get(), &error, &bad_message));
93 ASSERT_TRUE(c1);
94 ASSERT_TRUE(c2);
95 EXPECT_EQ(1, static_cast<const Foo*>(c1.get())->parameter());
96 EXPECT_EQ(2, static_cast<const Foo*>(c2.get())->parameter());
97
98 // This one produces an overflow, now the cache contains [2, 3]
99 scoped_refptr<const BaseClass> c3(
100 factory.Instantiate(kTypeName, d3.get(), &error, &bad_message));
101 ASSERT_TRUE(c3);
102 EXPECT_EQ(3, static_cast<const Foo*>(c3.get())->parameter());
103
104 // Reuse 2, this should give the same instance as c2.
105 scoped_refptr<const BaseClass> c2_b(
106 factory.Instantiate(kTypeName, d2.get(), &error, &bad_message));
107 EXPECT_EQ(2, static_cast<const Foo*>(c2_b.get())->parameter());
108 EXPECT_EQ(c2, c2_b);
109
110 // Also check that the reuse of 2 moved it to the end, so that the cache is
111 // now [3, 2] and 3 is discarded before 2.
112 // This discards 3, so the cache becomes [2, 1]
113 scoped_refptr<const BaseClass> c1_b(
114 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
115
116 scoped_refptr<const BaseClass> c2_c(
117 factory.Instantiate(kTypeName, d2.get(), &error, &bad_message));
118 EXPECT_EQ(2, static_cast<const Foo*>(c2_c.get())->parameter());
119 EXPECT_EQ(c2, c2_c);
120 }
121
122 TEST(DedupingFactoryTest, InstantiationNonParameterized) {
123 DedupingFactory<BaseClass> factory(2);
124 factory.RegisterFactoryMethod(
125 kTypeName, DedupingFactory<BaseClass>::IS_NOT_PARAMETERIZED, &CreateFoo);
126
127 scoped_ptr<base::DictionaryValue> d1(CreateDictWithParameter(1));
128 scoped_ptr<base::DictionaryValue> d2(CreateDictWithParameter(2));
129
130 std::string error;
131 bool bad_message;
132
133 // We create two instances with different dictionaries but because the type is
134 // declared to be not parameterized, we should get the same instance.
135 scoped_refptr<const BaseClass> c1(
136 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
137 scoped_refptr<const BaseClass> c2(
138 factory.Instantiate(kTypeName, d2.get(), &error, &bad_message));
139 ASSERT_TRUE(c1);
140 ASSERT_TRUE(c2);
141 EXPECT_EQ(1, static_cast<const Foo*>(c1.get())->parameter());
142 EXPECT_EQ(1, static_cast<const Foo*>(c2.get())->parameter());
143 EXPECT_EQ(c1, c2);
144 }
145
146 TEST(DedupingFactoryTest, TypeNames) {
147 DedupingFactory<BaseClass> factory(2);
148 factory.RegisterFactoryMethod(
149 kTypeName, DedupingFactory<BaseClass>::IS_PARAMETERIZED, &CreateFoo);
150 factory.RegisterFactoryMethod(
151 kTypeName2, DedupingFactory<BaseClass>::IS_PARAMETERIZED, &CreateFoo);
152
153 scoped_ptr<base::DictionaryValue> d1(CreateDictWithParameter(1));
154
155 std::string error;
156 bool bad_message;
157
158 scoped_refptr<const BaseClass> c1_a(
159 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
160 scoped_refptr<const BaseClass> c1_b(
161 factory.Instantiate(kTypeName2, d1.get(), &error, &bad_message));
162
163 ASSERT_TRUE(c1_a);
164 ASSERT_TRUE(c1_b);
165 EXPECT_NE(c1_a, c1_b);
166 }
167
168 TEST(DedupingFactoryTest, Clear) {
169 DedupingFactory<BaseClass> factory(2);
170 factory.RegisterFactoryMethod(
171 kTypeName, DedupingFactory<BaseClass>::IS_PARAMETERIZED, &CreateFoo);
172
173 scoped_ptr<base::DictionaryValue> d1(CreateDictWithParameter(1));
174
175 std::string error;
176 bool bad_message;
177
178 scoped_refptr<const BaseClass> c1_a(
179 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
180
181 factory.ClearPrototypes();
182
183 scoped_refptr<const BaseClass> c1_b(
184 factory.Instantiate(kTypeName, d1.get(), &error, &bad_message));
185
186 ASSERT_TRUE(c1_a);
187 ASSERT_TRUE(c1_b);
188 EXPECT_NE(c1_a, c1_b);
189 }
190
191 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698