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

Side by Side Diff: components/doodle/doodle_service_unittest.cc

Issue 2710003006: [Doodle] Introduce a DoodleService (Closed)
Patch Set: review2 Created 3 years, 9 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
OLDNEW
(Empty)
1 // Copyright 2017 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 "components/doodle/doodle_service.h"
6
7 #include <memory>
8 #include <utility>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/memory/ptr_util.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 using testing::Eq;
17 using testing::StrictMock;
18
19 namespace doodle {
20
21 namespace {
22
23 class FakeDoodleFetcher : public DoodleFetcher {
24 public:
25 FakeDoodleFetcher() = default;
26 ~FakeDoodleFetcher() override = default;
27
28 void FetchDoodle(FinishedCallback callback) override {
29 callbacks_.push_back(std::move(callback));
30 }
31
32 size_t num_pending_callbacks() const { return callbacks_.size(); }
33
34 void ServeAllCallbacks(DoodleState state,
35 const base::Optional<DoodleConfig>& config) {
36 for (auto& callback : callbacks_) {
37 std::move(callback).Run(state, config);
38 }
39 callbacks_.clear();
40 }
41
42 private:
43 std::vector<FinishedCallback> callbacks_;
44 };
45
46 class MockDoodleObserver : public DoodleService::Observer {
47 public:
48 MOCK_METHOD1(OnDoodleConfigUpdated,
49 void(const base::Optional<DoodleConfig>&));
50 };
51
52 } // namespace
53
54 // Equality operator for DoodleConfigs, for use by testing::Eq.
55 // Note: This must be outside of the anonymous namespace.
56 bool operator==(const DoodleConfig& lhs, const DoodleConfig& rhs) {
57 return lhs.IsEquivalent(rhs);
58 }
59
60 class DoodleServiceTest : public testing::Test {
61 public:
62 DoodleServiceTest() : fetcher_(nullptr) {
63 auto fetcher = base::MakeUnique<FakeDoodleFetcher>();
64 fetcher_ = fetcher.get();
65 service_ = base::MakeUnique<DoodleService>(std::move(fetcher));
66 }
67
68 DoodleService* service() { return service_.get(); }
69 FakeDoodleFetcher* fetcher() { return fetcher_; }
70
71 private:
72 std::unique_ptr<DoodleService> service_;
73 FakeDoodleFetcher* fetcher_;
74 };
75
76 TEST_F(DoodleServiceTest, FetchesConfigOnRefresh) {
vitaliii 2017/02/28 11:37:18 I felt like we prefer 'Should-Do-What-When' to 'Do
Marc Treib 2017/02/28 13:06:49 Ah, I didn't know we had a preference. I named the
77 ASSERT_THAT(service()->config(), Eq(base::nullopt));
78
79 // Request a refresh of the doodle config.
80 service()->Refresh();
81 // The request should have arrived at the fetcher.
82 EXPECT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
83
84 // Serve it (with an arbitrary config).
85 DoodleConfig config;
86 config.doodle_type = DoodleType::SIMPLE;
87 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, config);
88
89 // The config should be available.
90 EXPECT_THAT(service()->config(), Eq(config));
91
92 // Request a refresh again.
93 service()->Refresh();
94 // The request should have arrived at the fetcher again.
95 EXPECT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
96
97 // Serve it with a different config.
98 DoodleConfig config2;
99 config2.doodle_type = DoodleType::SLIDESHOW;
100 DCHECK(!config.IsEquivalent(config2));
101 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, config2);
102
103 // The config should have been updated.
104 EXPECT_THAT(service()->config(), Eq(config2));
105 }
106
107 TEST_F(DoodleServiceTest, CallsObserverOnConfigReceived) {
108 StrictMock<MockDoodleObserver> observer;
109 service()->AddObserver(&observer);
110
111 ASSERT_THAT(service()->config(), Eq(base::nullopt));
112
113 // Request a refresh of the doodle config.
114 service()->Refresh();
115 // The request should have arrived at the fetcher.
116 ASSERT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
117
118 // Serve it (with an arbitrary config). The observer should get notified.
119 DoodleConfig config;
120 config.doodle_type = DoodleType::SIMPLE;
121 EXPECT_CALL(observer, OnDoodleConfigUpdated(Eq(config)));
122 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, config);
123
124 // Remove the observer before the service gets destroyed.
125 service()->RemoveObserver(&observer);
126 }
127
128 TEST_F(DoodleServiceTest, CallsObserverOnConfigRemoved) {
129 // Load some doodle config.
130 service()->Refresh();
131 DoodleConfig config;
132 config.doodle_type = DoodleType::SIMPLE;
133 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, config);
134 ASSERT_THAT(service()->config(), Eq(config));
135
136 // Register an observer and request a refresh.
137 StrictMock<MockDoodleObserver> observer;
138 service()->AddObserver(&observer);
139 service()->Refresh();
140 ASSERT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
141
142 // Serve the request with an empty doodle config. The observer should get
143 // notified.
144 EXPECT_CALL(observer, OnDoodleConfigUpdated(Eq(base::nullopt)));
145 fetcher()->ServeAllCallbacks(DoodleState::NO_DOODLE, base::nullopt);
146
147 // Remove the observer before the service gets destroyed.
148 service()->RemoveObserver(&observer);
149 }
150
151 TEST_F(DoodleServiceTest, CallsObserverOnConfigUpdated) {
152 // Load some doodle config.
153 service()->Refresh();
154 DoodleConfig config;
155 config.doodle_type = DoodleType::SIMPLE;
156 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, config);
157 ASSERT_THAT(service()->config(), Eq(config));
158
159 // Register an observer and request a refresh.
160 StrictMock<MockDoodleObserver> observer;
161 service()->AddObserver(&observer);
162 service()->Refresh();
163 ASSERT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
164
165 // Serve the request with a different doodle config. The observer should get
166 // notified.
167 DoodleConfig config2;
168 config2.doodle_type = DoodleType::SLIDESHOW;
169 DCHECK(!config.IsEquivalent(config2));
vitaliii 2017/02/28 11:37:18 nit: making a typo in config2 is much easier than
Marc Treib 2017/02/28 13:06:49 Good point. Renamed.
170 EXPECT_CALL(observer, OnDoodleConfigUpdated(Eq(config2)));
171 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, config2);
172
173 // Remove the observer before the service gets destroyed.
174 service()->RemoveObserver(&observer);
175 }
176
177 TEST_F(DoodleServiceTest, DoesNotCallObserverWhenConfigEquivalent) {
178 // Load some doodle config.
179 service()->Refresh();
180 DoodleConfig config;
181 config.doodle_type = DoodleType::SIMPLE;
182 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, config);
183 ASSERT_THAT(service()->config(), Eq(config));
184
185 // Register an observer and request a refresh.
186 StrictMock<MockDoodleObserver> observer;
187 service()->AddObserver(&observer);
188 service()->Refresh();
189 ASSERT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
190
191 // Serve the request with an equivalent doodle config. The observer should get
vitaliii 2017/02/28 11:37:18 should not?
Marc Treib 2017/02/28 13:06:49 Indeed, thanks! Too much copypasta...
192 // notified.
193 DoodleConfig config2;
194 config2.doodle_type = DoodleType::SIMPLE;
195 DCHECK(config.IsEquivalent(config2));
196 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, config2);
197
198 // Remove the observer before the service gets destroyed.
199 service()->RemoveObserver(&observer);
200 }
201
202 } // namespace doodle
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698