summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorhuangs <huangs@chromium.org>2015-05-07 23:27:15 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-08 06:27:52 +0000
commit73fa324f9528194085909ebcdf54566ddfae28ab (patch)
treea26583bc204c774a63e338a32340c12c7b2676de /components
parent09db9160ab8676c5683383c5f39b59fe877a4e32 (diff)
downloadchromium_src-73fa324f9528194085909ebcdf54566ddfae28ab.zip
chromium_src-73fa324f9528194085909ebcdf54566ddfae28ab.tar.gz
chromium_src-73fa324f9528194085909ebcdf54566ddfae28ab.tar.bz2
[Large Icon Service] Adding unit test.
BUG=467712 Review URL: https://codereview.chromium.org/1124803005 Cr-Commit-Position: refs/heads/master@{#328933}
Diffstat (limited to 'components')
-rw-r--r--components/components_tests.gyp1
-rw-r--r--components/favicon/core/BUILD.gn18
-rw-r--r--components/favicon/core/favicon_service.h2
-rw-r--r--components/favicon/core/large_icon_service.cc3
-rw-r--r--components/favicon/core/large_icon_service.h3
-rw-r--r--components/favicon/core/large_icon_service_unittest.cc281
-rw-r--r--components/favicon_base/fallback_icon_style.cc7
-rw-r--r--components/favicon_base/fallback_icon_style.h2
8 files changed, 316 insertions, 1 deletions
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index 2266483..5178329 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -165,6 +165,7 @@
'favicon_unittest_sources': [
'favicon/content/content_favicon_driver_unittest.cc',
'favicon/core/favicon_handler_unittest.cc',
+ 'favicon/core/large_icon_service_unittest.cc',
],
'undo_unittest_sources': [
'undo/bookmark_undo_service_test.cc',
diff --git a/components/favicon/core/BUILD.gn b/components/favicon/core/BUILD.gn
index f4e8a15e..d411522 100644
--- a/components/favicon/core/BUILD.gn
+++ b/components/favicon/core/BUILD.gn
@@ -35,3 +35,21 @@ static_library("core") {
"//url",
]
}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "favicon_handler_unittest.cc",
+ "large_icon_service_unittest.cc",
+ ]
+
+ deps = [
+ "//base",
+ "//components/favicon_base",
+ "//skia",
+ "//testing/gtest",
+ "//ui/base",
+ "//ui/gfx",
+ "//url",
+ ]
+}
diff --git a/components/favicon/core/favicon_service.h b/components/favicon/core/favicon_service.h
index e237967..f8ebea4 100644
--- a/components/favicon/core/favicon_service.h
+++ b/components/favicon/core/favicon_service.h
@@ -117,7 +117,7 @@ class FaviconService : public KeyedService {
base::CancelableTaskTracker* tracker);
// See HistoryService::GetLargestFaviconForPageURL().
- base::CancelableTaskTracker::TaskId GetLargestRawFaviconForPageURL(
+ virtual base::CancelableTaskTracker::TaskId GetLargestRawFaviconForPageURL(
const GURL& page_url,
const std::vector<int>& icon_types,
int minimum_size_in_pixels,
diff --git a/components/favicon/core/large_icon_service.cc b/components/favicon/core/large_icon_service.cc
index 92ea4e0..ed1a17f 100644
--- a/components/favicon/core/large_icon_service.cc
+++ b/components/favicon/core/large_icon_service.cc
@@ -30,6 +30,9 @@ base::CancelableTaskTracker::TaskId
int desired_size_in_pixel,
const favicon_base::LargeIconCallback& callback,
base::CancelableTaskTracker* tracker) {
+ DCHECK_LE(1, min_source_size_in_pixel);
+ DCHECK_LE(0, desired_size_in_pixel);
+
// TODO(beaudoin): For now this is just a wrapper around
// GetLargestRawFaviconForPageURL. Add the logic required to select the best
// possible large icon. Also add logic to fetch-on-demand when the URL of
diff --git a/components/favicon/core/large_icon_service.h b/components/favicon/core/large_icon_service.h
index 0bb3998..a214e20 100644
--- a/components/favicon/core/large_icon_service.h
+++ b/components/favicon/core/large_icon_service.h
@@ -48,6 +48,9 @@ class LargeIconService : public KeyedService {
base::CancelableTaskTracker* tracker);
private:
+ // For testing.
+ friend class TestLargeIconService;
+
// Resizes |bitmap_result| to |desired_size_in_pixel|x|desired_size_in_pixel|.
// Stores the resized bitmap data in |resized_bitmap_result| and returns true
// if successful.
diff --git a/components/favicon/core/large_icon_service_unittest.cc b/components/favicon/core/large_icon_service_unittest.cc
new file mode 100644
index 0000000..48422ab
--- /dev/null
+++ b/components/favicon/core/large_icon_service_unittest.cc
@@ -0,0 +1,281 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/favicon/core/large_icon_service.h"
+
+#include <deque>
+
+#include "base/bind.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/task/cancelable_task_tracker.h"
+#include "components/favicon/core/favicon_service.h"
+#include "components/favicon_base/fallback_icon_style.h"
+#include "components/favicon_base/favicon_types.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/image/image.h"
+#include "url/gurl.h"
+
+namespace favicon {
+namespace {
+
+const char kDummyUrl[] = "http://www.example.com";
+const char kDummyIconUrl[] = "http://www.example.com/touch_icon.png";
+
+const SkColor kTestColor = SK_ColorRED;
+
+favicon_base::FaviconRawBitmapResult CreateTestBitmap(
+ int w, int h, SkColor color) {
+ favicon_base::FaviconRawBitmapResult result;
+ result.expired = false;
+
+ // Create bitmap and fill with |color|.
+ scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(w, h);
+ bitmap.eraseColor(color);
+ gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data->data());
+ result.bitmap_data = data;
+
+ result.pixel_size = gfx::Size(w, h);
+ result.icon_url = GURL(kDummyIconUrl);
+ result.icon_type = favicon_base::TOUCH_ICON;
+ CHECK(result.is_valid());
+ return result;
+}
+
+// A mock FaviconService that emits pre-programmed response.
+class MockFaviconService : public FaviconService {
+ public:
+ MockFaviconService() : FaviconService(nullptr, nullptr) {
+ }
+
+ ~MockFaviconService() override {
+ }
+
+ base::CancelableTaskTracker::TaskId GetLargestRawFaviconForPageURL(
+ const GURL& page_url,
+ const std::vector<int>& icon_types,
+ int minimum_size_in_pixels,
+ const favicon_base::FaviconRawBitmapCallback& callback,
+ base::CancelableTaskTracker* tracker) override {
+ favicon_base::FaviconRawBitmapResult mock_result =
+ mock_result_queue_.front();
+ mock_result_queue_.pop_front();
+ return tracker->PostTask(
+ base::MessageLoop::current()->task_runner().get(), FROM_HERE,
+ base::Bind(callback, mock_result));
+ }
+
+ void InjectResult(const favicon_base::FaviconRawBitmapResult& mock_result) {
+ mock_result_queue_.push_back(mock_result);
+ }
+
+ bool HasUnusedResults() {
+ return !mock_result_queue_.empty();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockFaviconService);
+
+ std::deque<favicon_base::FaviconRawBitmapResult> mock_result_queue_;
+};
+
+// This class provides access to LargeIconService internals.
+class TestLargeIconService : public LargeIconService {
+ public:
+ explicit TestLargeIconService(MockFaviconService* mock_favicon_service)
+ : LargeIconService(mock_favicon_service) {
+ }
+ ~TestLargeIconService() override {
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestLargeIconService);
+};
+
+class LargeIconServiceTest : public testing::Test {
+ public:
+ LargeIconServiceTest() : is_callback_invoked_(false) {
+ }
+
+ ~LargeIconServiceTest() override {
+ }
+
+ void SetUp() override {
+ testing::Test::SetUp();
+ mock_favicon_service_.reset(new MockFaviconService());
+ large_icon_service_.reset(
+ new TestLargeIconService(mock_favicon_service_.get()));
+ }
+
+ void ResultCallback(const favicon_base::LargeIconResult& result) {
+ is_callback_invoked_ = true;
+
+ // Checking presence and absence of results.
+ EXPECT_EQ(expected_bitmap_.is_valid(), result.bitmap.is_valid());
+ EXPECT_EQ(expected_fallback_icon_style_ != nullptr,
+ result.fallback_icon_style != nullptr);
+
+ if (expected_bitmap_.is_valid()) {
+ EXPECT_EQ(expected_bitmap_.pixel_size, result.bitmap.pixel_size);
+ // Not actually checking bitmap content.
+ }
+ if (expected_fallback_icon_style_.get()) {
+ EXPECT_EQ(*expected_fallback_icon_style_,
+ *result.fallback_icon_style);
+ }
+ // Ensure all mock results have been consumed.
+ EXPECT_FALSE(mock_favicon_service_->HasUnusedResults());
+ }
+
+ protected:
+ base::MessageLoopForIO loop_;
+
+ scoped_ptr<MockFaviconService> mock_favicon_service_;
+ scoped_ptr<TestLargeIconService> large_icon_service_;
+ base::CancelableTaskTracker cancelable_task_tracker_;
+
+ favicon_base::FaviconRawBitmapResult expected_bitmap_;
+ scoped_ptr<favicon_base::FallbackIconStyle> expected_fallback_icon_style_;
+
+ bool is_callback_invoked_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LargeIconServiceTest);
+};
+
+TEST_F(LargeIconServiceTest, SameSize) {
+
+ mock_favicon_service_->InjectResult(CreateTestBitmap(24, 24, kTestColor));
+ expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor);
+ large_icon_service_->GetLargeIconOrFallbackStyle(
+ GURL(kDummyUrl),
+ 24, // |min_source_size_in_pixel|
+ 24, // |desired_size_in_pixel|
+ base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
+ &cancelable_task_tracker_);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(is_callback_invoked_);
+}
+
+TEST_F(LargeIconServiceTest, ScaleDown) {
+ mock_favicon_service_->InjectResult(CreateTestBitmap(32, 32, kTestColor));
+ expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor);
+ large_icon_service_->GetLargeIconOrFallbackStyle(
+ GURL(kDummyUrl),
+ 24,
+ 24,
+ base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
+ &cancelable_task_tracker_);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(is_callback_invoked_);
+}
+
+TEST_F(LargeIconServiceTest, ScaleUp) {
+ mock_favicon_service_->InjectResult(CreateTestBitmap(16, 16, kTestColor));
+ expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor);
+ large_icon_service_->GetLargeIconOrFallbackStyle(
+ GURL(kDummyUrl),
+ 14, // Lowered requirement so stored bitmap is admitted.
+ 24,
+ base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
+ &cancelable_task_tracker_);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(is_callback_invoked_);
+}
+
+// |desired_size_in_pixel| == 0 means retrieve original image without scaling.
+TEST_F(LargeIconServiceTest, NoScale) {
+ mock_favicon_service_->InjectResult(CreateTestBitmap(24, 24, kTestColor));
+ expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor);
+ large_icon_service_->GetLargeIconOrFallbackStyle(
+ GURL(kDummyUrl),
+ 16,
+ 0,
+ base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
+ &cancelable_task_tracker_);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(is_callback_invoked_);
+}
+
+TEST_F(LargeIconServiceTest, FallbackSinceIconTooSmall) {
+ mock_favicon_service_->InjectResult(CreateTestBitmap(16, 16, kTestColor));
+ expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
+ expected_fallback_icon_style_->background_color = kTestColor;
+ large_icon_service_->GetLargeIconOrFallbackStyle(
+ GURL(kDummyUrl),
+ 24,
+ 24,
+ base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
+ &cancelable_task_tracker_);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(is_callback_invoked_);
+}
+
+TEST_F(LargeIconServiceTest, FallbackSinceIconNotSquare) {
+ mock_favicon_service_->InjectResult(CreateTestBitmap(24, 32, kTestColor));
+ expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
+ expected_fallback_icon_style_->background_color = kTestColor;
+ large_icon_service_->GetLargeIconOrFallbackStyle(
+ GURL(kDummyUrl),
+ 24,
+ 24,
+ base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
+ &cancelable_task_tracker_);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(is_callback_invoked_);
+}
+
+TEST_F(LargeIconServiceTest, FallbackSinceIconMissing) {
+ mock_favicon_service_->InjectResult(favicon_base::FaviconRawBitmapResult());
+ // Expect default fallback style, including background.
+ expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
+ large_icon_service_->GetLargeIconOrFallbackStyle(
+ GURL(kDummyUrl),
+ 24,
+ 24,
+ base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
+ &cancelable_task_tracker_);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(is_callback_invoked_);
+}
+
+TEST_F(LargeIconServiceTest, FallbackSinceIconMissingNoScale) {
+ mock_favicon_service_->InjectResult(favicon_base::FaviconRawBitmapResult());
+ // Expect default fallback style, including background.
+ expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
+ large_icon_service_->GetLargeIconOrFallbackStyle(
+ GURL(kDummyUrl),
+ 24,
+ 0,
+ base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
+ &cancelable_task_tracker_);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(is_callback_invoked_);
+}
+
+// Oddball case where we demand a high resolution icon to scale down. Generates
+// fallback even though an icon with the final size is available.
+TEST_F(LargeIconServiceTest, FallbackSinceTooPicky) {
+ mock_favicon_service_->InjectResult(CreateTestBitmap(24, 24, kTestColor));
+ expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
+ expected_fallback_icon_style_->background_color = kTestColor;
+ large_icon_service_->GetLargeIconOrFallbackStyle(
+ GURL(kDummyUrl),
+ 32,
+ 24,
+ base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
+ &cancelable_task_tracker_);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(is_callback_invoked_);
+}
+
+} // namespace
+} // namespace favicon
diff --git a/components/favicon_base/fallback_icon_style.cc b/components/favicon_base/fallback_icon_style.cc
index d3e395b..a3aa658 100644
--- a/components/favicon_base/fallback_icon_style.cc
+++ b/components/favicon_base/fallback_icon_style.cc
@@ -41,6 +41,13 @@ FallbackIconStyle::FallbackIconStyle()
FallbackIconStyle::~FallbackIconStyle() {
}
+bool FallbackIconStyle::operator==(const FallbackIconStyle& other) const {
+ return background_color == other.background_color &&
+ text_color == other.text_color &&
+ font_size_ratio == other.font_size_ratio &&
+ roundness == other.roundness;
+}
+
void MatchFallbackIconTextColorAgainstBackgroundColor(
FallbackIconStyle* style) {
int luminance = color_utils::GetLuminanceForColor(style->background_color);
diff --git a/components/favicon_base/fallback_icon_style.h b/components/favicon_base/fallback_icon_style.h
index 84842ed..478efb8 100644
--- a/components/favicon_base/fallback_icon_style.h
+++ b/components/favicon_base/fallback_icon_style.h
@@ -30,6 +30,8 @@ struct FallbackIconStyle {
// The roundness of the icon's corners. 0 => square icon, 1 => circle icon.
double roundness;
+
+ bool operator==(const FallbackIconStyle& other) const;
};
// Reassigns |style|'s |text_color| to matches well against |background_color|.