summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2015-01-15 16:31:51 -0800
committerTom Sepez <tsepez@chromium.org>2015-01-15 16:31:51 -0800
commitd0edcea1a1b22813f593022ca29fca79074757bf (patch)
treef595d536595cafac145a92ebeb3540f4b383b8a1
parentf061e44695fc438f3fc9877f5bf8f0f8397ed186 (diff)
downloadpdfium-d0edcea1a1b22813f593022ca29fca79074757bf.tar.xz
Create first pdfium embedder test.
BUG=https://code.google.com/p/pdfium/issues/detail?id=62 R=jam@chromium.org Review URL: https://codereview.chromium.org/827733006
-rw-r--r--pdfium.gyp19
-rw-r--r--testing/basic_embeddertest.cpp19
-rw-r--r--testing/embedder_test.cpp303
-rw-r--r--testing/embedder_test.h78
-rw-r--r--testing/resources/about_blank.pdfbin0 -> 735 bytes
5 files changed, 419 insertions, 0 deletions
diff --git a/pdfium.gyp b/pdfium.gyp
index 5b41ed08fe..fb6771f0cd 100644
--- a/pdfium.gyp
+++ b/pdfium.gyp
@@ -826,5 +826,24 @@
'core/src/fxcrt/fx_basic_bstring_unittest.cpp',
],
},
+ {
+ 'target_name': 'pdfium_embeddertests',
+ 'type': 'executable',
+ 'dependencies': [
+ '<(DEPTH)/testing/gtest.gyp:gtest_main',
+ '<(DEPTH)/testing/gtest.gyp:gtest',
+ 'pdfium',
+ ],
+ 'include_dirs': [
+ '<(DEPTH)'
+ ],
+ 'sources': [
+ 'testing/basic_embeddertest.cpp',
+ 'testing/embedder_test.cpp',
+ 'testing/embedder_test.h',
+ 'testing/fx_string_testhelpers.cpp',
+ 'testing/fx_string_testhelpers.h',
+ ],
+ },
],
}
diff --git a/testing/basic_embeddertest.cpp b/testing/basic_embeddertest.cpp
new file mode 100644
index 0000000000..210fabd71a
--- /dev/null
+++ b/testing/basic_embeddertest.cpp
@@ -0,0 +1,19 @@
+// Copyright (c) 2015 PDFium 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 "embedder_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class BasicEmbeddertest : public EmbedderTest {
+};
+
+TEST_F(BasicEmbeddertest, GetPageCount) {
+ EXPECT_TRUE(OpenDocument("testing/resources/about_blank.pdf"));
+ EXPECT_EQ(1, GetPageCount());
+}
+
+TEST_F(BasicEmbeddertest, GetFirstPageNum) {
+ EXPECT_TRUE(OpenDocument("testing/resources/about_blank.pdf"));
+ EXPECT_EQ(0, GetFirstPageNum());
+}
diff --git a/testing/embedder_test.cpp b/testing/embedder_test.cpp
new file mode 100644
index 0000000000..7b8498345a
--- /dev/null
+++ b/testing/embedder_test.cpp
@@ -0,0 +1,303 @@
+// Copyright (c) 2015 PDFium 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 "embedder_test.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <list>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "../fpdfsdk/include/fpdf_ext.h"
+#include "../fpdfsdk/include/fpdftext.h"
+#include "../fpdfsdk/include/fpdfview.h"
+#include "../core/include/fxcrt/fx_system.h"
+#include "v8/include/v8.h"
+
+#ifdef _WIN32
+#define snprintf _snprintf
+#define PATH_SEPARATOR '\\'
+#else
+#define PATH_SEPARATOR '/'
+#endif
+
+namespace {
+
+// Reads the entire contents of a file into a newly malloc'd buffer.
+static char* GetFileContents(const char* filename, size_t* retlen) {
+ FILE* file = fopen(filename, "rb");
+ if (!file) {
+ fprintf(stderr, "Failed to open: %s\n", filename);
+ return NULL;
+ }
+ (void) fseek(file, 0, SEEK_END);
+ size_t file_length = ftell(file);
+ if (!file_length) {
+ return NULL;
+ }
+ (void) fseek(file, 0, SEEK_SET);
+ char* buffer = (char*) malloc(file_length);
+ if (!buffer) {
+ return NULL;
+ }
+ size_t bytes_read = fread(buffer, 1, file_length, file);
+ (void) fclose(file);
+ if (bytes_read != file_length) {
+ fprintf(stderr, "Failed to read: %s\n", filename);
+ free(buffer);
+ return NULL;
+ }
+ *retlen = bytes_read;
+ return buffer;
+}
+
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+// Returns the full path for an external V8 data file based on either
+// the currect exectuable path or an explicit override.
+static std::string GetFullPathForSnapshotFile(const Options& options,
+ const std::string& filename) {
+ std::string result;
+ if (!options.bin_directory.empty()) {
+ result = options.bin_directory;
+ if (*options.bin_directory.rbegin() != PATH_SEPARATOR) {
+ result += PATH_SEPARATOR;
+ }
+ } else if (!options.exe_path.empty()) {
+ size_t last_separator = options.exe_path.rfind(PATH_SEPARATOR);
+ if (last_separator != std::string::npos) {
+ result = options.exe_path.substr(0, last_separator + 1);
+ }
+ }
+ result += filename;
+ return result;
+}
+
+// Reads an extenal V8 data file from the |options|-indicated location,
+// returing true on success and false on error.
+static bool GetExternalData(const Options& options,
+ const std::string& bin_filename,
+ v8::StartupData* result_data) {
+ std::string full_path = GetFullPathForSnapshotFile(options, bin_filename);
+ size_t data_length = 0;
+ char* data_buffer = GetFileContents(full_path.c_str(), &data_length);
+ if (!data_buffer) {
+ return false;
+ }
+ result_data->data = const_cast<const char*>(data_buffer);
+ result_data->raw_size = data_length;
+ return true;
+}
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
+
+} // namespace
+
+int Form_Alert(IPDF_JSPLATFORM*, FPDF_WIDESTRING, FPDF_WIDESTRING, int, int) {
+ printf("Form_Alert called.\n");
+ return 0;
+}
+
+void Unsupported_Handler(UNSUPPORT_INFO*, int type) {
+ std::string feature = "Unknown";
+ switch (type) {
+ case FPDF_UNSP_DOC_XFAFORM:
+ feature = "XFA";
+ break;
+ case FPDF_UNSP_DOC_PORTABLECOLLECTION:
+ feature = "Portfolios_Packages";
+ break;
+ case FPDF_UNSP_DOC_ATTACHMENT:
+ case FPDF_UNSP_ANNOT_ATTACHMENT:
+ feature = "Attachment";
+ break;
+ case FPDF_UNSP_DOC_SECURITY:
+ feature = "Rights_Management";
+ break;
+ case FPDF_UNSP_DOC_SHAREDREVIEW:
+ feature = "Shared_Review";
+ break;
+ case FPDF_UNSP_DOC_SHAREDFORM_ACROBAT:
+ case FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM:
+ case FPDF_UNSP_DOC_SHAREDFORM_EMAIL:
+ feature = "Shared_Form";
+ break;
+ case FPDF_UNSP_ANNOT_3DANNOT:
+ feature = "3D";
+ break;
+ case FPDF_UNSP_ANNOT_MOVIE:
+ feature = "Movie";
+ break;
+ case FPDF_UNSP_ANNOT_SOUND:
+ feature = "Sound";
+ break;
+ case FPDF_UNSP_ANNOT_SCREEN_MEDIA:
+ case FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA:
+ feature = "Screen";
+ break;
+ case FPDF_UNSP_ANNOT_SIG:
+ feature = "Digital_Signature";
+ break;
+ }
+ printf("Unsupported feature: %s.\n", feature.c_str());
+}
+
+class TestLoader {
+ public:
+ TestLoader(const char* pBuf, size_t len);
+
+ const char* m_pBuf;
+ size_t m_Len;
+};
+
+TestLoader::TestLoader(const char* pBuf, size_t len)
+ : m_pBuf(pBuf), m_Len(len) {
+}
+
+int Get_Block(void* param, unsigned long pos, unsigned char* pBuf,
+ unsigned long size) {
+ TestLoader* pLoader = (TestLoader*) param;
+ if (pos + size < pos || pos + size > pLoader->m_Len) return 0;
+ memcpy(pBuf, pLoader->m_pBuf + pos, size);
+ return 1;
+}
+
+bool Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) {
+ return true;
+}
+
+void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {
+}
+
+void EmbedderTest::SetUp() {
+ v8::V8::InitializeICU();
+
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ ASSERT_TRUE(GetExternalData(options, "natives_blob.bin", &natives_));
+ ASSERT_TRUE(GetExternalData(options, "snapshot_blob.bin", &snapshot_));
+ v8::V8::SetNativesDataBlob(&natives);
+ v8::V8::SetSnapshotDataBlob(&snapshot);
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
+
+ FPDF_InitLibrary();
+
+ UNSUPPORT_INFO unsuppored_info;
+ memset(&unsuppored_info, '\0', sizeof(unsuppored_info));
+ unsuppored_info.version = 1;
+ unsuppored_info.FSDK_UnSupport_Handler = Unsupported_Handler;
+ FSDK_SetUnSpObjProcessHandler(&unsuppored_info);
+ }
+
+void EmbedderTest::TearDown() {
+ FPDF_CloseDocument(document_);
+ FPDFAvail_Destroy(avail_);
+ if (file_contents_) {
+ free(file_contents_);
+ }
+}
+
+bool EmbedderTest::OpenDocument(const std::string& filename) {
+ file_contents_ = GetFileContents(filename.c_str(), &file_length_);
+ if (!file_contents_) {
+ return false;
+ }
+
+ TestLoader loader(file_contents_, file_length_);
+
+ file_access_.m_FileLen = static_cast<unsigned long>(file_length_);
+ file_access_.m_GetBlock = Get_Block;
+ file_access_.m_Param = &loader;
+
+ file_avail_.version = 1;
+ file_avail_.IsDataAvail = Is_Data_Avail;
+
+ hints_.version = 1;
+ hints_.AddSegment = Add_Segment;
+
+ avail_ = FPDFAvail_Create(&file_avail_, &file_access_);
+ (void) FPDFAvail_IsDocAvail(avail_, &hints_);
+
+ if (!FPDFAvail_IsLinearized(avail_)) {
+ document_ = FPDF_LoadCustomDocument(&file_access_, NULL);
+ } else {
+ document_ = FPDFAvail_GetDocument(avail_, NULL);
+ }
+
+ (void) FPDF_GetDocPermissions(document_);
+ (void) FPDFAvail_IsFormAvail(avail_, &hints_);
+ return true;
+}
+
+FPDF_FORMHANDLE EmbedderTest::SetFormFillEnvironment() {
+ IPDF_JSPLATFORM platform_callbacks;
+ memset(&platform_callbacks, '\0', sizeof(platform_callbacks));
+ platform_callbacks.version = 1;
+ platform_callbacks.app_alert = Form_Alert;
+
+ FPDF_FORMFILLINFO form_callbacks;
+ memset(&form_callbacks, '\0', sizeof(form_callbacks));
+ form_callbacks.version = 1;
+ form_callbacks.m_pJsPlatform = &platform_callbacks;
+
+ FPDF_FORMHANDLE form = FPDFDOC_InitFormFillEnvironment(document_,
+ &form_callbacks);
+ FPDF_SetFormFieldHighlightColor(form, 0, 0xFFE4DD);
+ FPDF_SetFormFieldHighlightAlpha(form, 100);
+ return form;
+}
+
+void EmbedderTest::ClearFormFillEnvironment(FPDF_FORMHANDLE form) {
+ FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC);
+ FPDFDOC_ExitFormFillEnvironment(form);
+}
+
+void EmbedderTest::DoOpenActions(FPDF_FORMHANDLE form) {
+ FORM_DoDocumentJSAction(form);
+ FORM_DoDocumentOpenAction(form);
+}
+
+int EmbedderTest::GetFirstPageNum() {
+ int first_page = FPDFAvail_GetFirstPageNum(document_);
+ (void) FPDFAvail_IsPageAvail(avail_, first_page, &hints_);
+ return first_page;
+}
+
+int EmbedderTest::GetPageCount() {
+ int page_count = FPDF_GetPageCount(document_);
+ for (int i = 0; i < page_count; ++i) {
+ (void) FPDFAvail_IsPageAvail(avail_, i, &hints_);
+ }
+ return page_count;
+}
+
+FPDF_PAGE EmbedderTest::LoadPage(int page_number,
+ FPDF_FORMHANDLE form) {
+ FPDF_PAGE page = FPDF_LoadPage(document_, page_number);
+ if (!page) {
+ return nullptr;
+ }
+ FORM_OnAfterLoadPage(page, form);
+ FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_OPEN);
+ return page;
+}
+
+FPDF_BITMAP EmbedderTest::RenderPage(FPDF_PAGE page,
+ FPDF_FORMHANDLE form) {
+ int width = static_cast<int>(FPDF_GetPageWidth(page));
+ int height = static_cast<int>(FPDF_GetPageHeight(page));
+ FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0);
+ FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF);
+ FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0);
+ FPDF_FFLDraw(form, bitmap, page, 0, 0, width, height, 0, 0);
+ return bitmap;
+}
+
+void EmbedderTest::UnloadPage(FPDF_PAGE page, FPDF_FORMHANDLE form) {
+ FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE);
+ FORM_OnBeforeClosePage(page, form);
+ FPDF_ClosePage(page);
+}
diff --git a/testing/embedder_test.h b/testing/embedder_test.h
new file mode 100644
index 0000000000..b127eadbde
--- /dev/null
+++ b/testing/embedder_test.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2015 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TESTING_EMBEDDER_TEST_H_
+#define TESTING_EMBEDDER_TEST_H_
+
+#include <string>
+
+#include "../core/include/fxcrt/fx_system.h"
+#include "../fpdfsdk/include/fpdf_dataavail.h"
+#include "../fpdfsdk/include/fpdfformfill.h"
+#include "../fpdfsdk/include/fpdfview.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "v8/include/v8.h"
+
+// This class is used to load a PDF document, and then run programatic
+// API tests against it.
+class EmbedderTest : public ::testing::Test {
+ public:
+ EmbedderTest() :
+ document_(nullptr),
+ avail_(nullptr),
+ file_length_(0),
+ file_contents_(nullptr) {
+ memset(&hints_, 0, sizeof(hints_));
+ memset(&file_access_, 0, sizeof(file_access_));
+ memset(&file_avail_, 0, sizeof(file_avail_));
+ }
+
+ virtual ~EmbedderTest() { }
+
+ void SetUp() override;
+ void TearDown() override;
+
+ FPDF_DOCUMENT document() { return document_; }
+
+ // Open the document specified by |filename|, or return false on failure.
+ virtual bool OpenDocument(const std::string& filename);
+
+ // Create and return a handle to the form fill module for use with the
+ // FORM_ family of functions from fpdfformfill.h, or return NULL on failure.
+ virtual FPDF_FORMHANDLE SetFormFillEnvironment();
+
+ // Release the resources obtained from SetFormFillEnvironment().
+ virtual void ClearFormFillEnvironment(FPDF_FORMHANDLE form);
+
+ // Perform JavaScript actions that are to run at document open time.
+ virtual void DoOpenActions(FPDF_FORMHANDLE form);
+
+ // Determine the page numbers present in the document.
+ virtual int GetFirstPageNum();
+ virtual int GetPageCount();
+
+ // Load a specific page of the open document.
+ virtual FPDF_PAGE LoadPage(int page_number, FPDF_FORMHANDLE form);
+
+ // Convert a loaded page into a bitmap.
+ virtual FPDF_BITMAP RenderPage(FPDF_PAGE page, FPDF_FORMHANDLE form);
+
+ // Relese the resources obtained from LoadPage(). Further use of |page|
+ // is prohibited after this call is made.
+ virtual void UnloadPage(FPDF_PAGE page, FPDF_FORMHANDLE form);
+
+ private:
+ FPDF_DOCUMENT document_;
+ FPDF_AVAIL avail_;
+ FX_DOWNLOADHINTS hints_;
+ FPDF_FILEACCESS file_access_;
+ FX_FILEAVAIL file_avail_;
+ v8::StartupData natives_;
+ v8::StartupData snapshot_;
+ size_t file_length_;
+ char* file_contents_;
+};
+
+#endif // TESTING_EMBEDDER_TEST_H_
+
diff --git a/testing/resources/about_blank.pdf b/testing/resources/about_blank.pdf
new file mode 100644
index 0000000000..d640582d6a
--- /dev/null
+++ b/testing/resources/about_blank.pdf
Binary files differ