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

Unified Diff: components/dom_distiller/core/distiller_unittest.cc

Issue 178303004: Add incremental updates for multipage distillation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix compile by adding a header. Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: components/dom_distiller/core/distiller_unittest.cc
diff --git a/components/dom_distiller/core/distiller_unittest.cc b/components/dom_distiller/core/distiller_unittest.cc
index d3467c72aec481f1117c2b21b06cab57a27898c2..032da936a334854b77d3e883385d33908a164e04 100644
--- a/components/dom_distiller/core/distiller_unittest.cc
+++ b/components/dom_distiller/core/distiller_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <algorithm>
#include <map>
#include <string>
#include <vector>
@@ -13,6 +14,7 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
+#include "components/dom_distiller/core/article_distillation_update.h"
#include "components/dom_distiller/core/distiller.h"
#include "components/dom_distiller/core/distiller_page.h"
#include "components/dom_distiller/core/proto/distilled_article.pb.h"
@@ -58,6 +60,19 @@ namespace {
return list.Pass();
}
+ // Return the sequence in which Distiller will distill pages.
+ // Note: ignores any delays due to fetching images etc.
+ vector<int> get_pages_in_sequence(int start_page_num, int num_pages) {
+ // Distiller prefers distilling past pages first. E.g. when distillation
+ // starts on page 2 then pages are distilled in the order: 2, 1, 0, 3, 4.
+ vector<int> page_nums;
+ for (int page = start_page_num; page >= 0; --page)
+ page_nums.push_back(page);
+ for (int page = start_page_num + 1; page < num_pages; ++page)
+ page_nums.push_back(page);
+ return page_nums;
+ }
+
} // namespace
namespace dom_distiller {
@@ -122,13 +137,26 @@ class MockDistillerPageFactory : public DistillerPageFactory {
class DistillerTest : public testing::Test {
public:
virtual ~DistillerTest() {}
- void OnDistillPageDone(scoped_ptr<DistilledArticleProto> proto) {
+ void OnDistillArticleDone(scoped_ptr<DistilledArticleProto> proto) {
article_proto_ = proto.Pass();
}
+ void OnDistillArticleUpdate(const ArticleDistillationUpdate& article_update) {
+ in_sequence_updates_.push_back(article_update);
+ }
+
+ void DistillPage(const std::string& url) {
+ distiller_->DistillPage(GURL(url),
+ base::Bind(&DistillerTest::OnDistillArticleDone,
+ base::Unretained(this)),
+ base::Bind(&DistillerTest::OnDistillArticleUpdate,
+ base::Unretained(this)));
+ }
+
protected:
scoped_ptr<DistillerImpl> distiller_;
scoped_ptr<DistilledArticleProto> article_proto_;
+ std::vector<ArticleDistillationUpdate> in_sequence_updates_;
MockDistillerPageFactory page_factory_;
TestDistillerURLFetcherFactory url_fetcher_factory_;
};
@@ -155,14 +183,7 @@ ACTION_P4(CreateMockDistillerPages, lists, kurls, num_pages, start_page_num) {
EXPECT_CALL(*distiller_page, InitImpl());
{
testing::InSequence s;
- // Distiller prefers distilling past pages first. E.g. when distillation
- // starts on page 2 then pages are distilled in the order: 2, 1, 0, 3, 4.
- vector<int> page_nums;
- for (int page = start_page_num; page >= 0; --page)
- page_nums.push_back(page);
- for (int page = start_page_num + 1; page < num_pages; ++page)
- page_nums.push_back(page);
-
+ vector<int> page_nums = get_pages_in_sequence(start_page_num, num_pages);
for (size_t page_num = 0; page_num < page_nums.size(); ++page_num) {
int page = page_nums[page_num];
GURL url = GURL(kurls[page]);
@@ -177,6 +198,43 @@ ACTION_P4(CreateMockDistillerPages, lists, kurls, num_pages, start_page_num) {
return distiller_page;
}
+ACTION_P5(VerifyIncrementalUpdatesMatch,
cjhopman 2014/02/28 02:38:14 Why is this an action? It isn't ever used as an ac
shashi 2014/03/02 02:53:40 Changed to function.
+ start_page_num,
+ kNumPages,
cjhopman 2014/02/28 02:38:14 nit: the capitalization of this is wrong
shashi 2014/03/02 02:53:40 Done.
+ expected_page_urls,
+ expected_content,
+ incremental_updates) {
+ vector<int> page_nums = get_pages_in_sequence(start_page_num, kNumPages);
cjhopman 2014/02/28 02:38:14 This function contains the following names: start_
shashi 2014/03/02 02:53:40 Done.
+ // Updates should contain a list of pages. Pages in a update should be in
+ // the correct ascending page order regardless of start_page_num.
+ // E.g. if distillation starts at page 2 of a 3 page article, the updates
+ // will be [ [2], [1, 2], [1, 2, 3]]. This example assumes that image fetches
+ // do not delay distillation of a page. There can be scenarios when image
+ // fetch delays distillation of a page (E.g. 1 is delayed due to image fetches
+ // so updates can be in this order [ [2], [2,3], [1,2,3]].
+ for (int page_num = 0; page_num < incremental_updates.size(); ++page_num) {
cjhopman 2014/02/28 02:38:14 This seems like the index of an incremental update
cjhopman 2014/02/28 02:38:14 incremental_updates is a vector, why not use an it
shashi 2014/03/02 02:53:40 Done.
shashi 2014/03/02 02:53:40 Done.
shashi 2014/03/02 02:53:40 Done.
+ size_t num_pages = incremental_updates[page_num].getPagesSize();
+ EXPECT_EQ(static_cast<size_t>(page_num + 1), num_pages);
+ vector<int> update_pages(page_nums.begin(), page_nums.begin() + num_pages);
cjhopman 2014/02/28 02:38:14 I'd rename this: expected_pages_in_update or some
shashi 2014/03/02 02:53:40 Done.
+ std::sort(update_pages.begin(), update_pages.end());
+
+ // If we already got the first page then there is no previous page.
+ EXPECT_EQ((update_pages[0] != 0),
+ incremental_updates[page_num].hasPrevPage());
+
+ // if we already got the last page then there is no next page.
+ EXPECT_EQ((*update_pages.rbegin()) != kNumPages - 1,
+ incremental_updates[page_num].hasNextPage());
+ for (size_t j = 0; j < num_pages; ++j) {
+ int actual_page_num = update_pages[j];
+ EXPECT_EQ(expected_page_urls[actual_page_num],
+ incremental_updates[page_num].getDistilledPage(j)->data.url());
+ EXPECT_EQ(expected_content[actual_page_num],
+ incremental_updates[page_num].getDistilledPage(j)->data.html());
+ }
+ }
+}
+
TEST_F(DistillerTest, DistillPage) {
base::MessageLoopForUI loop;
scoped_ptr<base::ListValue> list =
@@ -185,9 +243,7 @@ TEST_F(DistillerTest, DistillPage) {
.WillOnce(CreateMockDistillerPage(list.get(), GURL(kURL)));
distiller_.reset(new DistillerImpl(page_factory_, url_fetcher_factory_));
distiller_->Init();
- distiller_->DistillPage(
- GURL(kURL),
- base::Bind(&DistillerTest::OnDistillPageDone, base::Unretained(this)));
+ DistillPage(kURL);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(kTitle, article_proto_->title());
EXPECT_EQ(article_proto_->pages_size(), 1);
@@ -208,9 +264,7 @@ TEST_F(DistillerTest, DistillPageWithImages) {
CreateMockDistillerPage(list.get(), GURL(kURL)));
distiller_.reset(new DistillerImpl(page_factory_, url_fetcher_factory_));
distiller_->Init();
- distiller_->DistillPage(
- GURL(kURL),
- base::Bind(&DistillerTest::OnDistillPageDone, base::Unretained(this)));
+ DistillPage(kURL);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(kTitle, article_proto_->title());
EXPECT_EQ(article_proto_->pages_size(), 1);
@@ -259,9 +313,7 @@ TEST_F(DistillerTest, DistillMultiplePages) {
distiller_.reset(new DistillerImpl(page_factory_, url_fetcher_factory_));
distiller_->Init();
- distiller_->DistillPage(
- GURL(page_urls[0]),
- base::Bind(&DistillerTest::OnDistillPageDone, base::Unretained(this)));
+ DistillPage(page_urls[0]);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(kTitle, article_proto_->title());
EXPECT_EQ(article_proto_->pages_size(), kNumPages);
@@ -291,9 +343,7 @@ TEST_F(DistillerTest, DistillLinkLoop) {
.WillOnce(CreateMockDistillerPage(list.get(), GURL(kURL)));
distiller_.reset(new DistillerImpl(page_factory_, url_fetcher_factory_));
distiller_->Init();
- distiller_->DistillPage(
- GURL(kURL),
- base::Bind(&DistillerTest::OnDistillPageDone, base::Unretained(this)));
+ DistillPage(kURL);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(kTitle, article_proto_->title());
EXPECT_EQ(article_proto_->pages_size(), 1);
@@ -326,9 +376,7 @@ TEST_F(DistillerTest, CheckMaxPageLimit) {
distiller_->SetMaxNumPagesInArticle(kMaxPagesInArticle);
distiller_->Init();
- distiller_->DistillPage(
- GURL(page_urls[0]),
- base::Bind(&DistillerTest::OnDistillPageDone, base::Unretained(this)));
+ DistillPage(page_urls[0]);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(kTitle, article_proto_->title());
EXPECT_EQ(kMaxPagesInArticle,
@@ -346,9 +394,7 @@ TEST_F(DistillerTest, CheckMaxPageLimit) {
distiller_->SetMaxNumPagesInArticle(kMaxPagesInArticle);
distiller_->Init();
- distiller_->DistillPage(
- GURL(page_urls[0]),
- base::Bind(&DistillerTest::OnDistillPageDone, base::Unretained(this)));
+ DistillPage(page_urls[0]);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(kTitle, article_proto_->title());
EXPECT_EQ(kMaxPagesInArticle,
@@ -366,9 +412,7 @@ TEST_F(DistillerTest, CheckMaxPageLimit) {
distiller_->SetMaxNumPagesInArticle(kMaxPagesInArticle);
distiller_->Init();
- distiller_->DistillPage(
- GURL(page_urls[0]),
- base::Bind(&DistillerTest::OnDistillPageDone, base::Unretained(this)));
+ DistillPage(page_urls[0]);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(kTitle, article_proto_->title());
EXPECT_EQ(kMaxPagesInArticle,
@@ -383,9 +427,7 @@ TEST_F(DistillerTest, SinglePageDistillationFailure) {
.WillOnce(CreateMockDistillerPage(nullValue.get(), GURL(kURL)));
distiller_.reset(new DistillerImpl(page_factory_, url_fetcher_factory_));
distiller_->Init();
- distiller_->DistillPage(
- GURL(kURL),
- base::Bind(&DistillerTest::OnDistillPageDone, base::Unretained(this)));
+ DistillPage(kURL);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ("", article_proto_->title());
EXPECT_EQ(0, article_proto_->pages_size());
@@ -419,9 +461,7 @@ TEST_F(DistillerTest, MultiplePagesDistillationFailure) {
distiller_.reset(new DistillerImpl(page_factory_, url_fetcher_factory_));
distiller_->Init();
- distiller_->DistillPage(
- GURL(page_urls[0]),
- base::Bind(&DistillerTest::OnDistillPageDone, base::Unretained(this)));
+ DistillPage(page_urls[0]);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(kTitle, article_proto_->title());
EXPECT_EQ(article_proto_->pages_size(), failed_page_num);
@@ -440,36 +480,153 @@ TEST_F(DistillerTest, DistillPreviousPage) {
scoped_ptr<base::Value> distilled_values[kNumPages];
// The page number of the article on which distillation starts.
- int start_page_number = 3;
+ int start_page_num = 3;
string url_prefix = "http://a.com/";
- for (int page_no = 0; page_no < kNumPages; ++page_no) {
- page_urls[page_no] = url_prefix + base::IntToString(page_no);
- content[page_no] = "Content for page:" + base::IntToString(page_no);
- string next_page_url = (page_no + 1 < kNumPages)
- ? url_prefix + base::IntToString(page_no + 1)
+ for (int page_num = 0; page_num < kNumPages; ++page_num) {
+ page_urls[page_num] = url_prefix + base::IntToString(page_num);
+ content[page_num] = "Content for page:" + base::IntToString(page_num);
+ string next_page_url = (page_num + 1 < kNumPages)
+ ? url_prefix + base::IntToString(page_num + 1)
: "";
- string prev_page_url = (page_no > 0) ? page_urls[page_no - 1] : "";
- distilled_values[page_no] = CreateDistilledValueReturnedFromJS(
- kTitle, content[page_no], vector<int>(), next_page_url, prev_page_url);
+ string prev_page_url = (page_num > 0) ? page_urls[page_num - 1] : "";
+ distilled_values[page_num] = CreateDistilledValueReturnedFromJS(
+ kTitle, content[page_num], vector<int>(), next_page_url, prev_page_url);
}
EXPECT_CALL(page_factory_, CreateDistillerPageMock(_))
.WillOnce(CreateMockDistillerPages(
- distilled_values, page_urls, kNumPages, start_page_number));
+ distilled_values, page_urls, kNumPages, start_page_num));
distiller_.reset(new DistillerImpl(page_factory_, url_fetcher_factory_));
distiller_->Init();
- distiller_->DistillPage(
- GURL(page_urls[start_page_number]),
- base::Bind(&DistillerTest::OnDistillPageDone, base::Unretained(this)));
+ DistillPage(page_urls[start_page_num]);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(kTitle, article_proto_->title());
EXPECT_EQ(kNumPages, article_proto_->pages_size());
- for (int page_no = 0; page_no < kNumPages; ++page_no) {
- const DistilledPageProto& page = article_proto_->pages(page_no);
- EXPECT_EQ(content[page_no], page.html());
- EXPECT_EQ(page_urls[page_no], page.url());
+ for (int page_num = 0; page_num < kNumPages; ++page_num) {
+ const DistilledPageProto& page = article_proto_->pages(page_num);
+ EXPECT_EQ(content[page_num], page.html());
+ EXPECT_EQ(page_urls[page_num], page.url());
+ }
+}
+
+TEST_F(DistillerTest, IncrementalUpdates) {
+ base::MessageLoopForUI loop;
+ const int kNumPages = 8;
+ string content[kNumPages];
+ string page_urls[kNumPages];
+ scoped_ptr<base::Value> distilled_values[kNumPages];
+
+ // The page number of the article on which distillation starts.
+ int start_page_num = 3;
+ string url_prefix = "http://a.com/";
+ for (int page_num = 0; page_num < kNumPages; ++page_num) {
+ page_urls[page_num] = url_prefix + base::IntToString(page_num);
+ content[page_num] = "Content for page:" + base::IntToString(page_num);
+ string next_page_url = (page_num + 1 < kNumPages)
+ ? url_prefix + base::IntToString(page_num + 1)
+ : "";
+ string prev_page_url = (page_num > 0) ? page_urls[page_num - 1] : "";
+ distilled_values[page_num] = CreateDistilledValueReturnedFromJS(
+ kTitle, content[page_num], vector<int>(), next_page_url, prev_page_url);
}
+
+ EXPECT_CALL(page_factory_, CreateDistillerPageMock(_))
+ .WillOnce(CreateMockDistillerPages(
+ distilled_values, page_urls, kNumPages, start_page_num));
+
+ distiller_.reset(new DistillerImpl(page_factory_, url_fetcher_factory_));
+ distiller_->Init();
+ DistillPage(page_urls[start_page_num]);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_EQ(kTitle, article_proto_->title());
+ EXPECT_EQ(kNumPages, article_proto_->pages_size());
+ EXPECT_EQ(static_cast<size_t>(kNumPages), in_sequence_updates_.size());
+
+ VerifyIncrementalUpdatesMatch(
+ start_page_num, kNumPages, page_urls, content, in_sequence_updates_);
+}
+
+TEST_F(DistillerTest, IncrementalUpdatesDoNotDeleteFinalArticle) {
+ base::MessageLoopForUI loop;
+ const int kNumPages = 8;
+ string content[kNumPages];
+ string page_urls[kNumPages];
+ scoped_ptr<base::Value> distilled_values[kNumPages];
+
+ // The page number of the article on which distillation starts.
+ int start_page_num = 3;
+ string url_prefix = "http://a.com/";
+ for (int page_num = 0; page_num < kNumPages; ++page_num) {
+ page_urls[page_num] = url_prefix + base::IntToString(page_num);
+ content[page_num] = "Content for page:" + base::IntToString(page_num);
+ string next_page_url = (page_num + 1 < kNumPages)
+ ? url_prefix + base::IntToString(page_num + 1)
+ : "";
+ string prev_page_url = (page_num > 0) ? page_urls[page_num - 1] : "";
+ distilled_values[page_num] = CreateDistilledValueReturnedFromJS(
+ kTitle, content[page_num], vector<int>(), next_page_url, prev_page_url);
+ }
+
+ EXPECT_CALL(page_factory_, CreateDistillerPageMock(_))
+ .WillOnce(CreateMockDistillerPages(
+ distilled_values, page_urls, kNumPages, start_page_num));
+
+ distiller_.reset(new DistillerImpl(page_factory_, url_fetcher_factory_));
+ distiller_->Init();
+ DistillPage(page_urls[start_page_num]);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_EQ(static_cast<size_t>(kNumPages), in_sequence_updates_.size());
+
+ in_sequence_updates_.clear();
+
+ // Should still be able to access article and pages.
+ EXPECT_EQ(kTitle, article_proto_->title());
+ EXPECT_EQ(kNumPages, article_proto_->pages_size());
+ for (int page_num = 0; page_num < kNumPages; ++page_num) {
+ const DistilledPageProto& page = article_proto_->pages(page_num);
+ EXPECT_EQ(content[page_num], page.html());
+ EXPECT_EQ(page_urls[page_num], page.url());
+ }
+}
+
+TEST_F(DistillerTest, DeletingArticleDoesNotInterfereWithUpdates) {
+ base::MessageLoopForUI loop;
+ const int kNumPages = 8;
+ string content[kNumPages];
+ string page_urls[kNumPages];
+ scoped_ptr<base::Value> distilled_values[kNumPages];
+
+ // The page number of the article on which distillation starts.
+ int start_page_num = 3;
+ string url_prefix = "http://a.com/";
+ for (int page_num = 0; page_num < kNumPages; ++page_num) {
+ page_urls[page_num] = url_prefix + base::IntToString(page_num);
+ content[page_num] = "Content for page:" + base::IntToString(page_num);
+ string next_page_url = (page_num + 1 < kNumPages)
+ ? url_prefix + base::IntToString(page_num + 1)
+ : "";
+ string prev_page_url = (page_num > 0) ? page_urls[page_num - 1] : "";
+ distilled_values[page_num] = CreateDistilledValueReturnedFromJS(
+ kTitle, content[page_num], vector<int>(), next_page_url, prev_page_url);
+ }
cjhopman 2014/02/28 02:38:14 This setup code seems to be repeated three times.
shashi 2014/03/02 02:53:40 Good point, done, though it might make it slightly
+
+ EXPECT_CALL(page_factory_, CreateDistillerPageMock(_))
+ .WillOnce(CreateMockDistillerPages(
+ distilled_values, page_urls, kNumPages, start_page_num));
+
+ distiller_.reset(new DistillerImpl(page_factory_, url_fetcher_factory_));
+ distiller_->Init();
+ DistillPage(page_urls[start_page_num]);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_EQ(static_cast<size_t>(kNumPages), in_sequence_updates_.size());
+ EXPECT_EQ(kTitle, article_proto_->title());
+ EXPECT_EQ(kNumPages, article_proto_->pages_size());
+
+ // Delete the article.
+ article_proto_.reset();
+ VerifyIncrementalUpdatesMatch(
+ start_page_num, kNumPages, page_urls, content, in_sequence_updates_);
}
} // namespace dom_distiller

Powered by Google App Engine
This is Rietveld 408576698