- add sources.
[platform/framework/web/crosswalk.git] / src / ui / app_list / pagination_model_unittest.cc
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 "ui/app_list/pagination_model.h"
6
7 #include <string>
8
9 #include "base/basictypes.h"
10 #include "base/compiler_specific.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/strings/stringprintf.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "ui/app_list/pagination_model_observer.h"
15
16 namespace app_list {
17 namespace test {
18
19 class TestPaginationModelObserver : public PaginationModelObserver {
20  public:
21   TestPaginationModelObserver()
22       : model_(NULL),
23         expected_page_selection_(0),
24         expected_transition_start_(0),
25         expected_transition_end_(0),
26         transition_page_(-1) {
27     Reset();
28   }
29   virtual ~TestPaginationModelObserver() {}
30
31   void Reset() {
32     selection_count_ = 0;
33     transition_start_count_ = 0;
34     transition_end_count_ = 0;
35     selected_pages_.clear();
36   }
37
38   void set_model(PaginationModel* model) { model_ = model; }
39
40   void set_expected_page_selection(int expected_page_selection) {
41     expected_page_selection_ = expected_page_selection;
42   }
43   void set_expected_transition_start(int expected_transition_start) {
44     expected_transition_start_ = expected_transition_start;
45   }
46   void set_expected_transition_end(int expected_transition_end) {
47     expected_transition_end_ = expected_transition_end;
48   }
49   void set_transition_page(int page) { transition_page_ = page; }
50
51   const std::string& selected_pages() const { return selected_pages_; }
52   int selection_count() const { return selection_count_; }
53   int transition_start_count() const { return transition_start_count_; }
54   int transition_end_count() const { return transition_end_count_; }
55
56  private:
57   void AppendSelectedPage(int page) {
58     if (selected_pages_.length())
59       selected_pages_.append(std::string(" "));
60     selected_pages_.append(base::StringPrintf("%d", page));
61   }
62
63   // PaginationModelObserver overrides:
64   virtual void TotalPagesChanged() OVERRIDE {}
65   virtual void SelectedPageChanged(int old_selected,
66                                    int new_selected) OVERRIDE {
67     AppendSelectedPage(new_selected);
68     ++selection_count_;
69     if (expected_page_selection_ &&
70         selection_count_ == expected_page_selection_) {
71       base::MessageLoop::current()->Quit();
72     }
73   }
74
75   virtual void TransitionStarted() OVERRIDE {
76   }
77
78   virtual void TransitionChanged() OVERRIDE {
79     if (transition_page_ == -1 ||
80         model_->transition().target_page == transition_page_) {
81       if (model_->transition().progress == 0)
82         ++transition_start_count_;
83       if (model_->transition().progress == 1)
84         ++transition_end_count_;
85     }
86
87     if ((expected_transition_start_ &&
88          transition_start_count_ == expected_transition_start_) ||
89         (expected_transition_end_ &&
90          transition_end_count_ == expected_transition_end_)) {
91       base::MessageLoop::current()->Quit();
92     }
93   }
94
95   PaginationModel* model_;
96
97   int expected_page_selection_;
98   int expected_transition_start_;
99   int expected_transition_end_;
100
101   int selection_count_;
102   int transition_start_count_;
103   int transition_end_count_;
104
105   // Indicate which page index should be counted for |transition_start_count_|
106   // and |transition_end_count_|. -1 means all the pages should be counted.
107   int transition_page_;
108
109   std::string selected_pages_;
110
111   DISALLOW_COPY_AND_ASSIGN(TestPaginationModelObserver);
112 };
113
114 class PaginationModelTest : public testing::Test {
115  public:
116   PaginationModelTest() {}
117   virtual ~PaginationModelTest() {}
118
119   // testing::Test overrides:
120   virtual void SetUp() OVERRIDE {
121     pagination_.SetTotalPages(5);
122     pagination_.SetTransitionDurations(1, 1);
123     observer_.set_model(&pagination_);
124     pagination_.AddObserver(&observer_);
125   }
126   virtual void TearDown() OVERRIDE {
127     pagination_.RemoveObserver(&observer_);
128     observer_.set_model(NULL);
129   }
130
131  protected:
132   void SetStartPageAndExpects(int start_page,
133                               int expected_selection,
134                               int expected_transition_start,
135                               int expected_transition_end) {
136     observer_.set_expected_page_selection(0);
137     pagination_.SelectPage(start_page, false /* animate */);
138     observer_.Reset();
139     observer_.set_expected_page_selection(expected_selection);
140     observer_.set_expected_transition_start(expected_transition_start);
141     observer_.set_expected_transition_end(expected_transition_end);
142   }
143
144   PaginationModel pagination_;
145   TestPaginationModelObserver observer_;
146
147  private:
148   base::MessageLoopForUI message_loop_;
149
150   DISALLOW_COPY_AND_ASSIGN(PaginationModelTest);
151 };
152
153 TEST_F(PaginationModelTest, SelectPage) {
154   pagination_.SelectPage(2, false /* animate */);
155   pagination_.SelectPage(4, false /* animate */);
156   pagination_.SelectPage(3, false /* animate */);
157   pagination_.SelectPage(1, false /* animate */);
158
159   EXPECT_EQ(0, observer_.transition_start_count());
160   EXPECT_EQ(0, observer_.transition_end_count());
161   EXPECT_EQ(4, observer_.selection_count());
162   EXPECT_EQ(std::string("2 4 3 1"), observer_.selected_pages());
163
164   // Nothing happens if select the same page.
165   pagination_.SelectPage(1, false /* animate */);
166   EXPECT_EQ(4, observer_.selection_count());
167   EXPECT_EQ(std::string("2 4 3 1"), observer_.selected_pages());
168 }
169
170 TEST_F(PaginationModelTest, SelectPageAnimated) {
171   const int kStartPage = 0;
172
173   // One transition.
174   SetStartPageAndExpects(kStartPage, 1, 0, 0);
175   pagination_.SelectPage(1, true /* animate */);
176   base::MessageLoop::current()->Run();
177   EXPECT_EQ(1, observer_.transition_start_count());
178   EXPECT_EQ(1, observer_.transition_end_count());
179   EXPECT_EQ(1, observer_.selection_count());
180   EXPECT_EQ(std::string("1"), observer_.selected_pages());
181
182   // Two transitions in a row.
183   SetStartPageAndExpects(kStartPage, 2, 0, 0);
184   pagination_.SelectPage(1, true /* animate */);
185   pagination_.SelectPage(3, true /* animate */);
186   base::MessageLoop::current()->Run();
187   EXPECT_EQ(2, observer_.transition_start_count());
188   EXPECT_EQ(2, observer_.transition_end_count());
189   EXPECT_EQ(2, observer_.selection_count());
190   EXPECT_EQ(std::string("1 3"), observer_.selected_pages());
191
192   // Transition to same page twice and only one should happen.
193   SetStartPageAndExpects(kStartPage, 1, 0, 0);
194   pagination_.SelectPage(1, true /* animate */);
195   pagination_.SelectPage(1, true /* animate */);  // Ignored.
196   base::MessageLoop::current()->Run();
197   EXPECT_EQ(1, observer_.transition_start_count());
198   EXPECT_EQ(1, observer_.transition_end_count());
199   EXPECT_EQ(1, observer_.selection_count());
200   EXPECT_EQ(std::string("1"), observer_.selected_pages());
201
202   // More than two transitions and only the first and last would happen.
203   SetStartPageAndExpects(kStartPage, 2, 0, 0);
204   pagination_.SelectPage(1, true /* animate */);
205   pagination_.SelectPage(3, true /* animate */);  // Ignored
206   pagination_.SelectPage(4, true /* animate */);  // Ignored
207   pagination_.SelectPage(2, true /* animate */);
208   base::MessageLoop::current()->Run();
209   EXPECT_EQ(2, observer_.transition_start_count());
210   EXPECT_EQ(2, observer_.transition_end_count());
211   EXPECT_EQ(2, observer_.selection_count());
212   EXPECT_EQ(std::string("1 2"), observer_.selected_pages());
213
214   // Multiple transitions with one transition that goes back to the original
215   // and followed by a new transition. Two transitions would happen. The first
216   // one will be reversed by the kStart transition and the second one will be
217   // finished.
218   SetStartPageAndExpects(kStartPage, 1, 0, 0);
219   pagination_.SelectPage(1, true /* animate */);
220   pagination_.SelectPage(2, true /* animate */);  // Ignored
221   pagination_.SelectPage(kStartPage, true /* animate */);
222   pagination_.SelectPage(3, true /* animate */);
223   base::MessageLoop::current()->Run();
224   EXPECT_EQ(std::string("3"), observer_.selected_pages());
225 }
226
227 TEST_F(PaginationModelTest, SimpleScroll) {
228   const int kStartPage = 2;
229
230   // Scroll to the next page (negative delta) and finish it.
231   SetStartPageAndExpects(kStartPage, 1, 0, 0);
232   pagination_.StartScroll();
233   pagination_.UpdateScroll(-0.1);
234   EXPECT_EQ(kStartPage + 1, pagination_.transition().target_page);
235   pagination_.EndScroll(false);  // Finish transition
236   base::MessageLoop::current()->Run();
237   EXPECT_EQ(1, observer_.selection_count());
238
239   // Scroll to the previous page (positive delta) and finish it.
240   SetStartPageAndExpects(kStartPage, 1, 0, 0);
241   pagination_.StartScroll();
242   pagination_.UpdateScroll(0.1);
243   EXPECT_EQ(kStartPage - 1, pagination_.transition().target_page);
244   pagination_.EndScroll(false);  // Finish transition
245   base::MessageLoop::current()->Run();
246   EXPECT_EQ(1, observer_.selection_count());
247
248   // Scroll to the next page (negative delta) and cancel it.
249   SetStartPageAndExpects(kStartPage, 0, 1, 0);
250   pagination_.StartScroll();
251   pagination_.UpdateScroll(-0.1);
252   EXPECT_EQ(kStartPage + 1, pagination_.transition().target_page);
253   pagination_.EndScroll(true);  // Cancel transition
254   base::MessageLoop::current()->Run();
255   EXPECT_EQ(0, observer_.selection_count());
256
257   // Scroll to the previous page (position delta) and cancel it.
258   SetStartPageAndExpects(kStartPage, 0, 1, 0);
259   pagination_.StartScroll();
260   pagination_.UpdateScroll(0.1);
261   EXPECT_EQ(kStartPage - 1, pagination_.transition().target_page);
262   pagination_.EndScroll(true);  // Cancel transition
263   base::MessageLoop::current()->Run();
264   EXPECT_EQ(0, observer_.selection_count());
265 }
266
267 TEST_F(PaginationModelTest, ScrollWithTransition) {
268   const int kStartPage = 2;
269
270   // Scroll to the next page (negative delta) with a transition in the same
271   // direction.
272   SetStartPageAndExpects(kStartPage, 1, 0, 0);
273   pagination_.SetTransition(PaginationModel::Transition(kStartPage + 1, 0.5));
274   pagination_.StartScroll();
275   pagination_.UpdateScroll(-0.1);
276   EXPECT_EQ(kStartPage + 1, pagination_.transition().target_page);
277   EXPECT_EQ(0.6, pagination_.transition().progress);
278   pagination_.EndScroll(false);
279   base::MessageLoop::current()->Run();
280   EXPECT_EQ(1, observer_.selection_count());
281
282   // Scroll to the next page (negative delta) with a transition in a different
283   // direction.
284   SetStartPageAndExpects(kStartPage, 0, 1, 0);
285   pagination_.SetTransition(PaginationModel::Transition(kStartPage - 1, 0.5));
286   pagination_.StartScroll();
287   pagination_.UpdateScroll(-0.1);
288   EXPECT_EQ(kStartPage - 1, pagination_.transition().target_page);
289   EXPECT_EQ(0.4, pagination_.transition().progress);
290   pagination_.EndScroll(true);
291
292   // Scroll to the previous page (positive delta) with a transition in the same
293   // direction.
294   SetStartPageAndExpects(kStartPage, 1, 0, 0);
295   pagination_.SetTransition(PaginationModel::Transition(kStartPage - 1, 0.5));
296   pagination_.StartScroll();
297   pagination_.UpdateScroll(0.1);
298   EXPECT_EQ(kStartPage - 1, pagination_.transition().target_page);
299   EXPECT_EQ(0.6, pagination_.transition().progress);
300   pagination_.EndScroll(false);
301   base::MessageLoop::current()->Run();
302   EXPECT_EQ(1, observer_.selection_count());
303
304   // Scroll to the previous page (positive delta) with a transition in a
305   // different direction.
306   SetStartPageAndExpects(kStartPage, 0, 1, 0);
307   pagination_.SetTransition(PaginationModel::Transition(kStartPage + 1, 0.5));
308   pagination_.StartScroll();
309   pagination_.UpdateScroll(0.1);
310   EXPECT_EQ(kStartPage + 1, pagination_.transition().target_page);
311   EXPECT_EQ(0.4, pagination_.transition().progress);
312   pagination_.EndScroll(true);
313 }
314
315 TEST_F(PaginationModelTest, LongScroll) {
316   const int kStartPage = 2;
317
318   // Scroll to the next page (negative delta) with a transition in the same
319   // direction. And scroll enough to change page twice.
320   SetStartPageAndExpects(kStartPage, 2, 0, 0);
321   pagination_.SetTransition(PaginationModel::Transition(kStartPage + 1, 0.5));
322   pagination_.StartScroll();
323   pagination_.UpdateScroll(-0.1);
324   EXPECT_EQ(kStartPage + 1, pagination_.transition().target_page);
325   EXPECT_EQ(0.6, pagination_.transition().progress);
326   pagination_.UpdateScroll(-0.5);
327   EXPECT_EQ(1, observer_.selection_count());
328   pagination_.UpdateScroll(-0.5);
329   EXPECT_EQ(kStartPage + 2, pagination_.transition().target_page);
330   pagination_.EndScroll(false);
331   base::MessageLoop::current()->Run();
332   EXPECT_EQ(2, observer_.selection_count());
333
334   // Scroll to the next page (negative delta) with a transition in a different
335   // direction. And scroll enough to revert it and switch page once.
336   SetStartPageAndExpects(kStartPage, 1, 0, 0);
337   pagination_.SetTransition(PaginationModel::Transition(kStartPage - 1, 0.5));
338   pagination_.StartScroll();
339   pagination_.UpdateScroll(-0.1);
340   EXPECT_EQ(kStartPage - 1, pagination_.transition().target_page);
341   EXPECT_EQ(0.4, pagination_.transition().progress);
342   pagination_.UpdateScroll(-0.5);  // This clears the transition.
343   pagination_.UpdateScroll(-0.5);  // This starts a new transition.
344   EXPECT_EQ(kStartPage + 1, pagination_.transition().target_page);
345   pagination_.EndScroll(false);
346   base::MessageLoop::current()->Run();
347   EXPECT_EQ(1, observer_.selection_count());
348
349   // Similar cases as above but in the opposite direction.
350   // Scroll to the previous page (positive delta) with a transition in the same
351   // direction. And scroll enough to change page twice.
352   SetStartPageAndExpects(kStartPage, 2, 0, 0);
353   pagination_.SetTransition(PaginationModel::Transition(kStartPage - 1, 0.5));
354   pagination_.StartScroll();
355   pagination_.UpdateScroll(0.1);
356   EXPECT_EQ(kStartPage - 1, pagination_.transition().target_page);
357   EXPECT_EQ(0.6, pagination_.transition().progress);
358   pagination_.UpdateScroll(0.5);
359   EXPECT_EQ(1, observer_.selection_count());
360   pagination_.UpdateScroll(0.5);
361   EXPECT_EQ(kStartPage - 2, pagination_.transition().target_page);
362   pagination_.EndScroll(false);
363   base::MessageLoop::current()->Run();
364   EXPECT_EQ(2, observer_.selection_count());
365
366   // Scroll to the previous page (positive delta) with a transition in a
367   // different direction. And scroll enough to revert it and switch page once.
368   SetStartPageAndExpects(kStartPage, 1, 0, 0);
369   pagination_.SetTransition(PaginationModel::Transition(kStartPage + 1, 0.5));
370   pagination_.StartScroll();
371   pagination_.UpdateScroll(0.1);
372   EXPECT_EQ(kStartPage + 1, pagination_.transition().target_page);
373   EXPECT_EQ(0.4, pagination_.transition().progress);
374   pagination_.UpdateScroll(0.5);  // This clears the transition.
375   pagination_.UpdateScroll(0.5);  // This starts a new transition.
376   EXPECT_EQ(kStartPage - 1, pagination_.transition().target_page);
377   pagination_.EndScroll(false);
378   base::MessageLoop::current()->Run();
379   EXPECT_EQ(1, observer_.selection_count());
380 }
381
382 TEST_F(PaginationModelTest, FireTransitionZero) {
383   const int kStartPage = 2;
384
385   // Scroll to next page then revert the scroll and make sure transition
386   // progress 0 is fired when previous scroll is cleared.
387   SetStartPageAndExpects(kStartPage, 0, 0, 0);
388   pagination_.StartScroll();
389   pagination_.UpdateScroll(-0.1);
390
391   int target_page = kStartPage + 1;
392   EXPECT_EQ(target_page, pagination_.transition().target_page);
393   observer_.set_transition_page(target_page);
394
395   pagination_.UpdateScroll(0.2);  // This clears the transition.
396   EXPECT_EQ(1, observer_.transition_start_count());
397   pagination_.EndScroll(true);  // Cancel transition.
398
399   // Similar to above but in the other direction.
400   SetStartPageAndExpects(kStartPage, 0, 0, 0);
401   pagination_.StartScroll();
402   pagination_.UpdateScroll(0.1);
403
404   target_page = kStartPage - 1;
405   EXPECT_EQ(target_page, pagination_.transition().target_page);
406   observer_.set_transition_page(target_page);
407
408   pagination_.UpdateScroll(-0.2);  // This clears the transition.
409   EXPECT_EQ(1, observer_.transition_start_count());
410   pagination_.EndScroll(true);  // Cancel transition.
411 }
412
413 TEST_F(PaginationModelTest, SelectedPageIsLost) {
414   pagination_.SetTotalPages(2);
415   // The selected page is set to 0 once the total number of pages are set.
416   EXPECT_EQ(0, pagination_.selected_page());
417
418   pagination_.SelectPage(1, false /* animate */);
419   EXPECT_EQ(1, pagination_.selected_page());
420
421   // The selected page is unchanged if it's still valid.
422   pagination_.SetTotalPages(3);
423   EXPECT_EQ(1, pagination_.selected_page());
424   pagination_.SetTotalPages(2);
425   EXPECT_EQ(1, pagination_.selected_page());
426
427   // But if the currently selected_page exceeds the total number of pages,
428   // it automatically switches to the last page.
429   pagination_.SetTotalPages(1);
430   EXPECT_EQ(0, pagination_.selected_page());
431 }
432
433 }  // namespace test
434 }  // namespace app_list