summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD.gn1
-rw-r--r--core/src/fpdfapi/fpdf_page/fpdf_page_func_embeddertest.cpp4
-rw-r--r--core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp9
-rw-r--r--core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_unittest.cpp7
-rw-r--r--core/src/fpdfapi/fpdf_render/fpdf_render_pattern_embeddertest.cpp4
-rw-r--r--fpdfsdk/src/fpdf_dataavail_embeddertest.cpp6
-rw-r--r--fpdfsdk/src/fpdfdoc_embeddertest.cpp14
-rw-r--r--fpdfsdk/src/fpdfformfill_embeddertest.cpp16
-rw-r--r--fpdfsdk/src/fpdftext_embeddertest.cpp10
-rw-r--r--fpdfsdk/src/fpdfview_embeddertest.cpp22
-rw-r--r--pdfium.gyp1
-rw-r--r--testing/embedder_test.cpp10
-rw-r--r--testing/embedder_test.h2
-rw-r--r--testing/test_support.cpp8
-rw-r--r--testing/utils/path_service.cpp101
-rw-r--r--testing/utils/path_service.h37
16 files changed, 199 insertions, 53 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 57d9eaf69a..caec43d978 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -165,6 +165,7 @@ source_set("test_support") {
"testing/fx_string_testhelpers.h",
"testing/test_support.cpp",
"testing/test_support.h",
+ 'testing/utils/path_service.cpp',
]
deps = [
"//testing/gmock",
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_func_embeddertest.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_func_embeddertest.cpp
index af04b4aebb..2892036882 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_func_embeddertest.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_func_embeddertest.cpp
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "../../../testing/embedder_test.h"
+#include "testing/embedder_test.h"
#include "testing/gtest/include/gtest/gtest.h"
class FPDFPageFuncEmbeddertest : public EmbedderTest {};
@@ -11,7 +11,7 @@ TEST_F(FPDFPageFuncEmbeddertest, Bug_551460) {
// Should not crash under ASan.
// Tests that the number of inputs is not simply calculated from the domain
// and trusted. The number of inputs has to be 1.
- EXPECT_TRUE(OpenDocument("testing/resources/bug_551460.pdf"));
+ EXPECT_TRUE(OpenDocument("bug_551460.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
FPDF_BITMAP bitmap = RenderPage(page);
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp
index ed2863bcf3..8737566619 100644
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp
@@ -2,19 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "../../../testing/embedder_test.h"
+#include "testing/embedder_test.h"
#include "testing/gtest/include/gtest/gtest.h"
class FPDFParserEmbeddertest : public EmbedderTest {};
TEST_F(FPDFParserEmbeddertest, LoadError_454695) {
// Test trailer dictionary with $$ze instead of Size.
- EXPECT_FALSE(OpenDocument("testing/resources/bug_454695.pdf"));
+ // Verify that the defective pdf shouldn't be opened correctly.
+ EXPECT_FALSE(OpenDocument("bug_454695.pdf"));
}
TEST_F(FPDFParserEmbeddertest, Bug_481363) {
// Test colorspace object with malformed dictionary.
- EXPECT_TRUE(OpenDocument("testing/resources/bug_481363.pdf"));
+ EXPECT_TRUE(OpenDocument("bug_481363.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
UnloadPage(page);
@@ -22,7 +23,7 @@ TEST_F(FPDFParserEmbeddertest, Bug_481363) {
TEST_F(FPDFParserEmbeddertest, Bug_544880) {
// Test self referencing /Pages object.
- EXPECT_TRUE(OpenDocument("testing/resources/bug_544880.pdf"));
+ EXPECT_TRUE(OpenDocument("bug_544880.pdf"));
// Shouldn't crash. We don't check the return value here because we get the
// the count from the "/Count 1" in the testcase (at the time of writing)
// rather than the actual count (0).
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_unittest.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_unittest.cpp
index 73b46b52c2..b86c20e9da 100644
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_unittest.cpp
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_unittest.cpp
@@ -6,6 +6,7 @@
#include "../../../include/fpdfapi/fpdf_parser.h"
#include "../../../include/fxcrt/fx_stream.h"
+#include "testing/utils/path_service.h"
class CPDF_TestParser : public CPDF_Parser {
public:
@@ -193,8 +194,10 @@ TEST(fpdf_parser_parser, ReadHexString) {
TEST(fpdf_parser_parser, RebuildCrossRefCorrectly) {
CPDF_TestParser parser;
- ASSERT_TRUE(
- parser.InitTest("testing/resources/parser_rebuildxref_correct.pdf"));
+ std::string test_file;
+ ASSERT_TRUE(PathService::GetTestFilePath("parser_rebuildxref_correct.pdf",
+ &test_file));
+ ASSERT_TRUE(parser.InitTest(test_file.c_str())) << test_file;
ASSERT_TRUE(parser.RebuildCrossRef());
const FX_FILESIZE offsets[] = {0, 15, 61, 154, 296, 374, 450};
diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_pattern_embeddertest.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_pattern_embeddertest.cpp
index 30d7a416be..744c4e5ea9 100644
--- a/core/src/fpdfapi/fpdf_render/fpdf_render_pattern_embeddertest.cpp
+++ b/core/src/fpdfapi/fpdf_render/fpdf_render_pattern_embeddertest.cpp
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "../../../testing/embedder_test.h"
+#include "testing/embedder_test.h"
#include "testing/gtest/include/gtest/gtest.h"
class FPDFRenderPatternEmbeddertest : public EmbedderTest {};
TEST_F(FPDFRenderPatternEmbeddertest, LoadError_547706) {
// Test shading where object is a dictionary instead of a stream.
- EXPECT_TRUE(OpenDocument("testing/resources/bug_547706.pdf"));
+ EXPECT_TRUE(OpenDocument("bug_547706.pdf"));
FPDF_PAGE page = LoadPage(0);
RenderPage(page);
UnloadPage(page);
diff --git a/fpdfsdk/src/fpdf_dataavail_embeddertest.cpp b/fpdfsdk/src/fpdf_dataavail_embeddertest.cpp
index ee4c3e6104..222fdc4be2 100644
--- a/fpdfsdk/src/fpdf_dataavail_embeddertest.cpp
+++ b/fpdfsdk/src/fpdf_dataavail_embeddertest.cpp
@@ -2,21 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "../../testing/embedder_test.h"
#include "public/fpdf_doc.h"
#include "public/fpdfview.h"
+#include "testing/embedder_test.h"
#include "testing/gtest/include/gtest/gtest.h"
class FPDFDataAvailEmbeddertest : public EmbedderTest {};
TEST_F(FPDFDataAvailEmbeddertest, TrailerUnterminated) {
// Document must load without crashing but is too malformed to be available.
- EXPECT_FALSE(OpenDocument("testing/resources/trailer_unterminated.pdf"));
+ EXPECT_FALSE(OpenDocument("trailer_unterminated.pdf"));
EXPECT_FALSE(FPDFAvail_IsDocAvail(avail_, &hints_));
}
TEST_F(FPDFDataAvailEmbeddertest, TrailerAsHexstring) {
// Document must load without crashing but is too malformed to be available.
- EXPECT_FALSE(OpenDocument("testing/resources/trailer_as_hexstring.pdf"));
+ EXPECT_FALSE(OpenDocument("trailer_as_hexstring.pdf"));
EXPECT_FALSE(FPDFAvail_IsDocAvail(avail_, &hints_));
}
diff --git a/fpdfsdk/src/fpdfdoc_embeddertest.cpp b/fpdfsdk/src/fpdfdoc_embeddertest.cpp
index ca5cbebf01..6435704cb2 100644
--- a/fpdfsdk/src/fpdfdoc_embeddertest.cpp
+++ b/fpdfsdk/src/fpdfdoc_embeddertest.cpp
@@ -2,17 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "../../core/include/fxcrt/fx_string.h"
-#include "../../testing/embedder_test.h"
-#include "../../testing/fx_string_testhelpers.h"
+#include "core/include/fxcrt/fx_string.h"
#include "public/fpdf_doc.h"
#include "public/fpdfview.h"
+#include "testing/embedder_test.h"
+#include "testing/fx_string_testhelpers.h"
#include "testing/gtest/include/gtest/gtest.h"
class FPDFDocEmbeddertest : public EmbedderTest {};
TEST_F(FPDFDocEmbeddertest, DestGetPageIndex) {
- EXPECT_TRUE(OpenDocument("testing/resources/named_dests.pdf"));
+ EXPECT_TRUE(OpenDocument("named_dests.pdf"));
// NULL FPDF_DEST case.
EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), nullptr));
@@ -39,7 +39,7 @@ TEST_F(FPDFDocEmbeddertest, DestGetPageIndex) {
}
TEST_F(FPDFDocEmbeddertest, ActionGetFilePath) {
- EXPECT_TRUE(OpenDocument("testing/resources/launch_action.pdf"));
+ EXPECT_TRUE(OpenDocument("launch_action.pdf"));
FPDF_PAGE page = FPDF_LoadPage(document(), 0);
ASSERT_TRUE(page);
@@ -65,7 +65,7 @@ TEST_F(FPDFDocEmbeddertest, ActionGetFilePath) {
TEST_F(FPDFDocEmbeddertest, NoBookmarks) {
// Open a file with no bookmarks.
- EXPECT_TRUE(OpenDocument("testing/resources/named_dests.pdf"));
+ EXPECT_TRUE(OpenDocument("named_dests.pdf"));
// The non-existent top-level bookmark has no title.
unsigned short buf[128];
@@ -77,7 +77,7 @@ TEST_F(FPDFDocEmbeddertest, NoBookmarks) {
TEST_F(FPDFDocEmbeddertest, Bookmarks) {
// Open a file with two bookmarks.
- EXPECT_TRUE(OpenDocument("testing/resources/bookmarks.pdf"));
+ EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
// The existent top-level bookmark has no title.
unsigned short buf[128];
diff --git a/fpdfsdk/src/fpdfformfill_embeddertest.cpp b/fpdfsdk/src/fpdfformfill_embeddertest.cpp
index f6d444abed..aae6ea7f77 100644
--- a/fpdfsdk/src/fpdfformfill_embeddertest.cpp
+++ b/fpdfsdk/src/fpdfformfill_embeddertest.cpp
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "../../testing/embedder_test.h"
-#include "../../testing/embedder_test_mock_delegate.h"
-#include "../../testing/embedder_test_timer_handling_delegate.h"
#include "public/fpdf_formfill.h"
+#include "testing/embedder_test.h"
+#include "testing/embedder_test_mock_delegate.h"
+#include "testing/embedder_test_timer_handling_delegate.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -22,7 +22,7 @@ TEST_F(FPDFFormFillEmbeddertest, FirstTest) {
EXPECT_CALL(mock, KillTimer(_)).Times(0);
SetDelegate(&mock);
- EXPECT_TRUE(OpenDocument("testing/resources/hello_world.pdf"));
+ EXPECT_TRUE(OpenDocument("hello_world.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
UnloadPage(page);
@@ -32,7 +32,7 @@ TEST_F(FPDFFormFillEmbeddertest, BUG_487928) {
EmbedderTestTimerHandlingDelegate delegate;
SetDelegate(&delegate);
- EXPECT_TRUE(OpenDocument("testing/resources/bug_487928.pdf"));
+ EXPECT_TRUE(OpenDocument("bug_487928.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
DoOpenActions();
@@ -44,7 +44,7 @@ TEST_F(FPDFFormFillEmbeddertest, BUG_507316) {
EmbedderTestTimerHandlingDelegate delegate;
SetDelegate(&delegate);
- EXPECT_TRUE(OpenDocument("testing/resources/bug_507316.pdf"));
+ EXPECT_TRUE(OpenDocument("bug_507316.pdf"));
FPDF_PAGE page = LoadAndCachePage(2);
EXPECT_NE(nullptr, page);
DoOpenActions();
@@ -53,7 +53,7 @@ TEST_F(FPDFFormFillEmbeddertest, BUG_507316) {
}
TEST_F(FPDFFormFillEmbeddertest, BUG_514690) {
- EXPECT_TRUE(OpenDocument("testing/resources/hello_world.pdf"));
+ EXPECT_TRUE(OpenDocument("hello_world.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
@@ -68,7 +68,7 @@ TEST_F(FPDFFormFillEmbeddertest, BUG_551248) {
EmbedderTestTimerHandlingDelegate delegate;
SetDelegate(&delegate);
- EXPECT_TRUE(OpenDocument("testing/resources/bug_551248.pdf"));
+ EXPECT_TRUE(OpenDocument("bug_551248.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
DoOpenActions();
diff --git a/fpdfsdk/src/fpdftext_embeddertest.cpp b/fpdfsdk/src/fpdftext_embeddertest.cpp
index 52cec7028a..6c1ae4ceb8 100644
--- a/fpdfsdk/src/fpdftext_embeddertest.cpp
+++ b/fpdfsdk/src/fpdftext_embeddertest.cpp
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "../../testing/embedder_test.h"
#include "public/fpdf_text.h"
#include "public/fpdfview.h"
+#include "testing/embedder_test.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -28,7 +28,7 @@ static bool check_unsigned_shorts(const char* expected,
class FPDFTextEmbeddertest : public EmbedderTest {};
TEST_F(FPDFTextEmbeddertest, Text) {
- EXPECT_TRUE(OpenDocument("testing/resources/hello_world.pdf"));
+ EXPECT_TRUE(OpenDocument("hello_world.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
@@ -136,7 +136,7 @@ TEST_F(FPDFTextEmbeddertest, Text) {
}
TEST_F(FPDFTextEmbeddertest, TextSearch) {
- EXPECT_TRUE(OpenDocument("testing/resources/hello_world.pdf"));
+ EXPECT_TRUE(OpenDocument("hello_world.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
@@ -243,7 +243,7 @@ TEST_F(FPDFTextEmbeddertest, TextSearch) {
// Test that the page has characters despite a bad stream length.
TEST_F(FPDFTextEmbeddertest, StreamLengthPastEndOfFile) {
- EXPECT_TRUE(OpenDocument("testing/resources/bug_57.pdf"));
+ EXPECT_TRUE(OpenDocument("bug_57.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
@@ -256,7 +256,7 @@ TEST_F(FPDFTextEmbeddertest, StreamLengthPastEndOfFile) {
}
TEST_F(FPDFTextEmbeddertest, WebLinks) {
- EXPECT_TRUE(OpenDocument("testing/resources/weblinks.pdf"));
+ EXPECT_TRUE(OpenDocument("weblinks.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
diff --git a/fpdfsdk/src/fpdfview_embeddertest.cpp b/fpdfsdk/src/fpdfview_embeddertest.cpp
index 2a00193a5e..35da9b6caf 100644
--- a/fpdfsdk/src/fpdfview_embeddertest.cpp
+++ b/fpdfsdk/src/fpdfview_embeddertest.cpp
@@ -5,9 +5,9 @@
#include <limits>
#include <string>
-#include "../../testing/embedder_test.h"
-#include "fpdfview_c_api_test.h"
+#include "fpdfsdk/src/fpdfview_c_api_test.h"
#include "public/fpdfview.h"
+#include "testing/embedder_test.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(fpdf, CApiTest) {
@@ -17,7 +17,7 @@ TEST(fpdf, CApiTest) {
class FPDFViewEmbeddertest : public EmbedderTest {};
TEST_F(FPDFViewEmbeddertest, Document) {
- EXPECT_TRUE(OpenDocument("testing/resources/about_blank.pdf"));
+ EXPECT_TRUE(OpenDocument("about_blank.pdf"));
EXPECT_EQ(1, GetPageCount());
EXPECT_EQ(0, GetFirstPageNum());
@@ -30,7 +30,7 @@ TEST_F(FPDFViewEmbeddertest, Document) {
}
TEST_F(FPDFViewEmbeddertest, Page) {
- EXPECT_TRUE(OpenDocument("testing/resources/about_blank.pdf"));
+ EXPECT_TRUE(OpenDocument("about_blank.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
EXPECT_EQ(612.0, FPDF_GetPageWidth(page));
@@ -40,14 +40,14 @@ TEST_F(FPDFViewEmbeddertest, Page) {
}
TEST_F(FPDFViewEmbeddertest, ViewerRef) {
- EXPECT_TRUE(OpenDocument("testing/resources/about_blank.pdf"));
+ EXPECT_TRUE(OpenDocument("about_blank.pdf"));
EXPECT_TRUE(FPDF_VIEWERREF_GetPrintScaling(document()));
EXPECT_EQ(1, FPDF_VIEWERREF_GetNumCopies(document()));
EXPECT_EQ(DuplexUndefined, FPDF_VIEWERREF_GetDuplex(document()));
}
TEST_F(FPDFViewEmbeddertest, NamedDests) {
- EXPECT_TRUE(OpenDocument("testing/resources/named_dests.pdf"));
+ EXPECT_TRUE(OpenDocument("named_dests.pdf"));
long buffer_size;
char fixed_buffer[512];
FPDF_DEST dest;
@@ -142,7 +142,7 @@ TEST_F(FPDFViewEmbeddertest, NamedDests) {
}
TEST_F(FPDFViewEmbeddertest, NamedDestsByName) {
- EXPECT_TRUE(OpenDocument("testing/resources/named_dests.pdf"));
+ EXPECT_TRUE(OpenDocument("named_dests.pdf"));
// Null pointer returns NULL.
FPDF_DEST dest = FPDF_GetNamedDestByName(document(), nullptr);
@@ -180,16 +180,16 @@ TEST_F(FPDFViewEmbeddertest, NamedDestsByName) {
// The following tests pass if the document opens without crashing.
TEST_F(FPDFViewEmbeddertest, Crasher_113) {
- EXPECT_TRUE(OpenDocument("testing/resources/bug_113.pdf"));
+ EXPECT_TRUE(OpenDocument("bug_113.pdf"));
}
TEST_F(FPDFViewEmbeddertest, Crasher_451830) {
// Document is damaged and can't be opened.
- EXPECT_FALSE(OpenDocument("testing/resources/bug_451830.pdf"));
+ EXPECT_FALSE(OpenDocument("bug_451830.pdf"));
}
TEST_F(FPDFViewEmbeddertest, Crasher_452455) {
- EXPECT_TRUE(OpenDocument("testing/resources/bug_452455.pdf"));
+ EXPECT_TRUE(OpenDocument("bug_452455.pdf"));
FPDF_PAGE page = LoadPage(0);
EXPECT_NE(nullptr, page);
UnloadPage(page);
@@ -197,5 +197,5 @@ TEST_F(FPDFViewEmbeddertest, Crasher_452455) {
TEST_F(FPDFViewEmbeddertest, Crasher_454695) {
// Document is damanged and can't be opened.
- EXPECT_FALSE(OpenDocument("testing/resources/bug_454695.pdf"));
+ EXPECT_FALSE(OpenDocument("bug_454695.pdf"));
}
diff --git a/pdfium.gyp b/pdfium.gyp
index df1b99c340..c12f0bb8ff 100644
--- a/pdfium.gyp
+++ b/pdfium.gyp
@@ -844,6 +844,7 @@
'testing/fx_string_testhelpers.h',
'testing/test_support.cpp',
'testing/test_support.h',
+ 'testing/utils/path_service.cpp',
],
'conditions': [
['pdf_enable_v8==1', {
diff --git a/testing/embedder_test.cpp b/testing/embedder_test.cpp
index ebd8c64b32..baaf016d9f 100644
--- a/testing/embedder_test.cpp
+++ b/testing/embedder_test.cpp
@@ -2,7 +2,7 @@
// 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/embedder_test.h"
#include <limits.h>
@@ -14,8 +14,9 @@
#include "public/fpdf_dataavail.h"
#include "public/fpdf_text.h"
#include "public/fpdfview.h"
-#include "test_support.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/test_support.h"
+#include "testing/utils/path_service.h"
#ifdef PDF_ENABLE_V8
#include "v8/include/v8.h"
@@ -97,7 +98,10 @@ void EmbedderTest::TearDown() {
}
bool EmbedderTest::OpenDocument(const std::string& filename) {
- file_contents_ = GetFileContents(filename.c_str(), &file_length_);
+ std::string file_path;
+ if (!PathService::GetTestFilePath(filename, &file_path))
+ return false;
+ file_contents_ = GetFileContents(file_path.c_str(), &file_length_);
if (!file_contents_)
return false;
diff --git a/testing/embedder_test.h b/testing/embedder_test.h
index 660acc386f..a5b5e33fae 100644
--- a/testing/embedder_test.h
+++ b/testing/embedder_test.h
@@ -80,6 +80,8 @@ class EmbedderTest : public ::testing::Test,
// Open the document specified by |filename|, and create its form fill
// environment, or return false on failure.
+ // The filename is relative to the test data directory where we store all the
+ // test files.
virtual bool OpenDocument(const std::string& filename);
// Perform JavaScript actions that are to run at document open time.
diff --git a/testing/test_support.cpp b/testing/test_support.cpp
index 8ecda30bce..f71f6f8b4f 100644
--- a/testing/test_support.cpp
+++ b/testing/test_support.cpp
@@ -2,16 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "test_support.h"
+#include "testing/test_support.h"
#include <stdio.h>
#include <string.h>
-#ifdef _WIN32
-#define PATH_SEPARATOR '\\'
-#else
-#define PATH_SEPARATOR '/'
-#endif
+#include "testing/utils/path_service.h"
#ifdef PDF_ENABLE_V8
#include "v8/include/libplatform/libplatform.h"
diff --git a/testing/utils/path_service.cpp b/testing/utils/path_service.cpp
new file mode 100644
index 0000000000..1501a2da68
--- /dev/null
+++ b/testing/utils/path_service.cpp
@@ -0,0 +1,101 @@
+// Copyright 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 "testing/utils/path_service.h"
+
+#ifdef _WIN32
+#include <Windows.h>
+#elif defined(__APPLE__)
+#include <mach-o/dyld.h>
+#else // Linux
+#include <linux/limits.h>
+#include <unistd.h>
+#endif // _WIN32
+
+#include "core/include/fxcrt/fx_system.h"
+
+// static
+bool PathService::EndsWithSeparator(const std::string& path) {
+ return path.size() > 1 && path[path.size() - 1] == PATH_SEPARATOR;
+}
+
+// static
+bool PathService::GetExecutableDir(std::string* path) {
+// Get the current executable file path.
+#ifdef _WIN32
+ char path_buffer[MAX_PATH];
+ path_buffer[0] = 0;
+
+ if (GetModuleFileNameA(NULL, path_buffer, MAX_PATH) == 0)
+ return false;
+ *path = std::string(path_buffer);
+#elif defined(__APPLE__)
+ FXSYS_assert(path);
+ unsigned int path_length = 0;
+ _NSGetExecutablePath(NULL, &path_length);
+ if (path_length == 0)
+ return false;
+
+ path->reserve(path_length);
+ path->resize(path_length - 1);
+ if (_NSGetExecutablePath(&((*path)[0]), &path_length))
+ return false;
+#else // Linux
+ static const char kProcSelfExe[] = "/proc/self/exe";
+ char buf[PATH_MAX];
+ ssize_t count = ::readlink(kProcSelfExe, buf, PATH_MAX);
+ if (count <= 0)
+ return false;
+
+ *path = std::string(buf, count);
+#endif // _WIN32
+
+ // Get the directory path.
+ std::size_t pos = path->size() - 1;
+ if (EndsWithSeparator(*path))
+ pos--;
+ std::size_t found = path->find_last_of(PATH_SEPARATOR, pos);
+ if (found == std::string::npos)
+ return false;
+ path->resize(found);
+ return true;
+}
+
+// static
+bool PathService::GetSourceDir(std::string* path) {
+ if (!GetExecutableDir(path))
+ return false;
+
+ if (!EndsWithSeparator(*path))
+ path->push_back(PATH_SEPARATOR);
+ path->append("..");
+ path->push_back(PATH_SEPARATOR);
+ path->append("..");
+ return true;
+}
+
+// static
+bool PathService::GetTestDataDir(std::string* path) {
+ if (!GetSourceDir(path))
+ return false;
+
+ if (!EndsWithSeparator(*path))
+ path->push_back(PATH_SEPARATOR);
+ path->append("testing");
+ path->push_back(PATH_SEPARATOR);
+ path->append("resources");
+ return true;
+}
+
+// static
+bool PathService::GetTestFilePath(const std::string& file_name,
+ std::string* path) {
+ if (!GetTestDataDir(path))
+ return false;
+
+ if (!EndsWithSeparator(*path))
+ path->push_back(PATH_SEPARATOR);
+ path->append(file_name);
+ return true;
+}
diff --git a/testing/utils/path_service.h b/testing/utils/path_service.h
new file mode 100644
index 0000000000..96fd69e889
--- /dev/null
+++ b/testing/utils/path_service.h
@@ -0,0 +1,37 @@
+// Copyright 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_UTILS_PATH_SERVICE_H_
+#define TESTING_UTILS_PATH_SERVICE_H_
+
+#include <string>
+
+#ifdef _WIN32
+#define PATH_SEPARATOR '\\'
+#else
+#define PATH_SEPARATOR '/'
+#endif
+
+// Get the various file directory and path information.
+class PathService {
+ public:
+ // Return true when the path ends with a path separator.
+ static bool EndsWithSeparator(const std::string& path);
+
+ // Retrieve the directory where executables run from.
+ static bool GetExecutableDir(std::string* path);
+
+ // Retrieve the root directory of the source tree.
+ // Assume executables always run from out/<Debug|Release>/, the source
+ // directory is two levels above the executable directory.
+ static bool GetSourceDir(std::string* path);
+
+ // Retrieve the test data directory where test files are stored.
+ // Currently, the test dir is under <source_dir>/testing/resources/.
+ static bool GetTestDataDir(std::string* path);
+
+ // Get the full path for a test file under the test data directory.
+ static bool GetTestFilePath(const std::string& file_name, std::string* path);
+};
+#endif // TESTING_UTILS_PATH_SERVICE_H_