1// Copyright 2013 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 "testing/gtest/include/gtest/gtest.h"
6#include "ui/gfx/image/image.h"
7#include "ui/gfx/image/image_family.h"
8#include "ui/gfx/image/image_skia.h"
9#include "ui/gfx/image/image_unittest_util.h"
10
11namespace {
12
13namespace gt = gfx::test;
14
15// Tests that |image| != NULL, and has the given width and height.
16// This is a macro instead of a function, so that the correct line numbers are
17// reported when a test fails.
18#define EXPECT_IMAGE_NON_NULL_AND_SIZE(image, expected_width, expected_height) \
19do { \
20  const gfx::Image* image_ = image; \
21  EXPECT_TRUE(image_); \
22  EXPECT_EQ(expected_width, image_->Width()); \
23  EXPECT_EQ(expected_height, image_->Height()); \
24} while(0)
25
26class ImageFamilyTest : public testing::Test {
27 public:
28  // Construct an ImageFamily. Implicitly tests Add and Empty.
29  virtual void SetUp() OVERRIDE {
30    EXPECT_TRUE(image_family_.empty());
31
32    // Aspect ratio 1:1.
33    image_family_.Add(gt::CreateImageSkia(32, 32));
34    EXPECT_FALSE(image_family_.empty());
35    image_family_.Add(gt::CreateImageSkia(16, 16));
36    image_family_.Add(gt::CreateImageSkia(64, 64));
37    // Duplicate (should override previous one).
38    // Insert an Image directly, instead of an ImageSkia.
39    gfx::Image image(gt::CreateImageSkia(32, 32));
40    image_family_.Add(image);
41    // Aspect ratio 1:4.
42    image_family_.Add(gt::CreateImageSkia(3, 12));
43    image_family_.Add(gt::CreateImageSkia(12, 48));
44    // Aspect ratio 4:1.
45    image_family_.Add(gt::CreateImageSkia(512, 128));
46    image_family_.Add(gt::CreateImageSkia(256, 64));
47
48    EXPECT_FALSE(image_family_.empty());
49  }
50
51  gfx::ImageFamily image_family_;
52};
53
54TEST_F(ImageFamilyTest, Clear) {
55  image_family_.clear();
56  EXPECT_TRUE(image_family_.empty());
57}
58
59// Tests iteration over an ImageFamily.
60TEST_F(ImageFamilyTest, Iteration) {
61  gfx::ImageFamily::const_iterator it = image_family_.begin();
62  gfx::ImageFamily::const_iterator end = image_family_.end();
63
64  // Expect iteration in order of aspect ratio (from thinnest to widest), then
65  // size.
66  EXPECT_TRUE(it != end);
67  EXPECT_EQ(gfx::Size(3, 12), it->Size());
68  ++it;
69  EXPECT_TRUE(it != end);
70  EXPECT_EQ(gfx::Size(12, 48), it->Size());
71  it++;   // Test post-increment.
72  EXPECT_TRUE(it != end);
73  EXPECT_EQ(gfx::Size(16, 16), it->Size());
74  ++it;
75  EXPECT_TRUE(it != end);
76  EXPECT_EQ(gfx::Size(32, 32), it->Size());
77  --it;   // Test decrement
78  EXPECT_TRUE(it != end);
79  EXPECT_EQ(gfx::Size(16, 16), it->Size());
80  ++it;
81  ++it;
82  EXPECT_TRUE(it != end);
83  EXPECT_EQ(gfx::Size(64, 64), (*it).Size());   // Test operator*.
84  ++it;
85  EXPECT_TRUE(it != end);
86  EXPECT_EQ(gfx::Size(256, 64), it->Size());
87  ++it;
88  EXPECT_TRUE(it != end);
89  EXPECT_EQ(gfx::Size(512, 128), it->Size());
90  ++it;
91
92  EXPECT_TRUE(it == end);
93}
94
95TEST_F(ImageFamilyTest, Get) {
96  // Get on an empty family.
97  gfx::ImageFamily empty_family;
98  EXPECT_TRUE(empty_family.empty());
99  EXPECT_FALSE(empty_family.GetBest(32, 32));
100  EXPECT_FALSE(empty_family.GetBest(0, 32));
101  EXPECT_FALSE(empty_family.GetBest(32, 0));
102
103  // Get various aspect ratios and sizes on the sample family.
104
105  // 0x0 (expect the smallest square image).
106  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(0, 0), 16, 16);
107  // GetBest(0, N) or GetBest(N, 0) should be treated the same as GetBest(0, 0).
108  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(0, 16), 16, 16);
109  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(0, 64), 16, 16);
110  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(16, 0), 16, 16);
111  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(64, 0), 16, 16);
112
113  // Thinner than thinnest image.
114  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(2, 12), 3, 12);
115  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(2, 13), 12, 48);
116  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(10, 60), 12, 48);
117
118  // Between two images' aspect ratio.
119  // Note: Testing the boundary around 1:2 and 2:1, half way to 1:4 and 4:1.
120  // Ties are broken by favouring the thinner aspect ratio.
121  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(63, 32), 64, 64);
122  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(64, 32), 64, 64);
123  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(65, 32), 256, 64);
124  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(32, 63), 64, 64);
125  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(32, 64), 12, 48);
126  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(32, 65), 12, 48);
127
128  // Exact match aspect ratio.
129  // Exact match size.
130  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(32, 32), 32, 32);
131  // Slightly smaller.
132  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(31, 31), 32, 32);
133  // Much smaller.
134  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(17, 17), 32, 32);
135  // Exact match size.
136  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(16, 16), 16, 16);
137  // Smaller than any image.
138  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(3, 3), 16, 16);
139  // Larger than any image.
140  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(512, 512), 64, 64);
141  // 1:4 aspect ratio.
142  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(16, 64), 12, 48);
143  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(2, 8), 3, 12);
144  // 4:1 aspect ratio.
145  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(64, 16), 256, 64);
146  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(260, 65), 512, 128);
147
148  // Wider than widest image.
149  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(255, 51), 256, 64);
150  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(260, 52), 512, 128);
151  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(654, 129), 512, 128);
152}
153
154// Test adding and looking up images with 0 width and height.
155TEST_F(ImageFamilyTest, ZeroWidthAndHeight) {
156  // An empty Image. Should be considered to have 0 width and height.
157  image_family_.Add(gfx::Image());
158  // Images with 0 width OR height should be treated the same as an image with 0
159  // width AND height (in fact, the ImageSkias should be indistinguishable).
160  image_family_.Add(gt::CreateImageSkia(32, 0));
161  image_family_.Add(gt::CreateImageSkia(0, 32));
162
163  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(0, 0), 0, 0);
164  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(1, 1), 16, 16);
165  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(32, 32), 32, 32);
166
167  // GetBest(0, N) or GetBest(N, 0) should be treated the same as GetBest(0, 0).
168  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(0, 1), 0, 0);
169  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(0, 32), 0, 0);
170  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(1, 0), 0, 0);
171  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(32, 0), 0, 0);
172
173  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(1, 32), 12, 48);
174  EXPECT_IMAGE_NON_NULL_AND_SIZE(image_family_.GetBest(32, 1), 256, 64);
175}
176
177}  // namespace
178