
The methodology used to generate this CL is documented in https://crbug.com/1098010#c95. No-Try: true Bug: 1098010 Change-Id: I6ae92e5d7ccbf73b176588124b2f8b4067f805b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3900575 Reviewed-by: Mark Mentovai <mark@chromium.org> Owners-Override: Avi Drissman <avi@chromium.org> Commit-Queue: Avi Drissman <avi@chromium.org> Auto-Submit: Avi Drissman <avi@chromium.org> Cr-Commit-Position: refs/heads/main@{#1047628}
245 lines
8.0 KiB
C++
245 lines
8.0 KiB
C++
// Copyright 2018 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "base/check_op.h"
|
|
#include "base/strings/utf_string_conversions.h"
|
|
#include "pdf/document_layout.h"
|
|
#include "pdf/pdfium/pdfium_engine.h"
|
|
#include "pdf/pdfium/pdfium_test_base.h"
|
|
#include "pdf/test/test_client.h"
|
|
#include "testing/gmock/include/gmock/gmock.h"
|
|
#include "third_party/abseil-cpp/absl/types/optional.h"
|
|
|
|
using testing::_;
|
|
using testing::InSequence;
|
|
|
|
namespace chrome_pdf {
|
|
|
|
namespace {
|
|
|
|
class FindTextTestClient : public TestClient {
|
|
public:
|
|
explicit FindTextTestClient(bool expected_case_sensitive)
|
|
: expected_case_sensitive_(expected_case_sensitive) {}
|
|
FindTextTestClient(const FindTextTestClient&) = delete;
|
|
FindTextTestClient& operator=(const FindTextTestClient&) = delete;
|
|
~FindTextTestClient() override = default;
|
|
|
|
// PDFEngine::Client:
|
|
MOCK_METHOD(void, NotifyNumberOfFindResultsChanged, (int, bool), (override));
|
|
MOCK_METHOD(void, NotifySelectedFindResultChanged, (int, bool), (override));
|
|
|
|
std::vector<SearchStringResult> SearchString(const char16_t* string,
|
|
const char16_t* term,
|
|
bool case_sensitive) override {
|
|
EXPECT_EQ(case_sensitive, expected_case_sensitive_);
|
|
std::u16string haystack = std::u16string(string);
|
|
std::u16string needle = std::u16string(term);
|
|
EXPECT_FALSE(haystack.empty());
|
|
EXPECT_FALSE(needle.empty());
|
|
|
|
std::vector<SearchStringResult> results;
|
|
|
|
size_t pos = 0;
|
|
while (true) {
|
|
pos = haystack.find(needle, pos);
|
|
if (pos == std::u16string::npos)
|
|
break;
|
|
|
|
SearchStringResult result;
|
|
result.length = needle.size();
|
|
result.start_index = pos;
|
|
results.push_back(result);
|
|
pos += needle.size();
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private:
|
|
const bool expected_case_sensitive_;
|
|
};
|
|
|
|
void ExpectInitialSearchResults(FindTextTestClient& client, int count) {
|
|
DCHECK_GE(count, 0);
|
|
|
|
if (count == 0) {
|
|
EXPECT_CALL(client,
|
|
NotifyNumberOfFindResultsChanged(0, /*final_result=*/true));
|
|
return;
|
|
}
|
|
|
|
InSequence sequence;
|
|
|
|
EXPECT_CALL(client,
|
|
NotifyNumberOfFindResultsChanged(1, /*final_result=*/false));
|
|
EXPECT_CALL(client,
|
|
NotifySelectedFindResultChanged(0, /*final_result=*/false));
|
|
for (int i = 2; i < count + 1; ++i) {
|
|
EXPECT_CALL(client,
|
|
NotifyNumberOfFindResultsChanged(i, /*final_result=*/false));
|
|
}
|
|
EXPECT_CALL(client,
|
|
NotifyNumberOfFindResultsChanged(count, /*final_result=*/true));
|
|
}
|
|
|
|
} // namespace
|
|
|
|
using FindTextTest = PDFiumTestBase;
|
|
|
|
TEST_F(FindTextTest, FindText) {
|
|
FindTextTestClient client(/*expected_case_sensitive=*/true);
|
|
std::unique_ptr<PDFiumEngine> engine =
|
|
InitializeEngine(&client, FILE_PATH_LITERAL("hello_world2.pdf"));
|
|
ASSERT_TRUE(engine);
|
|
|
|
ExpectInitialSearchResults(client, 10);
|
|
engine->StartFind("o", /*case_sensitive=*/true);
|
|
}
|
|
|
|
TEST_F(FindTextTest, FindHyphenatedText) {
|
|
FindTextTestClient client(/*expected_case_sensitive=*/true);
|
|
std::unique_ptr<PDFiumEngine> engine =
|
|
InitializeEngine(&client, FILE_PATH_LITERAL("spanner.pdf"));
|
|
ASSERT_TRUE(engine);
|
|
|
|
ExpectInitialSearchResults(client, 6);
|
|
engine->StartFind("application", /*case_sensitive=*/true);
|
|
}
|
|
|
|
TEST_F(FindTextTest, FindLineBreakText) {
|
|
FindTextTestClient client(/*expected_case_sensitive=*/true);
|
|
std::unique_ptr<PDFiumEngine> engine =
|
|
InitializeEngine(&client, FILE_PATH_LITERAL("spanner.pdf"));
|
|
ASSERT_TRUE(engine);
|
|
|
|
ExpectInitialSearchResults(client, 1);
|
|
engine->StartFind("is the first system", /*case_sensitive=*/true);
|
|
}
|
|
|
|
TEST_F(FindTextTest, FindSimpleQuotationMarkText) {
|
|
FindTextTestClient client(/*expected_case_sensitive=*/true);
|
|
std::unique_ptr<PDFiumEngine> engine =
|
|
InitializeEngine(&client, FILE_PATH_LITERAL("bug_142627.pdf"));
|
|
ASSERT_TRUE(engine);
|
|
|
|
ExpectInitialSearchResults(client, 2);
|
|
engine->StartFind("don't", /*case_sensitive=*/true);
|
|
}
|
|
|
|
TEST_F(FindTextTest, FindFancyQuotationMarkText) {
|
|
FindTextTestClient client(/*expected_case_sensitive=*/true);
|
|
std::unique_ptr<PDFiumEngine> engine =
|
|
InitializeEngine(&client, FILE_PATH_LITERAL("bug_142627.pdf"));
|
|
ASSERT_TRUE(engine);
|
|
|
|
ExpectInitialSearchResults(client, 2);
|
|
|
|
// don't, using right apostrophe instead of a single quotation mark
|
|
std::u16string term = {'d', 'o', 'n', 0x2019, 't'};
|
|
engine->StartFind(base::UTF16ToUTF8(term), /*case_sensitive=*/true);
|
|
}
|
|
|
|
TEST_F(FindTextTest, FindHiddenCroppedText) {
|
|
FindTextTestClient client(/*expected_case_sensitive=*/true);
|
|
std::unique_ptr<PDFiumEngine> engine =
|
|
InitializeEngine(&client, FILE_PATH_LITERAL("hello_world_cropped.pdf"));
|
|
ASSERT_TRUE(engine);
|
|
|
|
// The word "Hello" is cropped out.
|
|
ExpectInitialSearchResults(client, 0);
|
|
engine->StartFind("Hello", /*case_sensitive=*/true);
|
|
}
|
|
|
|
TEST_F(FindTextTest, FindVisibleCroppedText) {
|
|
FindTextTestClient client(/*expected_case_sensitive=*/true);
|
|
std::unique_ptr<PDFiumEngine> engine =
|
|
InitializeEngine(&client, FILE_PATH_LITERAL("hello_world_cropped.pdf"));
|
|
ASSERT_TRUE(engine);
|
|
|
|
// Only one instance of the word "world" is visible. The other is cropped out.
|
|
ExpectInitialSearchResults(client, 1);
|
|
engine->StartFind("world", /*case_sensitive=*/true);
|
|
}
|
|
|
|
TEST_F(FindTextTest, FindVisibleCroppedTextRepeatedly) {
|
|
FindTextTestClient client(/*expected_case_sensitive=*/true);
|
|
std::unique_ptr<PDFiumEngine> engine =
|
|
InitializeEngine(&client, FILE_PATH_LITERAL("hello_world_cropped.pdf"));
|
|
ASSERT_TRUE(engine);
|
|
|
|
// Only one instance of the word "world" is visible. The other is cropped out.
|
|
// These 2 find operations should not trigger https://crbug.com/1344057.
|
|
ExpectInitialSearchResults(client, 1);
|
|
engine->StartFind("worl", /*case_sensitive=*/true);
|
|
ExpectInitialSearchResults(client, 1);
|
|
engine->StartFind("world", /*case_sensitive=*/true);
|
|
}
|
|
|
|
TEST_F(FindTextTest, SelectFindResult) {
|
|
FindTextTestClient client(/*expected_case_sensitive=*/true);
|
|
std::unique_ptr<PDFiumEngine> engine =
|
|
InitializeEngine(&client, FILE_PATH_LITERAL("hello_world2.pdf"));
|
|
ASSERT_TRUE(engine);
|
|
|
|
ExpectInitialSearchResults(client, 4);
|
|
engine->StartFind("world", /*case_sensitive=*/true);
|
|
|
|
EXPECT_CALL(client, NotifyNumberOfFindResultsChanged(_, _)).Times(0);
|
|
EXPECT_CALL(client,
|
|
NotifySelectedFindResultChanged(1, /*final_result=*/true));
|
|
|
|
ASSERT_TRUE(engine->SelectFindResult(/*forward=*/true));
|
|
|
|
EXPECT_CALL(client,
|
|
NotifySelectedFindResultChanged(2, /*final_result=*/true));
|
|
ASSERT_TRUE(engine->SelectFindResult(/*forward=*/true));
|
|
|
|
EXPECT_CALL(client,
|
|
NotifySelectedFindResultChanged(1, /*final_result=*/true));
|
|
ASSERT_TRUE(engine->SelectFindResult(/*forward=*/false));
|
|
}
|
|
|
|
TEST_F(FindTextTest, SelectFindResultAndSwitchToTwoUpView) {
|
|
FindTextTestClient client(/*expected_case_sensitive=*/false);
|
|
std::unique_ptr<PDFiumEngine> engine =
|
|
InitializeEngine(&client, FILE_PATH_LITERAL("hello_world2.pdf"));
|
|
ASSERT_TRUE(engine);
|
|
|
|
ExpectInitialSearchResults(client, 4);
|
|
engine->StartFind("world", /*case_sensitive=*/false);
|
|
|
|
{
|
|
InSequence sequence;
|
|
|
|
EXPECT_CALL(client,
|
|
NotifySelectedFindResultChanged(1, /*final_result=*/true));
|
|
EXPECT_CALL(client,
|
|
NotifySelectedFindResultChanged(2, /*final_result=*/true));
|
|
}
|
|
ASSERT_TRUE(engine->SelectFindResult(/*forward=*/true));
|
|
ASSERT_TRUE(engine->SelectFindResult(/*forward=*/true));
|
|
|
|
{
|
|
InSequence sequence;
|
|
|
|
for (int i = 0; i < 5; ++i) {
|
|
EXPECT_CALL(client,
|
|
NotifyNumberOfFindResultsChanged(i, /*final_result=*/false));
|
|
}
|
|
EXPECT_CALL(client,
|
|
NotifyNumberOfFindResultsChanged(4, /*final_result=*/true));
|
|
}
|
|
engine->SetDocumentLayout(DocumentLayout::PageSpread::kTwoUpOdd);
|
|
|
|
{
|
|
InSequence sequence;
|
|
|
|
EXPECT_CALL(client,
|
|
NotifySelectedFindResultChanged(2, /*final_result=*/true));
|
|
}
|
|
ASSERT_TRUE(engine->SelectFindResult(/*forward=*/true));
|
|
}
|
|
|
|
} // namespace chrome_pdf
|