Index: components/favicon/core/favicon_selector_unittest.cc |
diff --git a/components/favicon/core/favicon_selector_unittest.cc b/components/favicon/core/favicon_selector_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b84a1c148213affd31951ff7ed3a8c6a447f39f2 |
--- /dev/null |
+++ b/components/favicon/core/favicon_selector_unittest.cc |
@@ -0,0 +1,254 @@ |
+// Copyright (c) 2017 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/favicon_selector.h" |
+ |
+#include <memory> |
+#include <vector> |
+ |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace favicon { |
+namespace { |
+ |
+using favicon_base::FAVICON; |
+using favicon_base::FaviconRawBitmapResult; |
+using testing::ElementsAre; |
+using testing::Eq; |
+using testing::IsNull; |
+using testing::Pointee; |
+ |
+MATCHER_P(HasIconURL, expected_url, "") { |
+ *result_listener << "where icon URL is " << arg.icon_url; |
+ return arg.icon_url == GURL(expected_url); |
+} |
+ |
+MATCHER_P(HasValueWithIconURL, expected_url, "") { |
+ if (!arg) |
+ *result_listener << "where value is empty"; |
+ else |
+ *result_listener << "where value's icon URL is " << arg.value().icon_url; |
+ return arg.value().icon_url == GURL(expected_url); |
+} |
+ |
+std::vector<FaviconRawBitmapResult> CreateRawBitmapResults( |
+ const std::vector<gfx::Size>& sizes) { |
+ std::vector<FaviconRawBitmapResult> results; |
+ for (const gfx::Size& size : sizes) { |
+ FaviconRawBitmapResult bitmap_result; |
+ bitmap_result.bitmap_data = |
+ new base::RefCountedBytes(std::vector<unsigned char>(1U, 0U)); |
+ bitmap_result.pixel_size = size; |
+ CHECK(bitmap_result.is_valid()); |
+ results.push_back(bitmap_result); |
+ } |
+ return results; |
+} |
+ |
+std::vector<SkBitmap> CreateBitmaps(const std::vector<gfx::Size>& sizes) { |
+ std::vector<SkBitmap> bitmaps; |
+ for (const gfx::Size& size : sizes) { |
+ SkBitmap bmp; |
+ bmp.allocN32Pixels(size.width(), size.height()); |
+ bmp.eraseColor(SK_ColorRED); |
+ bitmaps.push_back(bmp); |
+ } |
+ return bitmaps; |
+} |
+ |
+TEST(FaviconSelectorTest, ShouldSortAndPruneForLargest) { |
+ const FaviconSelector::TargetSizeSpec spec = |
+ FaviconSelector::TargetSizeSpec::ForLargest(); |
+ |
+ const std::vector<gfx::Size> kEmptySizes; |
+ const std::vector<favicon::FaviconURL> kSourceIconURLs{ |
+ FaviconURL(GURL("http://www.google.com/a"), FAVICON, |
+ {gfx::Size(1, 1), gfx::Size(17, 17)}), |
+ FaviconURL(GURL("http://www.google.com/b"), FAVICON, |
+ {gfx::Size(1024, 1024), gfx::Size(512, 512)}), |
+ FaviconURL(GURL("http://www.google.com/c"), FAVICON, |
+ {gfx::Size(16, 16), gfx::Size(14, 14)}), |
+ FaviconURL(GURL("http://www.google.com/d"), FAVICON, kEmptySizes), |
+ FaviconURL(GURL("http://www.google.com/e"), FAVICON, kEmptySizes), |
+ FaviconURL(GURL("http://www.google.com/f"), FAVICON, |
+ {gfx::Size(10, 10), gfx::Size(400, 400)})}; |
+ |
+ EXPECT_THAT(spec.SortAndPruneCandidates(kSourceIconURLs), |
+ ElementsAre(HasIconURL("http://www.google.com/f"), |
+ HasIconURL("http://www.google.com/b"), |
+ HasIconURL("http://www.google.com/a"), |
+ HasIconURL("http://www.google.com/c"), |
+ // The rest of bitmaps come in order, there is no |
+ // sizes attribute. |
+ HasIconURL("http://www.google.com/d"), |
+ HasIconURL("http://www.google.com/e"))); |
+} |
+ |
+TEST(FaviconSelectorTest, ShouldSortAndPruneFor16x16) { |
+ // The last element is guaranteed to search for 16x16 pixels. |
+ const FaviconSelector::TargetSizeSpec spec = |
+ FaviconSelector::TargetSizeSpec::For16x16Dips().back(); |
+ ASSERT_EQ(16, spec.pixel_size()); |
+ |
+ const std::vector<gfx::Size> kEmptySizes; |
+ const std::vector<favicon::FaviconURL> kSourceIconURLs{ |
+ FaviconURL(GURL("http://www.google.com/a"), FAVICON, |
+ {gfx::Size(1, 1), gfx::Size(17, 17)}), |
+ FaviconURL(GURL("http://www.google.com/b"), FAVICON, |
+ {gfx::Size(1024, 1024), gfx::Size(512, 512)}), |
+ FaviconURL(GURL("http://www.google.com/c"), FAVICON, |
+ {gfx::Size(16, 16), gfx::Size(14, 14)}), |
+ FaviconURL(GURL("http://www.google.com/d"), FAVICON, kEmptySizes), |
+ FaviconURL(GURL("http://www.google.com/e"), FAVICON, kEmptySizes), |
+ FaviconURL(GURL("http://www.google.com/f"), FAVICON, |
+ {gfx::Size(10, 10), gfx::Size(400, 400)})}; |
+ |
+ EXPECT_THAT(spec.SortAndPruneCandidates(kSourceIconURLs), |
+ ElementsAre(HasIconURL("http://www.google.com/c"), |
+ HasIconURL("http://www.google.com/a"), |
+ HasIconURL("http://www.google.com/f"), |
+ HasIconURL("http://www.google.com/b"), |
+ // The rest of bitmaps come in order, there is no |
+ // sizes attribute. |
+ HasIconURL("http://www.google.com/d"), |
+ HasIconURL("http://www.google.com/e"))); |
+} |
+ |
+TEST(FaviconSelectorTest, ShouldReportSatisfyingResultForLargest) {} |
+ |
+TEST(FaviconSelectorTest, ShouldReportSatisfyingResultFor16x16) { |
+ // The last element is guaranteed to search for 16x16 pixels. |
+ const FaviconSelector::TargetSizeSpec spec = |
+ FaviconSelector::TargetSizeSpec::For16x16Dips().back(); |
+ ASSERT_EQ(16, spec.pixel_size()); |
+ |
+ EXPECT_FALSE(spec.HasSatisfyingResult(std::vector<FaviconRawBitmapResult>())); |
+ EXPECT_FALSE( |
+ spec.HasSatisfyingResult(CreateRawBitmapResults({gfx::Size(15, 15)}))); |
+ EXPECT_FALSE( |
+ spec.HasSatisfyingResult(CreateRawBitmapResults({gfx::Size(17, 17)}))); |
+ EXPECT_FALSE(spec.HasSatisfyingResult( |
+ CreateRawBitmapResults({gfx::Size(15, 15), gfx::Size(17, 17)}))); |
+ |
+ EXPECT_TRUE( |
+ spec.HasSatisfyingResult(CreateRawBitmapResults({gfx::Size(16, 16)}))); |
+ EXPECT_TRUE(spec.HasSatisfyingResult(CreateRawBitmapResults( |
+ {gfx::Size(15, 15), gfx::Size(16, 16), gfx::Size(17, 17)}))); |
+} |
+ |
+TEST(FaviconSelectorTest, ShouldDequeueSortedForLargest) { |
+ const std::vector<gfx::Size> kEmptySizes; |
+ |
+ FaviconSelector selector( |
+ FaviconSelector::TargetSizeSpec::ForLargest(), |
+ {FaviconURL(GURL("http://www.google.com/a"), FAVICON, |
+ {gfx::Size(1, 1), gfx::Size(17, 17)}), |
+ FaviconURL(GURL("http://www.google.com/b"), FAVICON, |
+ {gfx::Size(1024, 1024), gfx::Size(512, 512)}), |
+ FaviconURL(GURL("http://www.google.com/c"), FAVICON, |
+ {gfx::Size(16, 16), gfx::Size(14, 14)}), |
+ FaviconURL(GURL("http://www.google.com/d"), FAVICON, kEmptySizes), |
+ FaviconURL(GURL("http://www.google.com/e"), FAVICON, kEmptySizes)}); |
+ |
+ EXPECT_THAT(selector.CurrentCandidate(), |
+ Pointee(HasIconURL("http://www.google.com/b"))); |
+ EXPECT_THAT(selector.DequeueCandidate(), |
+ HasValueWithIconURL("http://www.google.com/b")); |
+ EXPECT_THAT(selector.CurrentCandidate(), |
+ Pointee(HasIconURL("http://www.google.com/a"))); |
+ EXPECT_THAT(selector.DequeueCandidate(), |
+ HasValueWithIconURL("http://www.google.com/a")); |
+ EXPECT_THAT(selector.CurrentCandidate(), |
+ Pointee(HasIconURL("http://www.google.com/c"))); |
+ EXPECT_THAT(selector.DequeueCandidate(), |
+ HasValueWithIconURL("http://www.google.com/c")); |
+ EXPECT_THAT(selector.CurrentCandidate(), |
+ Pointee(HasIconURL("http://www.google.com/d"))); |
+ EXPECT_THAT(selector.DequeueCandidate(), |
+ HasValueWithIconURL("http://www.google.com/d")); |
+ EXPECT_THAT(selector.CurrentCandidate(), |
+ Pointee(HasIconURL("http://www.google.com/e"))); |
+ EXPECT_THAT(selector.DequeueCandidate(), |
+ HasValueWithIconURL("http://www.google.com/e")); |
+ EXPECT_THAT(selector.CurrentCandidate(), IsNull()); |
+ EXPECT_FALSE(selector.DequeueCandidate().has_value()); |
+} |
+ |
+TEST(FaviconSelectorTest, ShouldDequeueSortedFor16x16) { |
+ // The last element is guaranteed to search for 16x16 pixels. |
+ const FaviconSelector::TargetSizeSpec spec = |
+ FaviconSelector::TargetSizeSpec::For16x16Dips().back(); |
+ ASSERT_EQ(16, spec.pixel_size()); |
+ |
+ FaviconSelector selector( |
+ FaviconSelector::TargetSizeSpec::ForLargest(), |
+ {FaviconURL(GURL("http://www.google.com/a"), FAVICON, |
+ {gfx::Size(15, 15)}), |
+ FaviconURL(GURL("http://www.google.com/b"), FAVICON, |
+ {gfx::Size(14, 14), gfx::Size(16, 16)})}); |
+ |
+ EXPECT_THAT(selector.CurrentCandidate(), |
+ Pointee(HasIconURL("http://www.google.com/b"))); |
+ EXPECT_THAT(selector.DequeueCandidate(), |
+ HasValueWithIconURL("http://www.google.com/b")); |
+ EXPECT_THAT(selector.CurrentCandidate(), |
+ Pointee(HasIconURL("http://www.google.com/a"))); |
+ EXPECT_THAT(selector.DequeueCandidate(), |
+ HasValueWithIconURL("http://www.google.com/a")); |
+ EXPECT_THAT(selector.CurrentCandidate(), IsNull()); |
+ EXPECT_FALSE(selector.DequeueCandidate().has_value()); |
+} |
+ |
+TEST(FaviconSelectorTest, ShouldProcessDownloadedImage) { |
+ const GURL kIconURL1("http://www.google.com/a"); |
+ const GURL kIconURL2("http://www.google.com/b"); |
+ const GURL kIconURL3("http://www.google.com/c"); |
+ const GURL kIconURL4("http://www.google.com/d"); |
+ |
+ const std::vector<gfx::Size> kSizes1{gfx::Size(14, 14), gfx::Size(16, 16)}; |
+ const std::vector<gfx::Size> kSizes2{gfx::Size(15, 15)}; |
+ const std::vector<gfx::Size> kSizes3{gfx::Size(1, 1), gfx::Size(8, 8)}; |
+ const std::vector<gfx::Size> kSizes4{gfx::Size(2, 2), gfx::Size(4, 4)}; |
+ |
+ // The last element is guaranteed to search for 16x16 pixels. |
+ const FaviconSelector::TargetSizeSpec spec = |
+ FaviconSelector::TargetSizeSpec::For16x16Dips().back(); |
+ ASSERT_EQ(16, spec.pixel_size()); |
+ |
+ FaviconSelector selector(spec, {FaviconURL(kIconURL1, FAVICON, kSizes1), |
+ FaviconURL(kIconURL2, FAVICON, kSizes2)}); |
+ ASSERT_FALSE(selector.BestBitmap()); |
+ ASSERT_TRUE(selector.CurrentCandidate()); |
+ |
+ // Any downloaded image should be better than hypothetical future candidates. |
+ EXPECT_TRUE(selector.ProcessDownloadedImage(kIconURL3, FAVICON, |
+ CreateBitmaps(kSizes3), kSizes3)); |
+ ASSERT_TRUE(selector.BestBitmap()); |
+ EXPECT_THAT(selector.BestBitmap()->candidate.icon_url, Eq(kIconURL3)); |
+ EXPECT_THAT(selector.BestBitmap()->original_size, Eq(kSizes3[1])); |
+ |
+ // Feed in a worse bitmap. |
+ EXPECT_FALSE(selector.ProcessDownloadedImage( |
+ kIconURL4, FAVICON, CreateBitmaps(kSizes4), kSizes4)); |
+ ASSERT_TRUE(selector.BestBitmap()); |
+ EXPECT_THAT(selector.BestBitmap()->candidate.icon_url, Eq(kIconURL3)); |
+ EXPECT_THAT(selector.BestBitmap()->original_size, Eq(kSizes3[1])); |
+ |
+ // Feed in an even better bitmap, registered in the queue. We'll verify that |
+ // the candidate gets removed from the queue. |
+ ASSERT_TRUE(selector.CurrentCandidate()); |
+ ASSERT_THAT(selector.CurrentCandidate()->icon_url, Eq(kIconURL1)); |
+ EXPECT_TRUE(selector.ProcessDownloadedImage(kIconURL1, FAVICON, |
+ CreateBitmaps(kSizes1), kSizes1)); |
+ ASSERT_TRUE(selector.BestBitmap()); |
+ EXPECT_THAT(selector.BestBitmap()->candidate.icon_url, Eq(kIconURL1)); |
+ EXPECT_THAT(selector.BestBitmap()->original_size, Eq(kSizes1[1])); |
+ |
+ EXPECT_FALSE(selector.CurrentCandidate()); |
+ EXPECT_FALSE(selector.DequeueCandidate()); |
+} |
+ |
+} // namespace |
+} // namespace favicon |