| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/dom_distiller/core/dom_distiller_service.h" | 5 #include "components/dom_distiller/core/dom_distiller_service.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 12 #include "base/strings/string_number_conversions.h" |
| 12 #include "components/dom_distiller/core/article_entry.h" | 13 #include "components/dom_distiller/core/article_entry.h" |
| 13 #include "components/dom_distiller/core/dom_distiller_model.h" | 14 #include "components/dom_distiller/core/dom_distiller_model.h" |
| 14 #include "components/dom_distiller/core/dom_distiller_store.h" | 15 #include "components/dom_distiller/core/dom_distiller_store.h" |
| 15 #include "components/dom_distiller/core/dom_distiller_test_util.h" | 16 #include "components/dom_distiller/core/dom_distiller_test_util.h" |
| 16 #include "components/dom_distiller/core/fake_db.h" | 17 #include "components/dom_distiller/core/fake_db.h" |
| 17 #include "components/dom_distiller/core/fake_distiller.h" | 18 #include "components/dom_distiller/core/fake_distiller.h" |
| 18 #include "components/dom_distiller/core/task_tracker.h" | 19 #include "components/dom_distiller/core/task_tracker.h" |
| 19 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 22 |
| 22 using testing::Invoke; | 23 using testing::Invoke; |
| 23 using testing::Return; | 24 using testing::Return; |
| 24 using testing::_; | 25 using testing::_; |
| 25 | 26 |
| 26 namespace dom_distiller { | 27 namespace dom_distiller { |
| 27 namespace test { | 28 namespace test { |
| 28 | 29 |
| 29 namespace { | 30 namespace { |
| 30 | 31 |
| 31 class FakeViewRequestDelegate : public ViewRequestDelegate { | 32 class FakeViewRequestDelegate : public ViewRequestDelegate { |
| 32 public: | 33 public: |
| 33 virtual ~FakeViewRequestDelegate() {} | 34 virtual ~FakeViewRequestDelegate() {} |
| 34 MOCK_METHOD1(OnArticleReady, void(DistilledPageProto* proto)); | 35 MOCK_METHOD1(OnArticleReady, void(const DistilledArticleProto* proto)); |
| 35 }; | 36 }; |
| 36 | 37 |
| 37 class MockDistillerObserver : public DomDistillerObserver { | 38 class MockDistillerObserver : public DomDistillerObserver { |
| 38 public: | 39 public: |
| 39 MOCK_METHOD1(ArticleEntriesUpdated, void(const std::vector<ArticleUpdate>&)); | 40 MOCK_METHOD1(ArticleEntriesUpdated, void(const std::vector<ArticleUpdate>&)); |
| 40 virtual ~MockDistillerObserver() {} | 41 virtual ~MockDistillerObserver() {} |
| 41 }; | 42 }; |
| 42 | 43 |
| 43 class MockArticleAvailableCallback { | 44 class MockArticleAvailableCallback { |
| 44 public: | 45 public: |
| 45 MOCK_METHOD1(DistillationCompleted, void(bool)); | 46 MOCK_METHOD1(DistillationCompleted, void(bool)); |
| 46 }; | 47 }; |
| 47 | 48 |
| 48 DomDistillerService::ArticleAvailableCallback ArticleCallback( | 49 DomDistillerService::ArticleAvailableCallback ArticleCallback( |
| 49 MockArticleAvailableCallback* callback) { | 50 MockArticleAvailableCallback* callback) { |
| 50 return base::Bind(&MockArticleAvailableCallback::DistillationCompleted, | 51 return base::Bind(&MockArticleAvailableCallback::DistillationCompleted, |
| 51 base::Unretained(callback)); | 52 base::Unretained(callback)); |
| 52 } | 53 } |
| 53 | 54 |
| 54 void RunDistillerCallback(FakeDistiller* distiller, | 55 void RunDistillerCallback(FakeDistiller* distiller, |
| 55 scoped_ptr<DistilledPageProto> proto) { | 56 scoped_ptr<DistilledArticleProto> proto) { |
| 56 distiller->RunDistillerCallback(proto.Pass()); | 57 distiller->RunDistillerCallback(proto.Pass()); |
| 57 base::RunLoop().RunUntilIdle(); | 58 base::RunLoop().RunUntilIdle(); |
| 58 } | 59 } |
| 59 | 60 |
| 61 scoped_ptr<DistilledArticleProto> CreateArticleWithURL(const std::string& url) { |
| 62 scoped_ptr<DistilledArticleProto> proto(new DistilledArticleProto); |
| 63 DistilledPageProto* page = proto->add_pages(); |
| 64 page->set_url(url); |
| 65 return proto.Pass(); |
| 66 } |
| 67 |
| 68 scoped_ptr<DistilledArticleProto> CreateDefaultArticle() { |
| 69 return CreateArticleWithURL("http://www.example.com/default_article_page1") |
| 70 .Pass(); |
| 71 } |
| 72 |
| 60 } // namespace | 73 } // namespace |
| 61 | 74 |
| 62 class DomDistillerServiceTest : public testing::Test { | 75 class DomDistillerServiceTest : public testing::Test { |
| 63 public: | 76 public: |
| 64 virtual void SetUp() { | 77 virtual void SetUp() { |
| 65 main_loop_.reset(new base::MessageLoop()); | 78 main_loop_.reset(new base::MessageLoop()); |
| 66 FakeDB* fake_db = new FakeDB(&db_model_); | 79 FakeDB* fake_db = new FakeDB(&db_model_); |
| 67 FakeDB::EntryMap store_model; | 80 FakeDB::EntryMap store_model; |
| 68 store_ = test::util::CreateStoreWithFakeDB(fake_db, store_model); | 81 store_ = test::util::CreateStoreWithFakeDB(fake_db, store_model); |
| 69 distiller_factory_ = new MockDistillerFactory(); | 82 distiller_factory_ = new MockDistillerFactory(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 entry.add_pages()->set_url(url.spec()); | 115 entry.add_pages()->set_url(url.spec()); |
| 103 | 116 |
| 104 store_->AddEntry(entry); | 117 store_->AddEntry(entry); |
| 105 | 118 |
| 106 FakeViewRequestDelegate viewer_delegate; | 119 FakeViewRequestDelegate viewer_delegate; |
| 107 scoped_ptr<ViewerHandle> handle = | 120 scoped_ptr<ViewerHandle> handle = |
| 108 service_->ViewEntry(&viewer_delegate, entry_id); | 121 service_->ViewEntry(&viewer_delegate, entry_id); |
| 109 | 122 |
| 110 ASSERT_FALSE(distiller->GetCallback().is_null()); | 123 ASSERT_FALSE(distiller->GetCallback().is_null()); |
| 111 | 124 |
| 112 scoped_ptr<DistilledPageProto> proto(new DistilledPageProto); | 125 scoped_ptr<DistilledArticleProto> proto = CreateDefaultArticle(); |
| 113 EXPECT_CALL(viewer_delegate, OnArticleReady(proto.get())); | 126 EXPECT_CALL(viewer_delegate, OnArticleReady(proto.get())); |
| 114 | 127 |
| 115 RunDistillerCallback(distiller, proto.Pass()); | 128 RunDistillerCallback(distiller, proto.Pass()); |
| 116 } | 129 } |
| 117 | 130 |
| 118 TEST_F(DomDistillerServiceTest, TestViewUrl) { | 131 TEST_F(DomDistillerServiceTest, TestViewUrl) { |
| 119 FakeDistiller* distiller = new FakeDistiller(false); | 132 FakeDistiller* distiller = new FakeDistiller(false); |
| 120 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) | 133 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) |
| 121 .WillOnce(Return(distiller)); | 134 .WillOnce(Return(distiller)); |
| 122 | 135 |
| 123 FakeViewRequestDelegate viewer_delegate; | 136 FakeViewRequestDelegate viewer_delegate; |
| 124 GURL url("http://www.example.com/p1"); | 137 GURL url("http://www.example.com/p1"); |
| 125 scoped_ptr<ViewerHandle> handle = service_->ViewUrl(&viewer_delegate, url); | 138 scoped_ptr<ViewerHandle> handle = service_->ViewUrl(&viewer_delegate, url); |
| 126 | 139 |
| 127 ASSERT_FALSE(distiller->GetCallback().is_null()); | 140 ASSERT_FALSE(distiller->GetCallback().is_null()); |
| 128 EXPECT_EQ(url, distiller->GetUrl()); | 141 EXPECT_EQ(url, distiller->GetUrl()); |
| 129 | 142 |
| 130 scoped_ptr<DistilledPageProto> proto(new DistilledPageProto); | 143 scoped_ptr<DistilledArticleProto> proto = CreateDefaultArticle(); |
| 131 EXPECT_CALL(viewer_delegate, OnArticleReady(proto.get())); | 144 EXPECT_CALL(viewer_delegate, OnArticleReady(proto.get())); |
| 132 | 145 |
| 133 RunDistillerCallback(distiller, proto.Pass()); | 146 RunDistillerCallback(distiller, proto.Pass()); |
| 134 } | 147 } |
| 135 | 148 |
| 136 TEST_F(DomDistillerServiceTest, TestMultipleViewUrl) { | 149 TEST_F(DomDistillerServiceTest, TestMultipleViewUrl) { |
| 137 FakeDistiller* distiller = new FakeDistiller(false); | 150 FakeDistiller* distiller = new FakeDistiller(false); |
| 138 FakeDistiller* distiller2 = new FakeDistiller(false); | 151 FakeDistiller* distiller2 = new FakeDistiller(false); |
| 139 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) | 152 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) |
| 140 .WillOnce(Return(distiller)) | 153 .WillOnce(Return(distiller)) |
| 141 .WillOnce(Return(distiller2)); | 154 .WillOnce(Return(distiller2)); |
| 142 | 155 |
| 143 FakeViewRequestDelegate viewer_delegate; | 156 FakeViewRequestDelegate viewer_delegate; |
| 144 FakeViewRequestDelegate viewer_delegate2; | 157 FakeViewRequestDelegate viewer_delegate2; |
| 145 | 158 |
| 146 GURL url("http://www.example.com/p1"); | 159 GURL url("http://www.example.com/p1"); |
| 147 GURL url2("http://www.example.com/a/p1"); | 160 GURL url2("http://www.example.com/a/p1"); |
| 148 | 161 |
| 149 scoped_ptr<ViewerHandle> handle = service_->ViewUrl(&viewer_delegate, url); | 162 scoped_ptr<ViewerHandle> handle = service_->ViewUrl(&viewer_delegate, url); |
| 150 scoped_ptr<ViewerHandle> handle2 = service_->ViewUrl(&viewer_delegate2, url2); | 163 scoped_ptr<ViewerHandle> handle2 = service_->ViewUrl(&viewer_delegate2, url2); |
| 151 | 164 |
| 152 ASSERT_FALSE(distiller->GetCallback().is_null()); | 165 ASSERT_FALSE(distiller->GetCallback().is_null()); |
| 153 EXPECT_EQ(url, distiller->GetUrl()); | 166 EXPECT_EQ(url, distiller->GetUrl()); |
| 154 | 167 |
| 155 scoped_ptr<DistilledPageProto> proto(new DistilledPageProto); | 168 scoped_ptr<DistilledArticleProto> proto = CreateDefaultArticle(); |
| 156 EXPECT_CALL(viewer_delegate, OnArticleReady(proto.get())); | 169 EXPECT_CALL(viewer_delegate, OnArticleReady(proto.get())); |
| 157 | 170 |
| 158 RunDistillerCallback(distiller, proto.Pass()); | 171 RunDistillerCallback(distiller, proto.Pass()); |
| 159 | 172 |
| 160 ASSERT_FALSE(distiller2->GetCallback().is_null()); | 173 ASSERT_FALSE(distiller2->GetCallback().is_null()); |
| 161 EXPECT_EQ(url2, distiller2->GetUrl()); | 174 EXPECT_EQ(url2, distiller2->GetUrl()); |
| 162 | 175 |
| 163 scoped_ptr<DistilledPageProto> proto2(new DistilledPageProto); | 176 scoped_ptr<DistilledArticleProto> proto2 = CreateDefaultArticle(); |
| 164 EXPECT_CALL(viewer_delegate2, OnArticleReady(proto2.get())); | 177 EXPECT_CALL(viewer_delegate2, OnArticleReady(proto2.get())); |
| 165 | 178 |
| 166 RunDistillerCallback(distiller2, proto2.Pass()); | 179 RunDistillerCallback(distiller2, proto2.Pass()); |
| 167 } | 180 } |
| 168 | 181 |
| 169 TEST_F(DomDistillerServiceTest, TestViewUrlCancelled) { | 182 TEST_F(DomDistillerServiceTest, TestViewUrlCancelled) { |
| 170 FakeDistiller* distiller = new FakeDistiller(false); | 183 FakeDistiller* distiller = new FakeDistiller(false); |
| 171 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) | 184 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) |
| 172 .WillOnce(Return(distiller)); | 185 .WillOnce(Return(distiller)); |
| 173 | 186 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 203 | 216 |
| 204 std::string entry_id = service_->AddToList(url, ArticleCallback(&article_cb)); | 217 std::string entry_id = service_->AddToList(url, ArticleCallback(&article_cb)); |
| 205 | 218 |
| 206 ArticleEntry entry; | 219 ArticleEntry entry; |
| 207 EXPECT_TRUE(store_->GetEntryByUrl(url, &entry)); | 220 EXPECT_TRUE(store_->GetEntryByUrl(url, &entry)); |
| 208 EXPECT_EQ(entry.entry_id(), entry_id); | 221 EXPECT_EQ(entry.entry_id(), entry_id); |
| 209 | 222 |
| 210 ASSERT_FALSE(distiller->GetCallback().is_null()); | 223 ASSERT_FALSE(distiller->GetCallback().is_null()); |
| 211 EXPECT_EQ(url, distiller->GetUrl()); | 224 EXPECT_EQ(url, distiller->GetUrl()); |
| 212 | 225 |
| 213 scoped_ptr<DistilledPageProto> proto(new DistilledPageProto); | 226 scoped_ptr<DistilledArticleProto> proto = CreateArticleWithURL(url.spec()); |
| 214 RunDistillerCallback(distiller, proto.Pass()); | 227 RunDistillerCallback(distiller, proto.Pass()); |
| 215 | 228 |
| 216 EXPECT_TRUE(store_->GetEntryByUrl(url, &entry)); | 229 EXPECT_TRUE(store_->GetEntryByUrl(url, &entry)); |
| 217 EXPECT_EQ(1u, store_->GetEntries().size()); | 230 EXPECT_EQ(1u, store_->GetEntries().size()); |
| 218 service_->RemoveEntry(entry_id); | 231 service_->RemoveEntry(entry_id); |
| 219 base::RunLoop().RunUntilIdle(); | 232 base::RunLoop().RunUntilIdle(); |
| 220 EXPECT_EQ(0u, store_->GetEntries().size()); | 233 EXPECT_EQ(0u, store_->GetEntries().size()); |
| 221 } | 234 } |
| 222 | 235 |
| 223 TEST_F(DomDistillerServiceTest, TestCancellation) { | 236 TEST_F(DomDistillerServiceTest, TestCancellation) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 update.entry_id = entry_id; | 286 update.entry_id = entry_id; |
| 274 update.update_type = DomDistillerObserver::ArticleUpdate::UPDATE; | 287 update.update_type = DomDistillerObserver::ArticleUpdate::UPDATE; |
| 275 expected_updates.push_back(update); | 288 expected_updates.push_back(update); |
| 276 | 289 |
| 277 for (int i = 0; i < kObserverCount; ++i) { | 290 for (int i = 0; i < kObserverCount; ++i) { |
| 278 EXPECT_CALL( | 291 EXPECT_CALL( |
| 279 observers[i], | 292 observers[i], |
| 280 ArticleEntriesUpdated(util::HasExpectedUpdates(expected_updates))); | 293 ArticleEntriesUpdated(util::HasExpectedUpdates(expected_updates))); |
| 281 } | 294 } |
| 282 | 295 |
| 283 scoped_ptr<DistilledPageProto> proto(new DistilledPageProto); | 296 scoped_ptr<DistilledArticleProto> proto = CreateDefaultArticle(); |
| 284 RunDistillerCallback(distiller, proto.Pass()); | 297 RunDistillerCallback(distiller, proto.Pass()); |
| 285 | 298 |
| 286 // Remove should notify all observers that article is removed. | 299 // Remove should notify all observers that article is removed. |
| 287 update.update_type = DomDistillerObserver::ArticleUpdate::REMOVE; | 300 update.update_type = DomDistillerObserver::ArticleUpdate::REMOVE; |
| 288 expected_updates.clear(); | 301 expected_updates.clear(); |
| 289 expected_updates.push_back(update); | 302 expected_updates.push_back(update); |
| 290 for (int i = 0; i < kObserverCount; ++i) { | 303 for (int i = 0; i < kObserverCount; ++i) { |
| 291 EXPECT_CALL( | 304 EXPECT_CALL( |
| 292 observers[i], | 305 observers[i], |
| 293 ArticleEntriesUpdated(util::HasExpectedUpdates(expected_updates))); | 306 ArticleEntriesUpdated(util::HasExpectedUpdates(expected_updates))); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 309 const std::string entry_id = | 322 const std::string entry_id = |
| 310 service_->AddToList(url, ArticleCallback(&article_cb[0])); | 323 service_->AddToList(url, ArticleCallback(&article_cb[0])); |
| 311 EXPECT_CALL(article_cb[0], DistillationCompleted(true)); | 324 EXPECT_CALL(article_cb[0], DistillationCompleted(true)); |
| 312 | 325 |
| 313 for (int i = 1; i < kClientsCount; ++i) { | 326 for (int i = 1; i < kClientsCount; ++i) { |
| 314 EXPECT_EQ(entry_id, | 327 EXPECT_EQ(entry_id, |
| 315 service_->AddToList(url, ArticleCallback(&article_cb[i]))); | 328 service_->AddToList(url, ArticleCallback(&article_cb[i]))); |
| 316 EXPECT_CALL(article_cb[i], DistillationCompleted(true)); | 329 EXPECT_CALL(article_cb[i], DistillationCompleted(true)); |
| 317 } | 330 } |
| 318 | 331 |
| 319 scoped_ptr<DistilledPageProto> proto(new DistilledPageProto); | 332 scoped_ptr<DistilledArticleProto> proto = CreateArticleWithURL(url.spec()); |
| 320 RunDistillerCallback(distiller, proto.Pass()); | 333 RunDistillerCallback(distiller, proto.Pass()); |
| 321 | 334 |
| 322 // Add the same url again, all callbacks should be called with true. | 335 // Add the same url again, all callbacks should be called with true. |
| 323 for (int i = 0; i < kClientsCount; ++i) { | 336 for (int i = 0; i < kClientsCount; ++i) { |
| 324 EXPECT_CALL(article_cb[i], DistillationCompleted(true)); | 337 EXPECT_CALL(article_cb[i], DistillationCompleted(true)); |
| 325 EXPECT_EQ(entry_id, | 338 EXPECT_EQ(entry_id, |
| 326 service_->AddToList(url, ArticleCallback(&article_cb[i]))); | 339 service_->AddToList(url, ArticleCallback(&article_cb[i]))); |
| 327 } | 340 } |
| 328 | 341 |
| 329 base::RunLoop().RunUntilIdle(); | 342 base::RunLoop().RunUntilIdle(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 346 for (int i = 1; i < kClientsCount; ++i) { | 359 for (int i = 1; i < kClientsCount; ++i) { |
| 347 EXPECT_EQ(entry_id, | 360 EXPECT_EQ(entry_id, |
| 348 service_->AddToList(url, ArticleCallback(&article_cb[i]))); | 361 service_->AddToList(url, ArticleCallback(&article_cb[i]))); |
| 349 EXPECT_CALL(article_cb[i], DistillationCompleted(false)); | 362 EXPECT_CALL(article_cb[i], DistillationCompleted(false)); |
| 350 } | 363 } |
| 351 | 364 |
| 352 service_->RemoveEntry(entry_id); | 365 service_->RemoveEntry(entry_id); |
| 353 base::RunLoop().RunUntilIdle(); | 366 base::RunLoop().RunUntilIdle(); |
| 354 } | 367 } |
| 355 | 368 |
| 369 TEST_F(DomDistillerServiceTest, TestMultiplePageArticle) { |
| 370 FakeDistiller* distiller = new FakeDistiller(false); |
| 371 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) |
| 372 .WillOnce(Return(distiller)); |
| 373 |
| 374 const int kPageCount = 8; |
| 375 |
| 376 std::string base_url("http://www.example.com/p"); |
| 377 GURL pages_url[kPageCount]; |
| 378 for (int page_num = 0; page_num < kPageCount; ++page_num) { |
| 379 pages_url[page_num] = GURL(base_url + base::IntToString(page_num)); |
| 380 } |
| 381 |
| 382 MockArticleAvailableCallback article_cb; |
| 383 EXPECT_CALL(article_cb, DistillationCompleted(true)); |
| 384 |
| 385 std::string entry_id = |
| 386 service_->AddToList(pages_url[0], ArticleCallback(&article_cb)); |
| 387 |
| 388 ArticleEntry entry; |
| 389 ASSERT_FALSE(distiller->GetCallback().is_null()); |
| 390 EXPECT_EQ(pages_url[0], distiller->GetUrl()); |
| 391 |
| 392 // Create the article with pages to pass to the distiller. |
| 393 scoped_ptr<DistilledArticleProto> proto = |
| 394 CreateArticleWithURL(pages_url[0].spec()); |
| 395 for (int page_num = 1; page_num < kPageCount; ++page_num) { |
| 396 DistilledPageProto* distilled_page = proto->add_pages(); |
| 397 distilled_page->set_url(pages_url[page_num].spec()); |
| 398 } |
| 399 |
| 400 RunDistillerCallback(distiller, proto.Pass()); |
| 401 EXPECT_TRUE(store_->GetEntryByUrl(pages_url[0], &entry)); |
| 402 |
| 403 EXPECT_EQ(kPageCount, entry.pages_size()); |
| 404 // An article should have just one entry. |
| 405 EXPECT_EQ(1u, store_->GetEntries().size()); |
| 406 |
| 407 // All pages should have correct urls. |
| 408 for (int page_num = 0; page_num < kPageCount; ++page_num) { |
| 409 EXPECT_EQ(pages_url[page_num].spec(), entry.pages(page_num).url()); |
| 410 } |
| 411 |
| 412 // Should be able to query article using any of the pages url. |
| 413 for (int page_num = 0; page_num < kPageCount; ++page_num) { |
| 414 EXPECT_TRUE(store_->GetEntryByUrl(pages_url[page_num], &entry)); |
| 415 } |
| 416 |
| 417 service_->RemoveEntry(entry_id); |
| 418 base::RunLoop().RunUntilIdle(); |
| 419 EXPECT_EQ(0u, store_->GetEntries().size()); |
| 420 } |
| 421 |
| 356 } // namespace test | 422 } // namespace test |
| 357 } // namespace dom_distiller | 423 } // namespace dom_distiller |
| OLD | NEW |