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

Side by Side Diff: chrome/browser/device_orientation/provider_unittest.cc

Issue 3136008: Implement device_orientation::Provider. (Closed)
Patch Set: Patch Created 10 years, 4 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
« no previous file with comments | « chrome/browser/device_orientation/provider_impl.cc ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 <queue>
6
7 #include "base/lock.h"
8 #include "base/message_loop.h"
9 #include "base/task.h"
10 #include "chrome/browser/device_orientation/data_fetcher.h"
11 #include "chrome/browser/device_orientation/orientation.h"
12 #include "chrome/browser/device_orientation/provider.h"
13 #include "chrome/browser/device_orientation/provider_impl.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace device_orientation {
17 namespace {
18
19 // Class for checking expectations on orientation updates from the Provider.
20 class UpdateChecker : public Provider::Observer {
21 public:
22 explicit UpdateChecker(int* expectations_count_ptr)
23 : expectations_count_ptr_(expectations_count_ptr) {
24 }
25
26 // From Provider::Observer.
27 virtual void OnOrientationUpdate(const Orientation& orientation) {
28 ASSERT_FALSE(expectations_queue_.empty());
29
30 Orientation expected = expectations_queue_.front();
31 expectations_queue_.pop();
32
33 EXPECT_EQ(expected.can_provide_alpha_, orientation.can_provide_alpha_);
34 EXPECT_EQ(expected.can_provide_beta_, orientation.can_provide_beta_);
35 EXPECT_EQ(expected.can_provide_gamma_, orientation.can_provide_gamma_);
36 if (expected.can_provide_alpha_)
37 EXPECT_EQ(expected.alpha_, orientation.alpha_);
38 if (expected.can_provide_beta_)
39 EXPECT_EQ(expected.beta_, orientation.beta_);
40 if (expected.can_provide_gamma_)
41 EXPECT_EQ(expected.gamma_, orientation.gamma_);
42
43 --(*expectations_count_ptr_);
44
45 if (*expectations_count_ptr_ == 0) {
46 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
47 }
48 }
49
50 void AddExpectation(const Orientation& orientation) {
51 expectations_queue_.push(orientation);
52 ++(*expectations_count_ptr_);
53 }
54
55 private:
56 // Set up by the test fixture, which then blocks while it is accessed
57 // from OnOrientationUpdate which is executed on the test fixture's
58 // message_loop_.
59 int* expectations_count_ptr_;
60 std::queue<Orientation> expectations_queue_;
61 };
62
63 // Class for injecting test orientation data into the Provider.
64 class MockOrientationFactory : public base::RefCounted<MockOrientationFactory> {
65 public:
66 MockOrientationFactory() {
67 EXPECT_FALSE(instance_);
68 instance_ = this;
69 }
70
71 ~MockOrientationFactory() {
72 instance_ = NULL;
73 }
74
75 static DataFetcher* CreateDataFetcher() {
76 EXPECT_TRUE(instance_);
77 return new MockDataFetcher(instance_);
78 }
79
80 void SetOrientation(const Orientation& orientation) {
81 AutoLock auto_lock(lock_);
82 orientation_ = orientation;
83 }
84
85 private:
86 // Owned by ProviderImpl. Holds a reference back to MockOrientationFactory.
87 class MockDataFetcher : public DataFetcher {
88 public:
89 explicit MockDataFetcher(MockOrientationFactory* orientation_factory)
90 : orientation_factory_(orientation_factory) { }
91
92 // From DataFetcher. Called by the Provider.
93 virtual bool GetOrientation(Orientation* orientation) {
94 AutoLock auto_lock(orientation_factory_->lock_);
95 *orientation = orientation_factory_->orientation_;
96 return true;
97 }
98
99 private:
100 scoped_refptr<MockOrientationFactory> orientation_factory_;
101 };
102
103 static MockOrientationFactory* instance_;
104 Orientation orientation_;
105 Lock lock_;
106 };
107
108 MockOrientationFactory* MockOrientationFactory::instance_;
109
110 // Mock DataFetcher that always fails to provide any orientation data.
111 class FailingDataFetcher : public DataFetcher {
112 public:
113 // Factory method; passed to and called by the ProviderImpl.
114 static DataFetcher* Create() {
115 return new FailingDataFetcher();
116 }
117
118 // From DataFetcher.
119 virtual bool GetOrientation(Orientation* orientation) {
120 return false;
121 }
122
123 private:
124 FailingDataFetcher() {}
125 };
126
127 class DeviceOrientationProviderTest : public testing::Test {
128 public:
129 DeviceOrientationProviderTest() {
130 }
131
132 // Initialize the test fixture with a ProviderImpl that uses the
133 // DataFetcherFactories in the null-terminated factories array.
134 void Init(ProviderImpl::DataFetcherFactory* factories) {
135 provider_ = new ProviderImpl(&message_loop_, factories);
136 Provider::SetInstanceForTests(provider_);
137 }
138
139 // Initialize the test fixture with a ProviderImpl that uses the
140 // DataFetcherFactory factory.
141 void Init(ProviderImpl::DataFetcherFactory factory) {
142 ProviderImpl::DataFetcherFactory factories[] = { factory, NULL };
143 Init(factories);
144 }
145
146 void ScheduleAddObserver(Provider::Observer* observer) {
147 Task* task = NewRunnableMethod(provider_.get(), &Provider::AddObserver,
148 observer);
149 message_loop_.PostTask(FROM_HERE, task);
150 }
151
152 void RemoveObserver(Provider::Observer* observer) {
153 Task* task = NewRunnableMethod(provider_.get(), &Provider::RemoveObserver,
154 observer);
155 message_loop_.PostTask(FROM_HERE, task);
156 message_loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask());
157 message_loop_.Run();
158 }
159
160 MessageLoop* message_loop() {
161 return &message_loop_;
162 }
163
164 private:
165 // Provider instance under test.
166 scoped_refptr<Provider> provider_;
167
168 // Message loop for adding or removing observers of the provider, and
169 // receiving orientation updates. In non-test situations, this would
170 // be the message loop of the IO thread.
171 MessageLoop message_loop_;
172 };
173
174 TEST_F(DeviceOrientationProviderTest, FailingTest) {
175 Init(FailingDataFetcher::Create);
176 int expectations_count = 0;
177
178 scoped_ptr<UpdateChecker> checker_a(new UpdateChecker(&expectations_count));
179 scoped_ptr<UpdateChecker> checker_b(new UpdateChecker(&expectations_count));
180
181 checker_a->AddExpectation(Orientation::Empty());
182 ScheduleAddObserver(checker_a.get());
183 message_loop()->Run();
184
185 checker_b->AddExpectation(Orientation::Empty());
186 ScheduleAddObserver(checker_b.get());
187 message_loop()->Run();
188 }
189
190 TEST_F(DeviceOrientationProviderTest, ProviderIsSingleton) {
191 Init(FailingDataFetcher::Create);
192
193 scoped_refptr<Provider> provider_a(Provider::GetInstance());
194 scoped_refptr<Provider> provider_b(Provider::GetInstance());
195
196 EXPECT_EQ(provider_a.get(), provider_b.get());
197 }
198
199 TEST_F(DeviceOrientationProviderTest, BasicPushTest) {
200 scoped_refptr<MockOrientationFactory> orientation_factory(
201 new MockOrientationFactory());
202 Init(MockOrientationFactory::CreateDataFetcher);
203 int expectations_count = 0;
204 const Orientation kTestOrientation(true, 1, true, 2, true, 3);
205
206 scoped_ptr<UpdateChecker> checker(new UpdateChecker(&expectations_count));
207 checker->AddExpectation(kTestOrientation);
208 orientation_factory->SetOrientation(kTestOrientation);
209 ScheduleAddObserver(checker.get());
210 message_loop()->Run();
211
212 RemoveObserver(checker.get());
213 }
214
215 TEST_F(DeviceOrientationProviderTest, MultipleObserversPushTest) {
216 scoped_refptr<MockOrientationFactory> orientation_factory(
217 new MockOrientationFactory());
218 Init(MockOrientationFactory::CreateDataFetcher);
219 int expectations_count = 0;
220 const Orientation kTestOrientations[] = {
221 Orientation(true, 1, true, 2, true, 3),
222 Orientation(true, 4, true, 5, true, 6),
223 Orientation(true, 7, true, 8, true, 9)};
224
225 scoped_ptr<UpdateChecker> checker_a(new UpdateChecker(&expectations_count));
226 scoped_ptr<UpdateChecker> checker_b(new UpdateChecker(&expectations_count));
227 scoped_ptr<UpdateChecker> checker_c(new UpdateChecker(&expectations_count));
228
229 checker_a->AddExpectation(kTestOrientations[0]);
230 orientation_factory->SetOrientation(kTestOrientations[0]);
231 ScheduleAddObserver(checker_a.get());
232 message_loop()->Run();
233
234 checker_a->AddExpectation(kTestOrientations[1]);
235 checker_b->AddExpectation(kTestOrientations[0]);
236 checker_b->AddExpectation(kTestOrientations[1]);
237 orientation_factory->SetOrientation(kTestOrientations[1]);
238 ScheduleAddObserver(checker_b.get());
239 message_loop()->Run();
240
241 RemoveObserver(checker_a.get());
242 checker_b->AddExpectation(kTestOrientations[2]);
243 checker_c->AddExpectation(kTestOrientations[1]);
244 checker_c->AddExpectation(kTestOrientations[2]);
245 orientation_factory->SetOrientation(kTestOrientations[2]);
246 ScheduleAddObserver(checker_c.get());
247 message_loop()->Run();
248
249 RemoveObserver(checker_b.get());
250 RemoveObserver(checker_c.get());
251 }
252
253 TEST_F(DeviceOrientationProviderTest, ObserverNotRemoved) {
254 scoped_refptr<MockOrientationFactory> orientation_factory(
255 new MockOrientationFactory());
256 Init(MockOrientationFactory::CreateDataFetcher);
257 int expectations_count = 0;
258 const Orientation kTestOrientation(true, 1, true, 2, true, 3);
259
260 scoped_ptr<UpdateChecker> checker(new UpdateChecker(&expectations_count));
261 checker->AddExpectation(kTestOrientation);
262 orientation_factory->SetOrientation(kTestOrientation);
263 ScheduleAddObserver(checker.get());
264 message_loop()->Run();
265
266 // Note that checker is not removed. This should not be a problem.
267 }
268
269 TEST_F(DeviceOrientationProviderTest, StartFailing) {
270 scoped_refptr<MockOrientationFactory> orientation_factory(
271 new MockOrientationFactory());
272 Init(MockOrientationFactory::CreateDataFetcher);
273 int expectations_count = 0;
274 const Orientation kTestOrientation(true, 1, true, 2, true, 3);
275
276 scoped_ptr<UpdateChecker> checker_a(new UpdateChecker(&expectations_count));
277 scoped_ptr<UpdateChecker> checker_b(new UpdateChecker(&expectations_count));
278
279 orientation_factory->SetOrientation(kTestOrientation);
280 checker_a->AddExpectation(kTestOrientation);
281 ScheduleAddObserver(checker_a.get());
282 message_loop()->Run();
283
284 checker_a->AddExpectation(Orientation::Empty());
285 orientation_factory->SetOrientation(Orientation::Empty());
286 message_loop()->Run();
287
288 checker_b->AddExpectation(Orientation::Empty());
289 ScheduleAddObserver(checker_b.get());
290 message_loop()->Run();
291
292 RemoveObserver(checker_a.get());
293 RemoveObserver(checker_b.get());
294 }
295
296 TEST_F(DeviceOrientationProviderTest, StartStopStart) {
297 scoped_refptr<MockOrientationFactory> orientation_factory(
298 new MockOrientationFactory());
299 Init(MockOrientationFactory::CreateDataFetcher);
300 int expectations_count = 0;
301 const Orientation kTestOrientation(true, 1, true, 2, true, 3);
302 const Orientation kTestOrientation2(true, 4, true, 5, true, 6);
303
304 scoped_ptr<UpdateChecker> checker_a(new UpdateChecker(&expectations_count));
305 scoped_ptr<UpdateChecker> checker_b(new UpdateChecker(&expectations_count));
306
307 checker_a->AddExpectation(kTestOrientation);
308 orientation_factory->SetOrientation(kTestOrientation);
309 ScheduleAddObserver(checker_a.get());
310 message_loop()->Run();
311
312 RemoveObserver(checker_a.get()); // This stops the Provider.
313
314 checker_b->AddExpectation(kTestOrientation2);
315 orientation_factory->SetOrientation(kTestOrientation2);
316 ScheduleAddObserver(checker_b.get());
317 message_loop()->Run();
318 RemoveObserver(checker_b.get());
319 }
320
321 TEST_F(DeviceOrientationProviderTest, SignificantlyDifferent) {
322 scoped_refptr<MockOrientationFactory> orientation_factory(
323 new MockOrientationFactory());
324 Init(MockOrientationFactory::CreateDataFetcher);
325 int expectations_count = 0;
326
327 // Values that should be well below or above the implementation's
328 // significane threshold.
329 const double kInsignificantDifference = 1e-6;
330 const double kSignificantDifference = 30;
331 const double kAlpha = 4, kBeta = 5, kGamma = 6;
332
333 const Orientation first_orientation(true, kAlpha, true, kBeta, true, kGamma);
334
335 const Orientation second_orientation(true, kAlpha + kInsignificantDifference,
336 true, kBeta + kInsignificantDifference,
337 true, kGamma + kInsignificantDifference);
338
339 const Orientation third_orientation(true, kAlpha + kSignificantDifference,
340 true, kBeta + kSignificantDifference,
341 true, kGamma + kSignificantDifference);
342
343 scoped_ptr<UpdateChecker> checker_a(new UpdateChecker(&expectations_count));
344 scoped_ptr<UpdateChecker> checker_b(new UpdateChecker(&expectations_count));
345
346
347 orientation_factory->SetOrientation(first_orientation);
348 checker_a->AddExpectation(first_orientation);
349 ScheduleAddObserver(checker_a.get());
350 message_loop()->Run();
351
352 // The observers should not see this insignificantly different orientation.
353 orientation_factory->SetOrientation(second_orientation);
354 checker_b->AddExpectation(first_orientation);
355 ScheduleAddObserver(checker_b.get());
356 message_loop()->Run();
357
358 orientation_factory->SetOrientation(third_orientation);
359 checker_a->AddExpectation(third_orientation);
360 checker_b->AddExpectation(third_orientation);
361 message_loop()->Run();
362
363 RemoveObserver(checker_a.get());
364 RemoveObserver(checker_b.get());
365 }
366
367 } // namespace
368
369 } // namespace device_orientation
OLDNEW
« no previous file with comments | « chrome/browser/device_orientation/provider_impl.cc ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698