First JavaScript testing implementation.
authorTom Sepez <tsepez@chromium.org>
Fri, 6 Feb 2015 23:58:40 +0000 (15:58 -0800)
committerTom Sepez <tsepez@chromium.org>
Fri, 6 Feb 2015 23:58:40 +0000 (15:58 -0800)
This is a plan for testing JS inside of pdf files under pdfium:

Communication of results will be done via app.alert(), rather than
console.println(), since the latter is not hooked up to any API
callbacks.

pdfium_test.cc is modified to be more careful about use of stdout/stderr,
so that only the app.alert() and the unsupported feature callback use
stdout.  Diffing stdout against ..._expected.txt files gives the result.

I added a /javascript directory to separate these from the embeddertest
resources.

The alert callback is backported from XFA.  This was an omission.

BUG=https://code.google.com/p/pdfium/issues/detail?id=62
R=jam@chromium.org, thestig@chromium.org

Review URL: https://codereview.chromium.org/872103003

samples/pdfium_test.cc
testing/resources/javascript/app_alert.in [new file with mode: 0644]
testing/resources/javascript/app_alert.pdf [new file with mode: 0644]
testing/resources/javascript/app_alert_expected.txt [new file with mode: 0644]

index 7ba85ef..20658fb 100644 (file)
@@ -199,9 +199,9 @@ void WriteEmf(FPDF_PAGE page, const char* pdf_name, int num) {
   snprintf(filename, sizeof(filename), "%s.%d.emf", pdf_name, num);
 
   HDC dc = CreateEnhMetaFileA(NULL, filename, NULL, NULL);
-  
-  HRGN rgn = CreateRectRgn(0, 0, width, height); 
-  SelectClipRgn(dc, rgn); 
+
+  HRGN rgn = CreateRectRgn(0, 0, width, height);
+  SelectClipRgn(dc, rgn);
   DeleteObject(rgn);
 
   SelectObject(dc, GetStockObject(NULL_PEN));
@@ -216,8 +216,21 @@ void WriteEmf(FPDF_PAGE page, const char* pdf_name, int num) {
 }
 #endif
 
-int Form_Alert(IPDF_JSPLATFORM*, FPDF_WIDESTRING, FPDF_WIDESTRING, int, int) {
-  printf("Form_Alert called.\n");
+int Form_Alert(IPDF_JSPLATFORM*, FPDF_WIDESTRING msg, FPDF_WIDESTRING,
+               int, int) {
+  // Deal with differences between UTF16LE and wchar_t on this platform.
+  size_t characters = 0;
+  while (msg[characters]) {
+    ++characters;
+  }
+  wchar_t* platform_string =
+      (wchar_t*)malloc((characters + 1) * sizeof(wchar_t));
+  for (size_t i = 0; i < characters + 1; ++i) {
+    unsigned char* ptr = (unsigned char*)&msg[i];
+    platform_string[i] = ptr[0] + 256 * ptr[1];
+  }
+  printf("Alert: %ls\n", platform_string);
+  free(platform_string);
   return 0;
 }
 
@@ -355,7 +368,7 @@ void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {
 
 void RenderPdf(const std::string& name, const char* pBuf, size_t len,
                const Options& options) {
-  printf("Rendering PDF file %s.\n", name.c_str());
+  fprintf(stderr, "Rendering PDF file %s.\n", name.c_str());
 
   IPDF_JSPLATFORM platform_callbacks;
   memset(&platform_callbacks, '\0', sizeof(platform_callbacks));
@@ -391,10 +404,10 @@ void RenderPdf(const std::string& name, const char* pBuf, size_t len,
   (void) FPDFAvail_IsDocAvail(pdf_avail, &hints);
 
   if (!FPDFAvail_IsLinearized(pdf_avail)) {
-    printf("Non-linearized path...\n");
+    fprintf(stderr, "Non-linearized path...\n");
     doc = FPDF_LoadCustomDocument(&file_access, NULL);
   } else {
-    printf("Linearized path...\n");
+    fprintf(stderr, "Linearized path...\n");
     doc = FPDFAvail_GetDocument(pdf_avail, NULL);
   }
 
@@ -477,23 +490,26 @@ void RenderPdf(const std::string& name, const char* pBuf, size_t len,
   FPDF_CloseDocument(doc);
   FPDFAvail_Destroy(pdf_avail);
 
-  printf("Loaded, parsed and rendered %" PRIuS " pages.\n", rendered_pages);
-  printf("Skipped %" PRIuS " bad pages.\n", bad_pages);
+  fprintf(stderr, "Rendered %" PRIuS " pages.\n", rendered_pages);
+  fprintf(stderr, "Skipped %" PRIuS " bad pages.\n", bad_pages);
 }
 
+static const char usage_string[] =
+    "Usage: pdfium_test [OPTION] [FILE]...\n"
+    "  --bin-dir=<path> - override path to v8 external data\n"
+    "  --scale=<number> - scale output size by number (e.g. 0.5)\n"
+#ifdef _WIN32
+    "  --bmp - write page images <pdf-name>.<page-number>.bmp\n"
+    "  --emf - write page meta files <pdf-name>.<page-number>.emf\n"
+#endif
+    "  --ppm - write page images <pdf-name>.<page-number>.ppm\n";
+
 int main(int argc, const char* argv[]) {
   std::vector<std::string> args(argv, argv + argc);
   Options options;
   std::list<std::string> files;
   if (!ParseCommandLine(args, &options, &files)) {
-    printf("Usage: pdfium_test [OPTION] [FILE]...\n");
-    printf("--bin-dir=<path> - override path to v8 external data\n");
-    printf("--scale=<number> - scale output size by number (e.g. 0.5)\n");
-    printf("--ppm - write page images <pdf-name>.<page-number>.ppm\n");
-#ifdef _WIN32
-    printf("--bmp - write page images <pdf-name>.<page-number>.bmp\n");
-    printf("--emf - write page meta files <pdf-name>.<page-number>.emf\n");
-#endif
+    fprintf(stderr, "%s", usage_string);
     return 1;
   }
 
diff --git a/testing/resources/javascript/app_alert.in b/testing/resources/javascript/app_alert.in
new file mode 100644 (file)
index 0000000..42f970a
--- /dev/null
@@ -0,0 +1,45 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 10 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [
+    3 0 R
+  ]
+>>
+endobj
+% Page number 0.
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /Contents [21 0 R]
+  /MediaBox [0 0 612 792]
+>>
+% OpenAction action
+{{object 10 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS 11 0 R
+>>
+endobj
+% JS program to exexute
+{{object 11 0}} <<
+>>
+stream
+app.alert("This test passes if alert() logs output under the test utiltiy.");
+endstream
+endobj
+{{xref}}
+trailer <<
+  /Root 1 0 R
+>>
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/app_alert.pdf b/testing/resources/javascript/app_alert.pdf
new file mode 100644 (file)
index 0000000..091992c
--- /dev/null
@@ -0,0 +1,60 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 10 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [
+    3 0 R
+  ]
+>>
+endobj
+% Page number 0.
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /Contents [21 0 R]
+  /MediaBox [0 0 612 792]
+>>
+% OpenAction action
+10 0 obj <<
+  /Type /Action
+  /S /JavaScript
+  /JS 11 0 R
+>>
+endobj
+% JS program to exexute
+11 0 obj <<
+>>
+stream
+app.alert("This test passes if alert() logs output under the test utiltiy.");
+endstream
+endobj
+xref
+0 12
+0000000000 65535 f 
+0000000015 00000 n 
+0000000089 00000 n 
+0000000177 00000 n 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000334 00000 n 
+0000000426 00000 n 
+trailer <<
+  /Root 1 0 R
+>>
+startxref
+543
+%%EOF
diff --git a/testing/resources/javascript/app_alert_expected.txt b/testing/resources/javascript/app_alert_expected.txt
new file mode 100644 (file)
index 0000000..ac46b62
--- /dev/null
@@ -0,0 +1 @@
+Alert: This test passes if alert() logs output under the test utiltiy.