Make parallelized run_corpus_tests.py handle ctrl-c.
[pdfium.git] / testing / embedder_test.cpp
1 // Copyright (c) 2015 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "embedder_test.h"
6
7 #include <limits.h>
8
9 #include <list>
10 #include <string>
11 #include <utility>
12 #include <vector>
13
14 #include "../public/fpdf_text.h"
15 #include "../public/fpdfview.h"
16 #include "test_support.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18
19 #ifdef PDF_ENABLE_V8
20 #include "v8/include/libplatform/libplatform.h"
21 #include "v8/include/v8.h"
22 #endif  // PDF_ENABLE_V8
23
24 namespace {
25 const char* g_exe_path_ = nullptr;
26 }  // namespace
27
28 FPDF_BOOL Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) {
29   return true;
30 }
31
32 void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {}
33
34 EmbedderTest::EmbedderTest()
35     : default_delegate_(new EmbedderTest::Delegate()),
36       document_(nullptr),
37       form_handle_(nullptr),
38       avail_(nullptr),
39       external_isolate_(nullptr),
40       loader_(nullptr),
41       file_length_(0),
42       file_contents_(nullptr) {
43   memset(&hints_, 0, sizeof(hints_));
44   memset(&file_access_, 0, sizeof(file_access_));
45   memset(&file_avail_, 0, sizeof(file_avail_));
46   delegate_ = default_delegate_.get();
47 }
48
49 EmbedderTest::~EmbedderTest() {
50 }
51
52 void EmbedderTest::SetUp() {
53 #ifdef PDF_ENABLE_V8
54 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
55   InitializeV8ForPDFium(g_exe_path_, std::string(), &natives_, &snapshot_,
56                         &platform_);
57 #else
58   InitializeV8ForPDFium(&platform_);
59 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
60 #endif  // FPDF_ENABLE_V8
61
62   FPDF_LIBRARY_CONFIG config;
63   config.version = 2;
64   config.m_pUserFontPaths = nullptr;
65   config.m_v8EmbedderSlot = 0;
66   config.m_pIsolate = external_isolate_;
67   FPDF_InitLibraryWithConfig(&config);
68
69   UNSUPPORT_INFO* info = static_cast<UNSUPPORT_INFO*>(this);
70   memset(info, 0, sizeof(UNSUPPORT_INFO));
71   info->version = 1;
72   info->FSDK_UnSupport_Handler = UnsupportedHandlerTrampoline;
73   FSDK_SetUnSpObjProcessHandler(info);
74 }
75
76 void EmbedderTest::TearDown() {
77   if (document_) {
78     FORM_DoDocumentAAction(form_handle_, FPDFDOC_AACTION_WC);
79     FPDFDOC_ExitFormFillEnvironment(form_handle_);
80     FPDF_CloseDocument(document_);
81   }
82   FPDFAvail_Destroy(avail_);
83   FPDF_DestroyLibrary();
84
85 #ifdef PDF_ENABLE_V8
86   v8::V8::ShutdownPlatform();
87   delete platform_;
88 #endif  // PDF_ENABLE_V8
89
90   delete loader_;
91   free(file_contents_);
92 }
93
94 bool EmbedderTest::OpenDocument(const std::string& filename) {
95   file_contents_ = GetFileContents(filename.c_str(), &file_length_);
96   if (!file_contents_) {
97     return false;
98   }
99
100   loader_ = new TestLoader(file_contents_, file_length_);
101   file_access_.m_FileLen = static_cast<unsigned long>(file_length_);
102   file_access_.m_GetBlock = TestLoader::GetBlock;
103   file_access_.m_Param = loader_;
104
105   file_avail_.version = 1;
106   file_avail_.IsDataAvail = Is_Data_Avail;
107
108   hints_.version = 1;
109   hints_.AddSegment = Add_Segment;
110
111   avail_ = FPDFAvail_Create(&file_avail_, &file_access_);
112   (void)FPDFAvail_IsDocAvail(avail_, &hints_);
113
114   if (!FPDFAvail_IsLinearized(avail_)) {
115     document_ = FPDF_LoadCustomDocument(&file_access_, nullptr);
116   } else {
117     document_ = FPDFAvail_GetDocument(avail_, nullptr);
118   }
119
120   (void)FPDF_GetDocPermissions(document_);
121   (void)FPDFAvail_IsFormAvail(avail_, &hints_);
122
123   IPDF_JSPLATFORM* platform = static_cast<IPDF_JSPLATFORM*>(this);
124   memset(platform, 0, sizeof(IPDF_JSPLATFORM));
125   platform->version = 2;
126   platform->app_alert = AlertTrampoline;
127
128   FPDF_FORMFILLINFO* formfillinfo = static_cast<FPDF_FORMFILLINFO*>(this);
129   memset(formfillinfo, 0, sizeof(FPDF_FORMFILLINFO));
130   formfillinfo->version = 1;
131   formfillinfo->FFI_SetTimer = SetTimerTrampoline;
132   formfillinfo->FFI_KillTimer = KillTimerTrampoline;
133   formfillinfo->FFI_GetPage = GetPageTrampoline;
134   formfillinfo->m_pJsPlatform = platform;
135
136   form_handle_ = FPDFDOC_InitFormFillEnvironment(document_, formfillinfo);
137   FPDF_SetFormFieldHighlightColor(form_handle_, 0, 0xFFE4DD);
138   FPDF_SetFormFieldHighlightAlpha(form_handle_, 100);
139
140   return true;
141 }
142
143 void EmbedderTest::DoOpenActions() {
144   FORM_DoDocumentJSAction(form_handle_);
145   FORM_DoDocumentOpenAction(form_handle_);
146 }
147
148 int EmbedderTest::GetFirstPageNum() {
149   int first_page = FPDFAvail_GetFirstPageNum(document_);
150   (void)FPDFAvail_IsPageAvail(avail_, first_page, &hints_);
151   return first_page;
152 }
153
154 int EmbedderTest::GetPageCount() {
155   int page_count = FPDF_GetPageCount(document_);
156   for (int i = 0; i < page_count; ++i) {
157     (void)FPDFAvail_IsPageAvail(avail_, i, &hints_);
158   }
159   return page_count;
160 }
161
162 FPDF_PAGE EmbedderTest::LoadPage(int page_number) {
163   FPDF_PAGE page = FPDF_LoadPage(document_, page_number);
164   if (!page) {
165     return nullptr;
166   }
167   FORM_OnAfterLoadPage(page, form_handle_);
168   FORM_DoPageAAction(page, form_handle_, FPDFPAGE_AACTION_OPEN);
169   return page;
170 }
171
172 FPDF_PAGE EmbedderTest::LoadAndCachePage(int page_number) {
173   FPDF_PAGE page = delegate_->GetPage(form_handle_, document_, page_number);
174   if (!page) {
175     return nullptr;
176   }
177   FORM_DoPageAAction(page, form_handle_, FPDFPAGE_AACTION_OPEN);
178   return page;
179 }
180
181 FPDF_BITMAP EmbedderTest::RenderPage(FPDF_PAGE page) {
182   int width = static_cast<int>(FPDF_GetPageWidth(page));
183   int height = static_cast<int>(FPDF_GetPageHeight(page));
184   FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0);
185   FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF);
186   FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0);
187   FPDF_FFLDraw(form_handle_, bitmap, page, 0, 0, width, height, 0, 0);
188   return bitmap;
189 }
190
191 void EmbedderTest::UnloadPage(FPDF_PAGE page) {
192   FORM_DoPageAAction(page, form_handle_, FPDFPAGE_AACTION_CLOSE);
193   FORM_OnBeforeClosePage(page, form_handle_);
194   FPDF_ClosePage(page);
195 }
196
197 FPDF_PAGE EmbedderTest::Delegate::GetPage(FPDF_FORMHANDLE form_handle,
198                                           FPDF_DOCUMENT document,
199                                           int page_index) {
200   auto it = m_pageMap.find(page_index);
201   if (it != m_pageMap.end()) {
202     return it->second;
203   }
204   FPDF_PAGE page = FPDF_LoadPage(document, page_index);
205   if (!page) {
206     return nullptr;
207   }
208   m_pageMap[page_index] = page;
209   FORM_OnAfterLoadPage(page, form_handle);
210   return page;
211 }
212
213 // static
214 void EmbedderTest::UnsupportedHandlerTrampoline(UNSUPPORT_INFO* info,
215                                                 int type) {
216   EmbedderTest* test = static_cast<EmbedderTest*>(info);
217   test->delegate_->UnsupportedHandler(type);
218 }
219
220 // static
221 int EmbedderTest::AlertTrampoline(IPDF_JSPLATFORM* platform,
222                                   FPDF_WIDESTRING message,
223                                   FPDF_WIDESTRING title,
224                                   int type,
225                                   int icon) {
226   EmbedderTest* test = static_cast<EmbedderTest*>(platform);
227   return test->delegate_->Alert(message, title, type, icon);
228 }
229
230 // static
231 int EmbedderTest::SetTimerTrampoline(FPDF_FORMFILLINFO* info,
232                                      int msecs,
233                                      TimerCallback fn) {
234   EmbedderTest* test = static_cast<EmbedderTest*>(info);
235   return test->delegate_->SetTimer(msecs, fn);
236 }
237
238 // static
239 void EmbedderTest::KillTimerTrampoline(FPDF_FORMFILLINFO* info, int id) {
240   EmbedderTest* test = static_cast<EmbedderTest*>(info);
241   return test->delegate_->KillTimer(id);
242 }
243
244 // static
245 FPDF_PAGE EmbedderTest::GetPageTrampoline(FPDF_FORMFILLINFO* info,
246                                           FPDF_DOCUMENT document,
247                                           int page_index) {
248   EmbedderTest* test = static_cast<EmbedderTest*>(info);
249   return test->delegate_->GetPage(test->form_handle(), document, page_index);
250 }
251
252 // Can't use gtest-provided main since we need to stash the path to the
253 // executable in order to find the external V8 binary data files.
254 int main(int argc, char** argv) {
255   g_exe_path_ = argv[0];
256   testing::InitGoogleTest(&argc, argv);
257   testing::InitGoogleMock(&argc, argv);
258   return RUN_ALL_TESTS();
259 }